modern-cmdk 1.0.0 → 1.0.2

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
- import { C as itemId, S as groupId, d as formatShortcut, f as parseShortcut, i as createCommandMachine } from "../core-Bq0eDvlc.mjs";
1
+ import { C as itemId, S as groupId, d as formatShortcut, f as parseShortcut, i as createCommandMachine } from "../core-CgQYpHK3.mjs";
2
2
  import * as React from "react";
3
- import { Component, Suspense, createContext, use, useCallback, useEffect, useId, useInsertionEffect, useMemo, useOptimistic, useRef, useState, useSyncExternalStore, useTransition } from "react";
3
+ import { Component, Suspense, createContext, use, useCallback, useEffect, useId, useLayoutEffect, useMemo, useOptimistic, useRef, useState, useSyncExternalStore, useTransition } from "react";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Dialog } from "radix-ui";
6
6
  //#region src/react/activity.tsx
@@ -20,6 +20,14 @@ function CommandActivity({ mode, children }) {
20
20
  }
21
21
  //#endregion
22
22
  //#region src/react/context.ts
23
+ const CommandStableContext = createContext(null);
24
+ CommandStableContext.displayName = "CommandStableContext";
25
+ const CommandStateContext = createContext(null);
26
+ CommandStateContext.displayName = "CommandStateContext";
27
+ /**
28
+ * @deprecated Use CommandStableContext and CommandStateContext instead.
29
+ * Kept for backward compatibility with useCommandState hook.
30
+ */
23
31
  const CommandContext = createContext(null);
24
32
  CommandContext.displayName = "CommandContext";
25
33
  const CommandGroupContext = createContext(null);
@@ -28,15 +36,15 @@ CommandGroupContext.displayName = "CommandGroupContext";
28
36
  //#region src/react/async-items.tsx
29
37
  /** Inner component that suspends via use() until items resolve */
