UNPKG

@melt-ui/svelte

Version:
114 lines (113 loc) 4.08 kB
import { derived } from 'svelte/store'; import { isBrowser, isHTMLElement, noop } from './index.js'; import { removeUndefined } from './object.js'; import { lightable } from './store/lightable.js'; /* @deprecated * We need to stop using `data-melt-id` and use normal ids for a11y compatibility. * Use the `id` and use `getElementById` */ export function getElementByMeltId(id, rootElement) { if (!isBrowser) return null; const el = (rootElement ?? document).querySelector(`[data-melt-id="${id}"]`); return isHTMLElement(el) ? el : null; } export function getElementById(id, rootElement) { if (!isBrowser) return null; const el = (rootElement ?? document).querySelector(`[id="${id}"]`); return isHTMLElement(el) ? el : null; } export const hiddenAction = (obj) => { return new Proxy(obj, { get(target, prop, receiver) { return Reflect.get(target, prop, receiver); }, ownKeys(target) { return Reflect.ownKeys(target).filter((key) => key !== 'action'); }, }); }; const isFunctionWithParams = (fn) => { return typeof fn === 'function'; }; export const emptyMeltElement = makeElement('empty'); export function makeElement(name, args) { const { stores, action, returned } = args ?? {}; const derivedStore = (() => { if (stores && returned) { // If stores are provided, create a derived store from them return derived(stores, (values) => { const result = returned(values); if (isFunctionWithParams(result)) { const fn = (...args) => { return hiddenAction(removeUndefined({ ...result(...args), [`data-melt-${name}`]: '', action: action ?? noop, })); }; fn.action = action ?? noop; return fn; } return hiddenAction(removeUndefined({ ...result, [`data-melt-${name}`]: '', action: action ?? noop, })); }); } else { // If stores are not provided, return a lightable store, for consistency const returnedFn = returned; const result = returnedFn?.(); if (isFunctionWithParams(result)) { const resultFn = (...args) => { return hiddenAction(removeUndefined({ ...result(...args), [`data-melt-${name}`]: '', action: action ?? noop, })); }; resultFn.action = action ?? noop; return lightable(resultFn); } return lightable(hiddenAction(removeUndefined({ ...result, [`data-melt-${name}`]: '', action: action ?? noop, }))); } })(); const actionFn = (action ?? (() => { /** noop */ })); actionFn.subscribe = derivedStore.subscribe; return actionFn; } export function makeElementArray(name, args) { const { stores, returned, action } = args; const { subscribe } = derived(stores, (values) => returned(values).map((value) => hiddenAction({ ...value, [`data-melt-${name}`]: '', action: action ?? noop, }))); const actionFn = (action ?? (() => { /** noop */ })); actionFn.subscribe = subscribe; return actionFn; } export function createElHelpers(prefix) { const name = (part) => (part ? `${prefix}-${part}` : prefix); const attribute = (part) => `data-melt-${prefix}${part ? `-${part}` : ''}`; const selector = (part) => `[data-melt-${prefix}${part ? `-${part}` : ''}]`; const getEl = (part) => document.querySelector(selector(part)); return { name, attribute, selector, getEl, }; }