UNPKG

melt

Version:

The next generation of Melt UI. Built for Svelte 5.

77 lines (76 loc) 2.87 kB
import { isFunction, isString } from "./is"; function isEventHandler(key) { return key.length > 2 && key.startsWith("on") && key.toLowerCase() === key; } /** * Composes event handlers into a single function that can be called with an event. * If the previous handler cancels the event using `event.preventDefault()`, the handlers * that follow will not be called. */ function composeHandlers(...handlers) { return function (e) { for (const handler of handlers) { handler.call(this, e); } }; } /** * Executes an array of callback functions with the same arguments. * @template T The types of the arguments that the callback functions take. * @param callbacks array of callback functions to execute. * @returns A new function that executes all of the original callback functions with the same arguments. */ export function executeCallbacks(...callbacks) { return (...args) => { for (const callback of callbacks) { if (typeof callback === "function") { callback(...args); } } }; } /** * Given a list of attribute objects, merges them into a single object. * - Automatically composes event handlers (e.g. `onclick`, `oninput`, etc.) * - Chains regular functions with the same name so they are called in order * - Handles a bug with Svelte where setting the `hidden` attribute to `false` doesn't remove it * - Merges style attributes * - Overrides other values with the last one */ export function mergeAttrs(...args) { const result = { ...args[0] }; for (let i = 1; i < args.length; i++) { const props = args[i]; for (const key in props) { const a = result[key]; const b = key in props ? props[key] : undefined; // compose event handlers if (isFunction(a) && isFunction(b) && isEventHandler(key)) { // handle merging of event handlers const aHandler = a; const bHandler = b; result[key] = composeHandlers(aHandler, bHandler); } else if (isFunction(a) && isFunction(b)) { // chain non-event handler functions result[key] = executeCallbacks(a, b); } else if (isString(a) && isString(b) && key === "style") { result[key] = [a, b].join(";"); } else { // override other values result[key] = b !== undefined ? b : a; } } } // handle weird svelte bug where `hidden` is not removed when set to `false` if (result.hidden !== true) { delete result.hidden; } // handle weird svelte bug where `disabled` is not removed when set to `false` if (result.disabled !== true) { delete result.disabled; } return result; }