diff --git a/src/lib/components/portal/Portal.svelte b/src/lib/components/portal/Portal.svelte index d75ccbf..c16a52e 100644 --- a/src/lib/components/portal/Portal.svelte +++ b/src/lib/components/portal/Portal.svelte @@ -2,6 +2,7 @@ import { usePortalGroupContext } from "./PortalGroup.svelte"; import { usePortalRoot } from "$lib/internal/ForcePortalRootContext.svelte"; import { portal } from "$lib/hooks/use-portal"; + import { tick } from "svelte"; let forceInRoot = usePortalRoot(); let groupTarget = usePortalGroupContext(); $: target = (() => { @@ -20,6 +21,15 @@ let root = document.createElement("div"); root.setAttribute("id", "headlessui-portal-root"); + // During initial render, the "portal" might be constructed before + // the root component has even attached, causing the portal to not work. + // This is a workaround for this issue--it can't guarantee the portal is + // **always** last, but it should catch the normal cases. + tick().then(() => { + if (root !== document.body.lastChild) { + document.body.appendChild(root); + } + }); return document.body.appendChild(root); })(); diff --git a/src/lib/components/portal/portal.test.ts b/src/lib/components/portal/portal.test.ts index 252228b..2a78929 100644 --- a/src/lib/components/portal/portal.test.ts +++ b/src/lib/components/portal/portal.test.ts @@ -334,26 +334,3 @@ it('should cleanup the Portal properly when Svelte would not detach it', async ( expect(getPortalRoot()).not.toBe(null) expect(getPortalRoot().childNodes).toHaveLength(1) }) - -it('should move the Portal last during initial render', async () => { - expect(getPortalRoot()).toBe(null) - - // We need to use a custom target because of the implementation of - // render() in the testing library - render(svelte` - - - - Portal - -
Main
- `) - - await tick(); - - expect(document.body.innerHTML).toMatchInlineSnapshot( - `"
Main
Portal
"` - ) -}) diff --git a/src/lib/hooks/use-portal.ts b/src/lib/hooks/use-portal.ts index 3669c92..bbda7e5 100644 --- a/src/lib/hooks/use-portal.ts +++ b/src/lib/hooks/use-portal.ts @@ -1,20 +1,9 @@ -import { tick } from "svelte"; - export function portal( element: HTMLElement, target: HTMLElement | null | undefined ) { if (target) { target.append(element); - // During initial render, the "portal" might be constructed before - // the root component has even attached, causing the portal to not work. - // This is a workaround for this issue--it can't guarantee the portal is - // **always** last, but it should catch the normal cases. - tick().then(() => { - if (target && element !== target.lastChild) { - target.appendChild(element); - } - }); } return { update(newTarget: HTMLElement) {