export interface ItemObserverOptions { /** Invoked, coalesced to once per frame, when any observed item's box changes. */ onChange: () => void; /** * Also attach one-shot `load`/`error` listeners to images inside observed * items. Covers layouts where the wrapper's box does not change even though * its content settles. Default: true */ watchImages?: boolean; } export interface ItemObserver { /** Start observing an element. Idempotent; `null` is ignored. */ observe(el: HTMLElement | null): void; /** Stop observing a single element and drop its listeners. */ unobserve(el: HTMLElement): void; /** Stop observing everything; the observer stays usable afterwards. */ reset(): void; /** Tear down permanently. */ disconnect(): void; } /** * Watch individual grid items for size changes and report them. * * This is what makes the grid self-healing. Item heights are measured once * during layout, but real content settles *after* that: images decode, fonts * swap, embeds resize, text reflows, collapsible sections open. Without this, * the only trigger for a fresh layout is a container **width** change — so an * image gallery lays out against zero-height images and stays broken until the * window happens to be resized. * * Every notification is funnelled through one animation-frame scheduler, so a * gallery of 200 images finishing at once costs a single relayout, not 200. */ export declare function createItemObserver(options: ItemObserverOptions): ItemObserver;