svelte-standalone
Version:
Transform Svelte components in standalone scripts!
104 lines (103 loc) • 3.23 kB
JavaScript
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))
};
}