@grail-ui/svelte
Version:
[](https://www.npmjs.com/package/@grail-ui/svelte) [](https://bundlephobia.com/package/@grail-ui/svelte) [ • 1.73 kB
JavaScript
import { tick } from 'svelte';
import { writable } from 'svelte/store';
export const usePortal = (node, config) => {
async function move() {
const { target } = config;
let targetEl;
if (!target) {
targetEl = document.body;
}
else if (typeof target === 'string') {
targetEl = document.querySelector(target);
if (targetEl === null) {
await tick();
targetEl = document.querySelector(target);
}
if (targetEl === null) {
throw new Error(`No element found matching CSS selector: "${target}"`);
}
}
else if (target instanceof HTMLElement) {
targetEl = target;
}
else {
throw new TypeError(`Unknown portal target type: ${target === null ? 'null' : typeof target}. Allowed types: string (CSS selector) or HTMLElement.`);
}
targetEl.appendChild(node);
}
move();
return {
update(newConfig) {
config = { ...newConfig };
move();
},
destroy() {
node.remove();
},
};
};
export const createPortal = (config = {}) => {
const target = writable(config.target);
const _usePortal = (node, _config) => {
const action = usePortal(node, {});
const unsubscribe = target.subscribe(($target) => {
action.update({ ...config, target: $target, ..._config });
});
return {
...action,
destroy() {
unsubscribe();
action.destroy();
},
};
};
return {
target,
usePortal: _usePortal,
};
};