npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

teleporte

v1.0.0-rc.3

Published

Like Vue‘s Teleport component, but different.

Downloads

367

Readme

teleporte

Like native Vue‘s built-in <Teleport> component, but different.

Why another vue teleport package

Was trying to refactor some project codebase from portal-vue to built-in Vue‘s <teleport> component and couldn't make it work with TransitionGroup. After a discussion on a Vue-related issue, I realized that it was a limitation due to its implementation.

I decided to keep portal-vue in the project, as I needed the extra features, but there were also some caveats with its implementation and I start to wonder how hard would be to implement a very minimalistic version of a teleport myself.

When should you use this package

This package is the middle-ground between simplicity and power:

  1. Try using built-in Vue‘s <teleport> first. No point in bringing a 3rd party lib into your app when you only need simple teleport capabilities, like sending modals/dropdowns to end of <body>.
  2. Use teleporte if you need good support for in-app dynamic transportation of content, with conditional/deferred rendering of both origin/target; when custom TransitionGroup is required at target level or when provide/inject is heavily used.
  3. Use portal-vue for everything else.

QuirksList

This is not a feature parity conversion, these are the quirks in the other Vue "teleport" implementations that motivated me to build this package in the first place.

| Quirks list | Vue's <teleport> | portal-vue | teleporte | |----------------------------------------------------------|--------------------|--------------|----------------------| | Works when target is mounted after teleport origin | x⁵ | ✔️ | ✔️ | | Teleported content can use provide/inject origin context | ✔️ | x | ✔️ | | Teleport Target can use <TransitionGroup> | x | ✔️¹ | ✔️¹ | | use of $parent | (TBD) | x | (TBD) | | vue-router view | (TBD) | x | x (will not support) | | use of $refs | ✔️ | ✔️² | ✔️³ | | SSR support | ✔️⁴ | ✔️⁴ | ✔️⁴ |

Footnotes
  1. Requires usage of target component #default slot bindings and loop over exposed vnodes directly into TransitionGroup default slot
  2. after nextTick (see caveats in docs)
  3. to assert the need for nextTick
  4. Yes with caveats (see SSR Section)
  5. Will be supported without workarounds in 3.5.x minor

Installation & basic usage.

# npm | yarn
pnpm install teleporte

[!WARNING] This package requires vue@^3.2.0 to be installed.

Then Import the components.

<sript setup>
import { TeleportOrigin, TeleportTarget } from 'teleporte'
</script>

<!-- Same API as portal-vue, in fact snippet is from their repo -->
<teleport-origin to="destination">
  <p>This slot content will be rendered wherever the
    <teleport-target> with name 'destination'
    is located.
  </p>
</teleporte>

<teleport-target name="destination">
  <!--
  This component can be located anywhere in your App
  (i.e. right before the </body> tag, good for overlays).
  The slot content of the above teleporte component will be rendered here.
  -->
</teleport-target>

Install as Vue plugin

import { TeleportPlugin } from 'teleporte'
import { createApp } from 'vue'

const app = createApp()
app.use(TeleportPlugin)
// exposes Teleporte and TeleportTarget as global components

Usage with TransitionGroup

<sript setup>
import { Teleporte, TeleporteTarget } from 'teleporte'
</script>

<teleport-origin to="destination">
  <p>This slot content will be rendered wherever the
    <teleport-target> with name 'destination'
    is located.
  </p>
</teleport-origin>

<teleport-target name="destination" #default="teleported">
  <transition-group>
    <component 
      v-for="teleport in teleported"
      :key="teleport.key"
      :is="teleport.component"
    />
  </transition-group>
</teleport-target>

SSR

cross-request-state-pollution

TL;DR we use a singleton pattern for storing teleports state so the module state is preserved on each request which would lead to content duplication. We prevent that within library code.

Hydration mismatches

Since the content will not render on server, you'll get a warning from Vue. The same caveat is present in the other "teleport" implementations so the workarounds are the same:

  1. defer <teleport-origin> mount with a ref at onMounted hook + v-if
  2. Your SSR framework (like nuxt) will probably provide a <client-only> component, so wrap inside it
  3. There are external <client-only> component implementations out there as well or you can roll your own.

See:

  • https://vuejs.org/guide/scaling-up/ssr#cross-request-state-pollution
  • https://vuejs.org/guide/scaling-up/ssr#teleports
  • https://portal-vue.linusb.org/guide/ssr.html

Contribute

See the guide at CONTRIBUTING.md

Goals

  1. To be deprecated if Vue‘s <teleport> adds fixes to the current quirks :)
    • [x] https://github.com/vuejs/core/issues/2015
    • [ ] https://github.com/vuejs/core/issues/4737
    • [ ] https://github.com/vuejs/core/issues/5836#issuecomment-2230343828
    • [ ] https://github.com/vuejs/core/issues/5864
  2. While that does not happen, this project aims to be a just minimalistic enhanced version of <teleport>:
    • bundle size to be kept below around ≈1.2KB gzip
    • No unnecessary features: it should do one thing and do it well, move content between target and origin without quirks.

Credits

  • portal-vue, the main inspiration for this package implementation
  • Vue‘s <teleport>
    quirks for the motivation to do it
  • To all maintainers from the packages in dependencies.

Footnotes

  • Teleporte is the Portuguese word for teleport. I found it curious how similar it was and in my mind the "e" suffix could also mean "enhanced": Teleport enhanced.
  • The original version started as a Vue playground, which I've then translated into this more generic package.