@nick-skriabin/glyph 0.1.65 → 0.1.67

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -276,6 +276,18 @@ Set `focusable={false}` if you want the ScrollView to only scroll when a child e
276
276
  </ScrollView>
277
277
  ```
278
278
 
279
+ **Virtualization:** For large lists (1000+ items), add the `virtualize` prop to only render visible children. Heights are auto-measured — no configuration needed:
280
+
281
+ ```tsx
282
+ <ScrollView virtualize style={{ height: 20, border: "single" }}>
283
+ {items.map((item) => (
284
+ <Text key={item.id}>{item.name}</Text>
285
+ ))}
286
+ </ScrollView>
287
+ ```
288
+
289
+ This renders only visible items + a small overscan buffer, making it fast even with 10,000+ items. Use `estimatedItemHeight` prop if your items are taller than 1 line (default).
290
+
279
291
  ### `<List>`
280
292
 
281
293
  Keyboard-navigable selection list with a render callback.
@@ -834,6 +846,7 @@ Interactive examples are included in the repo. Each demonstrates different compo
834
846
  | **jump-nav** | Quick navigation with keyboard hints | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/jump-nav) |
835
847
  | **ansi-text** | ANSI escape codes and colored output | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/ansi-text) |
836
848
  | **image** | Inline images and OS preview | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/image) |
849
+ | **virtualized-list** | Virtualized ScrollView with 10k+ items | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/virtualized-list) |
837
850
  | **showcase** | Progress bars, Spinners, Toasts | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/showcase) |
838
851
  | **dashboard** | Full task manager (all components) | [View →](https://github.com/nick-skriabin/glyph/tree/main/examples/dashboard) |
839
852
 
package/dist/index.d.ts CHANGED
@@ -208,8 +208,23 @@ interface ButtonProps {
208
208
  }
209
209
  declare function Button({ onPress, style, focusedStyle, children, disabled, }: ButtonProps): React.JSX.Element;
210
210
 
211
+ /** Visible range passed to render function in virtualized mode */
212
+ interface VisibleRange {
213
+ /** First visible line index (0-based) */
214
+ start: number;
215
+ /** One past the last visible line index */
216
+ end: number;
217
+ /** Current scroll offset */
218
+ scrollOffset: number;
219
+ /** Viewport height in lines */
220
+ viewportHeight: number;
221
+ }
211
222
  interface ScrollViewProps {
212
- children?: ReactNode;
223
+ /**
224
+ * Children to render. When `virtualize` is true, only visible children are rendered.
225
+ * Can also be a render function `(range: VisibleRange) => ReactNode` for line-based virtualization.
226
+ */
227
+ children?: ReactNode | ((range: VisibleRange) => ReactNode);
213
228
  style?: Style;
214
229
  /** Controlled scroll offset (rows from top) */
215
230
  scrollOffset?: number;
@@ -229,8 +244,25 @@ interface ScrollViewProps {
229
244
  focusable?: boolean;
230
245
  /** Style applied when ScrollView is focused */
231
246
  focusedStyle?: Style;
247
+ /**
248
+ * Total content height in lines (for render function mode).
249
+ * When set with a render function, enables line-based virtualization.
250
+ */
251
+ totalLines?: number;
252
+ /** Extra lines to render above/below viewport (default: 2) */
253
+ overscan?: number;
254
+ /**
255
+ * Enable virtualization. When true, only visible children are rendered.
256
+ * Heights are auto-measured - no need to specify them!
257
+ */
258
+ virtualize?: boolean;
259
+ /**
260
+ * Estimated height per child in lines (default: 1).
261
+ * Used for initial scroll calculations before actual heights are measured.
262
+ */
263
+ estimatedItemHeight?: number;
232
264
  }
233
- declare function ScrollView({ children, style, scrollOffset: controlledOffset, onScroll, defaultScrollOffset, scrollStep, disableKeyboard, scrollToFocus, showScrollbar, focusable, focusedStyle, }: ScrollViewProps): React.JSX.Element;
265
+ declare function ScrollView({ children, style, scrollOffset: controlledOffset, onScroll, defaultScrollOffset, scrollStep, disableKeyboard, scrollToFocus, showScrollbar, focusable, focusedStyle, totalLines, overscan, virtualize, estimatedItemHeight, }: ScrollViewProps): React.JSX.Element;
234
266
 
235
267
  interface ListItemInfo {
236
268
  index: number;
@@ -800,4 +832,4 @@ declare function detectTerminalCapabilities(debug?: boolean): TerminalCapabiliti
800
832
  */
801
833
  declare function supportsInlineImages(): boolean;
802
834
 
803
- export { type AlertOptions, type AnsiStyle, type AppHandle, type BorderStyle, Box, type BoxProps, Button, type ButtonProps, Checkbox, type CheckboxProps, type Color, type ConfirmOptions, type DialogContextValue, DialogHost, type DialogHostProps, type DimensionValue, type FocusRegistryValue, FocusScope, type FocusScopeProps, type FocusableElement, type HexColor, Image, type ImageProps, type ImageState, Input, type InputProps, type InputType, JumpNav, type JumpNavProps, type Key, Keybind, type KeybindProps, type LayoutRect, List, type ListItemInfo, type ListProps, type MaskOptions, Menu, type MenuItem, type MenuProps, type NamedColor, Portal, type PortalProps, Progress, type ProgressProps, type RGBColor, Radio, type RadioItem, type RadioProps, type RenderOptions, ScrollView, type ScrollViewProps, Select, type SelectItem, type SelectProps, Spacer, type SpacerProps, Spinner, type SpinnerProps, type Style, type StyledSegment, type TerminalCapabilities, Text, type TextAlign, type TextProps, type Toast, ToastHost, type ToastHostProps, type ToastPosition, type ToastVariant, type UseFocusableOptions, type UseFocusableResult, type WrapMode, createMask, detectTerminalCapabilities, masks, parseAnsi, render, stripAnsi, supportsInlineImages, useApp, useDialog, useFocus, useFocusRegistry, useFocusable, useInput, useLayout, useToast };
835
+ export { type AlertOptions, type AnsiStyle, type AppHandle, type BorderStyle, Box, type BoxProps, Button, type ButtonProps, Checkbox, type CheckboxProps, type Color, type ConfirmOptions, type DialogContextValue, DialogHost, type DialogHostProps, type DimensionValue, type FocusRegistryValue, FocusScope, type FocusScopeProps, type FocusableElement, type HexColor, Image, type ImageProps, type ImageState, Input, type InputProps, type InputType, JumpNav, type JumpNavProps, type Key, Keybind, type KeybindProps, type LayoutRect, List, type ListItemInfo, type ListProps, type MaskOptions, Menu, type MenuItem, type MenuProps, type NamedColor, Portal, type PortalProps, Progress, type ProgressProps, type RGBColor, Radio, type RadioItem, type RadioProps, type RenderOptions, ScrollView, type ScrollViewProps, Select, type SelectItem, type SelectProps, Spacer, type SpacerProps, Spinner, type SpinnerProps, type Style, type StyledSegment, type TerminalCapabilities, Text, type TextAlign, type TextProps, type Toast, ToastHost, type ToastHostProps, type ToastPosition, type ToastVariant, type UseFocusableOptions, type UseFocusableResult, type VisibleRange, type WrapMode, createMask, detectTerminalCapabilities, masks, parseAnsi, render, stripAnsi, supportsInlineImages, useApp, useDialog, useFocus, useFocusRegistry, useFocusable, useInput, useLayout, useToast };