/** * React-level virtualization hook for items inside a ScrollBox. * * Adapted from Claude Code's useVirtualScroll.ts. Core patterns extracted: * 1. ScrollTop quantization (40-row bins) for re-render gating * 2. Slide cap (25 items per commit) for smooth scroll during fast navigation * 3. Overscan (80 rows above/below) to absorb estimate errors * 4. Height measurement via Yoga layout nodes and caching * 5. Column-change scaling (proportional height adjustment, not cache clear) * 6. Range freezing during resize to prevent mount churn * * Made generic: no RenderableMessage dependency — works with any item type. * No TextHoverColorContext, ScrollChromeContext, or search/nav functionality. */ import type { RefObject } from 'react'; import type { ScrollBoxHandle } from '../components/ScrollBox.js'; import type { DOMElement } from '../dom.js'; export type VirtualScrollResult = { /** [startIndex, endIndex) half-open slice of items to render. */ range: readonly [number, number]; /** Height (rows) of spacer before the first rendered item. */ topSpacer: number; /** Height (rows) of spacer after the last rendered item. */ bottomSpacer: number; /** * Callback ref factory. Attach `measureRef(itemKey)` to each rendered * item's root Box; after Yoga layout, the computed height is cached. */ measureRef: (key: string) => (el: DOMElement | null) => void; /** * Attach to the topSpacer Box. Its Yoga computedTop IS listOrigin. */ spacerRef: RefObject; /** * Cumulative y-offset of each item in list-wrapper coords. * offsets[i] = rows above item i; offsets[n] = totalHeight. */ offsets: ArrayLike; /** Read Yoga computedTop for item at index. Returns -1 if not mounted. */ getItemTop: (index: number) => number; /** Get the mounted DOMElement for item at index, or null. */ getItemElement: (index: number) => DOMElement | null; /** Measured Yoga height. undefined = not yet measured; 0 = rendered nothing. */ getItemHeight: (index: number) => number | undefined; /** Scroll so item i is in the mounted range. */ scrollToIndex: (i: number) => void; }; /** * Virtual scroll hook for items inside a ScrollBox. * * The ScrollBox already does Ink-output-level viewport culling, but all React * fibers + Yoga nodes are still allocated. This hook mounts only items in * viewport + overscan, with spacer boxes holding the scroll height constant. * * @param scrollRef - Ref to the ScrollBox handle * @param itemKeys - Stable array of unique keys, one per item * @param columns - Terminal column count. On change, cached heights are scaled. */ export declare function useVirtualScroll(scrollRef: RefObject, itemKeys: readonly string[], columns: number): VirtualScrollResult; //# sourceMappingURL=use-virtual-scroll.d.ts.map