modern-cmdk 1.1.4 → 1.2.0

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.
@@ -1,6 +1,6 @@
1
1
  //#region src/codemod/transforms/data-attrs.ts
2
2
  /** Mapping from old bare attribute names to new data-attribute names */
3
- const ATTR_MAP = new Map([
3
+ const ATTR_MAP = /* @__PURE__ */ new Map([
4
4
  ["cmdk-root", "data-command"],
5
5
  ["cmdk-input", "data-command-input"],
6
6
  ["cmdk-list", "data-command-list"],
@@ -11,7 +11,7 @@ const ATTR_MAP = new Map([
11
11
  ["cmdk-loading", "data-command-loading"]
12
12
  ]);
13
13
  /** CSS custom property renames */
14
- const CSS_VAR_MAP = new Map([["--cmdk-list-height", "--command-list-height"]]);
14
+ const CSS_VAR_MAP = /* @__PURE__ */ new Map([["--cmdk-list-height", "--command-list-height"]]);
15
15
  /**
16
16
  * Replace all cmdk attribute selectors (bracketed) and CSS vars in a string.
17
17
  * Uses ES2026 Set.union to combine both maps into a single pass.
@@ -222,7 +222,8 @@ var FrecencyEngine = class {
222
222
  }
223
223
  /** Load frecency data from storage */
224
224
  async load() {
225
- this.#data = await this.#storage.load(this.#namespace);
225
+ const data = await this.#storage.load(this.#namespace);
226
+ this.#data = data;
226
227
  }
227
228
  /** Record a selection event for an item */
228
229
  recordSelection(itemId) {
@@ -1237,7 +1238,7 @@ function createCommandMachine(options = {}) {
1237
1238
  break;
1238
1239
  case "UNREGISTER_ITEM":
1239
1240
  registry.unregisterItem(event.id);
1240
- searchEngine.remove(new Set([event.id]));
1241
+ searchEngine.remove(/* @__PURE__ */ new Set([event.id]));
1241
1242
  keyboardRegistry.unregisterByItem(event.id);
1242
1243
  refilter(state.search);
1243
1244
  break;
@@ -1258,10 +1259,12 @@ function createCommandMachine(options = {}) {
1258
1259
  send(event) {
1259
1260
  scheduler.schedule(() => handleEvent(event));
1260
1261
  },
1262
+ /** useSyncExternalStore-compatible subscribe — returns cleanup function */
1261
1263
  subscribe(listener) {
1262
1264
  const disposable = emitter.on("stateChange", listener);
1263
1265
  return () => disposable[Symbol.dispose]();
1264
1266
  },
1267
+ /** Full state subscribe — returns Disposable for `using` pattern */
1265
1268
  subscribeState(listener) {
1266
1269
  return emitter.on("stateChange", listener);
1267
1270
  },
@@ -641,10 +641,10 @@ interface CommandErrorBoundaryState {
641
641
  }
642
642
  /** Error boundary for graceful failure recovery in command subtrees. */
643
643
  declare class CommandErrorBoundary extends Component<CommandErrorBoundaryProps, CommandErrorBoundaryState> {
644
- state: CommandErrorBoundaryState;
644
+ override state: CommandErrorBoundaryState;
645
645
  static getDerivedStateFromError(error: Error): CommandErrorBoundaryState;
646
- componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
647
- render(): ReactNode;
646
+ override componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
647
+ override render(): ReactNode;
648
648
  }
649
649
  //#endregion
650
650
  //#region src/react/hooks/use-command.d.ts
@@ -98,6 +98,82 @@ function ensureWellFormed(str) {
98
98
  return str.replace(LONE_SURROGATE_RE, REPLACEMENT_CHAR);
99
99
  }
100
100
  //#endregion
101
+ //#region src/core/keyboard/parser.ts
102
+ const isMac = typeof navigator !== "undefined" && (navigator.userAgentData?.platform === "macOS" || /Mac|iPod|iPhone|iPad/.test(navigator.platform));
103
+ /** Modifier aliases — cross-platform Mod resolution */
104
+ const MODIFIER_MAP = {
105
+ mod: isMac ? "meta" : "ctrl",
106
+ meta: "meta",
107
+ cmd: "meta",
108
+ command: "meta",
109
+ ctrl: "ctrl",
110
+ control: "ctrl",
111
+ shift: "shift",
112
+ alt: "alt",
113
+ option: "alt",
114
+ opt: "alt"
115
+ };
116
+ /**
117
+ * Parse a shortcut string like "Mod+Shift+K" into a structured ParsedShortcut.
118
+ * Ensures valid Unicode input via ensureWellFormed helper.
119
+ */
120
+ function parseShortcut(shortcut) {
121
+ const safeShortcut = ensureWellFormed(shortcut);
122
+ const parts = safeShortcut.split("+").map((p) => p.trim().toLowerCase());
123
+ let meta = false;
124
+ let ctrl = false;
125
+ let shift = false;
126
+ let alt = false;
127
+ let key = "";
128
+ for (const part of parts) {
129
+ const modifier = MODIFIER_MAP[part];
130
+ if (modifier) switch (modifier) {
131
+ case "meta":
132
+ meta = true;
133
+ break;
134
+ case "ctrl":
135
+ ctrl = true;
136
+ break;
137
+ case "shift":
138
+ shift = true;
139
+ break;
140
+ case "alt":
141
+ alt = true;
142
+ break;
143
+ }
144
+ else key = part;
145
+ }
146
+ const modifiers = [];
147
+ if (meta) modifiers.push("meta");
148
+ if (ctrl) modifiers.push("ctrl");
149
+ if (shift) modifiers.push("shift");
150
+ if (alt) modifiers.push("alt");
151
+ modifiers.push(key);
152
+ return {
153
+ key,
154
+ meta,
155
+ ctrl,
156
+ shift,
157
+ alt,
158
+ raw: safeShortcut,
159
+ normalized: modifiers.join("+")
160
+ };
161
+ }
162
+ /**
163
+ * Formats a ParsedShortcut for display using platform-appropriate symbols.
164
+ * On macOS: renders glyphs (⌘, ⇧, ⌥, ⌃). On other platforms: text labels joined by "+".
165
+ */
166
+ function formatShortcut(parsed) {
167
+ const parts = [];
168
+ if (parsed.meta) parts.push(isMac ? "⌘" : "Ctrl");
169
+ if (parsed.ctrl && !(!isMac && parsed.meta)) parts.push(isMac ? "⌃" : "Ctrl");
170
+ if (parsed.shift) parts.push(isMac ? "⇧" : "Shift");
171
+ if (parsed.alt) parts.push(isMac ? "⌥" : "Alt");
172
+ const displayKey = parsed.key.length === 1 ? parsed.key.toUpperCase() : parsed.key.charAt(0).toUpperCase() + parsed.key.slice(1);
173
+ parts.push(displayKey);
174
+ return isMac ? parts.join("") : parts.join("+");
175
+ }
176
+ //#endregion
101
177
  //#region src/core/types.ts
102
178
  /** Create a branded {@link ItemId} from a plain string. Ensures well-formed Unicode. */
103
179
  function itemId(id) {
@@ -194,7 +270,8 @@ var FrecencyEngine = class {
194
270
  }
195
271
  /** Load frecency data from storage */
196
272
  async load() {
197
- this.#data = await this.#storage.load(this.#namespace);
273
+ const data = await this.#storage.load(this.#namespace);
274
+ this.#data = data;
198
275
  }
199
276
  /** Record a selection event for an item */
200
277
  recordSelection(itemId) {
@@ -294,82 +371,6 @@ function detectConflicts(shortcuts) {
294
371
  return new Map(grouped.entries().filter(([, group]) => group.length > 1));
295
372
  }
296
373
  //#endregion
297
- //#region src/core/keyboard/parser.ts
298
- const isMac = typeof navigator !== "undefined" && (navigator.userAgentData?.platform === "macOS" || /Mac|iPod|iPhone|iPad/.test(navigator.platform));
299
- /** Modifier aliases — cross-platform Mod resolution */
300
- const MODIFIER_MAP = {
301
- mod: isMac ? "meta" : "ctrl",
302
- meta: "meta",
303
- cmd: "meta",
304
- command: "meta",
305
- ctrl: "ctrl",
306
- control: "ctrl",
307
- shift: "shift",
308
- alt: "alt",
309
- option: "alt",
310
- opt: "alt"
311
- };
312
- /**
313
- * Parse a shortcut string like "Mod+Shift+K" into a structured ParsedShortcut.
314
- * Ensures valid Unicode input via ensureWellFormed helper.
315
- */
316
- function parseShortcut(shortcut) {
317
- const safeShortcut = ensureWellFormed(shortcut);
318
- const parts = safeShortcut.split("+").map((p) => p.trim().toLowerCase());
319
- let meta = false;
320
- let ctrl = false;
321
- let shift = false;
322
- let alt = false;
323
- let key = "";
324
- for (const part of parts) {
325
- const modifier = MODIFIER_MAP[part];
326
- if (modifier) switch (modifier) {
327
- case "meta":
328
- meta = true;
329
- break;
330
- case "ctrl":
331
- ctrl = true;
332
- break;
333
- case "shift":
334
- shift = true;
335
- break;
336
- case "alt":
337
- alt = true;
338
- break;
339
- }
340
- else key = part;
341
- }
342
- const modifiers = [];
343
- if (meta) modifiers.push("meta");
344
- if (ctrl) modifiers.push("ctrl");
345
- if (shift) modifiers.push("shift");
346
- if (alt) modifiers.push("alt");
347
- modifiers.push(key);
348
- return {
349
- key,
350
- meta,
351
- ctrl,
352
- shift,
353
- alt,
354
- raw: safeShortcut,
355
- normalized: modifiers.join("+")
356
- };
357
- }
358
- /**
359
- * Formats a ParsedShortcut for display using platform-appropriate symbols.
360
- * On macOS: renders glyphs (⌘, ⇧, ⌥, ⌃). On other platforms: text labels joined by "+".
361
- */
362
- function formatShortcut(parsed) {
363
- const parts = [];
364
- if (parsed.meta) parts.push(isMac ? "⌘" : "Ctrl");
365
- if (parsed.ctrl && !(!isMac && parsed.meta)) parts.push(isMac ? "⌃" : "Ctrl");
366
- if (parsed.shift) parts.push(isMac ? "⇧" : "Shift");
367
- if (parsed.alt) parts.push(isMac ? "⌥" : "Alt");
368
- const displayKey = parsed.key.length === 1 ? parsed.key.toUpperCase() : parsed.key.charAt(0).toUpperCase() + parsed.key.slice(1);
369
- parts.push(displayKey);
370
- return isMac ? parts.join("") : parts.join("+");
371
- }
372
- //#endregion
373
374
  //#region src/core/keyboard/index.ts
374
375
  /**
375
376
  * Manages keyboard shortcut bindings with global keydown listening.
@@ -1165,7 +1166,7 @@ function createCommandMachine(options = {}) {
1165
1166
  break;
1166
1167
  case "UNREGISTER_ITEM":
1167
1168
  registry.unregisterItem(event.id);
1168
- searchEngine.remove(new Set([event.id]));
1169
+ searchEngine.remove(/* @__PURE__ */ new Set([event.id]));
1169
1170
  keyboardRegistry.unregisterByItem(event.id);
1170
1171
  refilter(state.search);
1171
1172
  break;
@@ -1186,10 +1187,12 @@ function createCommandMachine(options = {}) {
1186
1187
  send(event) {
1187
1188
  scheduler.schedule(() => handleEvent(event));
1188
1189
  },
1190
+ /** useSyncExternalStore-compatible subscribe — returns cleanup function */
1189
1191
  subscribe(listener) {
1190
1192
  const disposable = emitter.on("stateChange", listener);
1191
1193
  return () => disposable[Symbol.dispose]();
1192
1194
  },
1195
+ /** Full state subscribe — returns Disposable for `using` pattern */
1193
1196
  subscribeState(listener) {
1194
1197
  return emitter.on("stateChange", listener);
1195
1198
  },
@@ -1576,13 +1579,13 @@ function CommandHighlight({ text, ranges, highlightClassName }) {
1576
1579
  const sorted = ranges.toSorted((a, b) => a[0] - b[0]);
1577
1580
  const segments = [];
1578
1581
  let lastEnd = 0;
1579
- sorted.forEach(([start, end], i) => {
1582
+ sorted.forEach(([start, end]) => {
1580
1583
  if (start > lastEnd) segments.push(text.slice(lastEnd, start));
1581
1584
  segments.push(/* @__PURE__ */ jsx("mark", {
1582
1585
  "data-command-highlight": "",
1583
1586
  className: highlightClassName,
1584
1587
  children: text.slice(start, end)
1585
- }, i));
1588
+ }, `h${start}-${end}`));
1586
1589
  lastEnd = end;
1587
1590
  });
1588
1591
  if (lastEnd < text.length) segments.push(text.slice(lastEnd));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "modern-cmdk",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "type": "module",
5
5
  "description": "The definitive command palette engine for the modern web",
6
6
  "license": "MIT",
@@ -9,7 +9,7 @@
9
9
  "url": "https://github.com/ABCrimson/modern-cmdk/issues"
10
10
  },
11
11
  "engines": {
12
- "node": ">=22.0.0"
12
+ "node": ">=26.4.0"
13
13
  },
14
14
  "publishConfig": {
15
15
  "access": "public"
@@ -57,12 +57,12 @@
57
57
  }
58
58
  },
59
59
  "dependencies": {
60
- "idb-keyval": "6.2.2"
60
+ "idb-keyval": "6.2.5"
61
61
  },
62
62
  "devDependencies": {
63
- "globby": "16.1.1",
63
+ "globby": "16.2.0",
64
64
  "jscodeshift": "17.3.0",
65
- "radix-ui": "1.4.4-rc.1766004502650",
65
+ "radix-ui": "1.6.0",
66
66
  "@types/jscodeshift": "^17.3.0"
67
67
  },
68
68
  "keywords": [