romkor / svelte-portal

Svelte component for rendering outside the DOM of parent component
https://svelte.dev/repl/407576d4fa984cfb97dcdd3da98e833e
MIT License
444 stars 22 forks source link

use portal inside keyed_each block #101

Closed RyanYANG52 closed 2 years ago

RyanYANG52 commented 2 years ago

Nice portal!

One limitation I find is when use inside a keyed_each block (as tooltip or dropdown), parent will be change back to original parent by svelte.

https://github.com/sveltejs/svelte/blob/master/src/runtime/internal/keyed_each.ts#L46

demo: https://svelte.dev/repl/4023593f8d324c7587824b2da4f01f1d?version=3.44.2

one hack solution is add a MutationObserver to original parent, on mutation event change back to portal target again.

Another issue is portal node have to be wrapped by a container, svelte will try to change order by Node.insertBefore, but the node already change parent, this will result to DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

I don't think there is a fix for this "issue", maybe add some note in README, so folks can be aware of the potential limitation

patricknelson commented 6 months ago

@RyanYANG52 I wonder... In this particular demo, every single <p> tag inside the loop was portal'd. And, based on this use case, it appears that the goal is to ensure that the set of <p> tags are consistently relocated in the correct order reactively. I see that the demo does break since once you modify the options list that generates those tags, modifications accidentally leak out of the portal.

However, do you have a use case demonstrating the necessity to have the portal inside of that loop instead of relocated to a wrapper outside of the loop? e.g. https://svelte.dev/repl/e637747cd7674d739f14d8295fd1ede6?version=3.44.2

RyanYANG52 commented 6 months ago

I think I was creating a sortable list using SortableJS, and each item had some dropdown select using portal (menu is longer than item), keyed each is to avoid dom creation when reorder. In the end, I use floating-ui instead of portal

patricknelson commented 6 months ago

Ah, thanks for the explanation. I was exploring potential caveats and that one makes sense. Thankfully there was a better alternative for that particular use case.