Version v26.10.5 Size 2.9 KB gzip
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();
});| Feature | Per-component navigation | Focus |
|---|---|---|
| Bundle size | n/a | 2.9 KB |
| Zero dependencies | n/a | |
| RTL mirroring | Manual | Built in |
| Grid navigation | Flat only | createGridNavigation() |
| Quick Look grids | Manual Space handling | createQuickLookGrid() |
| Typeahead | Manual | Optional via typeahead |
| Focus restoration | Manual capture | captureFocus() / 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/focussh
npm install @vielzeug/focussh
yarn add @vielzeug/focusQuick 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 resultscreateGridNavigation(): two-dimensional arrow-key navigation with fixed or measured columnscreateQuickLookGrid(): 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(), andrescueFocus(): explicit return-focus and unmount-rescue helpers