useShortcutRecorder
Hook wrapper around engine.recordShortcut() — the building block for settings pages where users press a key to set a new shortcut.
import { useShortcutRecorder } from '@tactile-js/react';
const { isRecording, combo, start, stop } = useShortcutRecorder();| Field / method | Type | Description |
|---|---|---|
isRecording |
boolean |
Whether listening for the next keystroke. |
combo |
RecordedShortcut | null |
Last captured shortcut, or null before first capture. |
start() |
() => void |
Begin listening. Resolves on next complete keystroke. |
stop() |
() => void |
Cancel without capturing. |
RecordedShortcut
Section titled “RecordedShortcut”{ binding: string; // canonical: 'ctrl+shift+k' — save this to settings label: string; // display: '⇧⌘K' on macOS}Basic UI
Section titled “Basic UI”function RebindButton() { const { isRecording, combo, start, stop } = useShortcutRecorder();
return ( <div> <button onClick={isRecording ? stop : start}> {isRecording ? 'Press any combination…' : 'Change shortcut'} </button> {combo && ( <p> <kbd>{combo.label}</kbd> <span>({combo.binding})</span> </p> )} </div> );}Save to settings
Section titled “Save to settings”wouldCollide here is a small helper over getCollisions():
function wouldCollide(engine: KeybindingEngine, binding: string) { return engine.getCollisions().some((c) => c.keys === binding);}function ShortcutSettings() { const engine = useEngine(); const { combo, start } = useShortcutRecorder(); const [binding, setBinding] = useState('mod+s');
const save = () => { if (!combo) return; if (wouldCollide(engine, combo.binding)) { alert('That shortcut is already in use'); return; } setBinding(combo.binding); persistSettings(combo.binding); };
return ( <> <p>Current: <kbd>{engine.format(binding)}</kbd></p> <button onClick={start}>Record new</button> {combo && <button onClick={save}>Save {combo.label}</button>} </> );}Behavior details
Section titled “Behavior details”- Lone modifier presses are ignored — waits for a “real” key to complete the combo.
preventDefaultis called during recording so the key doesn’t trigger other shortcuts.- Cleans up on unmount — in-progress recording is cancelled if the component unmounts.
- Calling
start()again cancels any previous recording session.
Core equivalent
Section titled “Core equivalent”const stop = kb.recordShortcut(({ binding, label }) => { console.log(binding, label);});// stop(); // cancelNext steps
Section titled “Next steps”- Collision detection — validating a recorded binding before saving
- Playground — try the recorder live under “Advanced”