@ucdjs-internal/shared-ui 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/README.md +0 -3
  2. package/dist/components/shiki-code.d.mts +2 -2
  3. package/dist/components/shiki-code.mjs +1 -3
  4. package/dist/components/theme-toggle.d.mts +3 -3
  5. package/dist/components/theme-toggle.mjs +1 -3
  6. package/dist/components/ucd-logo.d.mts +10 -0
  7. package/dist/components/ucd-logo.mjs +61 -0
  8. package/dist/components.d.mts +30 -0
  9. package/dist/components.mjs +30 -0
  10. package/dist/hooks/index.mjs +2 -3
  11. package/dist/hooks/use-clipboard.mjs +2 -4
  12. package/dist/hooks/use-mobile.mjs +1 -3
  13. package/dist/hooks/use-theme.mjs +1 -3
  14. package/dist/index.mjs +2 -3
  15. package/dist/lib/theme-script.mjs +1 -2
  16. package/dist/lib/utils.mjs +1 -3
  17. package/dist/ui/alert-dialog.d.mts +17 -17
  18. package/dist/ui/alert-dialog.mjs +12 -13
  19. package/dist/ui/avatar.d.mts +11 -11
  20. package/dist/ui/avatar.mjs +7 -8
  21. package/dist/ui/badge.d.mts +4 -4
  22. package/dist/ui/badge.mjs +1 -3
  23. package/dist/ui/breadcrumb.d.mts +7 -7
  24. package/dist/ui/breadcrumb.mjs +2 -3
  25. package/dist/ui/button.d.mts +8 -8
  26. package/dist/ui/button.mjs +4 -6
  27. package/dist/ui/card.d.mts +8 -8
  28. package/dist/ui/card.mjs +2 -3
  29. package/dist/ui/checkbox.d.mts +5 -5
  30. package/dist/ui/checkbox.mjs +5 -7
  31. package/dist/ui/collapsible.d.mts +7 -7
  32. package/dist/ui/collapsible.mjs +6 -8
  33. package/dist/ui/combobox.d.mts +20 -20
  34. package/dist/ui/combobox.mjs +21 -23
  35. package/dist/ui/command.d.mts +55 -16
  36. package/dist/ui/command.mjs +327 -89
  37. package/dist/ui/context-menu.d.mts +24 -24
  38. package/dist/ui/context-menu.mjs +20 -21
  39. package/dist/ui/dialog.d.mts +17 -15
  40. package/dist/ui/dialog.mjs +52 -42
  41. package/dist/ui/dropdown-menu.d.mts +16 -16
  42. package/dist/ui/dropdown-menu.mjs +2 -3
  43. package/dist/ui/field.d.mts +13 -13
  44. package/dist/ui/field.mjs +1 -3
  45. package/dist/ui/input-group.d.mts +10 -10
  46. package/dist/ui/input-group.mjs +2 -3
  47. package/dist/ui/input.d.mts +2 -2
  48. package/dist/ui/input.mjs +5 -6
  49. package/dist/ui/label.d.mts +2 -2
  50. package/dist/ui/label.mjs +2 -3
  51. package/dist/ui/scroll-area.d.mts +6 -6
  52. package/dist/ui/scroll-area.mjs +9 -10
  53. package/dist/ui/select.d.mts +14 -14
  54. package/dist/ui/select.mjs +18 -19
  55. package/dist/ui/separator.d.mts +5 -5
  56. package/dist/ui/separator.mjs +4 -6
  57. package/dist/ui/sheet.d.mts +9 -9
  58. package/dist/ui/sheet.mjs +2 -3
  59. package/dist/ui/sidebar.d.mts +23 -23
  60. package/dist/ui/sidebar.mjs +4 -6
  61. package/dist/ui/skeleton.d.mts +2 -2
  62. package/dist/ui/skeleton.mjs +1 -3
  63. package/dist/ui/table.d.mts +9 -9
  64. package/dist/ui/table.mjs +2 -3
  65. package/dist/ui/textarea.d.mts +2 -2
  66. package/dist/ui/textarea.mjs +2 -3
  67. package/dist/ui/tooltip.d.mts +8 -8
  68. package/dist/ui/tooltip.mjs +9 -11
  69. package/dist/vscode/syntaxes/ucd.tmLanguage.mjs +1 -2
  70. package/package.json +22 -44
  71. package/dist/components/index.d.mts +0 -3
  72. package/dist/components/index.mjs +0 -4
  73. package/dist/vendor/cmdk/command-score.mjs +0 -62
  74. package/dist/vendor/cmdk/index.d.mts +0 -181
  75. package/dist/vendor/cmdk/index.mjs +0 -713
