Use createHotkeySequenceRecorder to capture a series of shortcut chords. By default, each step records its physical code: pressing G twice produces ['[KeyG]', '[KeyG]']. Set recordBy: 'key' to follow logical characters instead. Pass the resulting array directly to sequence registration and format each step for display.
This example uses a Save button so plain Enter can be recorded as a step:
import { Show } from 'solid-js'
import { createHotkeySequenceRecorder, formatForDisplay } from '@tanstack/solid-hotkeys'
function SequenceRecorder() {
const recorder = createHotkeySequenceRecorder({
commitKeys: 'none',
onRecord: (sequence) => console.log('Register or persist:', sequence),
onReject: ({ message }) => console.log(message),
})
const label = () =>
(recorder.isRecording() ? recorder.steps() : recorder.recordedSequence() ?? [])
.map((step) => formatForDisplay(step)).join(' → ')
return (
<div>
<button onClick={recorder.startRecording}>Record sequence</button>
<p>{label()}</p>
<Show when={recorder.isRecording()}>
<button onClick={recorder.commitRecording}>Save</button>
<button onClick={recorder.cancelRecording}>Cancel</button>
</Show>
</div>
)
}The recorder exposes isRecording, steps, and recordedSequence as accessors. steps contains the current attempt; recordedSequence contains the last committed result. startRecording() begins a new session. commitRecording() saves a nonempty attempt, while cancelRecording() discards it and calls onCancel. stopRecording() resets recorder state without calling onRecord or onCancel.
Escape cancels. Unmodified Backspace/Delete removes the last step; when already empty it stops and calls only onClear. Modifier-only presses, automatic repeats, and IME composition do not append steps. Recorded events and their releases do not trigger application shortcuts.
Set provider defaults through HotkeysProvider with defaultOptions.hotkeySequenceRecorder.
validate(sequence, { events, parsedSequence }) runs at commit. Return true to accept, or false/a message to reject. detectConflicts checks live bindings and sequence prefixes, including physical/logical overlap established by the recorded events. onReject receives feedback; rejected steps remain editable with Backspace.
The shared options and exclusions are described in the hotkey recording guide. The application owns reset, persistence, and any binding being edited; clearing never calls onRecord([]).