Shift+punctuation hotkeys (Mod+Shift+[ / ]) are layout-dependent
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 719
- Forks
- 47
- Avg merge
- 5d 5h
- Merged PRs (30d)
- 1
Description
TanStack Hotkeys version
0.1.0
Framework/Library version
React 19 (also reproducible with core matcher behavior)
Describe the bug
Mod+Shift+[ / ] cannot be represented robustly with a single registration across layouts/browser event variations.
For this common shortcut pattern, event.key may arrive as either [ / ] or { / } depending on layout/IME/browser behavior.
Current behavior appears to rely on event.key for punctuation matching, while event.code fallback exists only for letters/digits. That makes bracket shortcuts layout-sensitive.
Minimal repro
useHotkey({ key: '{', mod: true, shift: true }, () => console.log('prev'))
useHotkey({ key: '}', mod: true, shift: true }, () => console.log('next'))
And event logging for the same physical combo:
window.addEventListener('keydown', (e) => {
if (e.metaKey && e.shiftKey && (e.code === 'BracketLeft' || e.code === 'BracketRight')) {
console.log({ key: e.key, code: e.code })
}
})
Depending on environment, the combo can surface as key: '['/']' instead of {/} (or vice versa), so one registration path fails.
Expected behavior
A single logical definition for previous/next tab should work reliably across keyboard layouts/event key variants.
Possible fix directions
- Add optional
event.codefallback for punctuation keys (e.g.BracketLeft,BracketRight). - Add an explicit code-based registration mode/syntax.
- Provide a built-in alias strategy for shifted punctuation keys.
Related
- #17
- #19
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the core matcher behavior used by useHotkey and inspect how event.key is matched and when event.code fallback is applied. Reproduce the BracketLeft and BracketRight cases with the provided minimal example and event logging, then verify that one logical registration handles both bracket and brace key variants across layouts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100