@@ -1,713 +0,0 @@
1
- import { commandScore } from "./command-score.mjs";
2
- import * as React from "react";
3
- import { jsx, jsxs } from "react/jsx-runtime";
4
- import { Dialog } from "@base-ui/react";
5
- import { useId } from "@base-ui/utils/useId";
6
-
7
- //#region src/vendor/cmdk/index.tsx
8
- const GROUP_SELECTOR = `[cmdk-group=""]`;
9
- const GROUP_ITEMS_SELECTOR = `[cmdk-group-items=""]`;
10
- const GROUP_HEADING_SELECTOR = `[cmdk-group-heading=""]`;
11
- const ITEM_SELECTOR = `[cmdk-item=""]`;
12
- const VALID_ITEM_SELECTOR = `${ITEM_SELECTOR}:not([aria-disabled="true"])`;
13
- const SELECT_EVENT = `cmdk-item-select`;
14
- const VALUE_ATTR = `data-value`;
15
- const defaultFilter = (value, search, keywords = []) => commandScore(value, search, keywords);
16
- const useLayoutEffect = typeof window === "undefined" ? React.useEffect : React.useLayoutEffect;
17
- const srOnlyStyles = {
18
- position: "absolute",
19
- width: "1px",
20
- height: "1px",
21
- padding: "0",
22
- margin: "-1px",
23
- overflow: "hidden",
24
- clip: "rect(0, 0, 0, 0)",
25
- whiteSpace: "nowrap",
26
- borderWidth: "0"
27
- };
28
- const CommandContext = React.createContext(void 0);
29
- const useCommand = () => React.use(CommandContext);
30
- const StoreContext = React.createContext(void 0);
31
- const useStore = () => React.use(StoreContext);
32
- const GroupContext = React.createContext(void 0);
33
- function Command({ ref: forwardedRef, ...props }) {
34
- const state = useLazyRef(() => ({
35
- search: "",
36
- value: props.value ?? props.defaultValue ?? "",
37
- selectedItemId: void 0,
38
- filtered: {
39
- count: 0,
40
- items: /* @__PURE__ */ new Map(),
41
- groups: /* @__PURE__ */ new Set()
42
- }
43
- }));
44
- const allItems = useLazyRef(() => /* @__PURE__ */ new Set());
45
- const allGroups = useLazyRef(() => /* @__PURE__ */ new Map());
46
- const ids = useLazyRef(() => /* @__PURE__ */ new Map());
47
- const listeners = useLazyRef(() => /* @__PURE__ */ new Set());
48
- const propsRef = useAsRef(props);
49
- const { label, children: _children, value, onValueChange: _onValueChange, filter: _filter, shouldFilter: _shouldFilter, loop: _loop, disablePointerSelection: _disablePointerSelection = false, vimBindings = true, ...etc } = props;
50
- const listId = useId();
51
- const labelId = useId();
52
- const inputId = useId();
53
- const listInnerRef = React.useRef(null);
54
- const schedule = useScheduleLayoutEffect();
55
- const store = React.useMemo(() => {
56
- return {
57
- subscribe: (cb) => {
58
- listeners.current.add(cb);
59
- return () => listeners.current.delete(cb);
60
- },
61
- snapshot: () => {
62
- return state.current;
63
- },
64
- setState: (key, value, opts) => {
65
- if (Object.is(state.current[key], value)) return;
66
- state.current[key] = value;
67
- if (key === "search") {
68
- filterItems();
69
- sort();
70
- schedule(1, selectFirstItem);
71
- } else if (key === "value") {
72
- const activeElement = document.activeElement;
73
- if (activeElement && (activeElement.hasAttribute("cmdk-input") || activeElement.hasAttribute("cmdk-root"))) {
74
- const input = inputId ? document.getElementById(inputId) : null;
75
- if (input) input.focus();
76
- else if (listId) document.getElementById(listId)?.focus();
77
- }
78
- schedule(7, () => {
79
- state.current.selectedItemId = getSelectedItem()?.id;
80
- store.emit();
81
- });
82
- if (!opts) schedule(5, scrollSelectedIntoView);
83
- if (propsRef.current?.value !== void 0) {
84
- const newValue = value ?? "";
85
- propsRef.current.onValueChange?.(newValue);
86
- return;
87
- }
88
- }
89
- store.emit();
90
- },
91
- emit: () => {
92
- listeners.current.forEach((l) => l());
93
- }
94
- };
95
- }, []);
96
- const context = React.useMemo(() => ({
97
- value: (id, value, keywords) => {
98
- if (value !== ids.current.get(id)?.value) {
99
- ids.current.set(id, {
100
- value,
101
- keywords
102
- });
103
- state.current.filtered.items.set(id, score(value, keywords));
104
- schedule(2, () => {
105
- sort();
106
- store.emit();
107
- });
108
- }
109
- },
110
- item: (id, groupId) => {
111
- allItems.current.add(id);
112
- if (groupId) if (!allGroups.current.has(groupId)) allGroups.current.set(groupId, new Set([id]));
113
- else {
114
- const group = allGroups.current.get(groupId);
115
- if (group) group.add(id);
116
- }
117
- schedule(3, () => {
118
- filterItems();
119
- sort();
120
- if (!state.current.value) selectFirstItem();
121
- store.emit();
122
- });
123
- return () => {
124
- ids.current.delete(id);
125
- allItems.current.delete(id);
126
- state.current.filtered.items.delete(id);
127
- const selectedItem = getSelectedItem();
128
- schedule(4, () => {
129
- filterItems();
130
- if (selectedItem?.getAttribute("id") === id) selectFirstItem();
131
- store.emit();
132
- });
133
- };
134
- },
135
- group: (id) => {
136
- if (!allGroups.current.has(id)) allGroups.current.set(id, /* @__PURE__ */ new Set());
137
- return () => {
138
- ids.current.delete(id);
139
- allGroups.current.delete(id);
140
- };
141
- },
142
- filter: () => {
143
- return propsRef.current.shouldFilter ?? true;
144
- },
145
- label: label || props["aria-label"] || "",
146
- getDisablePointerSelection: () => {
147
- return propsRef.current.disablePointerSelection ?? false;
148
- },
149
- listId,
150
- inputId,
151
- labelId,
152
- listInnerRef
153
- }), []);
154
- /** Controlled mode `value` handling. */
155
- useLayoutEffect(() => {
156
- if (value !== void 0) {
157
- const v = value.trim();
158
- state.current.value = v;
159
- store.emit();
160
- }
161
- }, [store, value]);
162
- useLayoutEffect(() => {
163
- schedule(6, scrollSelectedIntoView);
164
- }, [schedule]);
165
- function score(value, keywords) {
166
- const filter = propsRef.current?.filter ?? defaultFilter;
167
- return value ? filter(value, state.current.search, keywords) : 0;
168
- }
169
- /** Sorts items by score, and groups by highest item score. */
170
- function sort() {
171
- if (!state.current.search || propsRef.current.shouldFilter === false) return;
172
- const scores = state.current.filtered.items;
173
- const groups = [];
174
- state.current.filtered.groups.forEach((value) => {
175
- const items = allGroups.current.get(value);
176
- let max = 0;
177
- if (items) items.forEach((item) => {
178
- const score = scores.get(item) ?? 0;
179
- max = Math.max(score, max);
180
- });
181
- groups.push([value, max]);
182
- });
183
- const listInsertionElement = listInnerRef.current;
184
- getValidItems().sort((a, b) => {
185
- const valueA = a.getAttribute("id") ?? "";
186
- const valueB = b.getAttribute("id") ?? "";
187
- return (scores.get(valueB) ?? 0) - (scores.get(valueA) ?? 0);
188
- }).forEach((item) => {
189
- const group = item.closest(GROUP_ITEMS_SELECTOR);
190
- if (group) {
191
- const target = item.parentElement === group ? item : item.closest(`${GROUP_ITEMS_SELECTOR} > *`);
192
- if (target) group.appendChild(target);
193
- } else if (listInsertionElement) {
194
- const target = item.parentElement === listInsertionElement ? item : item.closest(`${GROUP_ITEMS_SELECTOR} > *`);
195
- if (target) listInsertionElement.appendChild(target);
196
- }
197
- });
198
- groups.sort((a, b) => b[1] - a[1]).forEach((group) => {
199
- const element = listInnerRef.current?.querySelector(`${GROUP_SELECTOR}[${VALUE_ATTR}="${encodeURIComponent(group[0])}"]`);
200
- if (element && element.parentElement) element.parentElement.appendChild(element);
201
- });
202
- }
203
- function selectFirstItem() {
204
- const value = getValidItems().find((item) => item.getAttribute("aria-disabled") !== "true")?.getAttribute(VALUE_ATTR);
205
- store.setState("value", value ?? "");
206
- }
207
- /** Filters the current items. */
208
- function filterItems() {
209
- if (!state.current.search || propsRef.current.shouldFilter === false) {
210
- state.current.filtered.count = allItems.current.size;
211
- return;
212
- }
213
- state.current.filtered.groups = /* @__PURE__ */ new Set();
214
- let itemCount = 0;
215
- for (const id of allItems.current) {
216
- const rank = score(ids.current.get(id)?.value ?? "", ids.current.get(id)?.keywords ?? []);
217
- state.current.filtered.items.set(id, rank);
218
- if (rank > 0) itemCount++;
219
- }
220
- for (const [groupId, group] of allGroups.current) for (const itemId of group) if ((state.current.filtered.items.get(itemId) ?? 0) > 0) {
221
- state.current.filtered.groups.add(groupId);
222
- break;
223
- }
224
- state.current.filtered.count = itemCount;
225
- }
226
- function scrollSelectedIntoView() {
227
- requestAnimationFrame(() => {
228
- const item = getSelectedItem();
229
- if (item) {
230
- if (item.parentElement?.firstChild === item) item.closest(GROUP_SELECTOR)?.querySelector(GROUP_HEADING_SELECTOR)?.scrollIntoView({ block: "nearest" });
231
- item.scrollIntoView({ block: "nearest" });
232
- }
233
- });
234
- }
235
- /** Getters */
236
- function getSelectedItem() {
237
- return listInnerRef.current?.querySelector(`${ITEM_SELECTOR}[aria-selected="true"]`);
238
- }
239
- function getValidItems() {
240
- return Array.from(listInnerRef.current?.querySelectorAll(VALID_ITEM_SELECTOR) || []);
241
- }
242
- /** Setters */
243
- function updateSelectedToIndex(index) {
244
- const item = getValidItems()[index];
245
- if (item) store.setState("value", item.getAttribute(VALUE_ATTR) ?? "");
246
- }
247
- function updateSelectedByItem(change) {
248
- const selected = getSelectedItem();
249
- const items = getValidItems();
250
- const index = items.findIndex((item) => item === selected);
251
- let newSelected = items[index + change];
252
- if (propsRef.current?.loop) newSelected = index + change < 0 ? items[items.length - 1] : index + change === items.length ? items[0] : items[index + change];
253
- if (newSelected) store.setState("value", newSelected.getAttribute(VALUE_ATTR) ?? "");
254
- }
255
- function updateSelectedByGroup(change) {
256
- let group = getSelectedItem()?.closest(GROUP_SELECTOR);
257
- let item;
258
- while (group && !item) {
259
- group = change > 0 ? findNextSibling(group, GROUP_SELECTOR) : findPreviousSibling(group, GROUP_SELECTOR);
260
- item = group?.querySelector(VALID_ITEM_SELECTOR) ?? void 0;
261
- }
262
- if (item) store.setState("value", item.getAttribute(VALUE_ATTR) ?? "");
263
- else updateSelectedByItem(change);
264
- }
265
- const last = () => updateSelectedToIndex(getValidItems().length - 1);
266
- const next = (e) => {
267
- e.preventDefault();
268
- if (e.metaKey) last();
269
- else if (e.altKey) updateSelectedByGroup(1);
270
- else updateSelectedByItem(1);
271
- };
272
- const prev = (e) => {
273
- e.preventDefault();
274
- if (e.metaKey) updateSelectedToIndex(0);
275
- else if (e.altKey) updateSelectedByGroup(-1);
276
- else updateSelectedByItem(-1);
277
- };
278
- return /* @__PURE__ */ jsxs("div", {
279
- ref: forwardedRef,
280
- tabIndex: -1,
281
- ...etc,
282
- "cmdk-root": "",
283
- onKeyDown: (e) => {
284
- etc.onKeyDown?.(e);
285
- const isComposing = e.nativeEvent.isComposing || e.keyCode === 229;
286
- if (e.defaultPrevented || isComposing) return;
287
- switch (e.key) {
288
- case "n":
289
- case "j":
290
- if (vimBindings && e.ctrlKey) next(e);
291
- break;
292
- case "ArrowDown":
293
- next(e);
294
- break;
295
- case "p":
296
- case "k":
297
- if (vimBindings && e.ctrlKey) prev(e);
298
- break;
299
- case "ArrowUp":
300
- prev(e);
301
- break;
302
- case "Home":
303
- e.preventDefault();
304
- updateSelectedToIndex(0);
305
- break;
306
- case "End":
307
- e.preventDefault();
308
- last();
309
- break;
310
- case "Enter": {
311
- e.preventDefault();
312
- const item = getSelectedItem();
313
- if (item) {
314
- const event = new Event(SELECT_EVENT);
315
- item.dispatchEvent(event);
316
- }
317
- }
318
- }
319
- },
320
- children: [/* @__PURE__ */ jsx("label", {
321
- "cmdk-label": "",
322
- htmlFor: context.inputId,
323
- id: context.labelId,
324
- style: srOnlyStyles,
325
- children: label
326
- }), SlottableWithNestedChildren(props, (child) => /* @__PURE__ */ jsx(StoreContext, {
327
- value: store,
328
- children: /* @__PURE__ */ jsx(CommandContext, {
329
- value: context,
330
- children: child
331
- })
332
- }))]
333
- });
334
- }
335
- /**
336
- * Command menu item. Becomes active on pointer enter or through keyboard navigation.
337
- * Preferably pass a `value`, otherwise the value will be inferred from `children` or
338
- * the rendered item's `textContent`.
339
- */
340
- function Item({ ref: forwardedRef, ...props }) {
341
- const id = useId();
342
- const ref = React.useRef(null);
343
- const groupContext = React.use(GroupContext);
344
- const context = useCommand();
345
- const propsRef = useAsRef(props);
346
- const forceMount = propsRef.current?.forceMount ?? groupContext?.forceMount;
347
- useLayoutEffect(() => {
348
- if (!forceMount) return context.item(id, groupContext?.id ?? "");
349
- }, [
350
- context,
351
- forceMount,
352
- groupContext?.id,
353
- id
354
- ]);
355
- const value = useValue(id, ref, [
356
- props.value,
357
- props.children,
358
- ref
359
- ], props.keywords);
360
- const store = useStore();
361
- const selected = useCmdk((state) => state.value && state.value === value.current);
362
- const render = useCmdk((state) => forceMount ? true : context.filter() === false ? true : !state.search ? true : (state.filtered.items.get(id) ?? 0) > 0);
363
- const select = React.useCallback(() => {
364
- store.setState("value", value.current ?? "", true);
365
- }, [store, value]);
366
- const onSelect = React.useCallback(() => {
367
- select();
368
- propsRef.current.onSelect?.(value.current ?? "");
369
- }, [
370
- propsRef,
371
- select,
372
- value
373
- ]);
374
- React.useEffect(() => {
375
- const element = ref.current;
376
- if (!element || props.disabled) return;
377
- element.addEventListener(SELECT_EVENT, onSelect);
378
- return () => element.removeEventListener(SELECT_EVENT, onSelect);
379
- }, [
380
- onSelect,
381
- props.disabled,
382
- render
383
- ]);
384
- if (!render) return null;
385
- const { disabled, value: _, onSelect: __, forceMount: ___, keywords: ____, ...etc } = props;
386
- return /* @__PURE__ */ jsx("div", {
387
- ref: mergeRefs([ref, forwardedRef]),
388
- ...etc,
389
- id,
390
- "cmdk-item": "",
391
- role: "option",
392
- "aria-disabled": Boolean(disabled),
393
- "aria-selected": Boolean(selected),
394
- "data-disabled": Boolean(disabled),
395
- "data-selected": Boolean(selected),
396
- onPointerMove: disabled || context.getDisablePointerSelection() ? void 0 : select,
397
- onClick: disabled ? void 0 : onSelect,
398
- children: props.children
399
- });
400
- }
401
- /**
402
- * Group command menu items together with a heading.
403
- * Grouped items are always shown together.
404
- */
405
- function Group({ ref: forwardedRef, ...props }) {
406
- const { heading, children: _children, forceMount, ...etc } = props;
407
- const id = useId();
408
- const ref = React.useRef(null);
409
- const headingRef = React.useRef(null);
410
- const headingId = useId();
411
- const context = useCommand();
412
- const render = useCmdk((state) => forceMount ? true : context.filter() === false ? true : !state.search ? true : state.filtered.groups.has(id));
413
- useLayoutEffect(() => {
414
- return context.group(id);
415
- }, [context, id]);
416
- useValue(id, ref, [
417
- props.value,
418
- props.heading,
419
- headingRef
420
- ]);
421
- const contextValue = React.useMemo(() => ({
422
- id,
423
- forceMount
424
- }), [forceMount, id]);
425
- return /* @__PURE__ */ jsxs("div", {
426
- ref: mergeRefs([ref, forwardedRef]),
427
- ...etc,
428
- "cmdk-group": "",
429
- role: "presentation",
430
- hidden: render ? void 0 : true,
431
- children: [heading && /* @__PURE__ */ jsx("div", {
432
- ref: headingRef,
433
- "cmdk-group-heading": "",
434
- "aria-hidden": true,
435
- id: headingId,
436
- children: heading
437
- }), SlottableWithNestedChildren(props, (child) => /* @__PURE__ */ jsx("div", {
438
- "cmdk-group-items": "",
439
- role: "group",
440
- "aria-labelledby": heading ? headingId : void 0,
441
- children: /* @__PURE__ */ jsx(GroupContext, {
442
- value: contextValue,
443
- children: child
444
- })
445
- }))]
446
- });
447
- }
448
- /**
449
- * A visual and semantic separator between items or groups.
450
- * Visible when the search query is empty or `alwaysRender` is true, hidden otherwise.
451
- */
452
- function Separator({ ref: forwardedRef, ...props }) {
453
- const { alwaysRender, ...etc } = props;
454
- const ref = React.useRef(null);
455
- const render = useCmdk((state) => !state.search);
456
- if (!alwaysRender && !render) return null;
457
- return /* @__PURE__ */ jsx("div", {
458
- ref: mergeRefs([ref, forwardedRef]),
459
- ...etc,
460
- "cmdk-separator": "",
461
- role: "separator"
462
- });
463
- }
464
- /**
465
- * Command menu input.
466
- * All props are forwarded to the underyling `input` element.
467
- */
468
- function Input({ ref: forwardedRef, ...props }) {
469
- const { onValueChange, ...etc } = props;
470
- const isControlled = props.value != null;
471
- const store = useStore();
472
- const search = useCmdk((state) => state.search);
473
- const selectedItemId = useCmdk((state) => state.selectedItemId);
474
- const context = useCommand();
475
- React.useEffect(() => {
476
- if (props.value != null) store.setState("search", props.value);
477
- }, [props.value, store]);
478
- return /* @__PURE__ */ jsx("input", {
479
- ref: forwardedRef,
480
- ...etc,
481
- "cmdk-input": "",
482
- autoComplete: "off",
483
- autoCorrect: "off",
484
- spellCheck: false,
485
- "aria-autocomplete": "list",
486
- role: "combobox",
487
- "aria-expanded": true,
488
- "aria-controls": context.listId,
489
- "aria-labelledby": context.labelId,
490
- "aria-activedescendant": selectedItemId,
491
- id: context.inputId,
492
- type: "text",
493
- value: isControlled ? props.value : search,
494
- onChange: (e) => {
495
- if (!isControlled) store.setState("search", e.target.value);
496
- onValueChange?.(e.target.value);
497
- }
498
- });
499
- }
500
- /**
501
- * Contains `Item`, `Group`, and `Separator`.
502
- * Use the `--cmdk-list-height` CSS variable to animate height based on the number of results.
503
- */
504
- function List({ ref: forwardedRef, ...props }) {
505
- const { children: _children, label = "Suggestions", ...etc } = props;
506
- const ref = React.useRef(null);
507
- const heightRef = React.useRef(null);
508
- const selectedItemId = useCmdk((state) => state.selectedItemId);
509
- const context = useCommand();
510
- React.useEffect(() => {
511
- if (heightRef.current && ref.current) {
512
- const el = heightRef.current;
513
- const wrapper = ref.current;
514
- let animationFrame;
515
- const observer = new ResizeObserver(() => {
516
- animationFrame = requestAnimationFrame(() => {
517
- const height = el.offsetHeight;
518
- wrapper.style.setProperty(`--cmdk-list-height`, `${height.toFixed(1)}px`);
519
- });
520
- });
521
- observer.observe(el);
522
- return () => {
523
- if (animationFrame !== void 0) cancelAnimationFrame(animationFrame);
524
- observer.disconnect();
525
- };
526
- }
527
- }, []);
528
- return /* @__PURE__ */ jsx("div", {
529
- ref: mergeRefs([ref, forwardedRef]),
530
- ...etc,
531
- "cmdk-list": "",
532
- role: "listbox",
533
- tabIndex: -1,
534
- "aria-activedescendant": selectedItemId,
535
- "aria-label": label,
536
- id: context.listId,
537
- children: SlottableWithNestedChildren(props, (child) => /* @__PURE__ */ jsx("div", {
538
- ref: mergeRefs([heightRef, context.listInnerRef]),
539
- "cmdk-list-sizer": "",
540
- children: child
541
- }))
542
- });
543
- }
544
- /**
545
- * Renders the command menu in a Base UI Dialog.
546
- */
547
- function Dialog$1({ ref: forwardedRef, ...props }) {
548
- const { open, onOpenChange, overlayClassName, contentClassName, container, ...etc } = props;
549
- return /* @__PURE__ */ jsx(Dialog.Root, {
550
- open,
551
- onOpenChange,
552
- children: /* @__PURE__ */ jsxs(Dialog.Portal, {
553
- container,
554
- children: [/* @__PURE__ */ jsx(Dialog.Backdrop, {
555
- "cmdk-overlay": "",
556
- className: overlayClassName
557
- }), /* @__PURE__ */ jsx(Dialog.Popup, {
558
- "aria-label": props.label,
559
- "cmdk-dialog": "",
560
- className: contentClassName,
561
- children: /* @__PURE__ */ jsx(Command, {
562
- ref: forwardedRef,
563
- ...etc
564
- })
565
- })]
566
- })
567
- });
568
- }
569
- /**
570
- * Automatically renders when there are no results for the search query.
571
- */
572
- function Empty({ ref: forwardedRef, ...props }) {
573
- if (!useCmdk((state) => state.filtered.count === 0)) return null;
574
- return /* @__PURE__ */ jsx("div", {
575
- ref: forwardedRef,
576
- ...props,
577
- "cmdk-empty": "",
578
- role: "presentation"
579
- });
580
- }
581
- /**
582
- * You should conditionally render this with `progress` while loading asynchronous items.
583
- */
584
- function Loading({ ref: forwardedRef, ...props }) {
585
- const { progress, children: _children, label = "Loading...", ...etc } = props;
586
- return /* @__PURE__ */ jsx("div", {
587
- ref: forwardedRef,
588
- ...etc,
589
- "cmdk-loading": "",
590
- role: "progressbar",
591
- "aria-valuenow": progress,
592
- "aria-valuemin": 0,
593
- "aria-valuemax": 100,
594
- "aria-label": label,
595
- children: SlottableWithNestedChildren(props, (child) => /* @__PURE__ */ jsx("div", {
596
- "aria-hidden": true,
597
- children: child
598
- }))
599
- });
600
- }
601
- const pkg = Object.assign(Command, {
602
- List,
603
- Item,
604
- Input,
605
- Group,
606
- Separator,
607
- Dialog: Dialog$1,
608
- Empty,
609
- Loading
610
- });
611
- /**
612
- *
613
- *
614
- * Helpers
615
- *
616
- *
617
- */
618
- function findNextSibling(el, selector) {
619
- let sibling = el.nextElementSibling;
620
- while (sibling) {
621
- if (sibling.matches(selector)) return sibling;
622
- sibling = sibling.nextElementSibling;
623
- }
624
- }
625
- function findPreviousSibling(el, selector) {
626
- let sibling = el.previousElementSibling;
627
- while (sibling) {
628
- if (sibling.matches(selector)) return sibling;
629
- sibling = sibling.previousElementSibling;
630
- }
631
- }
632
- function useAsRef(data) {
633
- const ref = React.useRef(data);
634
- useLayoutEffect(() => {
635
- ref.current = data;
636
- });
637
- return ref;
638
- }
639
- function useLazyRef(fn) {
640
- const ref = React.useRef(void 0);
641
- if (ref.current === void 0) ref.current = fn();
642
- return ref;
643
- }
644
- /** Run a selector against the store state. */
645
- function useCmdk(selector) {
646
- const store = useStore();
647
- const cb = () => selector(store.snapshot());
648
- return React.useSyncExternalStore(store.subscribe, cb, cb);
649
- }
650
- function useValue(id, ref, deps, aliases = []) {
651
- const valueRef = React.useRef(void 0);
652
- const context = useCommand();
653
- useLayoutEffect(() => {
654
- const value = (() => {
655
- for (const part of deps) {
656
- if (typeof part === "string") return part.trim();
657
- if (typeof part === "object" && part !== null && "current" in part) {
658
- if (part.current) return part.current.textContent?.trim();
659
- return valueRef.current;
660
- }
661
- }
662
- })();
663
- const keywords = aliases.map((alias) => alias.trim());
664
- if (value) {
665
- context.value(id, value, keywords);
666
- ref.current?.setAttribute(VALUE_ATTR, value);
667
- valueRef.current = value;
668
- }
669
- });
670
- return valueRef;
671
- }
672
- /** Imperatively run a function on the next layout effect cycle. */
673
- function useScheduleLayoutEffect() {
674
- const [state, setState] = React.useState(null);
675
- const fnsRef = useLazyRef(() => /* @__PURE__ */ new Map());
676
- useLayoutEffect(() => {
677
- fnsRef.current.forEach((f) => f());
678
- fnsRef.current.clear();
679
- }, [fnsRef, state]);
680
- return (id, cb) => {
681
- fnsRef.current.set(id, cb);
682
- setState({});
683
- };
684
- }
685
- function renderChildren(children) {
686
- const childrenType = children.type;
687
- if (typeof childrenType === "function") return childrenType(children.props);
688
- else if ("render" in childrenType) return childrenType.render(children.props);
689
- else return children;
690
- }
691
- function SlottableWithNestedChildren({ asChild, children }, render) {
692
- if (asChild && React.isValidElement(children)) {
693
- const child = children;
694
- const renderedChild = renderChildren(child);
695
- if (!React.isValidElement(renderedChild)) return render(child.props.children);
696
- return React.createElement(renderedChild.type, {
697
- ...renderedChild.props,
698
- ref: child.ref
699
- }, render(child.props.children));
700
- }
701
- return render(children);
702
- }
703
- function mergeRefs(refs) {
704
- return (value) => {
705
- refs.forEach((ref) => {
706
- if (typeof ref === "function") ref(value);
707
- else if (ref != null) ref.current = value;
708
- });
709
- };
710
- }
711
-
712
- //#endregion
713
- export { pkg };