Files
sui/src/lib/util.ts

90 lines
2.7 KiB
TypeScript

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 | (() => 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<T extends HTMLElement>(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;
}