-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Wrapping element breaks "portals" #4036
Comments
For completeness I would like to point out that there is another pattern that can be used for portals. Initializing the component manually. Though I'm not sure how to pass slot content. https://svelte.dev/repl/3c73b9f9510b4ec383a9399046ab5858?version=3.16.0 Neither of these solutions are elegant and are really a hack. I would love to see a language feature to handle portals. |
If you include the onDestroy from the link it will work properly with the div.
https://svelte.dev/repl/331b576a6bfc4a3fb06bb791ae82a61e?version=3.16.0 This has to do with the if statement destroying the element directly when it becomes false. In reality though, you don't want the div around the portal as it doesn't make any sense (the portal is being pulled out of the dom tree and placed on the body). What this means is with your This gets you the same result without the breaking issue. However, somewhat related wrapping something with an if seems to fire onDestroy after the element is removed from the dom. |
I would like to propose a new svelte component to handle portals.
|
The primary issue with that - and with other related proposals that are very much tied to the DOM - is what to do in SSR. Just ignore it? |
My gut feeling is, that 99% of portals are used for modals, popovers and similar overlaid elements in reaction to user events. For all our use cases, ignoring them in SSR would be the desired behavior. |
I think it would make more sense to add a target attribute to the existing svelte:component e.g.
I agree with @arggh though, in SSR it should be ignored. However needing to understand that would add unnecessary cognitive load (consider someone who expects it to be rendered SSR and cant figure out why it doesn't). That alone seems to go against most svelte design philosophy. Perhaps a more fitting solution is to just allow components placed inside of |
I just want to add to this issue, that when making portals using the DOM API as seen here: Note that I can't demonstrate that using a REPL, because in a REPL sandbox the binding to dimensions don't work.
|
Just dropping by to mention that all of the Svelte portal workarounds/hacks are very brittle and break easily and we won't have proper portals in Svelte until they are added as first-class citizens to the framework itself. I think this issue is a subset of this one #1133 and we should be working to provide this API in Svelte: #1133 (comment) |
https://github.com/romkor/svelte-portal does a very good job of providing portals to svelte. |
Here's a surprisingly simple solution using just actions <div use:createPortal="portal-key" /> <div use:portal="portal-key"> Hello from Component ! </div> |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Closing in favor of #7082 |
Describe the bug
Wrapping a "portal" component in a div breaks the app, making the portal and it's contents permanent citizens of the DOM.
This also leads to duplicated content on each cycle of tries to show/hide the portal.
To Reproduce
https://svelte.dev/repl/7da6fc9ebae64ff6b2011417f37588cb?version=3.16.0
Remove the wrapping (commented in code) div to fix the demo.
Expected behavior
When I click "Teleport" the second time, I'd expect the content inside Portal to be removed from DOM.
Severity
💯 - a simple
{#if}
in template doesn't do what it's expected to.Additional context
Portals are undocumented and left to be solved in user-land, but the code in my REPL has been suggested as the way to handle this scenario since Svelte V2.
Also, adding the
onDestroy
hook to the Portal component like suggested in #1849 ......seems to "fix" the issue. However, if there is no wrapping
div
around thePortal
, the element and it's children get removed from the DOM by Svelte without the need for aonDestroy
hook to do it manually.Additional suggestions
As this is a somewhat common thing in a modern web app, it might be valuable to
a. figure out the proper way to handle a Portal scenario
b. document it
c. make a test for it
The text was updated successfully, but these errors were encountered: