feat(portal): support portal

This commit is contained in:
Eric Liu 2025-04-13 13:48:44 -07:00
commit 1ddd9ba1a5
14 changed files with 240 additions and 2 deletions

53
src/Portal/Portal.svelte Normal file
View file

@ -0,0 +1,53 @@
<script context="module">
/** @type {HTMLDivElement | null} */
let portalContainer = null;
let instances = 0;
/**
* Creates or returns the shared portal container
* @returns {HTMLDivElement}
*/
function getPortalContainer() {
if (!portalContainer && typeof document !== "undefined") {
portalContainer = document.createElement("div");
portalContainer.setAttribute("data-portal", "");
document.body.appendChild(portalContainer);
}
return portalContainer;
}
</script>
<script>
import { onMount } from "svelte";
/** @type {null | HTMLDivElement} */
let portal = null;
onMount(() => {
instances++;
const container = getPortalContainer();
if (portal && container) {
container.appendChild(portal);
}
return () => {
instances--;
if (portal?.parentNode) {
portal.parentNode.removeChild(portal);
}
if (instances === 0 && portalContainer?.parentNode) {
portalContainer.parentNode.removeChild(portalContainer);
portalContainer = null;
}
};
});
</script>
<div bind:this={portal}>
<slot />
</div>