Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

teleport should be reactive #5864

Open
telion2 opened this issue May 5, 2022 · 4 comments
Open

teleport should be reactive #5864

telion2 opened this issue May 5, 2022 · 4 comments
Labels
has workaround A workaround has been found to avoid the problem scope: teleport ✨ feature request New feature or request

Comments

@telion2
Copy link

telion2 commented May 5, 2022

What problem does this feature solve?

One of the main features of Vue is to control, what components are displayed.
Teleport however requires that an element is mounted before the teleport tag is mounted.
If for some reason the teleport target is removed but mounted again, the teleport does not work.

What I want is:
If teleport is enabled (:disable="false"), then look for the element to be teleported to.
return error or warning if not found.
teleport if found.

This feature would make teleport a lot more easy to use, because it fits better into an Vue environment where everything is reactive.

As for a use-case:
I currently want to teleport an input-field to a sidebar (https://www.primefaces.org/primevue/sidebar) that is displayed on small displays. The sidebar is displayed when I click on the inputfield. Even if I make sure that the teleport is enabled after (up to 10sec) the sidebar is displayed, the teleport fails silently.

What does the proposed API look like?

If teleport is enabled (:disable="false"), then look for the element to be teleported to.
return error or warning if not found.
teleport if found.

@posva posva added ✨ feature request New feature or request scope: teleport has workaround A workaround has been found to avoid the problem labels May 5, 2022
@posva
Copy link
Member

posva commented May 5, 2022

You should be able to use a key to force the recreation of the teleport

@telion2
Copy link
Author

telion2 commented May 5, 2022

It has a wierd workaround, that I found seconds before giving up:

    <Sidebar v-model:visible="showMobile" position="top">
      <div id="mobileTarget"></div>
    </Sidebar>
    <teleport
      v-if="ready"
      to="#mobileTarget"
      :disabled="disableTeleport"
    >
    ....
    @focus="switchToMobile"
    ....
</teleport>
 data() {
    return {
      showMobile: true,            //Initially the teleporttarget is present 
      ready: false,                     // Initially teleport is not created. 
      disableTeleport: true,       
    };
  },
mounted() {
    this.ready = true;                 //Delays the mount, therefore teleport will not throw an error, because teleporttarget is still present
    this.showMobile = false;     //removes teleporttarget, so its not displayed
  },
methods:{
allowTeleportToMobile(): boolean {
      return this.breakpoint === "xs" || this.breakpoint === "sm";
      },
 switchToMobile() {
      if (this.allowTeleportToMobile && !this.showMobile) {
        this.showMobile = true;              // first make the teleporttarget available 
        this.ready = false;                       // remove the teleport  
        setTimeout(() => {                      //wait a little (it doesn't work without setTimeout
          this.disableTeleport = false;     //enable the teleport 
          this.ready = true;                     // render it ==> now it teleports properly.
        }, 1);
      }
    },
}

But its a very verbose and ugly workaround if you ask me.
The teleport should check for the existence of the target, when activated. I would even propose that the target can be a vue component it self, but it would certainly help if that mounted requirement is gone.

Don't know what exactly you were proposing with the key. I only know it from lists (v-for), which isn't my current use-case.

@ScottAwesome
Copy link

ScottAwesome commented May 15, 2022

@telion2 the work around with key would be adding the :key attribute to the component (or teleport, not sure exactly which is most appropriate @posva). If you change the key, Vue will register that when diffing and that will force a re-render

Its not a feature that has to be exclusively used with v-for or iteration over data. It can be used in any situation.

@renatodeleao
Copy link

Have a very similar usecase — using portal-vue to make it work — but would be nice if Teleport supported these scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has workaround A workaround has been found to avoid the problem scope: teleport ✨ feature request New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants