UNPKG

@agnos-ui/core

Version:

Framework-agnostic headless component library.

261 lines (260 loc) 11.2 kB
import type { ReadableSignal, StoreOptions, SubscribableStore, WritableSignal } from '@amadeus-it-group/tansu'; /** * A type that maps each property of an object type `T` to either a `ReadableSignal` of that property type or the property type itself. * * @template T - The object type whose properties are being mapped. */ export type ValuesOrReadableSignals<T extends object> = { [K in keyof T]?: ReadableSignal<T[K] | undefined> | T[K]; }; /** * A type that maps the properties of an object type `T` to either a `WritableSignal` of the property type or the property type itself. * * @template T - The object type whose properties are being mapped. */ export type ValuesOrWritableSignals<T extends object> = { [K in keyof T]?: WritableSignal<T[K] | undefined> | T[K]; }; /** * Interface representing the configuration for properties. * * @template U - An object type representing the properties. */ export interface PropsConfig<U extends object> { /** * Object containing, for each property, either its initial value, or a store that will contain the value at any time. * When the value of a property is undefined or invalid, the value from the config is used. */ props?: ValuesOrWritableSignals<U>; /** * Either a store of objects containing, for each property, the default value, * or an object containing, for each property, either a store containing the default value or the default value itself. */ config?: ReadableSignal<Partial<U>> | ValuesOrReadableSignals<Partial<U>>; } /** * Represents a generic widget with reactive state, stores, and various functionalities. * * @template Props - The type of the properties that can be passed to the widget. * @template State - The type of the state managed by the widget. * @template Api - The type of the API functions available for interacting with the widget. * @template Actions - The type of the action handlers for user interactions. * @template Directives - The type of the directives used in the widget's template. */ export interface Widget<Props extends object = object, State extends object = object, Api extends object = object, Directives extends object = object> { /** * the reactive state of the widget, combining all the values served by the stores */ state$: ReadableSignal<State>; /** * the different stores of the widget, all reactive */ stores: { [K in keyof State as `${K & string}$`]: ReadableSignal<State[K]>; }; /** * Modify the parameter values, and recalculate the stores accordingly */ patch(parameters: Partial<Props>): void; /** * directives to be used on html elements in the template of the widget or in the slots */ directives: Directives; /** * all the api functions to interact with the widget */ api: Api; } /** * Represents the context for a widget slot, providing access to the widget and its state. * * @template W - The type of the widget. * */ export interface WidgetSlotContext<W extends Widget> extends Pick<W, 'api' | 'directives'> { /** * the state of the widget */ state: WidgetState<W>; } /** * Extracts the state type from a widget type that contains a `state$` property. * * @template T - A type that extends an object with a `state$` property of type `SubscribableStore<any>`. * @returns The type of the state contained within the `state$` property if it extends an object, otherwise `never`. */ export type WidgetState<T extends { state$: SubscribableStore<any>; }> = T extends { state$: SubscribableStore<infer U extends object>; } ? U : never; /** * Extracts the type of the argument expected by the `patch` method of a given type `T`. * * This utility type takes a generic type `T` which must have a `patch` method. The `patch` method * should accept an argument that is a partial of some object type `U`. If `T` meets this condition, * `WidgetProps` will resolve to the type `U`. Otherwise, it will resolve to `never`. * * @template T - A type that includes a `patch` method accepting a partial object. */ export type WidgetProps<T extends { patch: (arg: any) => void; }> = T extends { patch: (arg: Partial<infer U extends object>) => void; } ? U : never; /** * A unique symbol representing a widget factory widget name. */ export declare const FACTORY_WIDGET_NAME: unique symbol; /** * A factory function type for creating instances of a widget. * * @template W - The type of the widget that extends the base Widget type. * @template T - The type of the factory function that creates the widget. Useful when the factory function has a generic * @param props - Optional configuration properties for the widget. * @returns An instance of the widget. */ export type WidgetFactory<W extends Widget, T extends (props?: PropsConfig<WidgetProps<W>>) => W = (props?: PropsConfig<WidgetProps<W>>) => W> = T & { [FACTORY_WIDGET_NAME]?: string; }; /** * Represents a server-side rendered HTML element with limited functionality. * * This interface extends a subset of the {@link HTMLElement} interface, providing * methods to set and remove attributes, manipulate the element's classes, and * partially manipulate the element's style. * * It inherits the {@link https://developer.mozilla.org/docs/Web/API/Element/setAttribute | setAttribute} and {@link https://developer.mozilla.org/docs/Web/API/Element/getAttribute | getAttribute} methods from the {@link HTMLElement} interface. * */ export interface SSRHTMLElement extends Pick<HTMLElement, 'setAttribute' | 'removeAttribute'> { /** * Object allowing to manipulate the classes of the element. */ classList: Pick<HTMLElement['classList'], 'add' | 'remove' | 'toggle'>; /** * Object allowing to manipulate the style of the element. */ style: Partial<Record<StyleKey, StyleValue>>; } /** * Represents a directive function that can be applied to an SSRHTMLElement. * * @template T - The type of the arguments passed to the directive. * @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement. * * @param node - The SSRHTMLElement to which the directive is applied. * @param args - The arguments passed to the directive. * * @returns An optional object that may contain: * - `update`: A function to update the directive with new arguments. * - `destroy`: A function to clean up when the directive is no longer needed. */ export type Directive<T = void, U extends SSRHTMLElement = SSRHTMLElement> = (node: U, args: T) => void | { update?: (args: T) => void; destroy?: () => void; }; /** * Represents a tuple containing a directive and its associated parameter. * * @template T - The type of the parameter associated with the directive. * @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement. */ export type DirectiveAndParam<T, U extends SSRHTMLElement = SSRHTMLElement> = [Directive<T, U>, T]; /** * Represents a mapping of directives and their optional parameters. * * @template T - An array type representing the parameters for the directives. * @template U - The type of the SSR HTML element, defaults to `SSRHTMLElement`. */ export type DirectivesAndOptParam<T extends any[], U extends SSRHTMLElement = SSRHTMLElement> = { [K in keyof T]: Directive<void, U> | DirectiveAndParam<T[K], U>; }; /** * Represents the content that can be used in a slot. * The content can be one of the following: * - `undefined` * - `null` * - A `string` * - A function that takes `props` of type `Props` and returns a `string` * * @template Props - The type of the props when the slot is a function */ export type SlotContent<Props extends object = object> = undefined | null | string | ((props: Props) => string); /** * A unique symbol representing an invalid value. * This can be used as a sentinel value to indicate that a variable or property * does not hold a valid value. */ export declare const INVALID_VALUE: unique symbol; /** * A type alias for a function that normalizes a value of type `T`. * The function takes a value of type `T` and returns either a normalized value of type `T` * or a special constant `INVALID_VALUE` indicating that the value is invalid. * * @template T - The type of the value to be normalized. * @param value - The value to be normalized. * @returns The normalized value of type `T` or `INVALID_VALUE` if the value is invalid. */ export type NormalizeValue<T> = (value: T) => T | typeof INVALID_VALUE; /** * Interface representing options for a writable store with default values. * * @template T - The type of the value stored. */ export interface WritableWithDefaultOptions<T> { /** * the normalize value function. should return the {@link INVALID_VALUE} symbol when the provided value is invalid */ normalizeValue?: NormalizeValue<T>; /** * the equal function, allowing to compare two values. used to check if a previous and current values are equals. */ equal?: StoreOptions<T>['equal']; } /** * Represents a type that validates a configuration object. * * @template T - The type of the configuration object to be validated. * * This type maps each key of the configuration object `T` to an optional * `WritableWithDefaultOptions` type, allowing for partial validation. */ export type ConfigValidator<T extends object> = { [K in keyof T]: WritableWithDefaultOptions<T[K]> | undefined; }; /** * Represents a value that can be assigned to an attribute. */ export type AttributeValue = string | number | boolean | undefined; /** * Represents a key of the CSSStyleDeclaration interface, excluding certain properties and methods. * * This is useful for scenarios where you need to work with CSS properties directly without * dealing with the methods and other non-style properties of CSSStyleDeclaration. */ export type StyleKey = Exclude<keyof CSSStyleDeclaration, 'length' | 'item' | 'parentRule' | 'getPropertyValue' | 'getPropertyPriority' | 'setProperty' | 'removeProperty' | typeof Symbol.iterator | number | 'cssText'>; /** * Represents a value that can be used for styling purposes. * @remarks * This type can be a string representing a style value, or it can be undefined or null. * It is useful for scenarios where a style value might be optional or not set. */ export type StyleValue = string | undefined | null; /** * A conditional type that checks if type `T` extends type `U`. * @template T - The type to check. * @template U - The type to check against. * @returns `1` if `T` extends `U`, otherwise `0`. */ export type Extends<T, U> = T extends U ? 1 : 0; /** * Type utility to determine if a given type `T` is or extends `SlotContent<any>`. * * This utility uses conditional types to check if `T` extends `SlotContent<any>` or if `SlotContent<any>` extends `T`. * If either condition is true, it returns `T`, otherwise it returns `0`. * * @template T - The type to be checked. * @returns `T` if `T` is or extends `SlotContent<any>`, otherwise `0`. */ export type IsSlotContent<T> = Extends<T, SlotContent<any>> | Extends<SlotContent<any>, T> extends 1 ? T : 0;