TanStack Hotkeys version
v0.4.1
Framework/Library version
React v19 (Next.js 15)
Describe the bug and the steps to reproduce it
On macOS, the Option (Alt) key acts as a character composer. Pressing Option+- produces an en-dash (–, U+2013), so event.key is "–" instead of "-". This causes useHotkey("Alt+-", callback) to never fire.
The library correctly handles this remapping for letters and digits by falling back to event.code in matchesKeyboardEvent (in match.ts):
// These fallbacks exist and work:
if (event.code?.startsWith("Key")) { /* letter fallback ✅ */ }
if (event.code?.startsWith("Digit")) { /* digit fallback ✅ */ }
return false; // ← punctuation keys like "Minus" fall through here ❌
There is no equivalent fallback for punctuation keys whose event.code values (Minus, Equal, Slash, BracketLeft, etc.) don't start with Key or Digit.
Steps to reproduce:
- On macOS with an English (US) keyboard layout
- Register
useHotkey("Alt+-", callback)
- Press Option + minus key
- Callback never fires
For comparison, useHotkey("Alt+1", callback) works correctly because it hits the Digit code fallback.
All PUNCTUATION_KEYS are affected when combined with Alt on macOS:
| Hotkey |
event.key on macOS |
event.code |
Matched? |
Alt+- |
– (en-dash) |
Minus |
No |
Alt+= |
≠ |
Equal |
No |
Alt+/ |
÷ |
Slash |
No |
Alt+[ |
" |
BracketLeft |
No |
Alt+] |
' |
BracketRight |
No |
Alt+\ |
« |
Backslash |
No |
Alt+, |
≤ |
Comma |
No |
Alt+. |
≥ |
Period |
No |
Suggested fix — add a punctuation code fallback in matchesKeyboardEvent, after the existing Digit fallback:
const PUNCTUATION_CODE_MAP: Record<string, string> = {
Minus: "-",
Equal: "=",
Slash: "/",
BracketLeft: "[",
BracketRight: "]",
Backslash: "\\",
Comma: ",",
Period: ".",
Backquote: "`",
};
if (event.code && event.code in PUNCTUATION_CODE_MAP) {
return PUNCTUATION_CODE_MAP[event.code] === hotkeyKey;
}
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/vitejs-vite-6pdg1d7r?file=src%2FApp.tsx
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Yes, I am also opening a PR that solves the problem along side this issue
Terms & Code of Conduct
TanStack Hotkeys version
v0.4.1
Framework/Library version
React v19 (Next.js 15)
Describe the bug and the steps to reproduce it
On macOS, the Option (Alt) key acts as a character composer. Pressing
Option+-produces an en-dash (–, U+2013), soevent.keyis"–"instead of"-". This causesuseHotkey("Alt+-", callback)to never fire.The library correctly handles this remapping for letters and digits by falling back to
event.codeinmatchesKeyboardEvent(inmatch.ts):There is no equivalent fallback for punctuation keys whose
event.codevalues (Minus,Equal,Slash,BracketLeft, etc.) don't start withKeyorDigit.Steps to reproduce:
useHotkey("Alt+-", callback)For comparison,
useHotkey("Alt+1", callback)works correctly because it hits theDigitcode fallback.All
PUNCTUATION_KEYSare affected when combined withAlton macOS:event.keyon macOSevent.codeAlt+-–(en-dash)MinusAlt+=≠EqualAlt+/÷SlashAlt+["BracketLeftAlt+]'BracketRightAlt+\«BackslashAlt+,≤CommaAlt+.≥PeriodSuggested fix — add a punctuation code fallback in
matchesKeyboardEvent, after the existingDigitfallback:Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://stackblitz.com/edit/vitejs-vite-6pdg1d7r?file=src%2FApp.tsx
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Yes, I am also opening a PR that solves the problem along side this issue
Terms & Code of Conduct