Skip to content

Add list components: VirtualList, Paginator, Viewport, Autocomplete, and Confirm#4

Merged
zion-off merged 1 commit intomainfrom
create-list-components
Feb 20, 2026
Merged

Add list components: VirtualList, Paginator, Viewport, Autocomplete, and Confirm#4
zion-off merged 1 commit intomainfrom
create-list-components

Conversation

@zion-off
Copy link
Owner

Summary

Adds a set of new UI components for working with lists and user prompts, and enhances existing Select/MultiSelect with virtualization support.

  • VirtualList — a headless virtualized list that renders only a visible window of items, with auto-scroll (highlight-based) or controlled scroll offset modes
  • Paginator — overflow indicator with three styles: arrows, scrollbar, and counter
  • Viewport — a scrollable read-only view with keyboard navigation (j/k, page up/down, g/G) and optional line numbers
  • Autocomplete — a filterable select with a text input, inline cursor rendering, and case-aware matching
  • Confirm — a minimal yes/no prompt component

Select and MultiSelect now accept maxVisible, paginatorStyle, and wrap props, and delegate vertical rendering to VirtualList so long option lists are paginated automatically. Highlight navigation also wraps around by default.

Bumps version to 0.3.4.

@zion-off zion-off merged commit ed11591 into main Feb 20, 2026
zion-off added a commit that referenced this pull request Feb 23, 2026
useFocusNode is now store-based: registers in FocusStore via useEffect,
reads hasFocus reactively via useSyncExternalStore. The old focused/focus()
shape is gone.

UI components (Select, TextInput, Autocomplete, MultiSelect, Confirm) updated
to use focus.hasFocus. Viewport, Modal, and CommandPalette needed no changes.

FocusTrap now uses the store directly for setTrap/clearTrap/focusFirstChild/
focusNode/getFocusedId. Children are scoped via ScopeIdContext.Provider.

ScreenEntry (router) migrated from FocusContext to useFocusNode + store.

useKeybindingRegistry now reads the active branch path from the store
instead of FocusContext.

GigglesProvider no longer wraps children in FocusProvider — the store is
the only focus system.

Deleted: FocusContext, FocusGroup, useFocus, FocusBindContext, types (FocusHandle),
useFocusState. The dual-registration bridge from chunk #4 is gone.

Public API: FocusGroup/useFocus/FocusHandle/FocusGroupHelpers removed.
New exports: useFocusScope, FocusScope, useFocusNode (new), FocusScopeHandle,
FocusScopeHelpers, FocusScopeOptions, FocusNodeHandle.
zion-off added a commit that referenced this pull request Feb 24, 2026
useFocusNode is now store-based: registers in FocusStore via useEffect,
reads hasFocus reactively via useSyncExternalStore. The old focused/focus()
shape is gone.

UI components (Select, TextInput, Autocomplete, MultiSelect, Confirm) updated
to use focus.hasFocus. Viewport, Modal, and CommandPalette needed no changes.

FocusTrap now uses the store directly for setTrap/clearTrap/focusFirstChild/
focusNode/getFocusedId. Children are scoped via ScopeIdContext.Provider.

ScreenEntry (router) migrated from FocusContext to useFocusNode + store.

useKeybindingRegistry now reads the active branch path from the store
instead of FocusContext.

GigglesProvider no longer wraps children in FocusProvider — the store is
the only focus system.

Deleted: FocusContext, FocusGroup, useFocus, FocusBindContext, types (FocusHandle),
useFocusState. The dual-registration bridge from chunk #4 is gone.

Public API: FocusGroup/useFocus/FocusHandle/FocusGroupHelpers removed.
New exports: useFocusScope, FocusScope, useFocusNode (new), FocusScopeHandle,
FocusScopeHelpers, FocusScopeOptions, FocusNodeHandle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant