@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.
- package/dist/MultiSelect/components/Content/components/SelectAll/SelectAll.cjs +11 -7
- package/dist/MultiSelect/components/Content/components/SelectAll/SelectAll.js +12 -8
- package/dist/node_modules/@tanstack/hotkeys/dist/constants.cjs +389 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/constants.js +383 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/format.cjs +22 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/format.js +22 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/hotkey-manager.cjs +363 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/hotkey-manager.js +363 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/manager.utils.cjs +111 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/manager.utils.js +107 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/match.cjs +59 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/match.js +59 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/parse.cjs +143 -0
- package/dist/node_modules/@tanstack/hotkeys/dist/parse.js +141 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.cjs +10 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/HotkeysProvider.js +8 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/useHotkey.cjs +121 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/useHotkey.js +120 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/utils.cjs +9 -0
- package/dist/node_modules/@tanstack/react-hotkeys/dist/utils.js +9 -0
- package/dist/node_modules/@tanstack/store/dist/alien.cjs +183 -0
- package/dist/node_modules/@tanstack/store/dist/alien.js +182 -0
- package/dist/node_modules/@tanstack/store/dist/atom.cjs +161 -0
- package/dist/node_modules/@tanstack/store/dist/atom.js +160 -0
- package/dist/node_modules/@tanstack/store/dist/store.cjs +25 -0
- package/dist/node_modules/@tanstack/store/dist/store.js +25 -0
- package/package.json +3 -3
- package/skills/redis-ui-components/SKILL.md +1 -1
- package/skills/redis-ui-components/references/Icons.md +3 -3
- package/skills/redis-ui-components/references/SideBar.md +8 -8
- package/dist/node_modules/react-hotkeys-hook/dist/react-hotkeys-hook.esm.cjs +0 -289
- 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 };
|