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])
* //
* ```
* 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$;