UNPKG

@selenite/commons

Version:

This typescript package provides a set of frequently used utilities, types and svelte actions for building projects with Typescript and Svelte.

111 lines (110 loc) 3.51 kB
export const modalButtonTypes = ['cancel', 'promptConfirm', 'close', 'submit']; export function isComponentModalSettings(modal) { return 'component' in modal; } export function isSnippetModalSettings(modal) { return 'snippet' in modal; } export function isPromptModalSettings(modal) { return 'prompt' in modal; } export function modalButtonTypeToButton(type) { switch (type) { case 'cancel': return { label: 'Cancel', onclick: () => modals.close() }; case 'close': return { label: 'Close', level: 'neutral', onclick: () => modals.close() }; case 'submit': return { label: 'Submit', level: 'primary', onclick: async () => { const contentContainer = Modal.instance.contentContainer; if (contentContainer) { const forms = contentContainer.querySelectorAll('form'); for (const form of forms) if (!form.reportValidity()) return; } const r = await Modal.instance.childComponent?.getResponse?.(); Modal.instance.lastModal?.response?.(r); modals.close(); } }; case 'promptConfirm': return { label: 'Confirm', level: 'primary', onclick: () => { Modal.instance.lastModal?.response?.(Modal.instance.promptInput?.value); modals.close(); } }; } } /** * Singleton that manages modals. * * The singleton can be accessed with `Modal.instance`. */ export class Modal { static #instance; static get instance() { if (!this.#instance) { this.#instance = new Modal(); } return this.#instance; } queue = $state([]); lastModal = $derived(this.queue.at(-1)); promptInput = $state(); contentContainer = $state(); childComponent = $state(); resolvedButtons = $derived(this.lastModal?.buttons === undefined ? undefined : this.lastModal.buttons.map((btn) => { if (typeof btn === 'string') { return modalButtonTypeToButton(btn); } if ('type' in btn) { return { ...modalButtonTypeToButton(btn.type), ...btn }; } if ('formId' in btn) { return { label: 'Submit', level: 'primary', onclick: () => { const form = document.getElementById(btn.formId); if (form) { form.requestSubmit(); } } }; } return btn; })); constructor() { } show(params) { console.debug('Show modal', params); if ('prompt' in params) { params.buttons = params.buttons || ['cancel', 'promptConfirm']; params.title = params.title || params.prompt; } this.queue.push(params); } close() { console.debug('Close modal'); this.queue.pop(); } } export const modals = Modal.instance;