diff --git a/src/lib/components/portal/portal.test.ts b/src/lib/components/portal/portal.test.ts
index 580d07a..9dc518a 100644
--- a/src/lib/components/portal/portal.test.ts
+++ b/src/lib/components/portal/portal.test.ts
@@ -290,3 +290,46 @@ it('should be possible to force the Portal into a specific element using PortalG
`"
B
I am in the portal root
"`
)
})
+
+it('should cleanup the Portal properly when Svelte would not detach it', async () => {
+ expect(getPortalRoot()).toBe(null)
+
+ render(svelte`
+
+
+
+ {#if render}
+
+
+
Contents 1 ...
+
+
+ {/if}
+
+ `)
+
+ let a = document.getElementById('a')
+
+ expect(getPortalRoot()).toBe(null)
+
+ // Let's render the first Portal
+ await click(a)
+
+ expect(getPortalRoot()).not.toBe(null)
+ expect(getPortalRoot().childNodes).toHaveLength(1)
+
+ // Let's remove the first portal
+ await click(a)
+
+ expect(getPortalRoot()).toBe(null)
+
+ // Let's render the first Portal again
+ await click(a)
+
+ expect(getPortalRoot()).not.toBe(null)
+ expect(getPortalRoot().childNodes).toHaveLength(1)
+})
diff --git a/src/lib/hooks/use-portal.ts b/src/lib/hooks/use-portal.ts
index ebc32aa..bbda7e5 100644
--- a/src/lib/hooks/use-portal.ts
+++ b/src/lib/hooks/use-portal.ts
@@ -11,6 +11,11 @@ export function portal(
newTarget.append(element);
},
destroy() {
+ // Need to detach ourselves--we can't rely on Svelte always detaching
+ // us since we moved in the component tree.
+ if (target?.contains(element)) {
+ target.removeChild(element);
+ }
if (target && target.childNodes.length <= 0) {
target.parentElement?.removeChild(target);
}