30
38
  function AsyncItemsInner({ items: itemsPromise, children }) {
31
- const ctx = use(CommandContext);
32
- if (!ctx) throw new Error("Command.AsyncItems must be used within a <Command> component");
39
+ const stable = use(CommandStableContext);
40
+ if (!stable) throw new Error("Command.AsyncItems must be used within a <Command> component");
33
41
  const items = use(itemsPromise);
34
- useEffect(() => {
35
- ctx.machine.send({
42
+ useLayoutEffect(() => {
43
+ stable.machine.send({
36
44
  type: "ITEMS_LOADED",
37
45
  items
38
46
  });
39
- }, [ctx.machine, items]);
47
+ }, [stable.machine, items]);
40
48
  return /* @__PURE__ */ jsx(Fragment, { children: children(items) });
41
49
  }
42
50
  function CommandAsyncItems({ items, fallback, children }) {
@@ -140,12 +148,14 @@ function CommandDialog({ children, className, overlayClassName, contentClassName
140
148
  const rootId = useId();
141
149
  const listId = `${rootId}-list`;
142
150
  const inputId = `${rootId}-input`;
151
+ const onOpenChangeRef = useRef(onOpenChange);
152
+ onOpenChangeRef.current = onOpenChange;
143
153
  const machineRef = useRef(null);
144
154
  if (machineRef.current === null) machineRef.current = createCommandMachine({
145
155
  ...machineOptions,
146
156
  open: controlledOpen ?? false,
147
157
  onOpenChange: (open) => {
148
- onOpenChange?.(open);
158
+ onOpenChangeRef.current?.(open);
149
159
  }
150
160
  });
151
161
  const machine = machineRef.current;
@@ -174,28 +184,31 @@ function CommandDialog({ children, className, overlayClassName, contentClassName
174
184
  const handleRadixOpenChange = useCallback((open) => {
175
185
  machine.send({ type: open ? "OPEN" : "CLOSE" });
176
186
  }, [machine]);
177
- const contextValue = useMemo(() => ({
187
+ const stableContextValue = useMemo(() => ({
178
188
  machine,
179
- state,
180
- isPending,
181
- updateSearch,
182
- setOptimisticActiveId,
183
- filteredIdSet,
184
189
  rootId: id,
185
190
  listId,
186
191
  inputId,
187
- label
192
+ label,
193
+ updateSearch,
194
+ setOptimisticActiveId
188
195
  }), [
189
196
  machine,
190
- state,
191
- isPending,
192
- updateSearch,
193
- setOptimisticActiveId,
194
- filteredIdSet,
195
197
  id,
196
198
  listId,
197
199
  inputId,
198
- label
200
+ label,
201
+ updateSearch,
202
+ setOptimisticActiveId
203
+ ]);
204
+ const stateContextValue = useMemo(() => ({
205
+ state,
206
+ isPending,
207
+ filteredIdSet
208
+ }), [
209
+ state,
210
+ isPending,
211
+ filteredIdSet
199
212
  ]);
200
213
  return /* @__PURE__ */ jsx(Dialog.Root, {
201
214
  open: state.open,
@@ -224,16 +237,19 @@ function CommandDialog({ children, className, overlayClassName, contentClassName
224
237
  className: "sr-only",
225
238
  children: "Type a command or search..."
226
239
  }),
227
- /* @__PURE__ */ jsx(CommandContext, {
228
- value: contextValue,
229
- children: /* @__PURE__ */ jsx("div", {
230
- "data-command-dialog-content": "",
231
- className: contentClassName,
240
+ /* @__PURE__ */ jsx(CommandStableContext, {
241
+ value: stableContextValue,
242
+ children: /* @__PURE__ */ jsx(CommandStateContext, {
243
+ value: stateContextValue,
232
244
  children: /* @__PURE__ */ jsx("div", {
233
- "data-command-root": "",
234
- role: "search",
235
- "aria-label": label,
236
- children
245
+ "data-command-dialog-content": "",
246
+ className: contentClassName,
247
+ children: /* @__PURE__ */ jsx("div", {
248
+ "data-command-root": "",
249
+ role: "search",
250
+ "aria-label": label,
251
+ children
252
+ })
237
253
  })
238
254
  })
239
255
  })
@@ -245,9 +261,9 @@ function CommandDialog({ children, className, overlayClassName, contentClassName
245
261
  //#endregion
246
262
  //#region src/react/empty.tsx
247
263
  function CommandEmpty({ ref, children, ...props }) {
248
- const ctx = use(CommandContext);
249
- if (!ctx) throw new Error("Command.Empty must be used within a <Command> component");
250
- if (ctx.state.filteredCount > 0 || ctx.state.loading) return null;
264
+ const stateCtx = use(CommandStateContext);
265
+ if (!stateCtx) throw new Error("Command.Empty must be used within a <Command> component");
266
+ if (stateCtx.state.filteredCount > 0 || stateCtx.state.loading) return null;
251
267
  return /* @__PURE__ */ jsx("div", {
252
268
  ref,
253
269
  "data-command-empty": "",
@@ -261,11 +277,11 @@ function CommandEmpty({ ref, children, ...props }) {
261
277
  //#region src/react/hooks/use-register.ts
262
278
  /** Register a command item with the machine — auto-deregisters on unmount */
263
279
  function useRegisterItem(value, options) {
264
- const ctx = use(CommandContext);
265
- if (!ctx) throw new Error("useRegisterItem must be used within a <Command> component");
280
+ const stable = use(CommandStableContext);
281
+ if (!stable) throw new Error("useRegisterItem must be used within a <Command> component");
266
282
  const generatedId = useId();
267
283
  const id = itemId(options?.forceId ?? generatedId);
268
- useInsertionEffect(() => {
284
+ useLayoutEffect(() => {
269
285
  const item = {
270
286
  id,
271
287
  value,
@@ -276,18 +292,18 @@ function useRegisterItem(value, options) {
276
292
  onSelect: options?.onSelect,
277
293
  data: options?.data
278
294
  };
279
- ctx.machine.send({
295
+ stable.machine.send({
280
296
  type: "REGISTER_ITEM",
281
297
  item
282
298
  });
283
299
  return () => {
284
- ctx.machine.send({
300
+ stable.machine.send({
285
301
  type: "UNREGISTER_ITEM",
286
302
  id
287
303
  });
288
304
  };
289
305
  }, [
290
- ctx.machine,
306
+ stable.machine,
291
307
  id,
292
308
  value,
293
309
  options?.groupId,
@@ -301,28 +317,28 @@ function useRegisterItem(value, options) {
301
317
  }
302
318
  /** Register a command group with the machine — auto-deregisters on unmount */
303
319
  function useRegisterGroup(heading, options) {
304
- const ctx = use(CommandContext);
305
- if (!ctx) throw new Error("useRegisterGroup must be used within a <Command> component");
320
+ const stable = use(CommandStableContext);
321
+ if (!stable) throw new Error("useRegisterGroup must be used within a <Command> component");
306
322
  const generatedId = useId();
307
323
  const id = groupId(options?.forceId ?? generatedId);
308
- useInsertionEffect(() => {
324
+ useLayoutEffect(() => {
309
325
  const group = {
310
326
  id,
311
327
  heading,
312
328
  priority: options?.priority
313
329
  };
314
- ctx.machine.send({
330
+ stable.machine.send({
315
331
  type: "REGISTER_GROUP",
316
332
  group
317
333
  });
318
334
  return () => {
319
- ctx.machine.send({
335
+ stable.machine.send({
320
336
  type: "UNREGISTER_GROUP",
321
337
  id
322
338
  });
323
339
  };
324
340
  }, [
325
- ctx.machine,
341
+ stable.machine,
326
342
  id,
327
343
  heading,
328
344
  options?.priority
@@ -332,14 +348,14 @@ function useRegisterGroup(heading, options) {
332
348
  //#endregion
333
349
  //#region src/react/group.tsx
334
350
  function CommandGroup({ ref, children, heading, priority, forceId, ...props }) {
335
- const ctx = use(CommandContext);
336
- if (!ctx) throw new Error("Command.Group must be used within a <Command> component");
351
+ const stateCtx = use(CommandStateContext);
352
+ if (!stateCtx) throw new Error("Command.Group must be used within a <Command> component");
337
353
  const headingId = useId();
338
354
  const groupId = useRegisterGroup(heading, {
339
355
  ...priority !== void 0 && { priority },
340
356
  ...forceId !== void 0 && { forceId }
341
357
  });
342
- const groupItems = ctx.state.groupedIds.get(groupId);
358
+ const groupItems = stateCtx.state.groupedIds.get(groupId);
343
359
  const hasVisibleItems = groupItems !== void 0 && groupItems.length > 0;
344
360
  const groupContext = useMemo(() => ({
345
361
  groupId,
@@ -394,29 +410,31 @@ function CommandHighlight({ text, ranges, highlightClassName }) {
394
410
  //#endregion
395
411
  //#region src/react/input.tsx
396
412
  function CommandInput({ ref, placeholder = "Search...", onValueChange, ...props }) {
397
- const ctx = use(CommandContext);
398
- if (!ctx) throw new Error("Command.Input must be used within a <Command> component");
413
+ const stable = use(CommandStableContext);
414
+ if (!stable) throw new Error("Command.Input must be used within a <Command> component");
415
+ const stateCtx = use(CommandStateContext);
416
+ if (!stateCtx) throw new Error("Command.Input must be used within a <Command> component");
399
417
  const handleChange = useCallback((event) => {
400
418
  const { value } = event.target;
401
- ctx.updateSearch(value);
419
+ stable.updateSearch(value);
402
420
  onValueChange?.(value);
403
- }, [ctx.updateSearch, onValueChange]);
421
+ }, [stable.updateSearch, onValueChange]);
404
422
  return /* @__PURE__ */ jsx("input", {
405
423
  ref,
406
424
  "data-command-input": "",
407
425
  type: "text",
408
426
  role: "combobox",
409
- "aria-expanded": ctx.state.filteredCount > 0,
410
- "aria-controls": ctx.listId,
411
- "aria-activedescendant": ctx.state.activeId ?? void 0,
427
+ "aria-expanded": stateCtx.state.filteredCount > 0,
428
+ "aria-controls": stable.listId,
429
+ "aria-activedescendant": stateCtx.state.activeId ?? void 0,
412
430
  "aria-autocomplete": "list",
413
- "aria-label": ctx.label,
414
- id: ctx.inputId,
431
+ "aria-label": stable.label,
432
+ id: stable.inputId,
415
433
  autoComplete: "off",
416
434
  autoCorrect: "off",
417
435
  spellCheck: false,
418
436
  placeholder,
419
- value: ctx.state.search,
437
+ value: stateCtx.state.search,
420
438
  onChange: handleChange,
421
439
  ...props
422
440
  });
@@ -424,8 +442,10 @@ function CommandInput({ ref, placeholder = "Search...", onValueChange, ...props
424
442
  //#endregion
425
443
  //#region src/react/item.tsx
426
444
  function CommandItem({ ref, children, value, keywords, onSelect, disabled = false, shortcut, forceId, ...props }) {
427
- const ctx = use(CommandContext);
428
- if (!ctx) throw new Error("Command.Item must be used within a <Command> component");
445
+ const stable = use(CommandStableContext);
446
+ if (!stable) throw new Error("Command.Item must be used within a <Command> component");
447
+ const stateCtx = use(CommandStateContext);
448
+ if (!stateCtx) throw new Error("Command.Item must be used within a <Command> component");
429
449
  const id = useRegisterItem(value, {
430
450
  ...keywords !== void 0 && { keywords },
431
451
  ...shortcut !== void 0 && { shortcut },
@@ -433,31 +453,31 @@ function CommandItem({ ref, children, value, keywords, onSelect, disabled = fals
433
453
  ...onSelect !== void 0 && { onSelect },
434
454
  ...forceId !== void 0 && { forceId }
435
455
  });
436
- const isActive = ctx.state.activeId === id;
437
- const isFiltered = ctx.filteredIdSet.has(id);
456
+ const isActive = stateCtx.state.activeId === id;
457
+ const isFiltered = stateCtx.filteredIdSet.has(id);
438
458
  const handleSelect = useCallback(() => {
439
- if (!disabled) ctx.machine.send({
459
+ if (!disabled) stable.machine.send({
440
460
  type: "ITEM_SELECT",
441
461
  id
442
462
  });
443
463
  }, [
444
- ctx.machine,
464
+ stable.machine,
445
465
  id,
446
466
  disabled
447
467
  ]);
448
- const activeIdRef = useRef(ctx.state.activeId);
449
- activeIdRef.current = ctx.state.activeId;
468
+ const activeIdRef = useRef(stateCtx.state.activeId);
469
+ activeIdRef.current = stateCtx.state.activeId;
450
470
  const handlePointerMove = useCallback(() => {
451
471
  if (!disabled && activeIdRef.current !== id) {
452
- ctx.setOptimisticActiveId(id);
453
- ctx.machine.send({
472
+ stable.setOptimisticActiveId(id);
473
+ stable.machine.send({
454
474
  type: "ITEM_ACTIVATE",
455
475
  id
456
476
  });
457
477
  }
458
478
  }, [
459
- ctx.machine,
460
- ctx.setOptimisticActiveId,
479
+ stable.machine,
480
+ stable.setOptimisticActiveId,
461
481
  id,
462
482
  disabled
463
483
  ]);
@@ -511,9 +531,8 @@ function useVirtualizer(options) {
511
531
  const getItemSize = useCallback((index) => measuredSizes.current.get(index) ?? estimateSize, [estimateSize]);
512
532
  const totalSize = useMemo(() => {
513
533
  if (!enabled) return 0;
514
- const sizes = Iterator.from({ [Symbol.iterator]: function* () {
515
- for (let i = 0; i < count; i++) yield getItemSize(i);
516
- } }).toArray();
534
+ const sizes = [];
535
+ for (let i = 0; i < count; i++) sizes.push(getItemSize(i));
517
536
  return Math.sumPrecise(sizes);
518
537
  }, [
519
538
  enabled,
@@ -531,9 +550,8 @@ function useVirtualizer(options) {
531
550
  startIdx++;
532
551
  }
533
552
  startIdx = Math.max(0, startIdx - overscan);
534
- const offsetSizes = Iterator.from({ [Symbol.iterator]: function* () {
535
- for (let i = 0; i < startIdx; i++) yield getItemSize(i);
536
- } }).toArray();
553
+ const offsetSizes = [];
554
+ for (let i = 0; i < startIdx; i++) offsetSizes.push(getItemSize(i));
537
555
  offset = Math.sumPrecise(offsetSizes);
538
556
  const items = [];
539
557
  let currentOffset = offset;
@@ -562,10 +580,9 @@ function useVirtualizer(options) {
562
580
  totalSize,
563
581
  scrollToIndex: useCallback((index) => {
564
582
  if (!scrollElement || !enabled) return;
565
- const clampedIndex = Math.min(index, count);
566
- const sizes = Iterator.from({ [Symbol.iterator]: function* () {
567
- for (let i = 0; i < clampedIndex; i++) yield getItemSize(i);
568
- } }).toArray();
583
+ const clampedIndex = Math.min(index, count - 1);
584
+ const sizes = [];
585
+ for (let i = 0; i < clampedIndex; i++) sizes.push(getItemSize(i));
569
586
  const targetOffset = Math.sumPrecise(sizes);
570
587
  scrollElement.scrollTo({
571
588
  top: targetOffset,
@@ -596,12 +613,14 @@ function useVirtualizer(options) {
596
613
  //#endregion
597
614
  //#region src/react/list.tsx
598
615
  function CommandList({ ref, children, virtualize, estimateSize = 44, overscan = 8, style, ...props }) {
599
- const ctx = use(CommandContext);
600
- if (!ctx) throw new Error("Command.List must be used within a <Command> component");
616
+ const stable = use(CommandStableContext);
617
+ if (!stable) throw new Error("Command.List must be used within a <Command> component");
618
+ const stateCtx = use(CommandStateContext);
619
+ if (!stateCtx) throw new Error("Command.List must be used within a <Command> component");
601
620
  const innerRef = useRef(null);
602
621
  const scrollRef = useRef(null);
603
622
  const [height, setHeight] = useState(0);
604
- const shouldVirtualize = virtualize ?? ctx.state.filteredCount > 100;
623
+ const shouldVirtualize = virtualize ?? stateCtx.state.filteredCount > 100;
605
624
  useEffect(() => {
606
625
  const element = innerRef.current;
607
626
  if (!element) return;
@@ -615,27 +634,27 @@ function CommandList({ ref, children, virtualize, estimateSize = 44, overscan =
615
634
  };
616
635
  }, []);
617
636
  const virtualizer = useVirtualizer({
618
- count: ctx.state.filteredCount,
637
+ count: stateCtx.state.filteredCount,
619
638
  estimateSize,
620
639
  overscan,
621
640
  scrollElement: shouldVirtualize ? scrollRef.current : null,
622
641
  enabled: shouldVirtualize
623
642
  });
624
- const prevActiveId = useRef(ctx.state.activeId);
643
+ const prevActiveId = useRef(stateCtx.state.activeId);
625
644
  useEffect(() => {
626
- if (ctx.state.activeId && ctx.state.activeId !== prevActiveId.current) {
627
- prevActiveId.current = ctx.state.activeId;
645
+ if (stateCtx.state.activeId && stateCtx.state.activeId !== prevActiveId.current) {
646
+ prevActiveId.current = stateCtx.state.activeId;
628
647
  if (shouldVirtualize) {
629
- const idx = ctx.state.filteredIds.indexOf(ctx.state.activeId);
648
+ const idx = stateCtx.state.filteredIds.indexOf(stateCtx.state.activeId);
630
649
  if (idx >= 0) virtualizer.scrollToIndex(idx);
631
- } else (scrollRef.current?.querySelector(`[id="${CSS.escape(ctx.state.activeId)}"]`))?.scrollIntoView({
650
+ } else (scrollRef.current?.querySelector(`[id="${CSS.escape(stateCtx.state.activeId)}"]`))?.scrollIntoView({
632
651
  block: "nearest",
633
652
  behavior: "smooth"
634
653
  });
635
654
  }
636
655
  }, [
637
- ctx.state.activeId,
638
- ctx.state.filteredIds,
656
+ stateCtx.state.activeId,
657
+ stateCtx.state.filteredIds,
639
658
  shouldVirtualize,
640
659
  virtualizer
641
660
  ]);
@@ -651,9 +670,9 @@ function CommandList({ ref, children, virtualize, estimateSize = 44, overscan =
651
670
  }, [ref]),
652
671
  "data-command-list": "",
653
672
  role: "listbox",
654
- "aria-label": ctx.label,
655
- "aria-busy": ctx.state.loading,
656
- id: ctx.listId,
673
+ "aria-label": stable.label,
674
+ "aria-busy": stateCtx.state.loading,
675
+ id: stable.listId,
657
676
  style: mergedStyle,
658
677
  ...props,
659
678
  children: [shouldVirtualize ? /* @__PURE__ */ jsxs("div", {
@@ -685,10 +704,11 @@ function CommandList({ ref, children, virtualize, estimateSize = 44, overscan =
685
704
  "data-command-aria-live": "",
686
705
  className: "sr-only",
687
706
  children: [
688
- ctx.state.filteredCount,
707
+ stateCtx.state.filteredCount,
689
708
  " result",
690
- ctx.state.filteredCount !== 1 ? "s" : "",
691
- " available."
709
+ stateCtx.state.filteredCount !== 1 ? "s" : "",
710
+ " ",
711
+ "available."
692
712
  ]
693
713
  })]
694
714
  });
@@ -696,9 +716,9 @@ function CommandList({ ref, children, virtualize, estimateSize = 44, overscan =
696
716
  //#endregion
697
717
  //#region src/react/loading.tsx
698
718
  function CommandLoading({ ref, children, loading: loadingOverride, ...props }) {
699
- const ctx = use(CommandContext);
700
- if (!ctx) throw new Error("Command.Loading must be used within a <Command> component");
701
- if (!(loadingOverride ?? ctx.state.loading ?? ctx.isPending)) return null;
719
+ const stateCtx = use(CommandStateContext);
720
+ if (!stateCtx) throw new Error("Command.Loading must be used within a <Command> component");
721
+ if (!(loadingOverride ?? stateCtx.state.loading ?? stateCtx.isPending)) return null;
702
722
  return /* @__PURE__ */ jsx("div", {
703
723
  ref,
704
724
  "data-command-loading": "",
@@ -712,9 +732,9 @@ function CommandLoading({ ref, children, loading: loadingOverride, ...props }) {
712
732
  //#endregion
713
733
  //#region src/react/page.tsx
714
734
  function CommandPage({ id, children }) {
715
- const ctx = use(CommandContext);
716
- if (!ctx) throw new Error("Command.Page must be used within a <Command> component");
717
- if (ctx.state.page !== id) return null;
735
+ const stateCtx = use(CommandStateContext);
736
+ if (!stateCtx) throw new Error("Command.Page must be used within a <Command> component");
737
+ if (stateCtx.state.page !== id) return null;
718
738
  return /* @__PURE__ */ jsx("div", {
719
739
  "data-command-page": "",
720
740
  "data-command-page-id": id,
@@ -766,38 +786,43 @@ function CommandRoot({ children, className, label = "Command palette", ...machin
766
786
  document.removeEventListener("keydown", handleKeyDown);
767
787
  };
768
788
  }, [handleKeyDown]);
769
- return /* @__PURE__ */ jsx(CommandContext, {
789
+ return /* @__PURE__ */ jsx(CommandStableContext, {
770
790
  value: useMemo(() => ({
771
791
  machine,
772
- state,
773
- isPending,
774
- updateSearch,
775
- setOptimisticActiveId,
776
- filteredIdSet,
777
792
  rootId: id,
778
793
  listId,
779
794
  inputId,
780
- label
795
+ label,
796
+ updateSearch,
797
+ setOptimisticActiveId
781
798
  }), [
782
799
  machine,
783
- state,
784
- isPending,
785
- updateSearch,
786
- setOptimisticActiveId,
787
- filteredIdSet,
788
800
  id,
789
801
  listId,
790
802
  inputId,
791
- label
803
+ label,
804
+ updateSearch,
805
+ setOptimisticActiveId
792
806
  ]),
793
- children: /* @__PURE__ */ jsx("div", {
794
- ref: rootRef,
795
- "data-command-root": "",
796
- "data-command-state": state.open ? "open" : "closed",
797
- className,
798
- role: "search",
799
- "aria-label": label,
800
- children
807
+ children: /* @__PURE__ */ jsx(CommandStateContext, {
808
+ value: useMemo(() => ({
809
+ state,
810
+ isPending,
811
+ filteredIdSet
812
+ }), [
813
+ state,
814
+ isPending,
815
+ filteredIdSet
816
+ ]),
817
+ children: /* @__PURE__ */ jsx("div", {
818
+ ref: rootRef,
819
+ "data-command-root": "",
820
+ "data-command-state": state.open ? "open" : "closed",
821
+ className,
822
+ role: "search",
823
+ "aria-label": label,
824
+ children
825
+ })
801
826
  })
802
827
  });
803
828
  }
@@ -843,10 +868,12 @@ var CommandErrorBoundary = class extends Component {
843
868
  //#endregion
844
869
  //#region src/react/hooks/use-command-state.ts
845
870
  function useCommandState(selector) {
846
- const ctx = use(CommandContext);
847
- if (!ctx) throw new Error("useCommandState must be used within a <Command> component");
848
- const getSnapshot = useCallback(() => selector ? selector(ctx.machine.getState()) : ctx.machine.getState(), [ctx.machine, selector]);
849
- return useSyncExternalStore(ctx.machine.subscribe, getSnapshot, getSnapshot);
871
+ const stable = use(CommandStableContext);
872
+ if (!stable) throw new Error("useCommandState must be used within a <Command> component");
873
+ const selectorRef = useRef(selector);
874
+ selectorRef.current = selector;
875
+ const getSnapshot = useCallback(() => selectorRef.current ? selectorRef.current(stable.machine.getState()) : stable.machine.getState(), [stable.machine]);
876
+ return useSyncExternalStore(stable.machine.subscribe, getSnapshot, getSnapshot);
850
877
  }
851
878
  //#endregion
852
879
  //#region src/react/hooks/use-devtools.ts
@@ -866,14 +893,15 @@ const DEVTOOLS_KEY = "__CRIMSON_COMMAND_DEVTOOLS__";
866
893
  */
867
894
  function useCommandDevtools(label = "default") {
868
895
  if (!__DEV__) return;
869
- const ctx = use(CommandContext);
896
+ const stable = use(CommandStableContext);
897
+ const stateCtx = use(CommandStateContext);
870
898
  const stateRef = useRef(null);
871
899
  useEffect(() => {
872
- if (!ctx) return;
900
+ if (!stable || !stateCtx) return;
873
901
  const update = () => {
874
- const s = ctx.state;
902
+ const s = stateCtx.state;
875
903
  const devState = {
876
- registeredItems: s.filteredCount,
904
+ registeredItems: stable.machine.getRegistry().size,
877
905
  filteredItems: s.filteredIds.length,
878
906
  searchQuery: s.search,
879
907
  activeId: s.activeId,
@@ -891,15 +919,19 @@ function useCommandDevtools(label = "default") {
891
919
  state: devState
892
920
  } }));
893
921
  };
894
- const unsub = ctx.machine.subscribe(update);
922
+ const unsub = stable.machine.subscribe(update);
895
923
  update();
896
924
  return () => {
897
925
  unsub();
898
926
  globalThis[DEVTOOLS_KEY]?.delete(label);
899
927
  };
900
- }, [ctx, label]);
928
+ }, [
929
+ stable,
930
+ stateCtx,
931
+ label
932
+ ]);
901
933
  }
902
934
  //#endregion
903
- export { Command, CommandActivity, CommandAsyncItems, CommandBadge, CommandDialog, CommandEmpty, CommandErrorBoundary, CommandGroup, CommandHighlight, CommandInput, CommandItem, CommandList, CommandLoading, CommandPage, CommandSeparator, CommandShortcut, createKeydownHandler, useCommand, useCommandDevtools, useCommandState, useRegisterGroup, useRegisterItem, useVirtualizer };
935
+ export { Command, CommandActivity, CommandAsyncItems, CommandBadge, CommandDialog, CommandEmpty, CommandErrorBoundary, CommandGroup, CommandHighlight, CommandInput, CommandItem, CommandList, CommandLoading, CommandPage, CommandSeparator, CommandShortcut, CommandStableContext, CommandStateContext, createKeydownHandler, useCommand, useCommandDevtools, useCommandState, useRegisterGroup, useRegisterItem, useVirtualizer };
904
936
 
905
937
  //# sourceMappingURL=index.mjs.map