### Install ink-virtual-list Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Instructions for installing the ink-virtual-list package using npm, jsr, and bun. ```bash # npm npm install ink-virtual-list # jsr npx jsr add @archcorsair/ink-virtual-list # bun bun add ink-virtual-list ``` -------------------------------- ### Auto-fill Terminal Height with VirtualList (TSX) Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Shows how to configure the VirtualList to automatically fill the available terminal height. This example uses `height="auto"` and `reservedLines` to leave space for other UI elements like headers or footers. ```tsx {item}} /> ``` -------------------------------- ### Imperative Scrolling with VirtualList Ref (TSX) Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Demonstrates how to use the `useRef` hook to get a reference to the VirtualList component, enabling imperative control over scrolling. The example shows how to call `scrollToIndex` to programmatically scroll to a specific item. ```tsx import { useRef } from 'react'; import type { VirtualListRef } from 'ink-virtual-list'; function App() { const listRef = useRef(null); const scrollToTop = () => { listRef.current?.scrollToIndex(0, 'top'); }; return ( {item}} /> ); } ``` -------------------------------- ### Type-Safe Rendering of Complex Data with VirtualList in React Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt This example demonstrates using the VirtualList component from ink-virtual-list with TypeScript generics for type-safe rendering of complex data structures like user objects. It ensures that item properties and render functions adhere to the defined type safety at compile time. The VirtualList component efficiently renders large lists of items, displaying only those currently visible in the terminal. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Box, Text } from 'ink'; import { useState } from 'react'; interface User { id: number; name: string; email: string; role: 'admin' | 'user' | 'guest'; active: boolean; } function UserTable({ users }: { users: User[] }) { const [selectedIndex, setSelectedIndex] = useState(0); return ( Name Email Role Status items={users} selectedIndex={selectedIndex} height="auto" reservedLines={8} keyExtractor={(user) => String(user.id)} renderItem={({ item, isSelected }) => ( {item.name} {item.email} {item.role} {item.active ? 'Active' : 'Inactive'} )} /> ); } ``` -------------------------------- ### Get Terminal Size with useTerminalSize Hook in React Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt The useTerminalSize hook from ink-virtual-list provides the current terminal dimensions (rows and columns). It automatically updates these values when the terminal is resized, which is essential for creating responsive terminal UIs. This hook is useful for adapting the layout of your application based on available screen space. ```tsx import { useTerminalSize } from 'ink-virtual-list'; import { Box, Text } from 'ink'; function ResponsiveLayout() { const { rows, columns } = useTerminalSize(); const layout = columns > 100 ? 'wide' : columns > 60 ? 'medium' : 'narrow'; return ( Terminal size: {columns}×{rows} Layout mode: {layout} {layout === 'wide' && ( Left Panel Right Panel )} {layout === 'narrow' && ( Stacked layout for narrow terminals )} ); } ``` -------------------------------- ### VirtualList Ref Methods Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md This section outlines the imperative methods available through a ref attached to the VirtualList component. ```APIDOC ## VirtualList Ref Methods An imperative API is available via a ref attached to the `VirtualList` component. The ref should be typed as `VirtualListRef`. ```typescript interface VirtualListRef { scrollToIndex: (index: number, alignment?: 'auto' | 'top' | 'center' | 'bottom') => void; getViewport: () => ViewportState; remeasure: () => void; } ``` ### `scrollToIndex(index, alignment?)` Scrolls the list to bring the item at the specified `index` into view. The `alignment` parameter controls how the item is positioned within the viewport: - **`'auto'`** (default): The list only scrolls if the item is not already visible. - **`'top'`**: Aligns the top of the item with the top of the viewport. - **`'center'`**: Centers the item within the viewport. - **`'bottom'`**: Aligns the bottom of the item with the bottom of the viewport. ### `getViewport()` Returns the current state of the list's viewport. The returned `ViewportState` object contains: - **`offset`** (number): The number of items that have been scrolled past from the beginning of the list. - **`visibleCount`** (number): The number of items currently visible within the viewport. - **`totalCount`** (number): The total number of items in the list. ### `remeasure()` Forces the `VirtualList` to recalculate its dimensions and layout. This is useful if the content of the list or the terminal size changes in a way that the component cannot automatically detect. ``` -------------------------------- ### Basic VirtualList Usage in React (TSX) Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Demonstrates a basic implementation of the VirtualList component, rendering a large list of items with selection highlighting. It utilizes React's useState hook to manage the selected index and renders each item with conditional styling. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Text } from 'ink'; import { useState } from 'react'; function App() { const [selectedIndex, setSelectedIndex] = useState(0); const items = Array.from({ length: 1000 }, (_, i) => `Item ${i + 1}`); return ( ( {isSelected ? '> ' : ' '} {item} )} /> ); } ``` -------------------------------- ### VirtualList Component API Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md This section details the available props for configuring the VirtualList component. ```APIDOC ## VirtualList Component Props ### Required Props - **`items`** (T[]) - An array of items to be rendered in the list. `T` represents the type of items in the array. - **`renderItem`** ((props: RenderItemProps) => ReactNode) - A function that renders each visible item. It receives an object with `item` (the data for the item), `index` (the item's index in the `items` array), and `isSelected` (a boolean indicating if the item is currently selected). ### Optional Props - **`selectedIndex`** (number) - The index of the currently selected item. Defaults to `0`. - **`keyExtractor`** ((item: T, index: number) => string) - A function to extract a unique key for each item, which is crucial for React's reconciliation. Defaults to using the item's index. - **`height`** (number | "auto") - The height of the virtual list in terminal lines. Can be a number for a fixed height, or `'auto'` to fill the available terminal space. Defaults to `10`. - **`reservedLines`** (number) - When `height` is set to `'auto'`, this specifies the number of lines to reserve at the top and bottom for headers or footers. Defaults to `0`. - **`itemHeight`** (number) - The height of each individual item in terminal lines. Defaults to `1`. - **`showOverflowIndicators`** (boolean) - Determines whether to display indicators for hidden items above or below the visible viewport. Defaults to `true`. - **`renderOverflowTop`** ((count: number) => ReactNode) - A custom function to render the indicator for hidden items at the top of the list. Receives the `count` of hidden items. - **`renderOverflowBottom`** ((count: number) => ReactNode) - A custom function to render the indicator for hidden items at the bottom of the list. Receives the `count` of hidden items. - **`renderScrollBar`** ((viewport: ViewportState) => ReactNode) - A custom function to render a scrollbar based on the current `viewport` state. - **`onViewportChange`** ((viewport: ViewportState) => void) - A callback function that is invoked whenever the visible viewport of the list changes. It receives the current `ViewportState`. ``` -------------------------------- ### Basic VirtualList Component Usage with Keyboard Navigation Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt Demonstrates the core VirtualList component for rendering a large list of items. It uses Ink's `useInput` hook for basic keyboard navigation (up/down arrows) to select items and highlights the selected item. The component requires `items`, `selectedIndex`, `height`, and a `renderItem` function. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Box, Text, useInput } from 'ink'; import { useState } from 'react'; function App() { const [selectedIndex, setSelectedIndex] = useState(0); const items = Array.from({ length: 10000 }, (_, i) => `Item ${i + 1}`); useInput((input, key) => { if (key.upArrow) { setSelectedIndex(prev => Math.max(0, prev - 1)); } if (key.downArrow) { setSelectedIndex(prev => Math.min(items.length - 1, prev + 1)); } }); return ( ( {isSelected ? '> ' : ' '} {item} )} /> ); } ``` -------------------------------- ### Render Large List with Ink Virtual List Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md This snippet demonstrates rendering a large list of 'Todo' items using the 'ink-virtual-list' component. It utilizes React hooks for state management and a ref for list manipulation. The component handles item selection and custom rendering based on item properties. Dependencies include 'ink' and 'ink-virtual-list'. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Box, Text } from 'ink'; import { useRef, useState } from 'react'; import type { VirtualListRef } from 'ink-virtual-list'; interface Todo { id: string; title: string; completed: boolean; } function TodoApp() { const [todos] = useState([ { id: '1', title: 'Learn Ink', completed: true }, { id: '2', title: 'Build CLI', completed: false }, // ... 1000s more ]); const [selectedIndex, setSelectedIndex] = useState(0); const listRef = useRef(null); return ( My Todos ({todos.length}) todo.id} renderItem={({ item, isSelected }) => ( {isSelected ? '❯ ' : ' '} {item.completed ? '✓' : '○'} {item.title} )} /> {selectedIndex + 1} / {todos.length} ); } ``` -------------------------------- ### VirtualList Ref Methods TypeScript Interface Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Defines the TypeScript interface for the `VirtualListRef`, outlining the available methods for imperative control over the list, such as scrolling and retrieving viewport information. ```typescript interface VirtualListRef { scrollToIndex: (index: number, alignment?: 'auto' | 'top' | 'center' | 'bottom') => void; getViewport: () => ViewportState; remeasure: () => void; } ``` -------------------------------- ### ViewportState TypeScript Interface Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md TypeScript interface describing the state of the VirtualList's viewport, providing information about the scroll offset, the number of visible items, and the total number of items in the list. ```typescript interface ViewportState { offset: number; // Items scrolled past visibleCount: number; // Items currently visible totalCount: number; // Total items } ``` -------------------------------- ### Custom Overflow Indicators for VirtualList (TSX) Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Illustrates how to customize the overflow indicators displayed by VirtualList when there are hidden items above or below the visible viewport. This allows for custom styling and text for these indicators. ```tsx ↑ {count} hidden} renderOverflowBottom={(count) => ↓ {count} hidden} renderItem={({ item }) => {item}} /> ``` -------------------------------- ### Multi-line Items with ink-virtual-list Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt Configure `itemHeight` to support items that span multiple lines, ensuring consistent viewport calculations and proper clipping of content that exceeds the allocated height. This requires the `VirtualList` component from 'ink-virtual-list' and `Box`, `Text` from 'ink'. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Box, Text } from 'ink'; interface Task { id: string; title: string; description: string; status: 'todo' | 'in-progress' | 'done'; } function TaskList({ tasks }: { tasks: Task[] }) { return ( task.id} renderItem={({ item, isSelected }) => ( {item.title} [{item.status}] {item.description} )} /> ); } ``` -------------------------------- ### Imperative Scrolling API with ink-virtual-list Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt Programmatically control scroll position using ref methods with multiple alignment options. This is useful for features like 'jump to top', search result navigation, or bookmark navigation. It requires the `VirtualList` component and `VirtualListRef` type from 'ink-virtual-list', and `Box`, `Text`, `useInput` from 'ink'. ```tsx import { VirtualList, type VirtualListRef } from 'ink-virtual-list'; import { Box, Text, useInput } from 'ink'; import { useRef, useState } from 'react'; function SearchableList({ items }: { items: string[] }) { const listRef = useRef(null); const [selectedIndex, setSelectedIndex] = useState(0); useInput((input, key) => { if (key.upArrow) { setSelectedIndex(prev => Math.max(0, prev - 1)); } if (key.downArrow) { setSelectedIndex(prev => Math.min(items.length - 1, prev + 1)); } if (input === 'h') { // Jump to top setSelectedIndex(0); listRef.current?.scrollToIndex(0, 'top'); } if (input === 'l') { // Jump to bottom const lastIndex = items.length - 1; setSelectedIndex(lastIndex); listRef.current?.scrollToIndex(lastIndex, 'bottom'); } if (input === 'm') { // Jump to middle const middleIndex = Math.floor(items.length / 2); setSelectedIndex(middleIndex); listRef.current?.scrollToIndex(middleIndex, 'center'); } }); const viewport = listRef.current?.getViewport(); return ( h: home | l: end | m: middle | ↑↓: navigate {viewport && ( Viewing {viewport.offset + 1}-{viewport.offset + viewport.visibleCount} of {viewport.totalCount} )} ( {isSelected ? '► ' : ' '}{item} )} /> ); } ``` -------------------------------- ### VirtualList Types Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md Defines the TypeScript types used by the ink-virtual-list component. ```APIDOC ## VirtualList Types ### `RenderItemProps` This interface describes the props passed to the `renderItem` function. ```typescript interface RenderItemProps { item: T; index: number; isSelected: boolean; } ``` - **`item`** (T): The data for the current item being rendered. - **`index`** (number): The index of the current item in the `items` array. - **`isSelected`** (boolean): A flag indicating whether this item is currently the selected item in the list. ### `ViewportState` This interface represents the current state of the list's visible viewport. ```typescript interface ViewportState { offset: number; visibleCount: number; totalCount: number; } ``` - **`offset`** (number): The number of items that are above the visible area (scrolled past). - **`visibleCount`** (number): The number of items that are currently visible within the viewport. - **`totalCount`** (number): The total number of items available in the list. ``` -------------------------------- ### Customizing Overflow Indicators for VirtualList Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt Illustrates how to customize the overflow indicators for the VirtualList component. By setting `showOverflowIndicators={true}` and providing `renderOverflowTop` and `renderOverflowBottom` functions, you can replace the default indicators with custom UI elements to visually represent hidden content. ```tsx import { VirtualList } from 'ink-virtual-list'; import { Box, Text } from 'ink'; function CustomList({ items }: { items: string[] }) { return ( ( ↑ {count} items hidden above ↑ )} renderOverflowBottom={(count) => ( ↓ {count} items hidden below ↓ )} renderItem={({ item, index }) => ( [{index + 1}] {item} )} /> ); } ``` -------------------------------- ### RenderItemProps TypeScript Interface Source: https://github.com/archcorsair/ink-virtual-list/blob/main/README.md TypeScript interface defining the properties passed to the `renderItem` function for each item in the VirtualList. It includes the item data, its index, and whether it's currently selected. ```typescript interface RenderItemProps { item: T; index: number; isSelected: boolean; } ``` -------------------------------- ### Viewport Change Callbacks with ink-virtual-list Source: https://context7.com/archcorsair/ink-virtual-list/llms.txt Monitor viewport state changes using the `onViewportChange` callback to implement features like lazy loading, analytics, or synchronized scrolling. This requires the `VirtualList` and `ViewportState` type from 'ink-virtual-list', and `Box`, `Text`, `useState`, `useEffect` from 'ink'. ```tsx import { VirtualList, type ViewportState } from 'ink-virtual-list'; import { Box, Text } from 'ink'; import { useState, useEffect } from 'react'; function InfiniteList() { const [items, setItems] = useState(() => Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`) ); const [isLoading, setIsLoading] = useState(false); const handleViewportChange = (viewport: ViewportState) => { const scrollProgress = (viewport.offset + viewport.visibleCount) / viewport.totalCount; // Load more when scrolled 80% through the list if (scrollProgress > 0.8 && !isLoading) { setIsLoading(true); setTimeout(() => { setItems(prev => [ ...prev, ...Array.from({ length: 50 }, (_, i) => `Item ${prev.length + i + 1}`) ]); setIsLoading(false); }, 500); } }; return ( {item}} /> {isLoading && Loading more items...} ); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.