@redis-ui/components 47.4.0 → 47.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/MultiSelect/components/Content/components/SelectAll/SelectAll.cjs +11 -7
  2. package/dist/MultiSelect/components/Content/components/SelectAll/SelectAll.js +12 -8
  3. package/dist/node_modules/@tanstack/hotkeys/dist/constants.cjs +389 -0
  4. package/dist/node_modules/@tanstack/hotkeys/dist/constants.js +383 -0
  5. package/dist/node_modules/@tanstack/hotkeys/dist/format.cjs +22 -0
  6. package/dist/node_modules/@tanstack/hotkeys/dist/format.js +22 -0
  7. package/dist/node_modules/@tanstack/hotkeys/dist/hotkey-manager.cjs +363 -0
  8. package/dist/node_modules/@tanstack/hotkeys/dist/hotkey-manager.js +363 -0
  9. package/dist/node_modules/@tanstack/hotkeys/dist/manager.utils.cjs +111 -0
  10. package/dist/node_modules/@tanstack/hotkeys/dist/manager.utils.js +107 -0
  11. package/dist/node_modules/@tanstack/hotkeys/dist/match.cjs +59 -0
  12. package/dist/node_modules/@tanstack/hotkeys/dist/match.js +59 -0
  13. package/dist/node_modules/@tanstack/hotkeys/dist/parse.cjs +143 -0
  14. package/dist/node_modules/@tanstack/hotkeys/dist/parse.js +141 -0
  15. package/dist/node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.cjs +10 -0
  16. package/dist/node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.js +8 -0
  17. package/dist/node_modules/@tanstack/react-hotkeys/dist/useHotkey.cjs +121 -0
  18. package/dist/node_modules/@tanstack/react-hotkeys/dist/useHotkey.js +120 -0
  19. package/dist/node_modules/@tanstack/react-hotkeys/dist/utils.cjs +9 -0
  20. package/dist/node_modules/@tanstack/react-hotkeys/dist/utils.js +9 -0
  21. package/dist/node_modules/@tanstack/store/dist/alien.cjs +183 -0
  22. package/dist/node_modules/@tanstack/store/dist/alien.js +182 -0
  23. package/dist/node_modules/@tanstack/store/dist/atom.cjs +161 -0
  24. package/dist/node_modules/@tanstack/store/dist/atom.js +160 -0
  25. package/dist/node_modules/@tanstack/store/dist/store.cjs +25 -0
  26. package/dist/node_modules/@tanstack/store/dist/store.js +25 -0
  27. package/package.json +3 -3
  28. package/skills/redis-ui-components/SKILL.md +1 -1
  29. package/skills/redis-ui-components/references/Icons.md +3 -3
  30. package/skills/redis-ui-components/references/SideBar.md +8 -8
  31. package/dist/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.cjs +0 -289
  32. package/dist/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.js +0 -288
