/** * useVirtualList Hook * * Enhanced virtual list hook with overscan support for smoother scrolling * and pinToEnd mode for log tailing. This is the successor to useScrollableList. * * @since v1.9.0 * @since v1.50.6 - Added scrollMode option for center-scroll behavior */ /** * Scroll mode for the virtual list * - 'item-by-item': Scrolls one item at a time when selection reaches edge (default) * - 'center': Keeps selection centered in viewport (Claude Code style) */ export type ScrollMode = 'item-by-item' | 'center'; /** * Options for the useVirtualList hook */ export interface VirtualListOptions { /** Total number of items in the list */ itemCount: number; /** Number of visible items in the viewport */ viewportHeight: number; /** Currently selected/focused index */ selectedIndex: number; /** * Number of extra items to render above/below viewport (default: 0). * * WARNING: any overscan > 0 is wrong for Ink (v2.11.60). Overscan exists for * browser-style virtualization where off-viewport items are positioned * off-screen via CSS — Ink has no off-screen positioning, so every rendered * child takes real flex space and overscan items overflow/clip/stack on top * of in-viewport rows ("items disappearing in the same spot"). The option is * kept only so the pure helpers stay testable; production call sites must * not pass a value > 0 (enforced by a hygiene test in useVirtualList.test.ts). */ overscan?: number; /** Pin scroll to end of list - useful for log tailing (default: false) */ pinToEnd?: boolean; /** Dependencies that should reset scroll position when changed */ resetDeps?: unknown[]; /** Scroll mode: 'item-by-item' (default) or 'center' (v1.50.6) */ scrollMode?: ScrollMode; } /** * State returned by the useVirtualList hook */ export interface VirtualListState { /** First item index to render (includes overscan) */ startIndex: number; /** Last item index to render - exclusive (includes overscan) */ endIndex: number; /** Number of items hidden above the logical viewport */ hiddenAbove: number; /** Number of items hidden below the logical viewport */ hiddenBelow: number; /** Current scroll offset (first visible item index, not including overscan) */ scrollOffset: number; /** Number of items in the logical viewport */ visibleCount: number; /** Function to scroll to a specific index */ scrollTo: (index: number) => void; } /** * Pure function to calculate new scroll offset based on selection * Compatible with useScrollableList for easy migration. * * @param prevOffset - Previous scroll offset * @param selectedIndex - Currently selected item index * @param itemCount - Total number of items * @param viewportHeight - Number of visible items * @param scrollMode - Scroll mode: 'item-by-item' or 'center' (v1.50.6) */ export declare function calculateScrollOffsetWithOverscan(prevOffset: number, selectedIndex: number, itemCount: number, viewportHeight: number, scrollMode?: ScrollMode): number; /** * Pure function to calculate visible window with overscan support */ export declare function calculateVirtualWindow(scrollOffset: number, options: VirtualListOptions): Omit; /** * Hook for managing virtual list state with overscan and pinToEnd support * * @example * ```tsx * const { startIndex, endIndex, scrollTo } = useVirtualList({ * itemCount: items.length, * viewportHeight: 10, * selectedIndex, * resetDeps: [searchQuery], * }); * * const visibleItems = items.slice(startIndex, endIndex); * ``` */ export declare function useVirtualList(options: VirtualListOptions): VirtualListState; //# sourceMappingURL=useVirtualList.d.ts.map