()
| 10 | import './index.css' |
| 11 | |
| 12 | function App() { |
| 13 | const [lastSequence, setLastSequence] = React.useState<string | null>(null) |
| 14 | const [history, setHistory] = React.useState<Array<string>>([]) |
| 15 | const [helloSequenceEnabled, setHelloSequenceEnabled] = React.useState(true) |
| 16 | |
| 17 | const addToHistory = (action: string) => { |
| 18 | setLastSequence(action) |
| 19 | setHistory((h) => [...h.slice(-9), action]) |
| 20 | } |
| 21 | |
| 22 | useHotkeySequence(['G', 'G'], () => addToHistory('gg → Go to top')) |
| 23 | useHotkeySequence(['Shift+G'], () => addToHistory('G → Go to bottom')) |
| 24 | useHotkeySequence(['D', 'D'], () => addToHistory('dd → Delete line')) |
| 25 | useHotkeySequence(['Y', 'Y'], () => addToHistory('yy → Yank (copy) line')) |
| 26 | useHotkeySequence(['D', 'W'], () => addToHistory('dw → Delete word')) |
| 27 | useHotkeySequence(['C', 'I', 'W'], () => |
| 28 | addToHistory('ciw → Change inner word'), |
| 29 | ) |
| 30 | |
| 31 | useHotkeySequence( |
| 32 | ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown'], |
| 33 | () => addToHistory('↑↑↓↓ → Konami code (partial)'), |
| 34 | { timeout: 1500 }, |
| 35 | ) |
| 36 | |
| 37 | useHotkeySequence( |
| 38 | ['ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight'], |
| 39 | () => addToHistory('←→←→ → Side to side!'), |
| 40 | { timeout: 1500 }, |
| 41 | ) |
| 42 | |
| 43 | useHotkeySequence( |
| 44 | ['H', 'E', 'L', 'L', 'O'], |
| 45 | () => addToHistory('hello → Hello World!'), |
| 46 | { enabled: helloSequenceEnabled }, |
| 47 | ) |
| 48 | |
| 49 | useHotkeySequence(['Shift+R', 'Shift+T'], () => |
| 50 | addToHistory('⇧R ⇧T → Chained Shift+letter (2 steps)'), |
| 51 | ) |
| 52 | |
| 53 | // Clear history with Escape |
| 54 | useHotkey('Escape', () => { |
| 55 | setLastSequence(null) |
| 56 | setHistory([]) |
| 57 | }) |
| 58 | |
| 59 | return ( |
| 60 | <div className="app"> |
| 61 | <header> |
| 62 | <h1>useHotkeySequence</h1> |
| 63 | <p> |
| 64 | Register multi-key sequences (like Vim commands). Keys must be pressed |
| 65 | within the timeout window (default: 1000ms). |
| 66 | </p> |
| 67 | </header> |
| 68 | |
| 69 | <main> |
nothing calls this directly
no test coverage detected