Skip to content
tactile

KeybindProvider

Creates (or adopts) a single engine and shares it with all descendants.

import { KeybindProvider } from '@tactile-js/react';
<KeybindProvider options={{ defaultMatch: 'hybrid', debug: false }}>
<App />
</KeybindProvider>
Prop Type Description
options EngineOptions Passed to createKeybindingEngine() when creating a new engine. Ignored if engine is set.
engine KeybindingEngine Supply a pre-built engine. Provider will not dispose it on unmount.
children ReactNode App tree.
  • Engine is created once per provider mount (lazy useState initializer).
  • Provider-created engines call engine.dispose() on unmount.
  • Injected engines are left alone.
// Testing: share one engine across tests
const kb = createKeybindingEngine();
render(
<KeybindProvider engine={kb}>
<ComponentUnderTest />
</KeybindProvider>,
);
// kb.dispose() — your responsibility
<KeybindProvider
options={{
defaultMatch: 'hybrid',
sequenceTimeout: 2000,
debug: import.meta.env.DEV,
ignore: defaultIgnore, // or () => false
}}
>

See Engine options.


Access the engine from any descendant of KeybindProvider.

import { useEngine } from '@tactile-js/react';
function HelpButton() {
const engine = useEngine();
return (
<button onClick={() => console.log(engine.getKeymap())}>
Log keymap
</button>
);
}

Throws a clear error if used outside a provider.

const engine = useEngine();
// Format labels
engine.format('mod+k'); // '⌘K' or 'Ctrl+K'
// Imperative context (prefer useScope in components)
engine.context.set('modalOpen', true);
// Introspection
engine.getCollisions();
engine.getKeymap();
// Subscribe outside React
engine.subscribeKeymap(() => refresh());
engine.context.subscribe(() => refresh());

Let the provider manage disposal. If you injected the engine, dispose it when your app shuts down.