UNPKG

reblend-typing

Version:
1,690 lines (1,666 loc) 136 kB
import * as CSS from "csstype"; import React from "react"; /** * Represents a generic event in the DOM. * * @export interface Event * @typedef {Event} */ export interface Event {} /** * Represents an event triggered by CSS animations. * * @export interface AnimationEvent * @typedef {AnimationEvent} * @extends {Event} */ export interface AnimationEvent extends Event {} /** * Represents an event triggered by interactions with the clipboard (e.g., cut, copy, paste). * * @export interface ClipboardEvent * @typedef {ClipboardEvent} * @extends {Event} */ export interface ClipboardEvent extends Event {} /** * Represents an event triggered by input composition (e.g., for non-Latin text). * * @export interface CompositionEvent * @typedef {CompositionEvent} * @extends {Event} */ export interface CompositionEvent extends Event {} /** * Represents an event related to drag-and-drop operations. * * @export interface DragEvent * @typedef {DragEvent} * @extends {Event} */ export interface DragEvent extends Event {} /** * Represents an event triggered when an element gains or loses focus. * * @export interface FocusEvent * @typedef {FocusEvent} * @extends {Event} */ export interface FocusEvent extends Event {} /** * Represents an event triggered by keyboard input. * * @export interface KeyboardEvent * @typedef {KeyboardEvent} * @extends {Event} */ export interface KeyboardEvent extends Event {} /** * Represents an event triggered by mouse interactions. * * @export interface MouseEvent * @typedef {MouseEvent} * @extends {Event} */ export interface MouseEvent extends Event {} /** * Represents an event triggered by touch interactions on touch devices. * * @export interface TouchEvent * @typedef {TouchEvent} * @extends {Event} */ export interface TouchEvent extends Event {} /** * Represents an event triggered by pointer device interactions (e.g., mouse, pen, touch). * * @export interface PointerEvent * @typedef {PointerEvent} * @extends {Event} */ export interface PointerEvent extends Event {} /** * Represents an event triggered by CSS transitions. * * @export interface TransitionEvent * @typedef {TransitionEvent} * @extends {Event} */ export interface TransitionEvent extends Event {} /** * Represents a user export interface event in the DOM. * * @export interface UIEvent * @typedef {UIEvent} * @extends {Event} */ export interface UIEvent extends Event {} /** * Represents an event triggered by the scrolling of a mouse wheel or similar device. * * @export interface WheelEvent * @typedef {WheelEvent} * @extends {Event} */ export interface WheelEvent extends Event {} /** * Represents a DOM object that can receive events. * * @export interface EventTarget * @typedef {EventTarget} */ export interface EventTarget {} /** * Represents the HTML document in the DOM. * * @export interface Document * @typedef {Document} */ export interface Document {} /** * Represents the data transferred during a drag-and-drop operation. * * @export interface DataTransfer * @typedef {DataTransfer} */ export interface DataTransfer {} /** * Represents the media queries associated with the current document. * * @export interface StyleMedia * @typedef {StyleMedia} */ export interface StyleMedia {} /** * Represents an HTML anchor element (`<a>`). * * @export interface HTMLAnchorElement * @typedef {HTMLAnchorElement} * @extends {HTMLElement} */ export interface HTMLAnchorElement extends HTMLElement {} /** * Represents an HTML area element (`<area>`). * * @export interface HTMLAreaElement * @typedef {HTMLAreaElement} * @extends {HTMLElement} */ export interface HTMLAreaElement extends HTMLElement {} /** * Represents an HTML audio element (`<audio>`). * * @export interface HTMLAudioElement * @typedef {HTMLAudioElement} * @extends {HTMLElement} */ export interface HTMLAudioElement extends HTMLElement {} /** * Represents an HTML base element (`<base>`). * * @export interface HTMLBaseElement * @typedef {HTMLBaseElement} * @extends {HTMLElement} */ export interface HTMLBaseElement extends HTMLElement {} /** * Represents an HTML body element (`<body>`). * * @export interface HTMLBodyElement * @typedef {HTMLBodyElement} * @extends {HTMLElement} */ export interface HTMLBodyElement extends HTMLElement {} /** * Represents an HTML break element (`<br>`). * * @export interface HTMLBRElement * @typedef {HTMLBRElement} * @extends {HTMLElement} */ export interface HTMLBRElement extends HTMLElement {} /** * Represents an HTML button element (`<button>`). * * @export interface HTMLButtonElement * @typedef {HTMLButtonElement} * @extends {HTMLElement} */ export interface HTMLButtonElement extends HTMLElement {} /** * Represents an HTML canvas element (`<canvas>`). * * @export interface HTMLCanvasElement * @typedef {HTMLCanvasElement} * @extends {HTMLElement} */ export interface HTMLCanvasElement extends HTMLElement {} /** * Represents an HTML data element (`<data>`). * * @export interface HTMLDataElement * @typedef {HTMLDataElement} * @extends {HTMLElement} */ export interface HTMLDataElement extends HTMLElement {} /** * Represents an HTML data list element (`<datalist>`). * * @export interface HTMLDataListElement * @typedef {HTMLDataListElement} * @extends {HTMLElement} */ export interface HTMLDataListElement extends HTMLElement {} /** * Represents an HTML details element (`<details>`). * * @export interface HTMLDetailsElement * @typedef {HTMLDetailsElement} * @extends {HTMLElement} */ export interface HTMLDetailsElement extends HTMLElement {} /** * Represents an HTML dialog element (`<dialog>`). * * @export interface HTMLDialogElement * @typedef {HTMLDialogElement} * @extends {HTMLElement} */ export interface HTMLDialogElement extends HTMLElement {} /** * Represents an HTML div element (`<div>`). * * @export interface HTMLDivElement * @typedef {HTMLDivElement} * @extends {HTMLElement} */ export interface HTMLDivElement extends HTMLElement {} /** * Represents an HTML description list element (`<dl>`). * * @export interface HTMLDListElement * @typedef {HTMLDListElement} * @extends {HTMLElement} */ export interface HTMLDListElement extends HTMLElement {} /** * Represents an HTML embed element (`<embed>`). * * @export interface HTMLEmbedElement * @typedef {HTMLEmbedElement} * @extends {HTMLElement} */ export interface HTMLEmbedElement extends HTMLElement {} /** * Represents an HTML field set element (`<fieldset>`). * * @export interface HTMLFieldSetElement * @typedef {HTMLFieldSetElement} * @extends {HTMLElement} */ export interface HTMLFieldSetElement extends HTMLElement {} /** * Represents an HTML form element (`<form>`). * * @export interface HTMLFormElement * @typedef {HTMLFormElement} * @extends {HTMLElement} */ export interface HTMLFormElement extends HTMLElement {} /** * Represents an HTML heading element (`<h1>`-`<h6>`). * * @export interface HTMLHeadingElement * @typedef {HTMLHeadingElement} * @extends {HTMLElement} */ export interface HTMLHeadingElement extends HTMLElement {} /** * Represents an HTML head element (`<head>`). * * @export interface HTMLHeadElement * @typedef {HTMLHeadElement} * @extends {HTMLElement} */ export interface HTMLHeadElement extends HTMLElement {} /** * Represents an HTML horizontal rule element (`<hr>`). * * @export interface HTMLHRElement * @typedef {HTMLHRElement} * @extends {HTMLElement} */ export interface HTMLHRElement extends HTMLElement {} /** * Represents an HTML root element (`<html>`). * * @export interface HTMLHtmlElement * @typedef {HTMLHtmlElement} * @extends {HTMLElement} */ export interface HTMLHtmlElement extends HTMLElement {} /** * Represents an HTML iframe element (`<iframe>`). * * @export interface HTMLIFrameElement * @typedef {HTMLIFrameElement} * @extends {HTMLElement} */ export interface HTMLIFrameElement extends HTMLElement {} /** * Represents an HTML image element (`<img>`). * * @export interface HTMLImageElement * @typedef {HTMLImageElement} * @extends {HTMLElement} */ export interface HTMLImageElement extends HTMLElement {} /** * Represents an HTML input element (`<input>`). * * @export interface HTMLInputElement * @typedef {HTMLInputElement} * @extends {HTMLElement} */ export interface HTMLInputElement extends HTMLElement {} /** * Represents an HTML modification element (`<del>` and `<ins>`). * * @export interface HTMLModElement * @typedef {HTMLModElement} * @extends {HTMLElement} */ export interface HTMLModElement extends HTMLElement {} /** * Represents an HTML label element (`<label>`). * * @export interface HTMLLabelElement * @typedef {HTMLLabelElement} * @extends {HTMLElement} */ export interface HTMLLabelElement extends HTMLElement {} /** * Represents an HTML legend element (`<legend>`). * * @export interface HTMLLegendElement * @typedef {HTMLLegendElement} * @extends {HTMLElement} */ export interface HTMLLegendElement extends HTMLElement {} /** * Represents an HTML list item element (`<li>`). * * @export interface HTMLLIElement * @typedef {HTMLLIElement} * @extends {HTMLElement} */ export interface HTMLLIElement extends HTMLElement {} /** * Represents an HTML link element (`<link>`). * * @export interface HTMLLinkElement * @typedef {HTMLLinkElement} * @extends {HTMLElement} */ export interface HTMLLinkElement extends HTMLElement {} /** * Represents an HTML map element (`<map>`). * * @export interface HTMLMapElement * @typedef {HTMLMapElement} * @extends {HTMLElement} */ export interface HTMLMapElement extends HTMLElement {} /** * Represents an HTML meta element (`<meta>`). * * @export interface HTMLMetaElement * @typedef {HTMLMetaElement} * @extends {HTMLElement} */ export interface HTMLMetaElement extends HTMLElement {} /** * Represents an HTML meter element (`<meter>`). * * @export interface HTMLMeterElement * @typedef {HTMLMeterElement} * @extends {HTMLElement} */ export interface HTMLMeterElement extends HTMLElement {} /** * Represents an HTML object element (`<object>`). * * @export interface HTMLObjectElement * @typedef {HTMLObjectElement} * @extends {HTMLElement} */ export interface HTMLObjectElement extends HTMLElement {} /** * Represents an HTML option element (`<option>`). * * @export interface HTMLOptionElement * @typedef {HTMLOptionElement} * @extends {HTMLElement} */ export interface HTMLOptionElement extends HTMLElement {} /** * Represents an HTML paragraph element (`<p>`). * * @export interface HTMLParagraphElement * @typedef {HTMLParagraphElement} * @extends {HTMLElement} */ export interface HTMLParagraphElement extends HTMLElement {} /** * Represents an HTML progress element (`<progress>`). * * @export interface HTMLProgressElement * @typedef {HTMLProgressElement} * @extends {HTMLElement} */ export interface HTMLProgressElement extends HTMLElement {} /** * Represents an HTML script element (`<script>`). * * @export interface HTMLScriptElement * @typedef {HTMLScriptElement} * @extends {HTMLElement} */ export interface HTMLScriptElement extends HTMLElement {} /** * Represents an HTML select element (`<select>`). * * @export interface HTMLSelectElement * @typedef {HTMLSelectElement} * @extends {HTMLElement} */ export interface HTMLSelectElement extends HTMLElement {} /** * Represents an HTML source element (`<source>`). * * @export interface HTMLSourceElement * @typedef {HTMLSourceElement} * @extends {HTMLElement} */ export interface HTMLSourceElement extends HTMLElement {} /** * Represents an HTML span element (`<span>`). * * @export interface HTMLSpanElement * @typedef {HTMLSpanElement} * @extends {HTMLElement} */ export interface HTMLSpanElement extends HTMLElement {} /** * Represents an HTML style element (`<style>`). * * @export interface HTMLStyleElement * @typedef {HTMLStyleElement} * @extends {HTMLElement} */ export interface HTMLStyleElement extends HTMLElement {} /** * Represents an HTML table element (`<table>`). * * @export interface HTMLTableElement * @typedef {HTMLTableElement} * @extends {HTMLElement} */ export interface HTMLTableElement extends HTMLElement {} /** * Represents an HTML table column element (`<col>`). * * @export interface HTMLTableColElement * @typedef {HTMLTableColElement} * @extends {HTMLElement} */ export interface HTMLTableColElement extends HTMLElement {} /** * Represents an HTML table row element (`<tr>`). * * @export interface HTMLTableRowElement * @typedef {HTMLTableRowElement} * @extends {HTMLElement} */ export interface HTMLTableRowElement extends HTMLElement {} /** * Represents an HTML table section element (`<thead>`, `<tbody>`, and `<tfoot>`). * * @export interface HTMLTableSectionElement * @typedef {HTMLTableSectionElement} * @extends {HTMLElement} */ export interface HTMLTableSectionElement extends HTMLElement {} /** * Represents an HTML template element (`<template>`). * * @export interface HTMLTemplateElement * @typedef {HTMLTemplateElement} * @extends {HTMLElement} */ export interface HTMLTemplateElement extends HTMLElement {} /** * Represents an HTML text area element (`<textarea>`). * * @export interface HTMLTextAreaElement * @typedef {HTMLTextAreaElement} * @extends {HTMLElement} */ export interface HTMLTextAreaElement extends HTMLElement {} /** * Represents an HTML time element (`<time>`). * * @export interface HTMLTimeElement * @typedef {HTMLTimeElement} * @extends {HTMLElement} */ export interface HTMLTimeElement extends HTMLElement {} /** * Represents an HTML title element (`<title>`). * * @export interface HTMLTitleElement * @typedef {HTMLTitleElement} * @extends {HTMLElement} */ export interface HTMLTitleElement extends HTMLElement {} /** * Represents an HTML track element (`<track>`). * * @export interface HTMLTrackElement * @typedef {HTMLTrackElement} * @extends {HTMLElement} */ export interface HTMLTrackElement extends HTMLElement {} /** * Represents an HTML video element (`<video>`). * * @export interface HTMLVideoElement * @typedef {HTMLVideoElement} * @extends {HTMLElement} */ export interface HTMLVideoElement extends HTMLElement {} /** * Represents a native animation event, typically fired when a CSS animation starts, ends, or is repeated. * * @typedef {NativeAnimationEvent} */ type NativeAnimationEvent = AnimationEvent; /** * Represents a native clipboard event, used when performing clipboard actions such as copy, paste, and cut. * * @typedef {NativeClipboardEvent} */ type NativeClipboardEvent = ClipboardEvent; /** * Represents a native composition event, which occurs when the user is composing text via an input method editor (IME). * * @typedef {NativeCompositionEvent} */ type NativeCompositionEvent = CompositionEvent; /** * Represents a native drag event, triggered when an element or text selection is being dragged. * * @typedef {NativeDragEvent} */ type NativeDragEvent = DragEvent; /** * Represents a native focus event, which occurs when an element gains or loses focus. * * @typedef {NativeFocusEvent} */ type NativeFocusEvent = FocusEvent; /** * Represents a native keyboard event, fired when the user presses or releases a key on the keyboard. * * @typedef {NativeKeyboardEvent} */ type NativeKeyboardEvent = KeyboardEvent; /** * Represents a native mouse event, typically triggered by mouse actions such as clicks or movements. * * @typedef {NativeMouseEvent} */ type NativeMouseEvent = MouseEvent; /** * Represents a native touch event, used when the user interacts with a touch screen. * * @typedef {NativeTouchEvent} */ type NativeTouchEvent = TouchEvent; /** * Represents a native pointer event, which encompasses mouse, touch, and pen/stylus input. * * @typedef {NativePointerEvent} */ type NativePointerEvent = PointerEvent; /** * Represents a native transition event, fired when a CSS transition ends. * * @typedef {NativeTransitionEvent} */ type NativeTransitionEvent = TransitionEvent; /** * Represents a native UI event, which provides basic information about user export interface events like focus or blur. * * @typedef {NativeUIEvent} */ type NativeUIEvent = UIEvent; /** * Represents a native wheel event, typically triggered when the user rotates a wheel device (e.g., a mouse wheel). * * @typedef {NativeWheelEvent} */ type NativeWheelEvent = WheelEvent; /** * Used to represent DOM API's where users can either pass * true or false as a boolean or as its equivalent strings. */ type Booleanish = boolean | "true" | "false"; /** * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin MDN} */ type CrossOrigin = "anonymous" | "use-credentials" | "" | undefined; export interface ChildWithProps<P, S> { child: Component<P, S>; propsKey: string[]; } export interface ReblendRenderingException<P, S> extends Error { component: Component<P, S>; } export interface PropPatch<P, S> { type: "REMOVE" | "UPDATE"; node: Component<P, S>; key: string; propValue?: string; } export type Primitive = boolean | null | number | string | undefined; export interface ReblendPrimitive<P, S> extends Component<P, S> { reblendPrimitiveData: any; setData(data: Primitive): this; getData(): Primitive; } export type IAny = { [key: string]: any; }; export type VNodeChild = Primitive | VNode; export type VNodeChildren = VNodeChild[]; export type DomNodeChild<P, S> = Component<P, S> | ReblendPrimitive<P, S>; export type DomNodeChildren<P, S> = DomNodeChild<P, S>[]; export interface ReactNode { $$typeof: symbol; displayName: string; render: (props: any) => any; } export interface VNode { [reblendVComponent: symbol]: boolean; props: IAny & { children?: VNodeChildren; }; //@ts-ignore displayName: string | typeof Component | ReactNode; } export interface Patch<P, S> { type: PatchTypeAndOrder; newNode?: VNodeChild; oldNode?: DomNodeChild<P, S>; parent?: Component<P, S>; patches?: PropPatch<P, S>[]; } export interface ReblendComponentConfig { /** * Component to render first if this component is asyncronous */ ReblendPlaceholder?: ReblendElement; /** * Style for default reblend placeholder i.e if your are not using custom placeholder for your async components */ defaultReblendPlaceholderStyle?: string | CSSProperties; } export interface EffectState { cache: any; cacher: () => any; type: EffectType; effect?: Function; disconnectEffect?: () => void | Promise<void>; } export type ComponentRef<T = any> = RefAttributes<T>["ref"]; /** * Represents a mutable reference object whose `current` property can hold a value of type `T` or an `HTMLElement`. * * @template T * @typedef {Object} Ref * @property {T | HTMLElement} [current] - The current value held by the reference, which can be of type `T` or an `HTMLElement`. */ export type Ref<T> = { current: T; }; /** * Represents a mutable reference object whose `current` property can hold a value of type `T` or an `HTMLElement`. * * @template T * @typedef {Object} Ref * @property {T | HTMLElement} [current] - The current value held by the reference, which can be of type `T` or an `HTMLElement`. */ export type RefCallback<T> = { (current: T): void; }; /** * A function that updates the state based on the provided value. It accepts a value or a function that returns a new value based on the previous state. * * @template T * @callback StateFunction * @param {StateFunctionValue<T>} value - The value or function used to update the state. * @param {boolean} [force=false] - Optional flag to force the update. */ export type StateFunction<T> = ( value: StateFunctionValue<T>, force?: boolean, ) => Promise<void>; /** * The value used to update the state, which can be either a new value directly or a function that computes the new value based on the previous state. * * @template T */ export type StateFunctionValue<T> = | ((previous: T) => T | Promise<T>) | T | Promise<T>; /** * A function for computing a memoized value of type `T` based on the previous and current state of type `E`. * Used for memoization in stateful components, allowing you to cache expensive computations. * * The function receives an object with: * - `previous` (optional): The previous state value of type `E`. * - `current`: The current state value of type `E`. * - `initial`: Whether the component is in its mounting (initialization) phase. * - `memoInitializationCall`: Whether this is the first call to initialize the memoized value. * * The function can return the computed value synchronously or as a Promise. * * @typeParam T - The type of the computed (memoized) value. * @typeParam E - The type representing the state. * @param args - The arguments object containing previous/current state and flags. * @returns The computed value of type `T`, either synchronously or as a Promise. */ export type StateEffectiveMemoFunction<T, E> = (args: { previous?: E; current: E; initial: boolean; memoInitializationCall: boolean; }) => T | Promise<T>; /** * A function that determines and runs side effects based on changes between two states. * Used for effect hooks in stateful components. * * The function receives an object with: * - `previous`: The previous state value of type `E`. * - `current`: The current state value of type `E`. * - `initial`: Whether the component is mounting. * * The function can return: * - A cleanup function (to dispose of side effects when the state changes), * - A promise resolving to a cleanup function or void, * - Or nothing. * * @typeParam E - The type of the state. * @param args - The arguments object containing previous/current state and initial flag. * @returns A cleanup function, a promise of a cleanup function, or nothing. */ export type StateEffectiveFunction<E> = (args: { previous: E; current: E; initial: boolean; }) => | (() => void) | Promise<(() => void) | void> | (() => Promise<void>) | void; /** * A reducer function for state management, similar to React's `useReducer`. * It takes the previous value and an incoming value (or action), and returns the new value. * The return value can be synchronous or a Promise. * * @typeParam ValueType - The type of the state value. * @typeParam IncomingType - The type of the incoming value or action. * @param previous - The previous state or value. * @param current - The incoming value or action that affects the state. * @returns The new value after applying the reducer logic, synchronously or as a Promise. */ export type StateReducerFunction<ValueType, IncomingType> = ( previous: ValueType, current: IncomingType, ) => Promise<ValueType> | ValueType; /** * Used to retrieve the possible components which accept a given set of props. * * Can be passed no type parameters to get a union of all possible components * and tags. * * Is a superset of {@link ComponentType}. * * @template P The props to match against. If not passed, defaults to any. * @template Tag An optional tag to match against. If not passed, attempts to match against all possible tags. * * @example * * ```tsx * // All components and tags (img, embed etc.) * // which accept `src` * type SrcComponents = ElementType<{ src: any }>; * ``` * * @example * * ```tsx * // All components * type AllComponents = ElementType; * ``` * * @example * * ```tsx * // All custom components which match `src`, and tags which * // match `src`, narrowed down to just `audio` and `embed` * type SrcComponents = ElementType<{ src: any }, 'audio' | 'embed'>; * ``` */ export type ElementType< P = any, Tag extends keyof JSX.IntrinsicElements = keyof JSX.IntrinsicElements, > = | { [K in Tag]: P extends JSX.IntrinsicElements[K] ? K : never; }[Tag] | ComponentType<P>; /** * Represents any user-defined component, either as a function or a class. * * Similar to {@link JSXElementConstructor}, but with extra properties like * {@link FunctionComponent.defaultProps defaultProps } and * {@link ComponentClass.contextTypes contextTypes}. * * @template P The props the component accepts. * * @see {@link ComponentClass} * @see {@link FunctionComponent} */ export type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>; /** * Represents any user-defined component, either as a function or a class. * * Similar to {@link ComponentType}, but without extra properties like * {@link FunctionComponent.defaultProps defaultProps } and * {@link ComponentClass.contextTypes contextTypes}. * * @template P The props the component accepts. */ export type JSXElementConstructor<P> = | string | Promise< ( props: P, ) => Promise<ReblendNode | ReblendNode[]> | ReblendNode | ReblendNode[] > | (( props: P, ) => Promise<ReblendNode | ReblendNode[]> | ReblendNode | ReblendNode[]); /** * Retrieves the type of the 'ref' prop for a given component type or tag name. * * @template C The component type. * * @example * * ```tsx * type MyComponentRef = Reblend.ElementRef<typeof MyComponent>; * ``` * * @example * * ```tsx * type DivRef = Reblend.ElementRef<'div'>; * ``` */ type ComponentState = any; /** * A value which uniquely identifies a node among items in an array. * * @see {@link https://reblend.dev/learn/rendering-lists#keeping-list-items-in-order-with-key Reblend Docs} */ type Key = string | number | bigint; /** * @internal The props any component can receive. * You don't have to add this type. All components automatically accept these props. * ```tsx * const Component = () => <div />; * <Component key="one" /> * ``` * * WARNING: The implementation of a component will never have access to these attributes. * The following example would be incorrect usage because {@link Component} would never have access to `key`: * ```tsx * const Component = (props: Reblend.Attributes) => props.key; * ``` */ export interface Attributes { key?: Key | null | undefined; } /** * The props any component accepting refs can receive. * Class components, built-in browser components (e.g. `div`) and forwardRef components can receive refs and automatically accept these props. * ```tsx * const Component = forwardRef(() => <div />); * <Component ref={(current) => console.log(current)} /> * ``` * * You only need this type if you manually author the types of props that need to be compatible with legacy refs. * ```tsx * export interface Props extends Reblend.RefAttributes<HTMLDivElement> {} * declare const Component: Reblend.FunctionComponent<Props>; * ``` * * Otherwise it's simpler to directly use {@link Ref} since you can safely use the * props type to describe to props that a consumer can pass to the component * as well as describing the props the implementation of a component "sees". * {@link RefAttributes} is generally not safe to describe both consumer and seen props. * * ```tsx * export interface Props extends { * ref?: Reblend.Ref<HTMLDivElement> | undefined; * } * declare const Component: Reblend.FunctionComponent<Props>; * ``` * * WARNING: The implementation of a component will not have access to the same type in versions of Reblend supporting string refs. * The following example would be incorrect usage because {@link Component} would never have access to a `ref` with type `string` * ```tsx * const Component = (props: Reblend.RefAttributes) => props.ref; * ``` */ export interface RefAttributes<T> extends Attributes { /** * Allows getting a ref to the component instance. * Once the component unmounts, Reblend will set `ref.current` to `null` * (or call the ref with `null` if you passed a callback ref). * * @see {@link https://reblend.dev/learn/referencing-values-with-refs#refs-and-the-dom Reblend Docs} */ ref?: ((arg: T) => void) | Ref<T> | undefined; } /** * Represents the built-in attributes available to class components. */ export interface ClassAttributes<T> extends RefAttributes<T> {} /** * Represents a JSX element. * * Where {@link ReblendNode} represents everything that can be rendered, `ReblendElement` * only represents JSX. * * @template P The type of the props object * @template T The type of the component or tag * * @example * * ```tsx * const element: ReblendElement = <div />; * ``` */ type HTMLs = | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLBodyElement | HTMLBRElement | HTMLButtonElement | HTMLCanvasElement | HTMLDataElement | HTMLDataListElement | HTMLDetailsElement | HTMLDialogElement | HTMLDivElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadingElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLInputElement | HTMLModElement | HTMLLabelElement | HTMLLegendElement | HTMLLIElement | HTMLLinkElement | HTMLMapElement | HTMLMetaElement | HTMLMeterElement | HTMLObjectElement | HTMLOListElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLParagraphElement | HTMLParamElement | HTMLPreElement | HTMLProgressElement | HTMLQuoteElement | HTMLSlotElement | HTMLScriptElement | HTMLSelectElement | HTMLSourceElement | HTMLSpanElement | HTMLStyleElement | HTMLTableElement | HTMLTableColElement | HTMLTableDataCellElement | HTMLTableHeaderCellElement | HTMLTableRowElement | HTMLTableSectionElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement | HTMLWebViewElement | SVGElement; /** * Represents a JSX element that is both a native `HTMLElement` and a `React` element, including support for portals. * * Where {@link ReblendNode} represents everything that can be rendered, `ReblendElement` * specifically represents JSX elements that are rendered via Reblend, including native HTML elements and React portals. * * @template P The type of the props object for the React element * @template T The type of the HTML component or tag name * * @example * ```tsx * const element: ReblendElement = <div />; * ``` */ export type ReblendElement = & HTMLElement & React.ReactElement & React.ReactPortal & React.ForwardRefExoticComponent<any> & undefined & null; //@ts-ignore Don't have to implement Component export interface FunctionComponentElement<P> extends Component<P, any> { ref?: | ("ref" extends keyof P ? P extends { ref?: infer R | undefined; } ? R : never : never) | undefined; } export interface DOMElement< P extends HTMLAttributes<T> | SVGAttributes<T>, T extends Element, > //@ts-ignore extends ReblendElement { ref: Ref<T>; } export interface ReblendHTMLElement<T extends HTMLElement> extends DetailedReblendHTMLElement<AllHTMLAttributes<T>, T> {} export interface DetailedReblendHTMLElement< P extends HTMLAttributes<T>, T extends HTMLElement, > extends DOMElement<P, T> { type: keyof ReblendHTML; } export interface ReblendSVGElement extends DOMElement<SVGAttributes<SVGElement>, SVGElement> { type: keyof ReblendSVG; } type DOMFactory<P extends DOMAttributes<T>, T extends Element> = ( props?: (ClassAttributes<T> & P) | null, ...children: ReblendNode[] ) => DOMElement<P, T>; export interface HTMLFactory<T extends HTMLElement> extends DetailedHTMLFactory<AllHTMLAttributes<T>, T> {} export interface DetailedHTMLFactory< P extends HTMLAttributes<T>, T extends HTMLElement, > extends DOMFactory<P, T> { ( props?: (ClassAttributes<T> & P) | null, ...children: ReblendNode[] ): DetailedReblendHTMLElement<P, T>; } export interface SVGFactory extends DOMFactory<SVGAttributes<SVGElement>, SVGElement> { ( props?: (ClassAttributes<SVGElement> & SVGAttributes<SVGElement>) | null, ...children: ReblendNode[] ): ReblendSVGElement; } /** * Represents all of the things Reblend can render. * * Where {@link ReblendElement} only represents JSX, `ReblendNode` represents everything that can be rendered. * * @see {@link https://reblend-typescript-cheatsheet.netlify.app/docs/reblend-types/reblendnode/ Reblend TypeScript Cheatsheet} * * @example * * ```tsx * // Typing children * type Props = { children: ReblendNode } * * const Component = ({ children }: Props) => <div>{children}</div> * * <Component>hello</Component> * ``` * * @example * * ```tsx * // Typing a custom element * type Props = { customElement: ReblendNode } * * const Component = ({ customElement }: Props) => <div>{customElement}</div> * * <Component customElement={<div>hello</div>} /> * ``` */ export type ReblendNode<P = any, S = any> = | ReblendElement | HTMLs | React.ReactNode | Iterable<ReblendNode> | FC<P> | Component<P, S> | typeof Component<P, S> | VNodeChild | VNodeChildren | DomNodeChild<P, S> | DomNodeChildren<P, S> | Promise<ReblendNode> | ((...args: any[]) => Promise<ReblendNode>) | ((...args: any[]) => ReblendNode) | undefined | null | void; /** * Tracks and manages the current rendering session for a component. * Used to implement rendering cancellation: if a new update is triggered * while a previous render is running, the previous render is aborted. * * A rendering session is a unique, versioned period of rendering work. * When a new session starts, any previous session is considered obsolete and * should be canceled. This ensures that only the latest state and effects are * applied, preventing race conditions and wasted work from overlapping renders. * * Typical usage: * - Call `startSession()` at the beginning of a render/update. * - Pass the returned session ID to all async work. * - After each async step, call `isCurrentSession(sessionId)` to check if the * session is still valid. If not, abort the rest of the work. * - Call `resetSession()` when the render is complete or canceled. */ export interface SessionTracker { /** * Returns the current session ID if a session is active, or undefined/null otherwise. * Useful for checking if a session is in progress. */ hasASession(): boolean; /** * Starts a new rendering session and returns a unique session ID. * Each call increments the internal version/token, invalidating any previous session. * Should be called at the start of a render or update. */ startSession(): number; /** * Returns true if a previous session was already running before this one. * Useful for detecting overlapping or re-entrant renders. */ hasPreviousSession(): boolean; /** * Returns true if the given session ID matches the current session. * Used to check if the current render/update is still valid (not canceled). * If false, the render should be aborted. */ isCurrentSession(sessionId: number): boolean; /** * Resets the tracker, invalidating any previous sessions. * Typically called when a render is completed or canceled. */ resetSession(): void; } /** * Represents a Reblend component, extending the standard HTMLElement with additional * properties and lifecycle methods for managing state, props, effects, and rendering. * * @template P - The type of the component's props. * @template S - The type of the component's state. * * This interface defines the contract for a Reblend component, including: * - Properties for managing props, state, effects, and children. * - Lifecycle methods for mounting, updating, and unmounting. * - Hooks for state, effects, memoization, and refs. * - Error handling and rendering logic. * * Implementations of this interface are expected to provide custom logic for rendering, * state management, and effect handling, similar to React components but tailored for * the Reblend framework. */ export interface Component<P, S> extends HTMLElement { /** * Holds the props (properties) of the component. * Can be any type of object containing the default component's configuration. * * @static * @type {IAny} */ props: any; /** * static configuration for the component */ config?: ReblendComponentConfig; nearestStandardParent?: HTMLElement; /** * The name of this component. * Use for debugging and to identify when an this component should be replaced with another. */ displayName: string; /** * Symbol representing type of reblend component. */ [reblendComponent: symbol]: boolean; /** * This holds reference to children of the component */ elementChildren: Set<Component<any, any>> | null; /** * This is a wrapper for the react element children */ reactElementChildrenWrapper: Component<any, any> | null; /** * This is a react dom root */ reactDomCreateRoot_root: import("react-dom/client").Root | null; /** * This denote when current component children has been initialized */ childrenInitialize: boolean; /** * The selector string for querying elements by data ID. */ dataIdQuerySelector: string; /** * The rendering error, if any occurred during rendering. */ renderingError?: ReblendRenderingException<P, S>; /** * The error handler for rendering exceptions. */ renderingErrorHandler?: (e: ReblendRenderingException<P, S>) => void; /** * Indicates whether the component is attached. */ attached: boolean; /** * Indicates that the component is part of a placeholder component. */ isPlaceholder: boolean; /** * Indicates a root component */ isRootComponent: boolean; /** * Indicates that a placeholder has been attached to the component. */ placeholderAttached: boolean; /** * Function that will be called when the children get attached */ removePlaceholder?: () => Promise<void>; /** * The React class associated with this component. */ ReactClass: () => any; /** * Component to render first if this component is asyncronous */ //@ts-ignore ReblendPlaceholder?: ReblendNode; /** * Style for default reblend placeholder i.e if your are not using custom placeholder for your async components */ defaultReblendPlaceholderStyle?: CSSProperties | string; /** * A reference for the component's DOM node. */ ref: Ref<HTMLElement> | ((node: HTMLElement) => any); /** * This hold effects functions */ effectsState: Map<string, EffectState>; /** * The effects to apply when the component is mounted. */ onMountEffects?: Set<StateEffectiveFunction<any>>; hookDisconnectedEffects?: Set<() => void>; /** * Indicates number of awaiting updates. */ numAwaitingUpdates: number; /** * Indicates whether state effects are currently running. */ stateEffectRunning: boolean; /** * Used for tracking update cycle of a component. */ renderingSessionTracker: SessionTracker; /** * Indicates when effects function are required to update regardless of changes */ forceEffects: boolean; /** * The parent of this component */ directParent: Component<any, any>; /** * Indicates when first time effects are being called. */ mountingEffects: boolean; /** * Indicates when first time after effects are being called. */ mountingAfterEffects: boolean; /** * Indicate state initialization */ initStateRunning: boolean; /** * Indicate when connectedCallback should be called but state has not finished initializing */ awaitingInitState: boolean; /** * Indicate when onStateChange of a component is triggered before its children initialized */ awaitingReRender: boolean; /** * Indicates whether this component disconnected callback was called. */ hasDisconnected: boolean; /** * Set of update types for children properties. */ childrenPropsUpdate?: Set<ChildrenPropsUpdateType>; /** * The component's state. */ state: S; /** * Lifecycle method for mounting the component in React. */ reactReblendMount?: undefined | ((afterNode?: HTMLElement) => void); /** * Populates the HTML elements for this component. */ populateHtmlElements(): void; /** * Callback invoked when the component is connected to the DOM. */ connectedCallback(): void; /** * Adds a hook disconnect effect function to be executed when the component is disconnected. * * @param {() => void} destructor - The destructor function to add. */ addHookDisconnectedEffect(destructor: () => void): void; /** * Adds styles to the component. * * @param {string[]} styles - An array of style strings to apply. * @param {IAny} style - An object representing styles as key-value pairs. * @param {string} style - A single style string to apply. * @param {string[] | IAny | string} style - The styles to apply. */ addStyle(style: string[] | IAny | string): void; /** * Initializes the component's state. */ initState<ExpectedReturn = any>(): Promise<ExpectedReturn>; /** * Initializes the component's properties. * * @param {P} props - The properties to set on the component. */ initProps(props: P): Promise<void>; /** * Lifecycle method called after the component is mounted. */ componentDidMount(): void | Promise<void>; /** * Sets the state of the component using the setter. * * @param {S} value - The new state value. */ setState(value: S): void; /** * Applies effects defined in the component, executing them in order. * * @param sessionId The rerendering circle id * @param type Type of effect */ applyEffects(sessionId: number, type: EffectType): Promise<void>; /** * Handles an error that occurs during rendering or lifecycle methods. * * @param {Error} error - The error to handle. */ handleError(error: Error): void; /** * Handles state changes, applying effects and updating virtual DOM nodes. * @async */ onStateChange(): Promise<void>; /** * Returns the virtual DOM structure. Must be implemented by subclasses. * @returns {ReblendNode} The reblend nodes. */ html(): Promise<ReblendNode>; /** * Checks for any changes in the props and updates the component accordingly. * React Reblend nodes can trigger different updates based on the type of children or non-children changes. * * @async * @returns {Promise<void>} * @throws {Error} Throws an error if an invalid props update type is provided. */ checkPropsChange(): Promise<void>; /** * Mounts effects defined in the component, executing them and storing disconnect functions. * @ */ mountEffects(): Promise<void>; /** * Lifecycle method called when the component is disconnected from the DOM. * Cleans up resources and removes the component from its parent. */ disconnectedCallback(): Promise<void>; /** * Cleans up resources before the component unmounts. */ cleanUp(): void | Promise<void>; /** * Lifecycle method for component unmount actions. */ componentWillUnmount(): Promise<void> | void; /** * Deep compare dependecies for changes * @param {Array<any>} currentDependencies * @param {Array<any>} previousDependencies * @returns {boolean} Returns true if the two object are not equal */ dependenciesChanged( currentDependencies: Array<any>, previousDependencies: Array<any>, ): boolean; /** * State management hook for functional components. * * @template T - The type of the state. * @param {StateFunctionValue<T>} initial - The initial state value. * @param {string} stateKey - State key. * @returns {[T, StateFunction<T>]} The current state and a function to update it. */ useState<T>( initial: StateFunctionValue<T>, stateKey: string, ): [T, StateFunction<T>]; /** * Effect hook for performing side effects in functional components. * * @param {StateEffectiveFunction} fn - The effect function to execute. * @param {() => any} dependencies - A function that returns dependency or array of dependencies for the effect. */ useEffect<T>(fn: StateEffectiveFunction<T>, dependencies?: () => any): void; /** * Effect hook for performing side effects after children of a component is populated or after state changes. * * @param {StateEffectiveFunction} fn - The effect function to execute. * @param {() => any} dependencies - A function that returns a dependency or array of dependencies for the effect. */ useEffectAfter<T>( fn: StateEffectiveFunction<T>, dependencies?: () => any, ): void; /** * Effect hook for performing side effects or have access to previous and current props usefull within custom hooks. * * @param {StateEffectiveFunction} fn - The effect function to execute. */ useProps(fn: StateEffectiveFunction<P>): void; /** * Reducer hook for managing state with a reducer function. * * @template T - The type of the state. * @template I - The type of the action. * @param {StateReducerFunction<T, I>} reducer - The reducer function. * @param {StateFunctionValue<T>} initial - The initial state value. * @param {string} stateKey - State key. * @returns {[T, StateFunction<I>]} The current state and a dispatch function. */ useReducer<T, I>( reducer: StateReducerFunction<T, I>, initial: StateFunctionValue<T>, stateKey: string, ): [T, StateFunction<I>]; /** * Memoization hook for caching values in functional components. * * @template T - The type of the memoized value. * @template E - The type of dependencies. * @param {StateEffectiveMemoFunction<T, E>} fn - The function to compute the value. * @param {string} stateKey - State key. * @param {() => any} dependencies - A function that returns dependency or array of dependencies for the effect. * @returns {T} The memoized value. */ useMemo<T, E>( fn: StateEffectiveMemoFunction<T, E>, stateKey: string, dependencies?: () => any, ): T; /** * Creates a ref object to hold mutable values that do not trigger re-renders. * * @template T - The type of the referenced value. * @param {T} [initial] - The initial value of the ref. * @param {T} [stateKey] - Added for compatibility with reblend function component transpiler * @returns {Ref<T>} The ref object. */ useRef<T>(initial: T): Ref<T>; /** * Binds a function to the current context. * * @param {() => any} fn - The function to bind. * @returns {Function} The bound function. */ useCallback(fn: () => any): Function; /** * Initializes the component, preparing effect management. * For compatibility in case a standard element inherits this prototype; can manually execute this constructor. */ _constructor(): void; } export class Component<P, S> {} /** * Represents the type of a function component. Can optionally * receive a type argument that represents the props the component * receives. * * @template P The props the component accepts. * @see {@link https://reblend-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components Reblend TypeScript Cheatsheet} * @alias for {@link FunctionComponent} * * @example * * ```tsx * // With props: * type Props = { name: string } * * const MyComponent: FC<Props> = (props) => { * return <div>{props.name}</div> * } * ``` * * @example * * ```tsx * // Without props: * const MyComponentWithoutProps: FC = () => { * return <div>MyComponentWithoutProps</div> * } * ``` */ export type FC<P = {}, RefType = any> = FunctionComponent< P & { ref?: Ref<RefType> } >; /** * Represents the type of a function component. Can optionally * receive a type argument that represents the props the component * receives. * * @template P The props the component accepts. * @see {@link https://reblend-typescript-cheatsheet.netlify.app/docs/basic/getting-started/function_components Reblend TypeScript Cheatsheet} * * @example * * ```tsx * // With props: * type Props = { name: string } * * const MyComponent: FunctionComponent<Props> = (props) => { * return <div>{props.name}</div> * } * ``` * * @example * * ```tsx * // Without props: * const MyComponentWithoutProps: FunctionComponent = () => { * return <div>MyComponentWithoutProps</div> * } * ``` */ export interface FunctionComponent<P = {}> { (props: P): ReblendNode; props?: Partial<P> | undefined; displayName?: string; ELEMENT_NAME?: string; } /** * Represents a component class in Reblend. * * @template P The props the component accepts. * @template S The internal state of the component. */ //@ts-expect-error export interface ComponentClass<P = {}, S = ComponentState> extends Component<P, S> { new (props: P): Component<P, S>; props?: Partial<P> | undefined; } /** * Omits the 'ref' attribute from the given props object. * * @template P The props object type. */ type PropsWithoutRef<P> = P extends any ? "ref" extends keyof P ? Omit<P, "ref"> : P : P; /** Ensures that the props do not include string ref, which cannot be forwarded */ type PropsWithRef<P> = "ref" extends keyof P ? P extends { ref?: infer R | undefined; } ? string extends R ? PropsWithoutRef<P> & { ref?: Exclude<R, string> | undefined; } : P : P : P; type PropsWithChildren<P = unknown> = P & { children?: ReblendNode | undefined; }; /** * Used to retrieve the props a component accepts. Can either be passed a string, * indicating a DOM element (e.g. 'div', 'span', etc.) or the type of a Reblend * component. * * It's usually better to use {@link ComponentPropsWithRef} or {@link ComponentPropsWithoutRef} * instead of this type, as they let you be explicit about whether or not to include * the `ref` prop. * * @see {@link https://reble