@melt-ui/svelte
Version:

114 lines (113 loc) • 4.08 kB
JavaScript
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,
};
}