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