UNPKG

mongoku

Version:

[![CI](https://github.com/huggingface/Mongoku/actions/workflows/ci.yml/badge.svg)](https://github.com/huggingface/Mongoku/actions/workflows/ci.yml)

50 lines (44 loc) 1.2 kB
import { tick } from "svelte"; /** * This action is used to create a portal for a given node. * * On the container: * <div use:createPortal></div> * * On the target: * <div use:portal></div> * * Or if you want to use a custom id: * <div use:createPortal="custom-id"></div> * <div use:portal="custom-id"></div> */ const portal_map = new Map<string, HTMLElement>(); export function createPortal(node: HTMLElement, id = "default") { const key = `$$portal.${id}`; if (portal_map.has(key)) { throw `duplicate portal key "${id}"`; } else { portal_map.set(key, node); } return { destroy: portal_map.delete.bind(portal_map, key) }; } function mount(node: HTMLElement, key: string) { if (!portal_map.has(key)) { throw `unknown portal ${key}`; } const host = portal_map.get(key)!; host.insertBefore(node, null); return () => host.contains(node) && host.removeChild(node); } export function portal(node: HTMLElement, id = "default") { let destroy: (() => void) | undefined; const key = `$$portal.${id}`; if (!portal_map.has(key)) { tick().then(() => { destroy = mount(node, key); }); } else { destroy = mount(node, key); } return { destroy: () => destroy?.() }; }