import { HTMLElement$ } from './core'; import { VirtualDOM, Observable } from './interface'; /** * Specifies the side effects associated to an update of children. * * @category Reactive Children */ export type ChildrenUpdateTrait = { /** * Execute side effects once the children have been updated. * * @param parent parent of the children * @param update description of the update */ sideEffects?: (parent: HTMLElement$, update: RenderingUpdate) => void; }; /** * Specifies the order in which children are included in the parent element. * * @category Reactive Children */ export type OrderingTrait = { /** * @hidden * @deprecated use orderOperator */ orderingIndex?: (data: TDomain) => number; /** * Specifies how the children are ordered in the parent element. * Order is defined using this callback. * * @param d1 Domain data associated to the first element for comparison * @param d2 Domain data associated to the second element for comparison * @return a value: * - if `>0`, sort `d1` after `d2` * - if `<0`, sort `d1` before `d2` */ orderOperator?: (d1: TDomain, d2: TDomain) => number; }; /** * ## RefElement * * Encapsulates domainData, VirtualDOM & HTMLElement. * * @category Reactive Children */ export type RefElement = { /** * domainData */ domainData: TDomain; /** * the virtual DOM as defined by the developer */ virtualDOM: VirtualDOM; /** * the actual DOM element */ element: HTMLElement$; }; /** * Describes an update when a DOM element has been modified when using {@link childrenAppendOnly$} or * {@link childrenFromStore$}. * * @category Reactive Children */ export type RenderingUpdate = { added: RefElement[]; updated: RefElement[]; removed: RefElement[]; }; /** * Base class used to define advanced **children** policy in {@link VirtualDOM} when * the source stream emit **array** of domain data. * * You can derive you own class by providing the implementation of {@link update}. * * Example of use: {@link AppendOnlyChildrenStream$}, {@link FromStoreChildrenStream$}. * * @category Advanced */ export declare abstract class ChildrenStream$ { readonly stream$: Observable>; readonly vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM; ClassType: string; /** * Callback that gets called when the DOM has been updated. * @param parent parent: parent {@link HTMLElement$} * @param update update: description of the update, see {@link RenderingUpdate} */ readonly sideEffects: (parent: HTMLElement$, update: RenderingUpdate) => void; /** * If orderingIndex is supplied, all children elements are sorted according to the index * @deprecated use domainComparator instead */ readonly orderingIndex: (data: TDomain) => number; protected readonly orderOperator: (d1: TDomain, d2: TDomain) => number; private readonly children; /** * * @param stream$ input stream * @param vDomMap mapping function domain data => {@link VirtualDOM} * @param sideEffects see {@link sideEffects} * @param orderingFunction see {@link orderOperator} */ protected constructor(stream$: Observable>, vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM, { sideEffects, orderingIndex, orderOperator, }: ChildrenUpdateTrait & OrderingTrait & ComparisonTrait); protected abstract update(parentElement: HTMLElement$, domainData: Array): RenderingUpdate; /** * Only for internal use (within {@link HTMLElement$}), should not actually be exposed. */ subscribe(parentElement: HTMLElement$): import("rxjs").Subscription; protected addChildRef(parentElement: HTMLElement$, ref: RefElement): void; protected removeChildRef(ref: RefElement): void; protected reorder(parentElement: HTMLElement$): void; } export declare function instanceOfChildrenStream$(obj: unknown): obj is ChildrenStream$; /** * See companion creation function {@link childrenAppendOnly$}. * * @category Advanced */ export declare class AppendOnlyChildrenStream$ extends ChildrenStream$ { readonly stream$: Observable; readonly vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM; readonly untilFirst: any; readonly sideEffects: any; constructor(stream$: Observable, vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM, options: ChildrenUpdateTrait & OrderingTrait); protected update(parentElement: HTMLElement$, domainData: TDomain[]): RenderingUpdate; } /** * Option definition for the function {@link childrenAppendOnly$}. * * @category Reactive Children */ export type ChildrenAppendOnlyOption = ChildrenUpdateTrait & OrderingTrait; /** * * Use case: when the emitting `source$` of the array of domain data is always emitting new data * for which associated DOM nodes need to be added. * * For instance: * * ```typescript * class DomainData{ * constructor( public readonly value: string){} * } * let hello = new DomainData("hello") * let world = new DomainData("world") * let foo = new DomainData("foo") * let stream$ = new BehaviorSubject([hello, world]) * let vDOM = { * children: appendOnlyChildren$( * stream$, * (data: DomainData) => ({innerText: data.value}) * ) * } * body.appendChild(render(vDOM)) * //
* //
hello
* //
world
* //
* stream$.next([hello, foo]) * //
* //
hello
* //
foo
* //
hello
* //
foo
* //
* ``` * * @param stream$ The stream of array of domain data * @param vDomMap The mapping between one DomainData and corresponding {@link VirtualDOM} * @param option * @template TDomain Domain data type * @category Reactive Children * @category Entry Points */ export declare function childrenAppendOnly$(stream$: Observable, vDomMap: (data: TDomain, ...args: unknown[]) => VirtualDOM, option?: ChildrenAppendOnlyOption): AppendOnlyChildrenStream$; /** * Specifies whether two domain data represents the same {@link VirtualDOM} (or {@link HTMLElement}). * * @category Reactive Children */ export type ComparisonTrait = { /** * Default is to use reference equality. * * @param d1 first domain data for comparison * @param d2 second domain data for comparison * @return `true` if the `d1` and `d2` represents the same element, `false` otherwise. */ comparisonOperator?: (d1: TDomain, d2: TDomain) => boolean; }; /** * See companion creation function {@link childrenFromStore$}. * * @category Advanced */ export declare class FromStoreChildrenStream$ extends ChildrenStream$ { readonly stream$: Observable; readonly vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM; /** * Comparison operator used to identify which elements need to be added/ updated/ replaced. * By default, reference equality is used, ideal when the domain data are immutables. */ readonly comparisonOperator: (rhs: TDomain, lhs: TDomain) => boolean; constructor(stream$: Observable, vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM, options: ChildrenUpdateTrait & OrderingTrait & ComparisonTrait); private actualElements; protected update(parentElement: HTMLElement$, expectedData: Array): RenderingUpdate; private isNotInList; } /** * Option definition for the function {@link childrenFromStore$}. * * @category Reactive Children */ export type ChildrenFromStoreOption = ChildrenUpdateTrait & OrderingTrait & ComparisonTrait; /** * @ignore * @hidden * @deprecated use childrenFromStore$ */ export declare function childrenWithReplace$(stream$: Observable, vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM, options?: ChildrenFromStoreOption): FromStoreChildrenStream$; /** * Use case: when the emitting `source$` of the array of domain data recycle some of its element. * * For instance: * * ```typescript * class DomainData{ * constructor( public readonly value: string){} * } * let hello = new DomainData("hello") * let world = new DomainData("world") * let foo = new DomainData("foo") * let stream$ = new BehaviorSubject([hello, world]) * let vDOM = { * children: childrenWithReplace$( * stream$, * (data: DomainData) => ({innerText: data.value}) * ) * } * body.appendChild(render(vDOM)) * //
* //
hello
* //
world
* //
* stream$.next([hello, foo]) * //
* //
hello
* //
foo
* //
* ``` * The key points in the above example is that when *stream$.next([hello, foo])* is called: * - ```
hello
``` was not re-rendered * - ```
world
``` has been removed * - ```
foo
``` has been added * - the policy does domain data comparison (to identify which elements are new or old) using reference by default, * a custom comparison operator can also be supplied. * * @param stream$ The stream of array of domain data * @param vDomMap The mapping between one DomainData and corresponding {@link VirtualDOM} * @param option * @template TDomain Domain data type * @category Reactive Children * @category Entry Points */ export declare function childrenFromStore$(stream$: Observable, vDomMap: (tDomain: TDomain, ...args: any[]) => VirtualDOM, option?: ChildrenFromStoreOption): FromStoreChildrenStream$;