@thi.ng/rdom
Version:
Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible
80 lines • 2.85 kB
TypeScript
import type { Predicate2 } from "@thi.ng/api";
import type { ISubscribable } from "@thi.ng/rstream";
import type { IComponent, IMountWithState, ListBaseOpts, NumOrNode } from "./api.js";
import { Component } from "./component.js";
export interface ListOpts<T> extends ListBaseOpts<T> {
/**
* Equality predicate function to determine if a list item has changed. Uses
* `===` by default.
*/
equiv?: Predicate2<T>;
}
/**
* Creates a generalized and dynamically updating list component from items of
* the given `src` stream.
*
* @remarks
* Only very basic key-less diffing of list items is performed (using the
* `equiv` equality predicate arg, i.e. `equiv(prev[i], curr[i])`).
*
* Use this list component only for cases when the child item components do not
* involve complex lifecycles (e.g. preloaders, intro animations etc.). Any list
* items changing position will be first unmounted, then remounted. To avoid
* this full lifecycle transition, consider using {@link $klist}, which employs
* a more elaborate diffing mechanism and keying to uniquely identify list items
* (regardless of their position in the array).
*
* See {@link ListBaseOpts} for more details about wrapped vs. bare lists, i.e.
* using a list wrapper element for items or attaching list items directly to
* this component's parent. Also see this example project to illustrate the
* structure/possibilities of bare lists:
*
* - https://demo.thi.ng/umbrella/rdom-bare-lists/
*
* @example
* ```ts
* import { $list } from "@thi.ng/rdom";
* import { reactive } from "@thi.ng/rstream";
*
* const items = reactive([{id: "a"}, {id: "b"}, {id: "c"}]);
*
* $list(
* // data source (rstream subsribable)
* items,
* {
* // outer list element & attribs
* el: "ul",
* attribs: { class: "list red" },
* // list item component constructor
* item: (x) => ["li", {}, x.id],
* // optional equality predicate (default this.ng/equiv)
* equiv: (a, b) => a.id === b.id
* }
* ).mount(document.body);
*
* // update list
* items.next([{id: "b"}, {id: "d"}, {id: "c"}]);
*
* // removes component for item A
* // recreates B in new position
* // creates D
* // keeps C
* ```
*
* @param src -
* @param opts -
*/
export declare const $list: <T>(src: ISubscribable<T[]>, opts: ListOpts<T>) => IComponent<T[]>;
export declare class List<T> extends Component implements IMountWithState<T[]> {
protected opts: ListOpts<T>;
protected prev?: T[];
protected items?: IComponent[];
protected anchor?: Comment;
protected offset: number;
protected numChildren: number;
constructor(opts: ListOpts<T>);
mount(parent: ParentNode, index: NumOrNode, state: T[]): Promise<Element>;
unmount(): Promise<void>;
update(curr: T[]): Promise<void>;
}
//# sourceMappingURL=list.d.ts.map