Keys
Composable, scoped keyboard navigation hooks for React >=19.2.0.
Composable, scoped keyboard navigation hooks for React >=19.2.0.
- Zero runtime dependencies
- Scope stack -- only the topmost scope receives events, no conflicts between layers
- React
>=19.2.0ready -- stable callback/ref patterns without stale closures - ESM only
Note: Diffgazer packages are not yet published to npm. Until the first release, pack @diffgazer/ui and @diffgazer/keys from the repository and install those tarballs.
Installation options
@diffgazer/ui components are not all visual-only. Some copied components include local keyboard handling, and some package-mode entries import hooks from @diffgazer/keys. You have four ways to source keyboard hooks:
Option 1: dgadd component install
When you install a @diffgazer/ui component that requires keyboard hooks via dgadd, choose whether to copy the standalone hooks or import the @diffgazer/keys package:
This works from bundled registry metadata. Components that reference keyboard hooks declare the keys hook dependency, and dgadd installs the matching integration before writing files.
You can also install hooks standalone:
Option 2: Install @diffgazer/keys package
Install the package. Before publication it is not on npm, so pack it from a checkout of the repository and install that tarball (Consumption Paths):
After publication, this becomes:
You can also let dgadd set up keys integration:
Components import hooks directly from the @diffgazer/keys package. Gives you the full API including KeyboardProvider, useKey, useScope, and useFocusZone.
Option 3: Copy standalone hooks
Copies standalone hooks into your project at @/hooks/. No @diffgazer/keys dependency required. Components import from local paths:
Option 4: Manual copy-paste
Copy the hook source code from the Hook Source Code section below into your project.
Quick start
Wrap your app with KeyboardProvider, then use hooks anywhere inside it:
mod maps to Meta on Mac and Ctrl on Windows/Linux.
Hooks reference
* useKey silently does nothing without a provider — safe to use in portable components.
Standalone hooks (useNavigation, useFocusTrap, useFocusRestore, useScrollLock) work without KeyboardProvider and are available in copy mode. The rest require the full @diffgazer/keys package.
Patterns with @diffgazer/ui
@diffgazer/ui components declare their keyboard dependencies through registry metadata. In copy mode, dgadd can copy standalone hooks. In keys mode and runtime package mode, imports resolve through @diffgazer/keys. Components that expose controlled highlight state, selection state, or onKeyDown composition can still be coordinated by app-level handlers. See the Patterns page for complete integration examples with Menu, Dialog, CommandPalette, Tabs, and multi-zone layouts.
What each path gives you
Hook source code
Utility hooks
For the complete API reference, visit the @diffgazer/keys documentation.