summaryrefslogtreecommitdiff
path: root/src/utils/portal.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/portal.ts')
-rw-r--r--src/utils/portal.ts34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/utils/portal.ts b/src/utils/portal.ts
new file mode 100644
index 0000000..0c61ed0
--- /dev/null
+++ b/src/utils/portal.ts
@@ -0,0 +1,34 @@
+/**
+ * Svelte action to move an element to a different part of the DOM (as specified by the `targetId`
+ * provided), effectively creating a "portal."
+ *
+ * @param {HTMLElement} node - The element to be moved (provided by Svelte's `use:action` syntax).
+ * @param {string} targetId - The ID of the target element where `node` should be moved.
+ * @returns {{ destroy(): void } | void} - An object with a `destroy` method to remove `node` from the target when unmounted.
+ *
+ * @example
+ * ```svelte
+ * <div use:portal={'target-container'}>
+ * This content will be moved to the element with ID "target-container".
+ * </div>
+ * ```
+ */
+export default function portal(node: HTMLElement, targetId: string) {
+ if (typeof document === 'undefined') {
+ return;
+ }
+
+ let targetElement: HTMLElement | null = document.getElementById(targetId);
+
+ if (!targetElement) {
+ return;
+ }
+
+ targetElement.appendChild(node);
+
+ return {
+ destroy() {
+ targetElement.removeChild(node);
+ },
+ };
+}