UNPKG

@thi.ng/rdom

Version:

Lightweight, reactive, VDOM-less UI/DOM components with async lifecycle and @thi.ng/hiccup compatible

80 lines 2.85 kB
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