@@ -0,0 +1,59 @@
1
+ import { PUNCTUATION_CODE_MAP, detectPlatform, isSingleLetterKey, normalizeKeyName } from "./constants.js";
2
+ import { parseHotkey } from "./parse.js";
3
+ //#region ../../node_modules/@tanstack/hotkeys/dist/match.js
4
+ /**
5
+ * Checks if a KeyboardEvent matches a hotkey.
6
+ *
7
+ * Uses the `key` property from KeyboardEvent for matching, with a fallback to `code`
8
+ * for letter keys, digit keys (0-9), and punctuation keys when `key` produces special
9
+ * characters (e.g., macOS Option+letter, Shift+number, or Option+punctuation).
10
+ * Letter keys are matched case-insensitively.
11
+ *
12
+ * Also handles "dead key" events where `event.key` is `'Dead'` instead of the expected
13
+ * character. This commonly occurs on macOS with Option+letter combinations (e.g., Option+E,
14
+ * Option+I, Option+U, Option+N) and on Windows/Linux with international keyboard layouts.
15
+ * In these cases, `event.code` is used to determine the physical key.
16
+ *
17
+ * @param event - The KeyboardEvent to check
18
+ * @param hotkey - The hotkey string or ParsedHotkey to match against
19
+ * @param platform - The target platform for resolving 'Mod' (defaults to auto-detection)
20
+ * @returns True if the event matches the hotkey
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * document.addEventListener('keydown', (event) => {
25
+ * if (matchesKeyboardEvent(event, 'Mod+S')) {
26
+ * event.preventDefault()
27
+ * handleSave()
28
+ * }
29
+ * })
30
+ * ```
31
+ */
32
+ function matchesKeyboardEvent(event, hotkey, platform = detectPlatform()) {
33
+ const parsed = typeof hotkey === "string" ? parseHotkey(hotkey, platform) : hotkey;
34
+ if (event.ctrlKey !== parsed.ctrl) return false;
35
+ if (event.shiftKey !== parsed.shift) return false;
36
+ if (event.altKey !== parsed.alt) return false;
37
+ if (event.metaKey !== parsed.meta) return false;
38
+ const eventKey = normalizeKeyName(event.key);
39
+ const hotkeyKey = parsed.key;
40
+ if (eventKey !== "Dead" && eventKey.length === 1 && hotkeyKey.length === 1) {
41
+ if (eventKey.toUpperCase() === hotkeyKey.toUpperCase()) return true;
42
+ if (isSingleLetterKey(eventKey) && (/^[A-Za-z]$/.test(eventKey) || !event.altKey)) return false;
43
+ }
44
+ if (event.code && (eventKey === "Dead" || eventKey.length === 1 && hotkeyKey.length === 1)) {
45
+ if (event.code.startsWith("Key")) {
46
+ const codeLetter = event.code.slice(3);
47
+ if (codeLetter.length === 1 && /^[A-Za-z]$/.test(codeLetter)) return codeLetter.toUpperCase() === hotkeyKey.toUpperCase();
48
+ }
49
+ if (event.code.startsWith("Digit")) {
50
+ const codeDigit = event.code.slice(5);
51
+ if (codeDigit.length === 1 && /^[0-9]$/.test(codeDigit)) return codeDigit === hotkeyKey;
52
+ }
53
+ if (event.code in PUNCTUATION_CODE_MAP) return PUNCTUATION_CODE_MAP[event.code] === hotkeyKey;
54
+ return false;
55
+ }
56
+ return eventKey === hotkeyKey;
57
+ }
58
+ //#endregion
59
+ export { matchesKeyboardEvent };
@@ -0,0 +1,143 @@
1
+ const require_constants = require("./constants.cjs");
2
+ //#region ../../node_modules/@tanstack/hotkeys/dist/parse.js
3
+ /**
4
+ * Parses a hotkey string into its component parts.
5
+ *
6
+ * @param hotkey - The hotkey string to parse (e.g., 'Mod+Shift+S')
7
+ * @param platform - The target platform for resolving 'Mod' (defaults to auto-detection)
8
+ * @returns A ParsedHotkey object with the key and modifier flags
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * parseHotkey('Mod+S') // On Mac: { key: 'S', ctrl: false, shift: false, alt: false, meta: true, modifiers: ['Meta'] }
13
+ * parseHotkey('Mod+S') // On Windows: { key: 'S', ctrl: true, shift: false, alt: false, meta: false, modifiers: ['Control'] }
14
+ * parseHotkey('Control+Shift+A') // { key: 'A', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] }
15
+ * ```
16
+ */
17
+ function parseHotkey(hotkey, platform = require_constants.detectPlatform()) {
18
+ const parts = hotkey.split("+");
19
+ const modifiers = /* @__PURE__ */ new Set();
20
+ let key = "";
21
+ for (let i = 0; i < parts.length; i++) {
22
+ const part = parts[i].trim();
23
+ if (i === parts.length - 1) key = require_constants.normalizeKeyName(part);
24
+ else {
25
+ const alias = require_constants.MODIFIER_ALIASES[part] ?? require_constants.MODIFIER_ALIASES[part.toLowerCase()];
26
+ if (alias) {
27
+ const resolved = require_constants.resolveModifier(alias, platform);
28
+ modifiers.add(resolved);
29
+ } else if (parts.length === 1) key = require_constants.normalizeKeyName(part);
30
+ }
31
+ }
32
+ if (!key && parts.length > 0) key = require_constants.normalizeKeyName(parts[parts.length - 1].trim());
33
+ return {
34
+ key,
35
+ ctrl: modifiers.has("Control"),
36
+ shift: modifiers.has("Shift"),
37
+ alt: modifiers.has("Alt"),
38
+ meta: modifiers.has("Meta"),
39
+ modifiers: require_constants.MODIFIER_ORDER.filter((m) => modifiers.has(m))
40
+ };
41
+ }
42
+ /**
43
+ * Converts a RawHotkey object to a ParsedHotkey.
44
+ * Optional modifier booleans default to false; modifiers array is derived from them.
45
+ * When `mod` is true, it is resolved to Control or Meta based on platform.
46
+ *
47
+ * @param raw - The raw hotkey object
48
+ * @param platform - The target platform for resolving 'Mod' (defaults to auto-detection)
49
+ * @returns A ParsedHotkey suitable for matching and formatting
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * rawHotkeyToParsedHotkey({ key: 'Escape' })
54
+ * // { key: 'Escape', ctrl: false, shift: false, alt: false, meta: false, modifiers: [] }
55
+ *
56
+ * rawHotkeyToParsedHotkey({ key: 'S', mod: true }, 'mac')
57
+ * // { key: 'S', ctrl: false, shift: false, alt: false, meta: true, modifiers: ['Meta'] }
58
+ *
59
+ * rawHotkeyToParsedHotkey({ key: 'S', mod: true, shift: true }, 'windows')
60
+ * // { key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] }
61
+ * ```
62
+ */
63
+ function rawHotkeyToParsedHotkey(raw, platform = require_constants.detectPlatform()) {
64
+ let ctrl = raw.ctrl ?? false;
65
+ const shift = raw.shift ?? false;
66
+ const alt = raw.alt ?? false;
67
+ let meta = raw.meta ?? false;
68
+ if (raw.mod) if (require_constants.resolveModifier("Mod", platform) === "Control") ctrl = true;
69
+ else meta = true;
70
+ const modifiers = require_constants.MODIFIER_ORDER.filter((m) => {
71
+ switch (m) {
72
+ case "Control": return ctrl;
73
+ case "Shift": return shift;
74
+ case "Alt": return alt;
75
+ case "Meta": return meta;
76
+ default: return false;
77
+ }
78
+ });
79
+ return {
80
+ key: raw.key,
81
+ ctrl,
82
+ shift,
83
+ alt,
84
+ meta,
85
+ modifiers
86
+ };
87
+ }
88
+ /**
89
+ * Serializes a parsed hotkey to the canonical string form used for registration
90
+ * and storage: `Mod` first when the platform allows, then `Alt`, then `Shift`;
91
+ * otherwise full `Control+Alt+Shift+Meta` order.
92
+ */
93
+ function normalizedHotkeyStringFromParsed(parsed, platform) {
94
+ const canUseMod = platform === "mac" ? parsed.meta && !parsed.ctrl : parsed.ctrl && !parsed.meta;
95
+ const parts = [];
96
+ if (canUseMod) {
97
+ parts.push("Mod");
98
+ if (parsed.alt) parts.push("Alt");
99
+ if (parsed.shift) parts.push("Shift");
100
+ } else for (const modifier of require_constants.MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(modifier);
101
+ parts.push(require_constants.normalizeKeyName(parsed.key));
102
+ return parts.join("+");
103
+ }
104
+ /**
105
+ * Normalizes a hotkey string to its canonical form.
106
+ *
107
+ * - When `Mod` is allowed for the platform (Command on Mac without Control;
108
+ * Control on Windows/Linux without Meta): emits `Mod`, then `Alt`, then `Shift`,
109
+ * then the key (e.g. `Mod+Shift+E`, `Mod+S`).
110
+ * - Otherwise: literal modifiers in `Control+Alt+Shift+Meta` order, then the key.
111
+ * - Resolves aliases and normalizes key casing (e.g. `esc` → `Escape`, `a` → `A`).
112
+ *
113
+ * @param hotkey - The hotkey string to normalize
114
+ * @param platform - The target platform for resolving `Mod` (defaults to auto-detection)
115
+ * @returns The normalized hotkey string
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * normalizeHotkey('shift+meta+e', 'mac') // 'Mod+Shift+E'
120
+ * normalizeHotkey('ctrl+a', 'windows') // 'Mod+A'
121
+ * normalizeHotkey('esc') // 'Escape'
122
+ * ```
123
+ */
124
+ function normalizeHotkey(hotkey, platform = require_constants.detectPlatform()) {
125
+ return normalizedHotkeyStringFromParsed(parseHotkey(hotkey, platform), platform);
126
+ }
127
+ /**
128
+ * Same canonical string as {@link normalizeHotkey}, but from an already-parsed hotkey.
129
+ */
130
+ function normalizeHotkeyFromParsed(parsed, platform = require_constants.detectPlatform()) {
131
+ return normalizedHotkeyStringFromParsed(parsed, platform);
132
+ }
133
+ /**
134
+ * Normalizes a string or {@link RawHotkey} object to the same canonical hotkey string.
135
+ * Use this in framework adapters instead of branching on `formatHotkey(rawHotkeyToParsedHotkey(...))`.
136
+ */
137
+ function normalizeRegisterableHotkey(hotkey, platform = require_constants.detectPlatform()) {
138
+ return typeof hotkey === "string" ? normalizeHotkey(hotkey, platform) : normalizeHotkeyFromParsed(rawHotkeyToParsedHotkey(hotkey, platform), platform);
139
+ }
140
+ //#endregion
141
+ exports.normalizeRegisterableHotkey = normalizeRegisterableHotkey;
142
+ exports.parseHotkey = parseHotkey;
143
+ exports.rawHotkeyToParsedHotkey = rawHotkeyToParsedHotkey;
@@ -0,0 +1,141 @@
1
+ import { MODIFIER_ALIASES, MODIFIER_ORDER, detectPlatform, normalizeKeyName, resolveModifier } from "./constants.js";
2
+ //#region ../../node_modules/@tanstack/hotkeys/dist/parse.js
3
+ /**
4
+ * Parses a hotkey string into its component parts.
5
+ *
6
+ * @param hotkey - The hotkey string to parse (e.g., 'Mod+Shift+S')
7
+ * @param platform - The target platform for resolving 'Mod' (defaults to auto-detection)
8
+ * @returns A ParsedHotkey object with the key and modifier flags
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * parseHotkey('Mod+S') // On Mac: { key: 'S', ctrl: false, shift: false, alt: false, meta: true, modifiers: ['Meta'] }
13
+ * parseHotkey('Mod+S') // On Windows: { key: 'S', ctrl: true, shift: false, alt: false, meta: false, modifiers: ['Control'] }
14
+ * parseHotkey('Control+Shift+A') // { key: 'A', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] }
15
+ * ```
16
+ */
17
+ function parseHotkey(hotkey, platform = detectPlatform()) {
18
+ const parts = hotkey.split("+");
19
+ const modifiers = /* @__PURE__ */ new Set();
20
+ let key = "";
21
+ for (let i = 0; i < parts.length; i++) {
22
+ const part = parts[i].trim();
23
+ if (i === parts.length - 1) key = normalizeKeyName(part);
24
+ else {
25
+ const alias = MODIFIER_ALIASES[part] ?? MODIFIER_ALIASES[part.toLowerCase()];
26
+ if (alias) {
27
+ const resolved = resolveModifier(alias, platform);
28
+ modifiers.add(resolved);
29
+ } else if (parts.length === 1) key = normalizeKeyName(part);
30
+ }
31
+ }
32
+ if (!key && parts.length > 0) key = normalizeKeyName(parts[parts.length - 1].trim());
33
+ return {
34
+ key,
35
+ ctrl: modifiers.has("Control"),
36
+ shift: modifiers.has("Shift"),
37
+ alt: modifiers.has("Alt"),
38
+ meta: modifiers.has("Meta"),
39
+ modifiers: MODIFIER_ORDER.filter((m) => modifiers.has(m))
40
+ };
41
+ }
42
+ /**
43
+ * Converts a RawHotkey object to a ParsedHotkey.
44
+ * Optional modifier booleans default to false; modifiers array is derived from them.
45
+ * When `mod` is true, it is resolved to Control or Meta based on platform.
46
+ *
47
+ * @param raw - The raw hotkey object
48
+ * @param platform - The target platform for resolving 'Mod' (defaults to auto-detection)
49
+ * @returns A ParsedHotkey suitable for matching and formatting
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * rawHotkeyToParsedHotkey({ key: 'Escape' })
54
+ * // { key: 'Escape', ctrl: false, shift: false, alt: false, meta: false, modifiers: [] }
55
+ *
56
+ * rawHotkeyToParsedHotkey({ key: 'S', mod: true }, 'mac')
57
+ * // { key: 'S', ctrl: false, shift: false, alt: false, meta: true, modifiers: ['Meta'] }
58
+ *
59
+ * rawHotkeyToParsedHotkey({ key: 'S', mod: true, shift: true }, 'windows')
60
+ * // { key: 'S', ctrl: true, shift: true, alt: false, meta: false, modifiers: ['Control', 'Shift'] }
61
+ * ```
62
+ */
63
+ function rawHotkeyToParsedHotkey(raw, platform = detectPlatform()) {
64
+ let ctrl = raw.ctrl ?? false;
65
+ const shift = raw.shift ?? false;
66
+ const alt = raw.alt ?? false;
67
+ let meta = raw.meta ?? false;
68
+ if (raw.mod) if (resolveModifier("Mod", platform) === "Control") ctrl = true;
69
+ else meta = true;
70
+ const modifiers = MODIFIER_ORDER.filter((m) => {
71
+ switch (m) {
72
+ case "Control": return ctrl;
73
+ case "Shift": return shift;
74
+ case "Alt": return alt;
75
+ case "Meta": return meta;
76
+ default: return false;
77
+ }
78
+ });
79
+ return {
80
+ key: raw.key,
81
+ ctrl,
82
+ shift,
83
+ alt,
84
+ meta,
85
+ modifiers
86
+ };
87
+ }
88
+ /**
89
+ * Serializes a parsed hotkey to the canonical string form used for registration
90
+ * and storage: `Mod` first when the platform allows, then `Alt`, then `Shift`;
91
+ * otherwise full `Control+Alt+Shift+Meta` order.
92
+ */
93
+ function normalizedHotkeyStringFromParsed(parsed, platform) {
94
+ const canUseMod = platform === "mac" ? parsed.meta && !parsed.ctrl : parsed.ctrl && !parsed.meta;
95
+ const parts = [];
96
+ if (canUseMod) {
97
+ parts.push("Mod");
98
+ if (parsed.alt) parts.push("Alt");
99
+ if (parsed.shift) parts.push("Shift");
100
+ } else for (const modifier of MODIFIER_ORDER) if (parsed.modifiers.includes(modifier)) parts.push(modifier);
101
+ parts.push(normalizeKeyName(parsed.key));
102
+ return parts.join("+");
103
+ }
104
+ /**
105
+ * Normalizes a hotkey string to its canonical form.
106
+ *
107
+ * - When `Mod` is allowed for the platform (Command on Mac without Control;
108
+ * Control on Windows/Linux without Meta): emits `Mod`, then `Alt`, then `Shift`,
109
+ * then the key (e.g. `Mod+Shift+E`, `Mod+S`).
110
+ * - Otherwise: literal modifiers in `Control+Alt+Shift+Meta` order, then the key.
111
+ * - Resolves aliases and normalizes key casing (e.g. `esc` → `Escape`, `a` → `A`).
112
+ *
113
+ * @param hotkey - The hotkey string to normalize
114
+ * @param platform - The target platform for resolving `Mod` (defaults to auto-detection)
115
+ * @returns The normalized hotkey string
116
+ *
117
+ * @example
118
+ * ```ts
119
+ * normalizeHotkey('shift+meta+e', 'mac') // 'Mod+Shift+E'
120
+ * normalizeHotkey('ctrl+a', 'windows') // 'Mod+A'
121
+ * normalizeHotkey('esc') // 'Escape'
122
+ * ```
123
+ */
124
+ function normalizeHotkey(hotkey, platform = detectPlatform()) {
125
+ return normalizedHotkeyStringFromParsed(parseHotkey(hotkey, platform), platform);
126
+ }
127
+ /**
128
+ * Same canonical string as {@link normalizeHotkey}, but from an already-parsed hotkey.
129
+ */
130
+ function normalizeHotkeyFromParsed(parsed, platform = detectPlatform()) {
131
+ return normalizedHotkeyStringFromParsed(parsed, platform);
132
+ }
133
+ /**
134
+ * Normalizes a string or {@link RawHotkey} object to the same canonical hotkey string.
135
+ * Use this in framework adapters instead of branching on `formatHotkey(rawHotkeyToParsedHotkey(...))`.
136
+ */
137
+ function normalizeRegisterableHotkey(hotkey, platform = detectPlatform()) {
138
+ return typeof hotkey === "string" ? normalizeHotkey(hotkey, platform) : normalizeHotkeyFromParsed(rawHotkeyToParsedHotkey(hotkey, platform), platform);
139
+ }
140
+ //#endregion
141
+ export { normalizeRegisterableHotkey, parseHotkey, rawHotkeyToParsedHotkey };
@@ -0,0 +1,10 @@
1
+ const require_runtime = require("../../../../_virtual/_rolldown/runtime.cjs");
2
+ let react = require("react");
3
+ react = require_runtime.__toESM(react, 1);
4
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.js
5
+ var HotkeysContext = (0, react.createContext)(null);
6
+ function useDefaultHotkeysOptions() {
7
+ return (0, react.useContext)(HotkeysContext)?.defaultOptions ?? {};
8
+ }
9
+ //#endregion
10
+ exports.useDefaultHotkeysOptions = useDefaultHotkeysOptions;
@@ -0,0 +1,8 @@
1
+ import { createContext, useContext } from "react";
2
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.js
3
+ var HotkeysContext = createContext(null);
4
+ function useDefaultHotkeysOptions() {
5
+ return useContext(HotkeysContext)?.defaultOptions ?? {};
6
+ }
7
+ //#endregion
8
+ export { useDefaultHotkeysOptions };
@@ -0,0 +1,121 @@
1
+ require("../../../../_virtual/_rolldown/runtime.cjs");
2
+ const require_HotkeysProvider = require("./HotkeysProvider.cjs");
3
+ const require_utils = require("./utils.cjs");
4
+ const require_constants = require("../../hotkeys/dist/constants.cjs");
5
+ const require_parse = require("../../hotkeys/dist/parse.cjs");
6
+ const require_hotkey_manager = require("../../hotkeys/dist/hotkey-manager.cjs");
7
+ let react = require("react");
8
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/useHotkey.js
9
+ /**
10
+ * React hook for registering a keyboard hotkey.
11
+ *
12
+ * Uses the singleton HotkeyManager for efficient event handling.
13
+ * The callback receives both the keyboard event and a context object
14
+ * containing the hotkey string and parsed hotkey.
15
+ *
16
+ * This hook syncs the callback and options on every render to avoid
17
+ * stale closures. This means
18
+ * callbacks that reference React state will always have access to
19
+ * the latest values.
20
+ *
21
+ * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)
22
+ * @param callback - The function to call when the hotkey is pressed
23
+ * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)
24
+ * and only suppresses firing; the hook updates the existing handle instead of unregistering.
25
+ *
26
+ * @example
27
+ * ```tsx
28
+ * function SaveButton() {
29
+ * const [count, setCount] = useState(0)
30
+ *
31
+ * // Callback always has access to latest count value
32
+ * useHotkey('Mod+S', (event, { hotkey }) => {
33
+ * console.log(`Save triggered, count is ${count}`)
34
+ * handleSave()
35
+ * })
36
+ *
37
+ * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
38
+ * }
39
+ * ```
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * function Modal({ isOpen, onClose }) {
44
+ * // enabled option is synced on every render
45
+ * useHotkey('Escape', () => {
46
+ * onClose()
47
+ * }, { enabled: isOpen })
48
+ *
49
+ * if (!isOpen) return null
50
+ * return <div className="modal">...</div>
51
+ * }
52
+ * ```
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * function Editor() {
57
+ * const editorRef = useRef<HTMLDivElement>(null)
58
+ *
59
+ * // Scoped to a specific element
60
+ * useHotkey('Mod+S', () => {
61
+ * save()
62
+ * }, { target: editorRef })
63
+ *
64
+ * return <div ref={editorRef}>...</div>
65
+ * }
66
+ * ```
67
+ */
68
+ function useHotkey(hotkey, callback, options = {}) {
69
+ const mergedOptions = {
70
+ ...require_HotkeysProvider.useDefaultHotkeysOptions().hotkey,
71
+ ...options
72
+ };
73
+ const manager = require_hotkey_manager.getHotkeyManager();
74
+ const registrationRef = (0, react.useRef)(null);
75
+ const callbackRef = (0, react.useRef)(callback);
76
+ const optionsRef = (0, react.useRef)(mergedOptions);
77
+ const managerRef = (0, react.useRef)(manager);
78
+ callbackRef.current = callback;
79
+ optionsRef.current = mergedOptions;
80
+ managerRef.current = manager;
81
+ const prevTargetRef = (0, react.useRef)(null);
82
+ const prevHotkeyRef = (0, react.useRef)(null);
83
+ const hotkeyString = require_parse.normalizeRegisterableHotkey(hotkey, mergedOptions.platform ?? require_constants.detectPlatform());
84
+ const { target: _target, ...optionsWithoutTarget } = mergedOptions;
85
+ (0, react.useEffect)(() => {
86
+ const resolvedTarget = require_utils.isRef(optionsRef.current.target) ? optionsRef.current.target.current : optionsRef.current.target ?? (typeof document !== "undefined" ? document : null);
87
+ if (!resolvedTarget) {
88
+ if (registrationRef.current?.isActive) {
89
+ registrationRef.current.unregister();
90
+ registrationRef.current = null;
91
+ }
92
+ prevTargetRef.current = null;
93
+ prevHotkeyRef.current = null;
94
+ return;
95
+ }
96
+ const targetChanged = prevTargetRef.current !== null && prevTargetRef.current !== resolvedTarget;
97
+ const hotkeyChanged = prevHotkeyRef.current !== null && prevHotkeyRef.current !== hotkeyString;
98
+ if (registrationRef.current?.isActive && (targetChanged || hotkeyChanged)) {
99
+ registrationRef.current.unregister();
100
+ registrationRef.current = null;
101
+ }
102
+ if (!registrationRef.current || !registrationRef.current.isActive) registrationRef.current = managerRef.current.register(hotkeyString, callbackRef.current, {
103
+ ...optionsRef.current,
104
+ target: resolvedTarget
105
+ });
106
+ prevTargetRef.current = resolvedTarget;
107
+ prevHotkeyRef.current = hotkeyString;
108
+ return () => {
109
+ if (registrationRef.current?.isActive) {
110
+ registrationRef.current.unregister();
111
+ registrationRef.current = null;
112
+ }
113
+ };
114
+ }, [hotkeyString]);
115
+ if (registrationRef.current?.isActive) {
116
+ registrationRef.current.callback = callback;
117
+ registrationRef.current.setOptions(optionsWithoutTarget);
118
+ }
119
+ }
120
+ //#endregion
121
+ exports.useHotkey = useHotkey;
@@ -0,0 +1,120 @@
1
+ import { useDefaultHotkeysOptions } from "./HotkeysProvider.js";
2
+ import { isRef } from "./utils.js";
3
+ import { detectPlatform } from "../../hotkeys/dist/constants.js";
4
+ import { normalizeRegisterableHotkey } from "../../hotkeys/dist/parse.js";
5
+ import { getHotkeyManager } from "../../hotkeys/dist/hotkey-manager.js";
6
+ import { useEffect, useRef } from "react";
7
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/useHotkey.js
8
+ /**
9
+ * React hook for registering a keyboard hotkey.
10
+ *
11
+ * Uses the singleton HotkeyManager for efficient event handling.
12
+ * The callback receives both the keyboard event and a context object
13
+ * containing the hotkey string and parsed hotkey.
14
+ *
15
+ * This hook syncs the callback and options on every render to avoid
16
+ * stale closures. This means
17
+ * callbacks that reference React state will always have access to
18
+ * the latest values.
19
+ *
20
+ * @param hotkey - The hotkey string (e.g., 'Mod+S', 'Escape') or RawHotkey object (supports `mod` for cross-platform)
21
+ * @param callback - The function to call when the hotkey is pressed
22
+ * @param options - Options for the hotkey behavior. `enabled: false` keeps the registration (visible in devtools)
23
+ * and only suppresses firing; the hook updates the existing handle instead of unregistering.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * function SaveButton() {
28
+ * const [count, setCount] = useState(0)
29
+ *
30
+ * // Callback always has access to latest count value
31
+ * useHotkey('Mod+S', (event, { hotkey }) => {
32
+ * console.log(`Save triggered, count is ${count}`)
33
+ * handleSave()
34
+ * })
35
+ *
36
+ * return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
37
+ * }
38
+ * ```
39
+ *
40
+ * @example
41
+ * ```tsx
42
+ * function Modal({ isOpen, onClose }) {
43
+ * // enabled option is synced on every render
44
+ * useHotkey('Escape', () => {
45
+ * onClose()
46
+ * }, { enabled: isOpen })
47
+ *
48
+ * if (!isOpen) return null
49
+ * return <div className="modal">...</div>
50
+ * }
51
+ * ```
52
+ *
53
+ * @example
54
+ * ```tsx
55
+ * function Editor() {
56
+ * const editorRef = useRef<HTMLDivElement>(null)
57
+ *
58
+ * // Scoped to a specific element
59
+ * useHotkey('Mod+S', () => {
60
+ * save()
61
+ * }, { target: editorRef })
62
+ *
63
+ * return <div ref={editorRef}>...</div>
64
+ * }
65
+ * ```
66
+ */
67
+ function useHotkey(hotkey, callback, options = {}) {
68
+ const mergedOptions = {
69
+ ...useDefaultHotkeysOptions().hotkey,
70
+ ...options
71
+ };
72
+ const manager = getHotkeyManager();
73
+ const registrationRef = useRef(null);
74
+ const callbackRef = useRef(callback);
75
+ const optionsRef = useRef(mergedOptions);
76
+ const managerRef = useRef(manager);
77
+ callbackRef.current = callback;
78
+ optionsRef.current = mergedOptions;
79
+ managerRef.current = manager;
80
+ const prevTargetRef = useRef(null);
81
+ const prevHotkeyRef = useRef(null);
82
+ const hotkeyString = normalizeRegisterableHotkey(hotkey, mergedOptions.platform ?? detectPlatform());
83
+ const { target: _target, ...optionsWithoutTarget } = mergedOptions;
84
+ useEffect(() => {
85
+ const resolvedTarget = isRef(optionsRef.current.target) ? optionsRef.current.target.current : optionsRef.current.target ?? (typeof document !== "undefined" ? document : null);
86
+ if (!resolvedTarget) {
87
+ if (registrationRef.current?.isActive) {
88
+ registrationRef.current.unregister();
89
+ registrationRef.current = null;
90
+ }
91
+ prevTargetRef.current = null;
92
+ prevHotkeyRef.current = null;
93
+ return;
94
+ }
95
+ const targetChanged = prevTargetRef.current !== null && prevTargetRef.current !== resolvedTarget;
96
+ const hotkeyChanged = prevHotkeyRef.current !== null && prevHotkeyRef.current !== hotkeyString;
97
+ if (registrationRef.current?.isActive && (targetChanged || hotkeyChanged)) {
98
+ registrationRef.current.unregister();
99
+ registrationRef.current = null;
100
+ }
101
+ if (!registrationRef.current || !registrationRef.current.isActive) registrationRef.current = managerRef.current.register(hotkeyString, callbackRef.current, {
102
+ ...optionsRef.current,
103
+ target: resolvedTarget
104
+ });
105
+ prevTargetRef.current = resolvedTarget;
106
+ prevHotkeyRef.current = hotkeyString;
107
+ return () => {
108
+ if (registrationRef.current?.isActive) {
109
+ registrationRef.current.unregister();
110
+ registrationRef.current = null;
111
+ }
112
+ };
113
+ }, [hotkeyString]);
114
+ if (registrationRef.current?.isActive) {
115
+ registrationRef.current.callback = callback;
116
+ registrationRef.current.setOptions(optionsWithoutTarget);
117
+ }
118
+ }
119
+ //#endregion
120
+ export { useHotkey };
@@ -0,0 +1,9 @@
1
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/utils.js
2
+ /**
3
+ * Type guard to check if a value is a React ref-like object.
4
+ */
5
+ function isRef(value) {
6
+ return value !== null && typeof value === "object" && "current" in value;
7
+ }
8
+ //#endregion
9
+ exports.isRef = isRef;
@@ -0,0 +1,9 @@
1
+ //#region ../../node_modules/@tanstack/react-hotkeys/dist/utils.js
2
+ /**
3
+ * Type guard to check if a value is a React ref-like object.
4
+ */
5
+ function isRef(value) {
6
+ return value !== null && typeof value === "object" && "current" in value;
7
+ }
8
+ //#endregion
9
+ export { isRef };