UNPKG

@thi.ng/rdom

Version:

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

84 lines 2.86 kB
import type { Fn2, NumOrString } 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 KListOpts<T> extends ListBaseOpts<T> { key?: Fn2<T, number, NumOrString>; } export interface KListItem { k: NumOrString; v: IComponent; } /** * Similar to {@link $list}, however additionally uses keying to establish list * item identities and uses these keys (and *only* these!) in a more complex * diffing algorithm to avoid re-initialization of list items if they've been * re-ordered or changed positions due to removal/insertion of other items in * the list. * * @remarks * The given `key` function is used to obtain a *unique* key value for each list * item obtained from the reactive arrays obtained from `src`. Like a hash, the * key value MUST represent an item's *current* value such that if the value * changes, so does the key. * * 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 { $klist } from "@thi.ng/rdom"; * import { reactive } from "@thi.ng/rstream"; * * const items = reactive([{id: "a", val: 1}, {id: "b", val: 2}, {id: "c", val: 3}]); * * $klist( * // data source (any rstream subscribable) * items, * { * // outer list element & attribs * el: "ul", * attribs: { class: "list red" }, * // list item component constructor * item: (x) => ["li", {}, x.id, ` (${x.val})`], * // key function * key: (x) => `${x.id}-${x.val}` * } * ).mount(document.body); * * // update list: * // - item a will be removed * // - item b is unchanged * // - item d will be newly inserted * // - item c will be updated (due to new value) * setTimeout( * () => { * items.next([ * { id: "b", val: 2 }, * { id: "d", val: 4 }, * { id: "c", val: 30 }, * ]); * }, * 1000 * ); * ``` * * @param src - * @param opts - */ export declare const $klist: <T>(src: ISubscribable<T[]>, opts: KListOpts<T>) => IComponent<T[]>; export declare class KList<T> extends Component<T[]> implements IMountWithState<T[]> { protected opts: KListOpts<T>; protected items?: KListItem[]; protected cache?: Map<NumOrString, KListItem>; protected anchor?: Comment; constructor(opts: KListOpts<T>); mount(parent: ParentNode, index: NumOrNode, state: T[]): Promise<Element>; unmount(): Promise<void>; update(curr: T[]): Promise<void>; } //# sourceMappingURL=klist.d.ts.map