Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | import type { RefObject } from "react";
/**
* A hotkey string. Either a single **combo** (modifier tokens joined with `+`
* and a final key, e.g. `"mod+k"`, `"ctrl+shift+p"`, `"shift+?"`, `"Escape"`)
* or a **sequence** of combos separated by spaces (e.g. `"g i"`, `"g g"`).
*
* Modifier tokens (case-insensitive): `ctrl`/`control`, `shift`, `alt`/`option`,
* `meta`/`cmd`/`command`, and the cross-platform `mod` (Cmd on macOS, Ctrl
* elsewhere). The final non-modifier token is the key, matched against
* `KeyboardEvent.key` case-insensitively, with friendly aliases such as
* `esc`→`Escape`, `space`→`" "`, and `up`/`down`/`left`/`right`→arrow keys.
*/
export type Hotkey = string;
/**
* The DOM target the keyboard listener is attached to.
*
* - `undefined` (omitted) defaults to `document`.
* - `null` disables the listener (useful for conditional targets).
* - A `RefObject` is resolved lazily to its `.current` element.
*/
export type HotkeyTarget =
| Window
| Document
| HTMLElement
| RefObject<HTMLElement | null>
| null
| undefined;
/**
* Details about the binding that matched, passed to the handler as its second
* argument.
*/
export interface HotkeyMatch {
/** The raw hotkey string that matched (as written by the caller). */
hotkey: string;
/**
* The index of the matched binding within the `keys` array. `0` when a single
* string was passed.
*/
index: number;
/** `true` when the matched binding was a multi-combo sequence (e.g. `"g i"`). */
sequence: boolean;
}
/**
* The user callback invoked when a bound hotkey fires. Receives the raw
* {@link KeyboardEvent} (call `event.preventDefault()` here for manual control)
* and a {@link HotkeyMatch} describing which binding matched.
*/
export type HotkeyHandler = (event: KeyboardEvent, match: HotkeyMatch) => void;
/**
* A single parsed combo — one press of a key with a required modifier state.
* `"mod"` has already been resolved to `ctrl` or `meta` for the current
* platform.
*/
export interface ParsedChord {
/** Whether the Ctrl modifier must be held. */
ctrl: boolean;
/** Whether the Shift modifier must be held. */
shift: boolean;
/** Whether the Alt/Option modifier must be held. */
alt: boolean;
/** Whether the Meta/Command modifier must be held. */
meta: boolean;
/**
* The normalized (alias-resolved, lower-cased) key to match against
* `event.key`. Empty string for a modifier-only combo (which never matches a
* real key event).
*/
key: string;
}
/**
* A parsed hotkey binding: the original string plus its ordered list of combos.
* A single combo produces a length-1 `chords` array; a sequence produces one
* entry per space-separated combo.
*/
export interface ParsedHotkey {
/** The original hotkey string as written by the caller. */
raw: string;
/** The ordered combos that make up this binding. */
chords: ParsedChord[];
}
/**
* Configuration options for {@link useHotkeys}.
*/
export interface UseHotkeysOptions {
/**
* When `false`, no listener is attached and no hotkey fires. Any in-progress
* sequence buffer is cleared.
* @default true
*/
enabled?: boolean;
/**
* The element the keyboard listener is attached to. Accepts `document`,
* `window`, an `HTMLElement`, or a React `RefObject`. Pass `null` to detach.
* @default document
*/
target?: HotkeyTarget;
/**
* Which keyboard event drives matching.
* @default "keydown"
*/
eventType?: "keydown" | "keyup";
/**
* By default hotkeys do **not** fire while an editable element is focused
* (`<input>`, `<textarea>`, `<select>`, or a `contenteditable` node), so
* typing in a form never triggers shortcuts. Set to `true` to allow hotkeys
* to fire inside form fields as well.
* @default false
*/
enableOnFormTags?: boolean;
/**
* Call `event.preventDefault()` when a hotkey matches. Only affects matched
* events (never every keystroke), so it is safe to enable for overriding
* browser shortcuts such as `mod+s`.
* @default false
*/
preventDefault?: boolean;
/**
* How long (ms) the sequence buffer waits between combos before resetting.
* Only relevant for space-separated sequence bindings like `"g i"`.
* @default 1000
*/
sequenceTimeoutMs?: number;
/**
* Override platform detection for the `mod` alias. When `true`, `mod`
* resolves to `meta` (Cmd); when `false`, to `ctrl`. Leave undefined to
* auto-detect from the user agent. Primarily useful for tests.
* @default undefined (auto-detect)
*/
mac?: boolean;
}
|