UNPKG

svelte-standalone

Version:

Transform Svelte components in standalone scripts!

104 lines (103 loc) 3.23 kB
import { mount, unmount } from 'svelte'; /** * Singleton component manager * @param component - Svelte component to manage * @param id - Global window property key * * @example * embed(Modal, 'authDialog'); * window.authDialog.start({ title: 'Login' }); * window.authDialog.stop(); */ export function embed(component, id) { let instance; window[id] = { start: (props) => { if (!instance) { instance = mount(component, { target: document.body, props }); } }, stop: (options) => { if (instance) { unmount(instance, options); instance = undefined; } } }; } /** * Multi-instance component factory * @param component - Component to instantiate * @param id - Window namespace key * * @example * embedMultiple(Toast, 'notifications'); * const toast = window.notifications.start({ message: 'Saved!' }, 'status-area'); * toast.stop(); */ export function embedMultiple(component, id) { window[id] = { start: (props, target) => { const instance = mount(component, { target: document.getElementById(target) ?? document.body, props }); return { stop: () => unmount(instance) }; } }; } /** * Auto-mount to elements by URL parameter target * @param component - Component to auto-install * @param targetId - Target css id to mount your Component - can be provided dynamically by adding a `target` at your widget search params. * * @example * // Load script with ?target=chart-container * autoEmbedWithTarget(DataChart, 'chart'); * window['chart-container'].stop(); */ export function autoEmbedWithTarget(component, targetId) { const target = new URLSearchParams(window.location.search).get('target') ?? targetId; const instance = mount(component, { target: document.getElementById(target) ?? document.body }); window[target] = { stop: () => unmount(instance) }; } /** * Full-page component auto-mounter * @param component - Component to render * @param id - Window property key * * @example * autoEmbedOnBody(Loader, 'pageLoader'); * window.pageLoader.stop(); */ export function autoEmbedOnBody(component, id) { const instance = mount(component, { target: document.body }); window[id] = { stop: () => unmount(instance) }; } /** * Batch mount by CSS class selector * @param component - Component to replicate * @param targetClass - Target css class to mount your Component - can be provided dynamically by adding a `target` at your widget search params. * * @example * autoEmbedMultiple(Tooltip, 'hint'); * window.hint.stop(); // Removes all tooltips */ export function autoEmbedMultiple(component, targetClass) { const target = new URLSearchParams(window.location.search).get('target') ?? targetClass; const e = Array.from(document.getElementsByClassName(target)).map((el) => mount(component, { target: el })); window[target] = { stop: (options) => e.forEach((instance) => unmount(instance, options)) }; }