@dxos/react-ui-searchlist 0.8.4-main.ae835ea → 0.8.4-main.bc674ce

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 (49) hide show
  1. package/dist/lib/browser/index.mjs +669 -337
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +669 -337
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/Combobox/Combobox.d.ts +48 -8
  8. package/dist/types/src/components/Combobox/Combobox.d.ts.map +1 -1
  9. package/dist/types/src/components/Combobox/Combobox.stories.d.ts +1 -1
  10. package/dist/types/src/components/Combobox/Combobox.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/Listbox/Listbox.d.ts.map +1 -1
  12. package/dist/types/src/components/Listbox/Listbox.stories.d.ts +1 -1
  13. package/dist/types/src/components/SearchList/SearchList.d.ts +83 -20
  14. package/dist/types/src/components/SearchList/SearchList.d.ts.map +1 -1
  15. package/dist/types/src/components/SearchList/SearchList.stories.d.ts +10 -7
  16. package/dist/types/src/components/SearchList/SearchList.stories.d.ts.map +1 -1
  17. package/dist/types/src/components/SearchList/context.d.ts +33 -0
  18. package/dist/types/src/components/SearchList/context.d.ts.map +1 -0
  19. package/dist/types/src/components/SearchList/hooks/index.d.ts +5 -0
  20. package/dist/types/src/components/SearchList/hooks/index.d.ts.map +1 -0
  21. package/dist/types/src/components/SearchList/hooks/useGlobalFilter.d.ts +34 -0
  22. package/dist/types/src/components/SearchList/hooks/useGlobalFilter.d.ts.map +1 -0
  23. package/dist/types/src/components/SearchList/hooks/useSearchListInput.d.ts +12 -0
  24. package/dist/types/src/components/SearchList/hooks/useSearchListInput.d.ts.map +1 -0
  25. package/dist/types/src/components/SearchList/hooks/useSearchListItem.d.ts +10 -0
  26. package/dist/types/src/components/SearchList/hooks/useSearchListItem.d.ts.map +1 -0
  27. package/dist/types/src/components/SearchList/hooks/useSearchListResults.d.ts +36 -0
  28. package/dist/types/src/components/SearchList/hooks/useSearchListResults.d.ts.map +1 -0
  29. package/dist/types/src/components/SearchList/index.d.ts +1 -0
  30. package/dist/types/src/components/SearchList/index.d.ts.map +1 -1
  31. package/dist/types/src/translations.d.ts +2 -2
  32. package/dist/types/src/translations.d.ts.map +1 -1
  33. package/dist/types/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +20 -17
  35. package/src/components/Combobox/Combobox.stories.tsx +9 -4
  36. package/src/components/Combobox/Combobox.tsx +35 -14
  37. package/src/components/Listbox/Listbox.stories.tsx +1 -1
  38. package/src/components/Listbox/Listbox.tsx +8 -3
  39. package/src/components/SearchList/SearchList.stories.tsx +500 -30
  40. package/src/components/SearchList/SearchList.tsx +458 -62
  41. package/src/components/SearchList/context.ts +43 -0
  42. package/src/components/SearchList/hooks/index.ts +8 -0
  43. package/src/components/SearchList/hooks/useGlobalFilter.tsx +61 -0
  44. package/src/components/SearchList/hooks/useSearchListInput.ts +14 -0
  45. package/src/components/SearchList/hooks/useSearchListItem.ts +14 -0
  46. package/src/components/SearchList/hooks/useSearchListResults.ts +104 -0
  47. package/src/components/SearchList/index.ts +1 -0
  48. package/src/translations.ts +1 -1
  49. package/src/types/command-score.d.ts +16 -0
@@ -1,21 +1,19 @@
1
1
  // src/components/Combobox/Combobox.tsx
2
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
3
- import { createContext } from "@radix-ui/react-context";
4
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
5
- import React2, { forwardRef as forwardRef2, useCallback } from "react";
6
- import { Button, Icon, Popover } from "@dxos/react-ui";
2
+ import { createContext as createContext3 } from "@radix-ui/react-context";
3
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
4
+ import React3, { forwardRef as forwardRef2, useCallback as useCallback3 } from "react";
5
+ import { Button, Icon as Icon2, Popover } from "@dxos/react-ui";
7
6
  import { useId } from "@dxos/react-ui";
8
- import { mx as mx2, staticPlaceholderText } from "@dxos/react-ui-theme";
7
+ import { mx as mx2, staticPlaceholderText } from "@dxos/ui-theme";
9
8
 
10
9
  // src/components/SearchList/SearchList.tsx
11
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
12
- import { CommandEmpty, CommandInput, CommandItem, CommandList, CommandRoot } from "cmdk";
13
- import React, { forwardRef } from "react";
14
- import { useDensityContext, useElevationContext, useThemeContext, useTranslation } from "@dxos/react-ui";
15
- import { mx } from "@dxos/react-ui-theme";
10
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
11
+ import React, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
12
+ import { Icon, useDensityContext, useElevationContext, useThemeContext, useTranslation } from "@dxos/react-ui";
13
+ import { descriptionText, mx } from "@dxos/ui-theme";
16
14
 
17
15
  // src/translations.ts
