import type { IconComponentProps } from 'phosphor-svelte'; import type { Component } from 'svelte'; /** * IconDef is an object that represents an icon element from the phosphor library, alongside an optional set of typed properties. */ export type IconDef = { component: Component; props?: IconComponentProps; }; /** * Defines a set of default properties for icons used in the application. */ export const defaultIconProps: IconComponentProps = { size: '1.2rem', weight: 'bold' }; /** * MaybeGetter is a type that can either be a value of type T or a function that returns a value of type T. * This is useful for cases where you might want to pass a value directly or a function that computes the * value later, potentially taking advantage of reactivity. */ export type MaybeGetter = T | (() => T); /** * Generates a unique identifier string unless an identifier is provided. * If a prefix is provided, it will be prepended to the identifier. * The identifier is a combination of a random part and a timestamp. * * @param {string} [prefix] - Optional prefix to prepend to the identifier. * @param {string} [identifier] - Optional identifier to use instead of generating a new one. * @returns {string} - A unique identifier string. */ export const generateIdentifier = (prefix?: string, identifier?: string): string => { if (identifier) { return `${prefix ? prefix + '-' : ''}${identifier}`; } const randomPart = Math.random().toString(36).substring(2, 10); const timestampPart = Date.now().toString(36); return `${prefix ? prefix + '-' : ''}${randomPart}-${timestampPart}`; }; /** * Option type definition for a select option. Used in various components. */ export type Option = | { value: string; label?: string; } | string; /** getLabel returns the option label if it exists*/ export const getLabel = (option: Option): string => { if (typeof option === 'string') { return option; } else { return option.label ?? option.value; } }; /** getValue returns the option value */ export const getValue = (option: Option): string => { if (typeof option === 'string') { return option; } else { return option.value; } }; /** * targetMust returns the target of an event coerced to a particular type and * throws an error if the target does not exist or is not connected. * * @returns The target element coerced to a particular type. * @throws Will throw an error if the target is null or not connected to the DOM. */ export function targetMust(event: Event): T { const target = event.target as T | null; if (!target) { throw new Error('Event target is null'); } if (!target.isConnected) { throw new Error('Event target is not connected to the DOM'); } return target; }