@agnos-ui/core
Version:
Framework-agnostic headless component library.
298 lines (297 loc) • 15.6 kB
TypeScript
import type { ReadableSignal } from '@amadeus-it-group/tansu';
import type { AttributeValue, Directive, DirectivesAndOptParam, SSRHTMLElement, StyleKey, StyleValue } from '../types';
import { type ClassValue } from 'clsx';
/**
* On a browser environment, returns true if the given element is an HTMLElement.
* On a server environment, always returns false.
* @param element - The element to check.
* @returns true in a browser environment if the given element is an HTMLElement, otherwise false.
*/
export declare const isBrowserHTMLElement: (element: SSRHTMLElement) => element is HTMLElement;
/**
* A higher-order directive function that conditionally applies a directive based on the environment.
* If running in a browser environment, it applies the given directive to the node.
* If not in a browser environment, it returns a no-op function.
*
* @template T - The type of the directive's argument.
* @template U - The type of the HTML element the directive is applied to.
* @param directive - The directive to be conditionally applied.
* @returns - A directive that applies the given directive in a browser environment, or a no-op in a non-browser environment.
*/
export declare const browserDirective: <T, U extends HTMLElement>(directive: Directive<T, U>) => Directive<T, SSRHTMLElement>;
/**
* Binds the given directive to a store that provides its argument.
*
* @remarks
*
* The returned directive can be used without argument, it will ignore any argument passed to it
* and will call the provided directive with the content of the provided store as its argument,
* calling its update method when the content of the store changes.
*
* @template T - The type of the directive argument.
* @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement.
* @param directive - The directive to bind to the element.
* @param directiveArg$ - The signal to subscribe to for directive updates.
* @returns A directive that manages the lifecycle of the bound directive.
*/
export declare const bindDirective: <T, U extends SSRHTMLElement = SSRHTMLElement>(directive: Directive<T, U>, directiveArg$: ReadableSignal<T>) => Directive<void, U>;
/**
* Returns a directive that ignores any argument passed to it and calls the provided directive without any
* argument.
*
* @template T - The type of the directive's argument.
* @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement.
* @param directive - The directive to bind without arguments.
* @returns A new directive that does not require any arguments.
*/
export declare const bindDirectiveNoArg: <T, U extends SSRHTMLElement = SSRHTMLElement>(directive: Directive<T, U>) => Directive<void, U>;
/**
* Maps the argument of a directive to a new value using a provided function.
*
* @template T - The type of the original argument.
* @template U - The type of the mapped argument.
* @template V - The type of the SSRHTMLElement, defaults to SSRHTMLElement.
*
* @param directive - The original directive to be mapped.
* @param fn - The function to map the original argument to the new argument.
* @returns A new directive with the mapped argument.
*/
export declare const mapDirectiveArg: <T, U, V extends SSRHTMLElement = SSRHTMLElement>(directive: Directive<U, V>, fn: (arg: T) => U) => Directive<T, V>;
/**
* Returns a directive that subscribes to the given store while it is used on a DOM element,
* and that unsubscribes from it when it is no longer used.
*
* @param store - store on which there will be an active subscription while the returned directive is used.
* @param asyncUnsubscribe - true if unsubscribing from the store should be done asynchronously (which is the default), and
* false if it should be done synchronously when the directive is destroyed
* @returns The resulting directive.
*/
export declare const directiveSubscribe: (store: ReadableSignal<any>, asyncUnsubscribe?: boolean) => Directive;
/**
* Returns a directive that calls the provided function with the arguments passed to the directive
* on initialization and each time they are updated.
*
* @template T - The type of the argument that the update function accepts.
* @param update - Function called with the directive argument when the directive is initialized and when its argument is updated.
* @returns The resulting directive.
*/
export declare const directiveUpdate: <T>(update: (arg: T) => void) => Directive<T>;
/**
* Creates a registration array that allows elements to be added and removed.
*
* @template T - The type of elements in the array.
* @returns An object that includes a readable signal of the array and a register function.
*
* The returned object has the following properties:
* - `register`: A function to add an element to the array. It takes an element of type `T` as a parameter and returns a function to remove the element from the array.
*/
export declare const registrationArray: <T>() => ReadableSignal<T[]> & {
register: (element: T) => () => void;
};
/**
* Returns a directive and a store. The store contains at any time the array of all the DOM elements on which the directive is
* currently used.
*
* @remarks
* It is the same as {@link createBrowserStoreArrayDirective}, but the returned directive is also executed in a server environment
* and the type of the elements is {@link SSRHTMLElement} instead of HTMLElement.
*
* If the directive is intended to be used on a single element element, it may be more appropriate to use
* {@link createStoreDirective} instead.
*
* @returns An object with two properties: the `directive` property that is the directive to use on some DOM elements,
* and the `elements$` property that is the store containing an array of all the elements on which the directive is currently
* used.
*/
export declare const createStoreArrayDirective: () => {
directive: Directive;
elements$: ReadableSignal<SSRHTMLElement[]>;
};
/**
* Returns a directive and a store. The store contains at any time the array of all the DOM elements on which the directive is
* currently used.
*
* @remarks
* It is the same as {@link createStoreArrayDirective}, but the returned directive is only executed in a browser environment
* and the type of the elements is HTMLElement instead of {@link SSRHTMLElement}.
*
* If the directive is intended to be used on a single element element, it may be more appropriate to use
* {@link createBrowserStoreDirective} instead.
*
* @returns An object with two properties: the `directive` property that is the directive to use on some DOM elements,
* and the `elements$` property that is the store containing an array of all the elements on which the directive is currently
* used.
*/
export declare const createBrowserStoreArrayDirective: () => {
directive: Directive<void, SSRHTMLElement>;
elements$: ReadableSignal<HTMLElement[]>;
};
/**
* Returns a directive and a store. When the directive is used on a DOM element, the store contains that DOM element.
* When the directive is not used, the store contains null.
*
* @remarks
* It is the same as {@link createBrowserStoreDirective}, but the returned directive is also executed in a server environment
* and the type of the element is {@link SSRHTMLElement} instead of HTMLElement.
*
* If the directive is used on more than one element, an error is displayed in the console and the element is ignored.
* If the directive is intended to be used on more than one element, please use {@link createStoreArrayDirective} instead.
*
* @returns An object with two properties: the `directive` property that is the directive to use on one DOM element,
* and the `element$` property that is the store containing the element on which the directive is currently used (or null
* if the store is not currently used).
*/
export declare const createStoreDirective: () => {
directive: Directive;
element$: ReadableSignal<SSRHTMLElement | null>;
};
/**
* Returns a directive and a store. When the directive is used on a DOM element, the store contains that DOM element.
* When the directive is not used, the store contains null.
*
* @remarks
* It is the same as {@link createStoreDirective}, but the returned directive is only executed in a browser environment
* and the type of the element is HTMLElement instead of {@link SSRHTMLElement}.
*
* If the directive is used on more than one element, an error is displayed in the console and the element is ignored.
* If the directive is intended to be used on more than one element, please use {@link createStoreArrayDirective} instead.
*
* @returns An object with two properties: the `directive` property that is the directive to use on one DOM element,
* and the `element$` property that is the store containing the element on which the directive is currently used (or null
* if the store is not currently used).
*/
export declare const createBrowserStoreDirective: () => {
directive: Directive<void, SSRHTMLElement>;
element$: ReadableSignal<HTMLElement | null>;
};
/**
* Merges multiple directives into a single directive that executes all of them when called.
*
* @remarks
* All directives receive the same argument upon initialization and update.
* Directives are created and updated in the same order as they appear in the arguments list,
* they are destroyed in the reverse order.
* All calls to the directives (to create, update and destroy them) are wrapped in a call to the
* batch function of tansu
*
* @template T - The type of the argument passed to the directive.
* @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement.
* @param args - The directives to merge.
* @returns A new directive that applies all the given directives.
*
* The returned directive has the following lifecycle methods:
* - `update(arg)`: Updates all merged directives with the given argument.
* - `destroy()`: Destroys all merged directives in reverse order.
*/
export declare const mergeDirectives: <T, U extends SSRHTMLElement = SSRHTMLElement>(...args: (Directive<T, U> | Directive<void, U>)[]) => Directive<T, U>;
/**
* Applies multiple directives to a given SSRHTMLElement and provides methods to update or destroy them.
*
* @template T - A tuple type representing the arguments for each directive.
* @template U - The type of the SSRHTMLElement, defaults to SSRHTMLElement.
*
* @param element - The SSRHTMLElement to which the directives will be applied.
* @param directives - An array of directives and their optional parameters.
*
* @returns An object containing:
* - `update`: A function to update the directives with new parameters.
* - `destroy`: A function to destroy all applied directives.
*/
export declare const multiDirective: <T extends any[], U extends SSRHTMLElement = SSRHTMLElement>(element: U, directives: DirectivesAndOptParam<T, U>) => {
update: (directives: DirectivesAndOptParam<any[], U>) => void;
destroy: () => void;
};
/**
* Properties for configuring server-side rendering directives.
*/
export interface AttributesDirectiveProps {
/**
* Events to be attached to an HTML element.
* @remarks
* Key-value pairs where keys are event types and values are event handlers.
xw
*/
events?: Partial<{
[K in keyof HTMLElementEventMap]: {
handler: (this: HTMLElement, event: HTMLElementEventMap[K]) => void;
options?: boolean | AddEventListenerOptions;
} | ((this: HTMLElement, event: HTMLElementEventMap[K]) => void);
}>;
/**
* Attributes to be added to the provided node.
* @remarks
* The `style` attribute must be added separately.
*/
attributes?: Record<string, ReadableSignal<AttributeValue>>;
/**
* Styles to be added to an HTML element.
* @remarks
* Key-value pairs where keys are CSS style properties and values are style values.
*/
styles?: Partial<Record<StyleKey, ReadableSignal<StyleValue>>>;
/**
* Class names to be added to an HTML element.
* @remarks
* Key-value pairs where keys are class names and values indicate whether the class should be added (true) or removed (false).
*/
classNames?: Record<string, ReadableSignal<boolean>>;
}
/**
* Creates a directive that binds attributes, styles, class names, and events to a DOM node.
*
* @template T - The type of the arguments passed to the directive.
* @param propsFn - A function that takes a readable signal of type `T` and returns an object containing
* attributes, styles, class names, and events to bind to the node.
* @returns A directive function that can be used to bind the specified properties to a DOM node.
*
* The returned directive function takes a DOM node and arguments of type `T`, and sets up the bindings
* specified by the `propsFn` function. It returns an object with `update` and `destroy` methods:
* - `update(args: T)`: Updates the arguments passed to the directive.
* - `destroy()`: Cleans up all bindings and event listeners.
*/
export declare const createAttributesDirective: <T = void>(propsFn: (arg: ReadableSignal<T>) => AttributesDirectiveProps) => Directive<T>;
/**
* Returns an object with the attributes, style and class keys containing information derived from a list of directives.
*
* - The `attributes` value is a JSON representation of key/value attributes, excepted for the `class` and `style` attributes
* - The `classNames` value is an array of string representing the classes to be applied
* - The `style` value is a JSON representation of the styles to be applied
*
* @template T - The type of the directives array.
* @param directives - List of directives to generate attributes from. Each parameter can be the directive or an array with the directive and its parameter
* @returns JSON object with the `attributes`, `class` and `style` keys.
*/
export declare const attributesData: <T extends any[]>(...directives: DirectivesAndOptParam<T>) => {
attributes: Record<string, string>;
classNames: string[];
style: Partial<Record<StyleKey, StyleValue>>;
};
/**
* Directive that takes as an argument a string, array or object containing CSS classes to be put on the HTML element.
* The class attribute is computed using the clsx library.
*/
export declare const classDirective: Directive<ClassValue>;
/**
* Combines multiple directives into a single attributes object.
*
* This function processes an array of directives and optional parameters,
* extracting attributes, class names, and styles. It then combines these
* into a single attributes object, where class names are joined into a
* single string and styles are formatted as a CSS string.
*
* @template T - The type of the directives and optional parameters.
* @param directives - The directives and optional parameters to process.
* @returns An object containing the combined attributes.
*/
export declare function directiveAttributes<T extends any[]>(...directives: DirectivesAndOptParam<T>): Record<string, string>;
/**
* Generates a record of SSR (Server-Side Rendering) attributes based on the provided directives.
*
* This function behaves differently depending on the environment:
* - In a browser environment (`BROWSER` is true), it returns an empty object.
* - In a non-browser environment, it delegates to the `directiveAttributes` function.
*
* @template T - A tuple type representing the directives and optional parameters.
* @returns A record of SSR attributes.
*/
export declare const ssrAttributes: <T extends any[]>(...directives: DirectivesAndOptParam<T>) => Record<string, string>;