18
- var translationKey = "react-ui-searchlist";
16
+ var translationKey = "@dxos/react-ui-searchlist";
19
17
  var translations = [
20
18
  {
21
19
  "en-US": {
@@ -26,94 +24,459 @@ var translations = [
26
24
  }
27
25
  ];
28
26
 
27
+ // src/components/SearchList/context.ts
28
+ import { createContext } from "@radix-ui/react-context";
29
+ var [SearchListItemContextProvider, useSearchListItemContext] = createContext("SearchListItem");
30
+ var [SearchListInputContextProvider, useSearchListInputContext] = createContext("SearchListInput");
31
+
29
32
  // src/components/SearchList/SearchList.tsx
30
- var commandItem = "flex items-center overflow-hidden";
31
- var searchListItem = "plb-1 pli-2 rounded-sm select-none cursor-pointer data-[selected]:bg-hoverOverlay hover:bg-hoverOverlay";
32
- var SEARCHLIST_NAME = "SearchList";
33
- var SEARCHLIST_ITEM_NAME = "SearchListItem";
34
- var SearchListRoot = /* @__PURE__ */ forwardRef(({ children, classNames, ...props }, forwardedRef) => {
35
- var _effect = _useSignals();
36
- try {
37
- return /* @__PURE__ */ React.createElement(CommandRoot, {
38
- ...props,
39
- className: mx(classNames),
40
- ref: forwardedRef
41
- }, children);
42
- } finally {
43
- _effect.f();
44
- }
45
- });
46
- SearchListRoot.displayName = SEARCHLIST_NAME;
47
- var SearchListInput = /* @__PURE__ */ forwardRef(({ classNames, density: propsDensity, elevation: propsElevation, variant, ...props }, forwardedRef) => {
48
- var _effect = _useSignals();
49
- try {
50
- const { t } = useTranslation(translationKey);
51
- const placeholder = props.placeholder ?? t("search.placeholder");
52
- const { hasIosKeyboard } = useThemeContext();
53
- const { tx } = useThemeContext();
54
- const density = useDensityContext(propsDensity);
55
- const elevation = useElevationContext(propsElevation);
56
- return /* @__PURE__ */ React.createElement(CommandInput, {
57
- ...props,
58
- placeholder,
59
- className: tx("input.input", "input", {
60
- variant,
61
- disabled: props.disabled,
62
- density,
63
- elevation
64
- }, "mbe-cardSpacingBlock", classNames),
65
- ...props.autoFocus && !hasIosKeyboard && {
66
- autoFocus: true
67
- },
68
- ref: forwardedRef
69
- });
70
- } finally {
71
- _effect.f();
72
- }
33
+ var SearchListRoot = ({ children, value: valueProp, defaultValue = "", debounceMs = 200, onSearch }) => {
34
+ const [query = "", setQuery] = useControllableState({
35
+ prop: valueProp,
36
+ defaultProp: defaultValue,
37
+ onChange: void 0
38
+ });
39
+ const [selectedValue, setSelectedValue] = useState(void 0);
40
+ const itemsRef = useRef(/* @__PURE__ */ new Map());
41
+ const debounceRef = useRef(null);
42
+ const handleQueryChange = useCallback((newQuery) => {
43
+ setQuery(newQuery);
44
+ if (debounceRef.current) {
45
+ clearTimeout(debounceRef.current);
46
+ }
47
+ debounceRef.current = setTimeout(() => {
48
+ onSearch?.(newQuery);
49
+ }, debounceMs);
50
+ }, [
51
+ setQuery,
52
+ onSearch,
53
+ debounceMs
54
+ ]);
55
+ const [itemVersion, setItemVersion] = useState(0);
56
+ useEffect(() => {
57
+ return () => {
58
+ if (debounceRef.current) {
59
+ clearTimeout(debounceRef.current);
60
+ }
61
+ };
62
+ }, []);
63
+ useEffect(() => {
64
+ const currentItem = selectedValue !== void 0 ? itemsRef.current.get(selectedValue) : void 0;
65
+ const isSelectionValid = currentItem !== void 0 && !currentItem.disabled;
66
+ if (!isSelectionValid && itemsRef.current.size > 0) {
67
+ const entries = Array.from(itemsRef.current.entries()).filter(([, data]) => !data.disabled);
68
+ if (entries.length > 0) {
69
+ entries.sort(([, a], [, b]) => {
70
+ const position = a.element.compareDocumentPosition(b.element);
71
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
72
+ return -1;
73
+ }
74
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) {
75
+ return 1;
76
+ }
77
+ return 0;
78
+ });
79
+ const firstValue = entries[0]?.[0];
80
+ if (firstValue !== void 0 && firstValue !== selectedValue) {
81
+ setSelectedValue(firstValue);
82
+ }
83
+ } else if (selectedValue !== void 0) {
84
+ setSelectedValue(void 0);
85
+ }
86
+ }
87
+ }, [
88
+ itemVersion,
89
+ selectedValue
90
+ ]);
91
+ const registerItem = useCallback((value, element, onSelect, disabled) => {
92
+ if (element) {
93
+ itemsRef.current.set(value, {
94
+ element,
95
+ onSelect,
96
+ disabled
97
+ });
98
+ setItemVersion((v) => v + 1);
99
+ }
100
+ }, []);
101
+ const unregisterItem = useCallback((value) => {
102
+ itemsRef.current.delete(value);
103
+ setItemVersion((v) => v + 1);
104
+ }, []);
105
+ const getItemValues = useCallback(() => {
106
+ return Array.from(itemsRef.current.entries()).filter(([, data]) => !data.disabled).sort(([, a], [, b]) => {
107
+ const position = a.element.compareDocumentPosition(b.element);
108
+ return position & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : position & Node.DOCUMENT_POSITION_PRECEDING ? 1 : 0;
109
+ }).map(([value]) => value);
110
+ }, []);
111
+ const triggerSelect = useCallback(() => {
112
+ if (selectedValue !== void 0) {
113
+ const item = itemsRef.current.get(selectedValue);
114
+ item?.onSelect?.();
115
+ }
116
+ }, [
117
+ selectedValue
118
+ ]);
119
+ const itemContextValue = useMemo(() => ({
120
+ selectedValue,
121
+ onSelectedValueChange: setSelectedValue,
122
+ registerItem,
123
+ unregisterItem
124
+ }), [
125
+ selectedValue,
126
+ registerItem,
127
+ unregisterItem
128
+ ]);
129
+ const inputContextValue = useMemo(() => ({
130
+ query,
131
+ onQueryChange: handleQueryChange,
132
+ selectedValue,
133
+ onSelectedValueChange: setSelectedValue,
134
+ getItemValues,
135
+ triggerSelect
136
+ }), [
137
+ query,
138
+ handleQueryChange,
139
+ selectedValue,
140
+ getItemValues,
141
+ triggerSelect
142
+ ]);
143
+ return /* @__PURE__ */ React.createElement(SearchListInputContextProvider, {
144
+ query: inputContextValue.query,
145
+ onQueryChange: inputContextValue.onQueryChange,
146
+ selectedValue: inputContextValue.selectedValue,
147
+ onSelectedValueChange: inputContextValue.onSelectedValueChange,
148
+ getItemValues: inputContextValue.getItemValues,
149
+ triggerSelect: inputContextValue.triggerSelect
150
+ }, /* @__PURE__ */ React.createElement(SearchListItemContextProvider, {
151
+ selectedValue: itemContextValue.selectedValue,
152
+ onSelectedValueChange: itemContextValue.onSelectedValueChange,
153
+ registerItem: itemContextValue.registerItem,
154
+ unregisterItem: itemContextValue.unregisterItem
155
+ }, children));
156
+ };
157
+ SearchListRoot.displayName = "SearchList.Root";
158
+ var SearchListViewport = ({ classNames, children }) => {
159
+ return /* @__PURE__ */ React.createElement("div", {
160
+ role: "none",
161
+ className: mx("is-full min-bs-0 grow overflow-y-auto", classNames)
162
+ }, children);
163
+ };
164
+ SearchListViewport.displayName = "SearchList.Viewport";
165
+ var SearchListContent = /* @__PURE__ */ forwardRef(({ classNames, children }, forwardedRef) => {
166
+ return /* @__PURE__ */ React.createElement("div", {
167
+ ref: forwardedRef,
168
+ role: "listbox",
169
+ className: mx("flex flex-col is-full min-bs-0 grow overflow-hidden", classNames)
170
+ }, children);
73
171
  });
74
- var SearchListContent = /* @__PURE__ */ forwardRef(({ children, classNames, ...props }, forwardedRef) => {
75
- var _effect = _useSignals();
76
- try {
77
- return /* @__PURE__ */ React.createElement(CommandList, {
78
- ...props,
79
- className: mx(classNames),
80
- ref: forwardedRef
81
- }, children);
82
- } finally {
83
- _effect.f();
84
- }
172
+ SearchListContent.displayName = "SearchList.Content";
173
+ var SearchListInput = /* @__PURE__ */ forwardRef(({ classNames, density: propsDensity, elevation: propsElevation, variant, placeholder, onChange, ...props }, forwardedRef) => {
174
+ const { query, onQueryChange, selectedValue, onSelectedValueChange, getItemValues, triggerSelect } = useSearchListInputContext("SearchList.Input");
175
+ const { t } = useTranslation(translationKey);
176
+ const { hasIosKeyboard, tx } = useThemeContext();
177
+ const density = useDensityContext(propsDensity);
178
+ const elevation = useElevationContext(propsElevation);
179
+ const defaultPlaceholder = t("search.placeholder");
180
+ const handleChange = useCallback((event) => {
181
+ onQueryChange(event.target.value);
182
+ onChange?.(event);
183
+ }, [
184
+ onQueryChange,
185
+ onChange
186
+ ]);
187
+ const handleKeyDown = useCallback((event) => {
188
+ const values = getItemValues();
189
+ if (values.length === 0) {
190
+ if (event.key === "Escape") {
191
+ onQueryChange("");
192
+ }
193
+ return;
194
+ }
195
+ const currentIndex = selectedValue !== void 0 ? values.indexOf(selectedValue) : -1;
196
+ switch (event.key) {
197
+ case "ArrowDown": {
198
+ event.preventDefault();
199
+ const nextIndex = currentIndex === -1 ? 0 : Math.min(currentIndex + 1, values.length - 1);
200
+ const nextValue = values[nextIndex];
201
+ if (nextValue !== void 0) {
202
+ onSelectedValueChange(nextValue);
203
+ }
204
+ break;
205
+ }
206
+ case "ArrowUp": {
207
+ event.preventDefault();
208
+ const prevIndex = currentIndex === -1 ? values.length - 1 : Math.max(currentIndex - 1, 0);
209
+ const prevValue = values[prevIndex];
210
+ if (prevValue !== void 0) {
211
+ onSelectedValueChange(prevValue);
212
+ }
213
+ break;
214
+ }
215
+ case "Enter": {
216
+ if (selectedValue !== void 0) {
217
+ event.preventDefault();
218
+ triggerSelect();
219
+ }
220
+ break;
221
+ }
222
+ case "Home": {
223
+ event.preventDefault();
224
+ const firstValue = values[0];
225
+ if (firstValue !== void 0) {
226
+ onSelectedValueChange(firstValue);
227
+ }
228
+ break;
229
+ }
230
+ case "End": {
231
+ event.preventDefault();
232
+ const lastValue = values[values.length - 1];
233
+ if (lastValue !== void 0) {
234
+ onSelectedValueChange(lastValue);
235
+ }
236
+ break;
237
+ }
238
+ case "Escape": {
239
+ event.preventDefault();
240
+ if (selectedValue !== void 0) {
241
+ onSelectedValueChange(void 0);
242
+ } else {
243
+ onQueryChange("");
244
+ }
245
+ break;
246
+ }
247
+ }
248
+ }, [
249
+ selectedValue,
250
+ onSelectedValueChange,
251
+ getItemValues,
252
+ triggerSelect,
253
+ onQueryChange
254
+ ]);
255
+ return /* @__PURE__ */ React.createElement("input", {
256
+ ...props,
257
+ ...props.autoFocus && !hasIosKeyboard && {
258
+ autoFocus: true
259
+ },
260
+ type: "text",
261
+ value: query,
262
+ placeholder: placeholder ?? defaultPlaceholder,
263
+ className: tx("input.input", "input", {
264
+ variant,
265
+ disabled: props.disabled,
266
+ density,
267
+ elevation
268
+ }, classNames),
269
+ onChange: handleChange,
270
+ onKeyDown: handleKeyDown,
271
+ ref: forwardedRef
272
+ });
85
273
  });
86
- var SearchListEmpty = /* @__PURE__ */ forwardRef(({ children, classNames, ...props }, forwardedRef) => {
87
- var _effect = _useSignals();
88
- try {
89
- return /* @__PURE__ */ React.createElement(CommandEmpty, {
90
- ...props,
91
- className: mx(classNames),
92
- ref: forwardedRef
93
- }, children);
94
- } finally {
95
- _effect.f();
96
- }
274
+ SearchListInput.displayName = "SearchList.Input";
275
+ var SearchListItem = /* @__PURE__ */ forwardRef(({ classNames, value, label, icon, checked, suffix, onSelect, disabled }, forwardedRef) => {
276
+ const { selectedValue, registerItem, unregisterItem } = useSearchListItemContext("SearchList.Item");
277
+ const internalRef = useRef(null);
278
+ const isSelected = selectedValue === value && !disabled;
279
+ useEffect(() => {
280
+ const element = internalRef.current;
281
+ if (element) {
282
+ registerItem(value, element, onSelect, disabled);
283
+ }
284
+ return () => unregisterItem(value);
285
+ }, [
286
+ value,
287
+ onSelect,
288
+ disabled,
289
+ registerItem,
290
+ unregisterItem
291
+ ]);
292
+ useEffect(() => {
293
+ if (isSelected && internalRef.current) {
294
+ internalRef.current.scrollIntoView({
295
+ block: "nearest",
296
+ behavior: "smooth"
297
+ });
298
+ }
299
+ }, [
300
+ isSelected
301
+ ]);
302
+ const handleClick = useCallback(() => {
303
+ if (!disabled) {
304
+ onSelect?.();
305
+ }
306
+ }, [
307
+ onSelect,
308
+ disabled
309
+ ]);
310
+ return /* @__PURE__ */ React.createElement("div", {
311
+ ref: (node) => {
312
+ internalRef.current = node;
313
+ if (typeof forwardedRef === "function") {
314
+ forwardedRef(node);
315
+ } else if (forwardedRef) {
316
+ forwardedRef.current = node;
317
+ }
318
+ },
319
+ role: "option",
320
+ "aria-selected": isSelected,
321
+ "aria-disabled": disabled,
322
+ "data-selected": isSelected,
323
+ "data-disabled": disabled,
324
+ "data-value": value,
325
+ tabIndex: -1,
326
+ className: mx("flex gap-2 items-center", "plb-1 pli-2 rounded-sm select-none cursor-pointer data-[selected=true]:bg-hoverOverlay hover:bg-hoverOverlay", disabled && "opacity-50 cursor-not-allowed hover:bg-transparent data-[selected=true]:bg-transparent", classNames),
327
+ onClick: handleClick
328
+ }, icon && /* @__PURE__ */ React.createElement(Icon, {
329
+ icon,
330
+ size: 5
331
+ }), /* @__PURE__ */ React.createElement("span", {
332
+ className: "is-0 grow truncate"
333
+ }, label), suffix && /* @__PURE__ */ React.createElement("span", {
334
+ className: mx("shrink-0", descriptionText)
335
+ }, suffix), checked && /* @__PURE__ */ React.createElement(Icon, {
336
+ icon: "ph--check--regular",
337
+ size: 5
338
+ }));
97
339
  });
98
- var SearchListItem = /* @__PURE__ */ forwardRef(({ children, classNames, ...props }, forwardedRef) => {
99
- var _effect = _useSignals();
100
- try {
101
- return /* @__PURE__ */ React.createElement(CommandItem, {
102
- ...props,
103
- className: mx(searchListItem, classNames),
104
- ref: forwardedRef
105
- }, children);
106
- } finally {
107
- _effect.f();
108
- }
340
+ SearchListItem.displayName = "SearchList.Item";
341
+ var SearchListEmpty = ({ classNames, children }) => {
342
+ return /* @__PURE__ */ React.createElement("div", {
343
+ role: "status",
344
+ className: mx("flex flex-col is-full pli-2 plb-1", classNames)
345
+ }, children);
346
+ };
347
+ SearchListEmpty.displayName = "SearchList.Empty";
348
+ var SearchListGroup = /* @__PURE__ */ forwardRef(({ classNames, heading, children }, forwardedRef) => {
349
+ return /* @__PURE__ */ React.createElement("div", {
350
+ ref: forwardedRef,
351
+ role: "group",
352
+ className: mx("flex flex-col", classNames)
353
+ }, heading && /* @__PURE__ */ React.createElement("div", {
354
+ role: "presentation",
355
+ className: "pli-2 plb-1 text-xs font-medium text-description"
356
+ }, heading), children);
109
357
  });
110
- SearchListItem.displayName = SEARCHLIST_ITEM_NAME;
358
+ SearchListGroup.displayName = "SearchList.Group";
111
359
  var SearchList = {
112
360
  Root: SearchListRoot,
113
- Input: SearchListInput,
361
+ Viewport: SearchListViewport,
114
362
  Content: SearchListContent,
363
+ Input: SearchListInput,
364
+ Item: SearchListItem,
115
365
  Empty: SearchListEmpty,
116
- Item: SearchListItem
366
+ Group: SearchListGroup
367
+ };
368
+
369
+ // src/components/SearchList/hooks/useGlobalFilter.tsx
370
+ import React2, { createContext as createContext2, useContext, useMemo as useMemo2 } from "react";
371
+ var GlobalFilterContext = /* @__PURE__ */ createContext2({});
372
+ var GlobalFilterProvider = ({ children, filter }) => {
373
+ const value = useMemo2(() => ({
374
+ filter
375
+ }), [
376
+ filter
377
+ ]);
378
+ return /* @__PURE__ */ React2.createElement(GlobalFilterContext.Provider, {
379
+ value
380
+ }, children);
381
+ };
382
+ var useGlobalFilter = () => {
383
+ return useContext(GlobalFilterContext);
384
+ };
385
+ var useGlobalFilteredObjects = (objects) => {
386
+ const { filter } = useGlobalFilter();
387
+ return useMemo2(() => {
388
+ if (!objects) {
389
+ return [];
390
+ }
391
+ if (!filter) {
392
+ return objects;
393
+ }
394
+ return filter(objects);
395
+ }, [
396
+ objects,
397
+ filter
398
+ ]);
399
+ };
400
+
401
+ // src/components/SearchList/hooks/useSearchListInput.ts
402
+ var useSearchListInput = () => {
403
+ const { query, onQueryChange, selectedValue, onSelectedValueChange, getItemValues, triggerSelect } = useSearchListInputContext("useSearchListInput");
404
+ return {
405
+ query,
406
+ onQueryChange,
407
+ selectedValue,
408
+ onSelectedValueChange,
409
+ getItemValues,
410
+ triggerSelect
411
+ };
412
+ };
413
+
414
+ // src/components/SearchList/hooks/useSearchListItem.ts
415
+ var useSearchListItem = () => {
416
+ const { selectedValue, registerItem, unregisterItem } = useSearchListItemContext("useSearchListItem");
417
+ return {
418
+ selectedValue,
419
+ registerItem,
420
+ unregisterItem
421
+ };
422
+ };
423
+
424
+ // src/components/SearchList/hooks/useSearchListResults.ts
425
+ import commandScore from "command-score";
426
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef2, useState as useState2 } from "react";
427
+ var useSearchListResults = ({ items, filter, fuzzy = true, extract, minScore = 0 }) => {
428
+ const [query, setQuery] = useState2("");
429
+ const queryRef = useRef2("");
430
+ useEffect2(() => {
431
+ queryRef.current = "";
432
+ setQuery("");
433
+ }, [
434
+ items
435
+ ]);
436
+ const defaultExtract = useCallback2((item) => {
437
+ if (typeof item === "string") {
438
+ return item;
439
+ }
440
+ return item?.label ?? "";
441
+ }, []);
442
+ const extractFn = extract ?? defaultExtract;
443
+ const defaultFilter = useCallback2((item, query2) => {
444
+ const searchable = extractFn(item);
445
+ return searchable.toLowerCase().includes(query2.toLowerCase());
446
+ }, [
447
+ extractFn
448
+ ]);
449
+ const filterFn = filter ?? defaultFilter;
450
+ const handleSearch = useCallback2((searchQuery) => {
451
+ queryRef.current = searchQuery;
452
+ setQuery(searchQuery);
453
+ }, []);
454
+ const results = useMemo3(() => {
455
+ const currentQuery = queryRef.current;
456
+ if (!currentQuery) {
457
+ return items;
458
+ }
459
+ if (fuzzy) {
460
+ const scored = items.map((item) => ({
461
+ item,
462
+ score: commandScore(extractFn(item), currentQuery)
463
+ })).filter(({ score }) => score > minScore).sort((a, b) => b.score - a.score);
464
+ return scored.map(({ item }) => item);
465
+ } else {
466
+ return items.filter((item) => filterFn(item, currentQuery));
467
+ }
468
+ }, [
469
+ items,
470
+ query,
471
+ filterFn,
472
+ fuzzy,
473
+ extractFn,
474
+ minScore
475
+ ]);
476
+ return {
477
+ results,
478
+ handleSearch
479
+ };
117
480
  };
118
481
 
119
482
  // src/components/Combobox/Combobox.tsx
@@ -121,170 +484,155 @@ var COMBOBOX_NAME = "Combobox";
121
484
  var COMBOBOX_CONTENT_NAME = "ComboboxContent";
122
485
  var COMBOBOX_ITEM_NAME = "ComboboxItem";
123
486
  var COMBOBOX_TRIGGER_NAME = "ComboboxTrigger";
124
- var [ComboboxProvider, useComboboxContext] = createContext(COMBOBOX_NAME, {});
487
+ var [ComboboxProvider, useComboboxContext] = createContext3(COMBOBOX_NAME, {});
125
488
  var ComboboxRoot = ({ modal, modalId: propsModalId, open: propsOpen, defaultOpen, onOpenChange: propsOnOpenChange, value: propsValue, defaultValue, onValueChange: propsOnValueChange, placeholder, children }) => {
126
- var _effect = _useSignals2();
127
- try {
128
- const modalId = useId(COMBOBOX_NAME, propsModalId);
129
- const [open = false, onOpenChange] = useControllableState({
130
- prop: propsOpen,
131
- onChange: propsOnOpenChange,
132
- defaultProp: defaultOpen
133
- });
134
- const [value = "", onValueChange] = useControllableState({
135
- prop: propsValue,
136
- onChange: propsOnValueChange,
137
- defaultProp: defaultValue
138
- });
139
- return /* @__PURE__ */ React2.createElement(Popover.Root, {
140
- open,
141
- onOpenChange,
142
- modal
143
- }, /* @__PURE__ */ React2.createElement(ComboboxProvider, {
144
- isCombobox: true,
145
- modalId,
146
- placeholder,
147
- open,
148
- onOpenChange,
149
- value,
150
- onValueChange
151
- }, children));
152
- } finally {
153
- _effect.f();
154
- }
489
+ const modalId = useId(COMBOBOX_NAME, propsModalId);
490
+ const [open = false, onOpenChange] = useControllableState2({
491
+ prop: propsOpen,
492
+ onChange: propsOnOpenChange,
493
+ defaultProp: defaultOpen
494
+ });
495
+ const [value = "", onValueChange] = useControllableState2({
496
+ prop: propsValue,
497
+ onChange: propsOnValueChange,
498
+ defaultProp: defaultValue
499
+ });
500
+ return /* @__PURE__ */ React3.createElement(Popover.Root, {
501
+ open,
502
+ onOpenChange,
503
+ modal
504
+ }, /* @__PURE__ */ React3.createElement(ComboboxProvider, {
505
+ isCombobox: true,
506
+ modalId,
507
+ placeholder,
508
+ open,
509
+ onOpenChange,
510
+ value,
511
+ onValueChange
512
+ }, children));
155
513
  };
156
- var ComboboxContent = /* @__PURE__ */ forwardRef2(({ side = "bottom", collisionPadding = 48, sideOffset, align, alignOffset, avoidCollisions, collisionBoundary, arrowPadding, sticky, hideWhenDetached, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, forceMount, children, classNames, ...props }, forwardedRef) => {
157
- var _effect = _useSignals2();
158
- try {
159
- const { modalId } = useComboboxContext(COMBOBOX_CONTENT_NAME);
160
- return /* @__PURE__ */ React2.createElement(Popover.Content, {
161
- side,
162
- sideOffset,
163
- align,
164
- alignOffset,
165
- avoidCollisions,
166
- collisionBoundary,
167
- collisionPadding,
168
- arrowPadding,
169
- sticky,
170
- hideWhenDetached,
171
- onOpenAutoFocus,
172
- onCloseAutoFocus,
173
- onEscapeKeyDown,
174
- onPointerDownOutside,
175
- onFocusOutside,
176
- onInteractOutside,
177
- forceMount,
178
- classNames: [
179
- "is-[--radix-popover-trigger-width] max-bs-[--radix-popover-content-available-height] grid grid-rows-[min-content_1fr]",
180
- classNames
181
- ],
182
- id: modalId,
183
- ref: forwardedRef
184
- }, /* @__PURE__ */ React2.createElement(SearchList.Root, {
185
- ...props,
186
- classNames: "contents density-fine",
187
- role: "none"
188
- }, children));
189
- } finally {
190
- _effect.f();
191
- }
514
+ var ComboboxContent = /* @__PURE__ */ forwardRef2(({ side = "bottom", collisionPadding = 48, sideOffset, align, alignOffset, avoidCollisions, collisionBoundary, arrowPadding, sticky, hideWhenDetached, onOpenAutoFocus, onCloseAutoFocus, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, forceMount, children, classNames, onSearch, value, defaultValue, debounceMs, label }, forwardedRef) => {
515
+ const { modalId } = useComboboxContext(COMBOBOX_CONTENT_NAME);
516
+ return /* @__PURE__ */ React3.createElement(Popover.Content, {
517
+ side,
518
+ sideOffset,
519
+ align,
520
+ alignOffset,
521
+ avoidCollisions,
522
+ collisionBoundary,
523
+ collisionPadding,
524
+ arrowPadding,
525
+ sticky,
526
+ hideWhenDetached,
527
+ onOpenAutoFocus,
528
+ onCloseAutoFocus,
529
+ onEscapeKeyDown,
530
+ onPointerDownOutside,
531
+ onFocusOutside,
532
+ onInteractOutside,
533
+ forceMount,
534
+ classNames: [
535
+ "is-[--radix-popover-trigger-width] max-bs-[--radix-popover-content-available-height] grid grid-rows-[min-content_1fr]",
536
+ classNames
537
+ ],
538
+ id: modalId,
539
+ ref: forwardedRef
540
+ }, /* @__PURE__ */ React3.createElement(SearchList.Root, {
541
+ onSearch,
542
+ value,
543
+ defaultValue,
544
+ debounceMs
545
+ }, /* @__PURE__ */ React3.createElement("div", {
546
+ className: "contents density-fine",
547
+ "aria-label": label,
548
+ role: "combobox",
549
+ "aria-expanded": "true"
550
+ }, children)));
192
551
  });
193
552
  ComboboxContent.displayName = COMBOBOX_CONTENT_NAME;
194
553
  var ComboboxTrigger = /* @__PURE__ */ forwardRef2(({ children, onClick, ...props }, forwardedRef) => {
195
- var _effect = _useSignals2();
196
- try {
197
- const { modalId, open, onOpenChange, placeholder, value } = useComboboxContext(COMBOBOX_TRIGGER_NAME);
198
- const handleClick = useCallback((event) => {
199
- onClick?.(event);
200
- onOpenChange?.(true);
201
- }, [
202
- onClick,
203
- onOpenChange
204
- ]);
205
- return /* @__PURE__ */ React2.createElement(Popover.Trigger, {
206
- asChild: true
207
- }, /* @__PURE__ */ React2.createElement(Button, {
208
- ...props,
209
- role: "combobox",
210
- "aria-expanded": open,
211
- "aria-controls": modalId,
212
- "aria-haspopup": "dialog",
213
- onClick: handleClick,
214
- ref: forwardedRef
215
- }, children ?? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("span", {
216
- className: mx2("font-normal text-start flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
217
- }, value || placeholder), /* @__PURE__ */ React2.createElement(Icon, {
218
- icon: "ph--caret-down--bold",
219
- size: 3
220
- }))));
221
- } finally {
222
- _effect.f();
223
- }
554
+ const { modalId, open, onOpenChange, placeholder, value } = useComboboxContext(COMBOBOX_TRIGGER_NAME);
555
+ const handleClick = useCallback3((event) => {
556
+ onClick?.(event);
557
+ onOpenChange?.(true);
558
+ }, [
559
+ onClick,
560
+ onOpenChange
561
+ ]);
562
+ return /* @__PURE__ */ React3.createElement(Popover.Trigger, {
563
+ asChild: true
564
+ }, /* @__PURE__ */ React3.createElement(Button, {
565
+ ...props,
566
+ role: "combobox",
567
+ "aria-expanded": open,
568
+ "aria-controls": modalId,
569
+ "aria-haspopup": "dialog",
570
+ onClick: handleClick,
571
+ ref: forwardedRef
572
+ }, children ?? /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", {
573
+ className: mx2("font-normal text-start flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
574
+ }, value || placeholder), /* @__PURE__ */ React3.createElement(Icon2, {
575
+ icon: "ph--caret-down--bold",
576
+ size: 3
577
+ }))));
224
578
  });
225
579
  ComboboxTrigger.displayName = COMBOBOX_TRIGGER_NAME;
226
580
  var ComboboxVirtualTrigger = Popover.VirtualTrigger;
227
581
  var ComboboxInput = /* @__PURE__ */ forwardRef2(({ classNames, ...props }, forwardedRef) => {
228
- var _effect = _useSignals2();
229
- try {
230
- return /* @__PURE__ */ React2.createElement(SearchList.Input, {
231
- ...props,
232
- classNames: [
233
- "mli-cardSpacingChrome mbs-cardSpacingChrome mbe-0 is-[calc(100%-2*var(--dx-cardSpacingChrome))]",
234
- classNames
235
- ],
236
- ref: forwardedRef
237
- });
238
- } finally {
239
- _effect.f();
240
- }
582
+ return /* @__PURE__ */ React3.createElement(SearchList.Input, {
583
+ ...props,
584
+ classNames: [
585
+ "mli-cardSpacingChrome mbs-cardSpacingChrome mbe-0 is-[calc(100%-2*var(--dx-cardSpacingChrome))]",
586
+ classNames
587
+ ],
588
+ ref: forwardedRef
589
+ });
241
590
  });
242
591
  var ComboboxList = /* @__PURE__ */ forwardRef2(({ classNames, ...props }, forwardedRef) => {
243
- var _effect = _useSignals2();
244
- try {
245
- return /* @__PURE__ */ React2.createElement(SearchList.Content, {
246
- ...props,
247
- classNames: [
248
- "min-bs-0 overflow-y-auto plb-cardSpacingChrome",
249
- classNames
250
- ],
251
- ref: forwardedRef
252
- });
253
- } finally {
254
- _effect.f();
255
- }
592
+ return /* @__PURE__ */ React3.createElement(SearchList.Content, {
593
+ ...props,
594
+ classNames: [
595
+ "min-bs-0 overflow-y-auto plb-cardSpacingChrome",
596
+ classNames
597
+ ],
598
+ ref: forwardedRef
599
+ });
256
600
  });
257
- var ComboboxItem = /* @__PURE__ */ forwardRef2(({ classNames, onSelect, ...props }, forwardedRef) => {
258
- var _effect = _useSignals2();
259
- try {
260
- const { onValueChange, onOpenChange } = useComboboxContext(COMBOBOX_ITEM_NAME);
261
- const handleSelect = useCallback((nextValue) => {
262
- onSelect?.(nextValue);
263
- onValueChange?.(nextValue);
601
+ var ComboboxItem = /* @__PURE__ */ forwardRef2(({ classNames, onSelect, value, closeOnSelect = true, ...props }, forwardedRef) => {
602
+ const { onValueChange, onOpenChange } = useComboboxContext(COMBOBOX_ITEM_NAME);
603
+ const handleSelect = useCallback3(() => {
604
+ onSelect?.();
605
+ if (value !== void 0) {
606
+ onValueChange?.(value);
607
+ }
608
+ if (closeOnSelect) {
264
609
  onOpenChange?.(false);
265
- }, [
266
- onSelect,
267
- onValueChange,
268
- onOpenChange
269
- ]);
270
- return /* @__PURE__ */ React2.createElement(SearchList.Item, {
271
- ...props,
272
- classNames: [
273
- "mli-cardSpacingChrome pli-cardSpacingChrome",
274
- classNames
275
- ],
276
- onSelect: handleSelect,
277
- ref: forwardedRef
278
- });
279
- } finally {
280
- _effect.f();
281
- }
610
+ }
611
+ }, [
612
+ onSelect,
613
+ onValueChange,
614
+ onOpenChange,
615
+ value,
616
+ closeOnSelect
617
+ ]);
618
+ return /* @__PURE__ */ React3.createElement(SearchList.Item, {
619
+ ...props,
620
+ value,
621
+ classNames: [
622
+ "mli-cardSpacingChrome pli-cardSpacingChrome",
623
+ classNames
624
+ ],
625
+ onSelect: handleSelect,
626
+ ref: forwardedRef
627
+ });
282
628
  });
283
629
  ComboboxItem.displayName = COMBOBOX_ITEM_NAME;
284
630
  var ComboboxArrow = Popover.Arrow;
285
631
  var ComboboxEmpty = SearchList.Empty;
632
+ var ComboboxPortal = Popover.Portal;
286
633
  var Combobox = {
287
634
  Root: ComboboxRoot,
635
+ Portal: ComboboxPortal,
288
636
  Content: ComboboxContent,
289
637
  Trigger: ComboboxTrigger,
290
638
  VirtualTrigger: ComboboxVirtualTrigger,
@@ -296,14 +644,14 @@ var Combobox = {
296
644
  };
297
645
 
298
646
  // src/components/Listbox/Listbox.tsx
299
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
300
647
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
301
648
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
302
649
  import { createContextScope } from "@radix-ui/react-context";
303
- import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
304
- import React3, { forwardRef as forwardRef3, useCallback as useCallback2, useEffect, useRef } from "react";
305
- import { Icon as Icon2 } from "@dxos/react-ui";
306
- import { mx as mx3 } from "@dxos/react-ui-theme";
650
+ import { useControllableState as useControllableState3 } from "@radix-ui/react-use-controllable-state";
651
+ import React4, { forwardRef as forwardRef3, useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3 } from "react";
652
+ import { Icon as Icon3 } from "@dxos/react-ui";
653
+ import { mx as mx3 } from "@dxos/ui-theme";
654
+ var commandItem = "flex items-center overflow-hidden";
307
655
  var LISTBOX_NAME = "Listbox";
308
656
  var LISTBOX_OPTION_NAME = "ListboxOption";
309
657
  var LISTBOX_OPTION_LABEL_NAME = "ListboxOptionLabel";
@@ -315,108 +663,88 @@ var [createListboxOptionContext, createListboxOptionScope] = createContextScope(
315
663
  var [ListboxProvider, useListboxContext] = createListboxContext(LISTBOX_NAME);
316
664
  var [ListboxOptionProvider, useListboxOptionContext] = createListboxOptionContext(LISTBOX_OPTION_NAME);
317
665
  var ListboxRoot = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
318
- var _effect = _useSignals3();
319
- try {
320
- const { __listboxScope, children, classNames, value: propsValue, defaultValue, onValueChange, autoFocus, ...rootProps } = props;
321
- const arrowGroup = useArrowNavigationGroup({
322
- axis: "vertical"
323
- });
324
- const ref = useRef(null);
325
- const rootRef = useComposedRefs(ref, forwardedRef);
326
- const [selectedValue, setSelectedValue] = useControllableState2({
327
- prop: propsValue,
328
- defaultProp: defaultValue,
329
- onChange: onValueChange
330
- });
331
- const handleValueChange = (value) => {
332
- setSelectedValue(value);
333
- };
334
- useEffect(() => {
335
- ref.current?.querySelector('[aria-selected="true"]')?.focus();
336
- }, [
337
- autoFocus
338
- ]);
339
- return /* @__PURE__ */ React3.createElement(ListboxProvider, {
340
- scope: __listboxScope,
341
- selectedValue,
342
- onValueChange: handleValueChange
343
- }, /* @__PURE__ */ React3.createElement("ul", {
344
- role: "listbox",
345
- ...rootProps,
346
- className: mx3("is-full p-cardSpacingChrome", classNames),
347
- ref: rootRef,
348
- ...arrowGroup
349
- }, children));
350
- } finally {
351
- _effect.f();
352
- }
666
+ const { __listboxScope, children, classNames, value: propsValue, defaultValue, onValueChange, autoFocus, ...rootProps } = props;
667
+ const arrowGroup = useArrowNavigationGroup({
668
+ axis: "vertical"
669
+ });
670
+ const ref = useRef3(null);
671
+ const rootRef = useComposedRefs(ref, forwardedRef);
672
+ const [selectedValue, setSelectedValue] = useControllableState3({
673
+ prop: propsValue,
674
+ defaultProp: defaultValue,
675
+ onChange: onValueChange
676
+ });
677
+ const handleValueChange = (value) => {
678
+ setSelectedValue(value);
679
+ };
680
+ useEffect3(() => {
681
+ ref.current?.querySelector('[aria-selected="true"]')?.focus();
682
+ }, [
683
+ autoFocus
684
+ ]);
685
+ return /* @__PURE__ */ React4.createElement(ListboxProvider, {
686
+ scope: __listboxScope,
687
+ selectedValue,
688
+ onValueChange: handleValueChange
689
+ }, /* @__PURE__ */ React4.createElement("ul", {
690
+ role: "listbox",
691
+ ...rootProps,
692
+ className: mx3("is-full p-cardSpacingChrome", classNames),
693
+ ref: rootRef,
694
+ ...arrowGroup
695
+ }, children));
353
696
  });
354
697
  ListboxRoot.displayName = LISTBOX_NAME;
355
698
  var ListboxOption = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
356
- var _effect = _useSignals3();
357
- try {
358
- const { __listboxScope, children, classNames, value, ...rootProps } = props;
359
- const { selectedValue, onValueChange } = useListboxContext(LISTBOX_OPTION_NAME, __listboxScope);
360
- const isSelected = selectedValue === value;
361
- const handleSelect = useCallback2(() => {
362
- onValueChange(value);
363
- }, [
364
- value,
365
- onValueChange
366
- ]);
367
- return /* @__PURE__ */ React3.createElement(ListboxOptionProvider, {
368
- scope: __listboxScope,
369
- value,
370
- isSelected
371
- }, /* @__PURE__ */ React3.createElement("li", {
372
- role: "option",
373
- ...rootProps,
374
- "aria-selected": isSelected,
375
- tabIndex: 0,
376
- className: mx3("dx-focus-ring", commandItem, searchListItem, classNames),
377
- onClick: handleSelect,
378
- onKeyDown: ({ key }) => {
379
- if ([
380
- "Enter",
381
- " "
382
- ].includes(key)) {
383
- handleSelect();
384
- }
385
- },
386
- ref: forwardedRef
387
- }, children));
388
- } finally {
389
- _effect.f();
390
- }
699
+ const { __listboxScope, children, classNames, value, ...rootProps } = props;
700
+ const { selectedValue, onValueChange } = useListboxContext(LISTBOX_OPTION_NAME, __listboxScope);
701
+ const isSelected = selectedValue === value;
702
+ const handleSelect = useCallback4(() => {
703
+ onValueChange(value);
704
+ }, [
705
+ value,
706
+ onValueChange
707
+ ]);
708
+ return /* @__PURE__ */ React4.createElement(ListboxOptionProvider, {
709
+ scope: __listboxScope,
710
+ value,
711
+ isSelected
712
+ }, /* @__PURE__ */ React4.createElement("li", {
713
+ role: "option",
714
+ ...rootProps,
715
+ "aria-selected": isSelected,
716
+ tabIndex: 0,
717
+ className: mx3("dx-focus-ring", "plb-1 pli-2 rounded-sm select-none cursor-pointer data-[selected=true]:bg-hoverOverlay hover:bg-hoverOverlay", commandItem, classNames),
718
+ onClick: handleSelect,
719
+ onKeyDown: ({ key }) => {
720
+ if ([
721
+ "Enter",
722
+ " "
723
+ ].includes(key)) {
724
+ handleSelect();
725
+ }
726
+ },
727
+ ref: forwardedRef
728
+ }, children));
391
729
  });
392
730
  ListboxOption.displayName = LISTBOX_OPTION_NAME;
393
731
  var ListboxOptionLabel = /* @__PURE__ */ forwardRef3(({ children, classNames, ...rootProps }, forwardedRef) => {
394
- var _effect = _useSignals3();
395
- try {
396
- return /* @__PURE__ */ React3.createElement("span", {
397
- ...rootProps,
398
- className: mx3("grow truncate", classNames),
399
- ref: forwardedRef
400
- }, children);
401
- } finally {
402
- _effect.f();
403
- }
732
+ return /* @__PURE__ */ React4.createElement("span", {
733
+ ...rootProps,
734
+ className: mx3("grow truncate", classNames),
735
+ ref: forwardedRef
736
+ }, children);
404
737
  });
405
738
  ListboxOptionLabel.displayName = LISTBOX_OPTION_LABEL_NAME;
406
739
  var ListboxOptionIndicator = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
407
- var _effect = _useSignals3();
408
- try {
409
- const { __listboxOptionScope, classNames, ...rootProps } = props;
410
- const { isSelected } = useListboxOptionContext(LISTBOX_OPTION_INDICATOR_NAME, __listboxOptionScope);
411
- return /* @__PURE__ */ React3.createElement(Icon2, {
412
- icon: "ph--check--regular",
413
- ...rootProps,
414
- classNames: mx3(!isSelected && "invisible", classNames),
415
- ref: forwardedRef
416
- });
417
- } finally {
418
- _effect.f();
419
- }
740
+ const { __listboxOptionScope, classNames, ...rootProps } = props;
741
+ const { isSelected } = useListboxOptionContext(LISTBOX_OPTION_INDICATOR_NAME, __listboxOptionScope);
742
+ return /* @__PURE__ */ React4.createElement(Icon3, {
743
+ icon: "ph--check--regular",
744
+ ...rootProps,
745
+ classNames: mx3(!isSelected && "invisible", classNames),
746
+ ref: forwardedRef
747
+ });
420
748
  });
421
749
  ListboxOptionIndicator.displayName = LISTBOX_OPTION_INDICATOR_NAME;
422
750
  var Listbox = {
@@ -427,13 +755,17 @@ var Listbox = {
427
755
  };
428
756
  export {
429
757
  Combobox,
758
+ GlobalFilterProvider,
430
759
  Listbox,
431
760
  SearchList,
432
- commandItem,
433
761
  createListboxScope,
434
- searchListItem,
435
762
  translationKey,
436
763
  translations,
437
- useListboxContext
764
+ useGlobalFilter,
765
+ useGlobalFilteredObjects,
766
+ useListboxContext,
767
+ useSearchListInput,
768
+ useSearchListItem,
769
+ useSearchListResults
438
770
  };
439
771
  //# sourceMappingURL=index.mjs.map