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.
- package/README.md +261 -0
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.mjs +1 -1
- package/dist/{core-Bq0eDvlc.mjs → core-CgQYpHK3.mjs} +35 -17
- package/dist/core-CgQYpHK3.mjs.map +1 -0
- package/dist/{index-Ctz7l29k.d.mts → index-C6g94P7V.d.mts} +6 -5
- package/dist/index-C6g94P7V.d.mts.map +1 -0
- package/dist/react/index.d.mts +22 -3
- package/dist/react/index.d.mts.map +1 -1
- package/dist/react/index.mjs +167 -135
- package/dist/react/index.mjs.map +1 -1
- package/package.json +4 -2
- package/src/react/styles.css +1 -3
- package/dist/core-Bq0eDvlc.mjs.map +0 -1
- package/dist/index-Ctz7l29k.d.mts.map +0 -1
package/dist/react/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as itemId, S as groupId, d as formatShortcut, f as parseShortcut, i as createCommandMachine } from "../core-
|
|
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,
|
|
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
|
|
32
|
-
if (!
|
|
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
|
-
|
|
35
|
-
|
|
42
|
+
useLayoutEffect(() => {
|
|
43
|
+
stable.machine.send({
|
|
36
44
|
type: "ITEMS_LOADED",
|
|
37
45
|
items
|
|
38
46
|
});
|
|
39
|
-
}, [
|
|
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
|
-
|
|
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
|
|
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(
|
|
228
|
-
value:
|
|
229
|
-
children: /* @__PURE__ */ jsx(
|
|
230
|
-
|
|
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-
|
|
234
|
-
|
|
235
|
-
"
|
|
236
|
-
|
|
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
|
|
249
|
-
if (!
|
|
250
|
-
if (
|
|
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
|
|
265
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
295
|
+
stable.machine.send({
|
|
280
296
|
type: "REGISTER_ITEM",
|
|
281
297
|
item
|
|
282
298
|
});
|
|
283
299
|
return () => {
|
|
284
|
-
|
|
300
|
+
stable.machine.send({
|
|
285
301
|
type: "UNREGISTER_ITEM",
|
|
286
302
|
id
|
|
287
303
|
});
|
|
288
304
|
};
|
|
289
305
|
}, [
|
|
290
|
-
|
|
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
|
|
305
|
-
if (!
|
|
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
|
-
|
|
324
|
+
useLayoutEffect(() => {
|
|
309
325
|
const group = {
|
|
310
326
|
id,
|
|
311
327
|
heading,
|
|
312
328
|
priority: options?.priority
|
|
313
329
|
};
|
|
314
|
-
|
|
330
|
+
stable.machine.send({
|
|
315
331
|
type: "REGISTER_GROUP",
|
|
316
332
|
group
|
|
317
333
|
});
|
|
318
334
|
return () => {
|
|
319
|
-
|
|
335
|
+
stable.machine.send({
|
|
320
336
|
type: "UNREGISTER_GROUP",
|
|
321
337
|
id
|
|
322
338
|
});
|
|
323
339
|
};
|
|
324
340
|
}, [
|
|
325
|
-
|
|
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
|
|
336
|
-
if (!
|
|
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 =
|
|
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
|
|
398
|
-
if (!
|
|
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
|
-
|
|
419
|
+
stable.updateSearch(value);
|
|
402
420
|
onValueChange?.(value);
|
|
403
|
-
}, [
|
|
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":
|
|
410
|
-
"aria-controls":
|
|
411
|
-
"aria-activedescendant":
|
|
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":
|
|
414
|
-
id:
|
|
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:
|
|
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
|
|
428
|
-
if (!
|
|
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 =
|
|
437
|
-
const isFiltered =
|
|
456
|
+
const isActive = stateCtx.state.activeId === id;
|
|
457
|
+
const isFiltered = stateCtx.filteredIdSet.has(id);
|
|
438
458
|
const handleSelect = useCallback(() => {
|
|
439
|
-
if (!disabled)
|
|
459
|
+
if (!disabled) stable.machine.send({
|
|
440
460
|
type: "ITEM_SELECT",
|
|
441
461
|
id
|
|
442
462
|
});
|
|
443
463
|
}, [
|
|
444
|
-
|
|
464
|
+
stable.machine,
|
|
445
465
|
id,
|
|
446
466
|
disabled
|
|
447
467
|
]);
|
|
448
|
-
const activeIdRef = useRef(
|
|
449
|
-
activeIdRef.current =
|
|
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
|
-
|
|
453
|
-
|
|
472
|
+
stable.setOptimisticActiveId(id);
|
|
473
|
+
stable.machine.send({
|
|
454
474
|
type: "ITEM_ACTIVATE",
|
|
455
475
|
id
|
|
456
476
|
});
|
|
457
477
|
}
|
|
458
478
|
}, [
|
|
459
|
-
|
|
460
|
-
|
|
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 =
|
|
515
|
-
|
|
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 =
|
|
535
|
-
|
|
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 =
|
|
567
|
-
|
|
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
|
|
600
|
-
if (!
|
|
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 ??
|
|
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:
|
|
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(
|
|
643
|
+
const prevActiveId = useRef(stateCtx.state.activeId);
|
|
625
644
|
useEffect(() => {
|
|
626
|
-
if (
|
|
627
|
-
prevActiveId.current =
|
|
645
|
+
if (stateCtx.state.activeId && stateCtx.state.activeId !== prevActiveId.current) {
|
|
646
|
+
prevActiveId.current = stateCtx.state.activeId;
|
|
628
647
|
if (shouldVirtualize) {
|
|
629
|
-
const idx =
|
|
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(
|
|
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
|
-
|
|
638
|
-
|
|
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":
|
|
655
|
-
"aria-busy":
|
|
656
|
-
id:
|
|
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
|
-
|
|
707
|
+
stateCtx.state.filteredCount,
|
|
689
708
|
" result",
|
|
690
|
-
|
|
691
|
-
"
|
|
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
|
|
700
|
-
if (!
|
|
701
|
-
if (!(loadingOverride ??
|
|
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
|
|
716
|
-
if (!
|
|
717
|
-
if (
|
|
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(
|
|
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(
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
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
|
|
847
|
-
if (!
|
|
848
|
-
const
|
|
849
|
-
|
|
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
|
|
896
|
+
const stable = use(CommandStableContext);
|
|
897
|
+
const stateCtx = use(CommandStateContext);
|
|
870
898
|
const stateRef = useRef(null);
|
|
871
899
|
useEffect(() => {
|
|
872
|
-
if (!
|
|
900
|
+
if (!stable || !stateCtx) return;
|
|
873
901
|
const update = () => {
|
|
874
|
-
const s =
|
|
902
|
+
const s = stateCtx.state;
|
|
875
903
|
const devState = {
|
|
876
|
-
registeredItems:
|
|
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 =
|
|
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
|
-
}, [
|
|
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
|