Skip to content
focus logoFocusInput
Framework-neutral list navigation and focus restoration primitives.
Version
v26.10.5
Size
2.9 KB gzip
Browser
createListNavigationcreateGridNavigationcreateQuickLookGridcaptureFocusrestoreFocus View all 6 exports

Why Focus? ​

Composite widgets need consistent keyboard navigation and predictable return focus behavior. Focus centralizes those primitives without coupling to component rendering or framework state.

ts
// Before
list.addEventListener('keydown', (event) => {
  // arrow/home/end bookkeeping, disabled filtering, wrapping
});

// After
const nav = createListNavigation({ getItems });
list.addEventListener('keydown', (event) => {
  nav.handleKeydown(event)?.change?.item.focus();
});
FeaturePer-component navigationFocus
Bundle sizen/a2.9 KB
Zero dependenciesn/a
RTL mirroringManualBuilt in
Grid navigationFlat onlycreateGridNavigation()
Quick Look gridsManual Space handlingcreateQuickLookGrid()
TypeaheadManualOptional via typeahead
Focus restorationManual capturecaptureFocus() / restoreFocus()

Use Focus when a widget needs arrow-key navigation, Home/End, and controlled focus restoration.

Consider direct focus calls when interaction is a single isolated element with no composite navigation.

Installation ​

sh
pnpm add @vielzeug/focus
sh
npm install @vielzeug/focus
sh
yarn add @vielzeug/focus

Quick Start ​

ts
import { captureFocus, createListNavigation } from '@vielzeug/focus';

const restore = captureFocus();
const nav = createListNavigation({
  getItems: () => items,
  loop: true,
});
const onKeydown = (event: KeyboardEvent) => nav.handleKeydown(event)?.change?.item.focus();

container.addEventListener('keydown', onKeydown);

restore();
container.removeEventListener('keydown', onKeydown);

Features ​

  • createListNavigation(): pure composite navigation with explicit handled/change results
  • createGridNavigation(): two-dimensional arrow-key navigation with fixed or measured columns
  • createQuickLookGrid(): tile-grid arrow browsing with a Space preview key for card pickers
  • Orientation and direction support: vertical/horizontal/both with LTR/RTL defaults
  • Dynamic item queries: disabled filtering and loop control
  • Optional typeahead: label-based navigation in key-driven lists
  • captureFocus(), restoreFocus(), and rescueFocus(): explicit return-focus and unmount-rescue helpers

Documentation ​

See Also ​

  • Refine: component primitives integrating list navigation.
  • Keymap: global and scoped keyboard shortcuts.
  • Ore: lifecycle ownership used by consumer components.