@knitui/hooks
useKeyboardActions
Keyboard/accessibility activation for an interactive host that is NOT a native <button> — web implementation. Returns { tabIndex, onKeyDown } to spread onto the host so it is focusable and the configured {@link KeyboardActions} fire from the keyboard. The use-keyboard-actions.native sibling maps the same intents to React Native accessibility actions instead. The onKeyDown identity is stable across renders (it reads the latest actions through a ref), so spreading it does not churn the host. A key with no binding passes through to the browser, and a chord with Ctrl/Alt/Meta held is ignored so browser/OS shortcuts keep working. A matched key is preventDefault()ed so Space does not scroll and arrows do not pan the page.
Import
import { useKeyboardActions } from "@knitui/hooks";Signature
export function useKeyboardActions( actions: KeyboardActions, options: UseKeyboardActionsOptions = {}, ): KeyboardActionPropsMost controls in the kit are styled Box elements with a role, not native
<button> elements — which means none of the keyboard behaviour a browser gives
a button comes for free. useKeyboardActions puts it back. You describe intent
(onActivate, onIncrement, onDecrement, onEscape) and the hook returns
props to spread onto the host, mapping each intent to the right mechanism for the
platform.
On web that mapping is a key handler: Space and Enter activate, ArrowUp/ArrowRight
increment, ArrowDown/ArrowLeft decrement, Escape dismisses. On native there is no
DOM key event, so the same intents are exposed as React Native accessibility
actions (increment, decrement, escape) that a screen reader can trigger.
Callers write one set of handlers and get correct behaviour on both. Switch,
Checkbox, Rating and Tree are all built on it.
When to use it
- Making a custom control keyboard-operable when it is not a real
<button>. - Adding arrow-key stepping to something with
role="slider"orrole="spinbutton". - Giving a non-modal overlay an Escape route without a global key listener.
Notes
- Web only: a keypress with Ctrl, Alt or Meta held is ignored, so browser and OS
shortcuts keep working. A matched key is
preventDefault()ed, which is what stops Space from scrolling the page and arrows from panning it. onActivatedeliberately produces no native accessibility action. Native activation already flows through the host'sonPress, so emitting anactivateaction too would fire the handler twice.- The
keysoption (extraKeyboardEvent.keybindings such asHome/End) and thetabIndexoption are web-only, and are ignored on native. disabledremoves the host from the tab order on web (tabIndex: -1) and returns no props at all on native.