@dxos/react-ui-list 0.8.4-main.8360d9e660 → 0.8.4-main.8baae0fced

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 (87) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +764 -110
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +764 -110
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/components/Accordion/Accordion.d.ts +1 -1
  9. package/dist/types/src/components/Accordion/Accordion.d.ts.map +1 -1
  10. package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/Accordion/AccordionItem.d.ts.map +1 -1
  12. package/dist/types/src/components/Accordion/AccordionRoot.d.ts +1 -1
  13. package/dist/types/src/components/Accordion/AccordionRoot.d.ts.map +1 -1
  14. package/dist/types/src/components/Combobox/Combobox.d.ts +105 -0
  15. package/dist/types/src/components/Combobox/Combobox.d.ts.map +1 -0
  16. package/dist/types/src/components/Combobox/Combobox.stories.d.ts +12 -0
  17. package/dist/types/src/components/Combobox/Combobox.stories.d.ts.map +1 -0
  18. package/dist/types/src/components/Combobox/index.d.ts +2 -0
  19. package/dist/types/src/components/Combobox/index.d.ts.map +1 -0
  20. package/dist/types/src/components/List/List.d.ts +15 -4
  21. package/dist/types/src/components/List/List.d.ts.map +1 -1
  22. package/dist/types/src/components/List/List.stories.d.ts +2 -2
  23. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/List/ListItem.d.ts +3 -3
  25. package/dist/types/src/components/List/ListItem.d.ts.map +1 -1
  26. package/dist/types/src/components/List/ListRoot.d.ts.map +1 -1
  27. package/dist/types/src/components/List/testing.d.ts.map +1 -1
  28. package/dist/types/src/components/Listbox/Listbox.d.ts +27 -0
  29. package/dist/types/src/components/Listbox/Listbox.d.ts.map +1 -0
  30. package/dist/types/src/components/Listbox/Listbox.stories.d.ts +12 -0
  31. package/dist/types/src/components/Listbox/Listbox.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/Listbox/index.d.ts +2 -0
  33. package/dist/types/src/components/Listbox/index.d.ts.map +1 -0
  34. package/dist/types/src/components/Picker/Picker.d.ts +49 -0
  35. package/dist/types/src/components/Picker/Picker.d.ts.map +1 -0
  36. package/dist/types/src/components/Picker/Picker.stories.d.ts +28 -0
  37. package/dist/types/src/components/Picker/Picker.stories.d.ts.map +1 -0
  38. package/dist/types/src/components/Picker/context.d.ts +29 -0
  39. package/dist/types/src/components/Picker/context.d.ts.map +1 -0
  40. package/dist/types/src/components/Picker/index.d.ts +3 -0
  41. package/dist/types/src/components/Picker/index.d.ts.map +1 -0
  42. package/dist/types/src/components/RowList/RowList.d.ts +61 -0
  43. package/dist/types/src/components/RowList/RowList.d.ts.map +1 -0
  44. package/dist/types/src/components/RowList/RowList.stories.d.ts +35 -0
  45. package/dist/types/src/components/RowList/RowList.stories.d.ts.map +1 -0
  46. package/dist/types/src/components/RowList/index.d.ts +3 -0
  47. package/dist/types/src/components/RowList/index.d.ts.map +1 -0
  48. package/dist/types/src/components/Tree/Tree.d.ts +1 -1
  49. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  50. package/dist/types/src/components/Tree/Tree.stories.d.ts +1 -1
  51. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  53. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  54. package/dist/types/src/components/Tree/helpers.d.ts.map +1 -1
  55. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  56. package/dist/types/src/components/index.d.ts +4 -0
  57. package/dist/types/src/components/index.d.ts.map +1 -1
  58. package/dist/types/src/util/path.d.ts.map +1 -1
  59. package/dist/types/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +21 -21
  61. package/src/components/Accordion/Accordion.stories.tsx +3 -3
  62. package/src/components/Accordion/AccordionItem.tsx +1 -4
  63. package/src/components/Combobox/Combobox.stories.tsx +60 -0
  64. package/src/components/Combobox/Combobox.tsx +387 -0
  65. package/src/components/Combobox/index.ts +5 -0
  66. package/src/components/List/List.stories.tsx +5 -5
  67. package/src/components/List/List.tsx +12 -8
  68. package/src/components/List/ListItem.tsx +7 -9
  69. package/src/components/List/ListRoot.tsx +1 -1
  70. package/src/components/List/testing.ts +4 -4
  71. package/src/components/Listbox/Listbox.stories.tsx +48 -0
  72. package/src/components/Listbox/Listbox.tsx +201 -0
  73. package/src/components/Listbox/index.ts +5 -0
  74. package/src/components/Picker/Picker.stories.tsx +131 -0
  75. package/src/components/Picker/Picker.tsx +368 -0
  76. package/src/components/Picker/context.ts +43 -0
  77. package/src/components/Picker/index.ts +6 -0
  78. package/src/components/RowList/RowList.stories.tsx +163 -0
  79. package/src/components/RowList/RowList.tsx +350 -0
  80. package/src/components/RowList/index.ts +6 -0
  81. package/src/components/Tree/Tree.stories.tsx +4 -5
  82. package/src/components/Tree/Tree.tsx +1 -1
  83. package/src/components/Tree/TreeItem.tsx +14 -10
  84. package/src/components/Tree/TreeItemHeading.tsx +1 -2
  85. package/src/components/Tree/TreeItemToggle.tsx +3 -3
  86. package/src/components/Tree/testing.ts +5 -5
  87. package/src/components/index.ts +4 -0
@@ -57,7 +57,6 @@ var AccordionItemBody = ({ children, classNames }) => {
57
57
  return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Content, {
58
58
  className: "overflow-hidden data-[state=closed]:animate-slide-up data-[state=open]:animate-slide-down"
59
59
  }, /* @__PURE__ */ React2.createElement("div", {
60
- role: "none",
61
60
  className: mx2("p-2", classNames)
62
61
  }, children));
63
62
  };
@@ -70,30 +69,466 @@ var Accordion = {
70
69
  ItemBody: AccordionItemBody
71
70
  };
72
71
 
72
+ // src/components/Combobox/Combobox.tsx
73
+ import { createContext as createContext4 } from "@radix-ui/react-context";
74
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
75
+ import React4, { forwardRef as forwardRef2, useCallback as useCallback2 } from "react";
76
+ import { Button, Icon as Icon2, Popover, ScrollArea, useId } from "@dxos/react-ui";
77
+ import { composable, composableProps, mx as mx4 } from "@dxos/ui-theme";
78
+
79
+ // src/components/Picker/Picker.tsx
80
+ import { Slot } from "@radix-ui/react-slot";
81
+ import React3, { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
82
+ import { Input, useThemeContext } from "@dxos/react-ui";
83
+ import { mx as mx3 } from "@dxos/ui-theme";
84
+
85
+ // src/components/Picker/context.ts
86
+ import { createContext as createContext3 } from "@radix-ui/react-context";
87
+ var [PickerItemContextProvider, usePickerItemContext] = createContext3("PickerItem");
88
+ var [PickerInputContextProvider, usePickerInputContext] = createContext3("PickerInput");
89
+
90
+ // src/components/Picker/Picker.tsx
91
+ var PickerRoot = ({ children }) => {
92
+ const [selectedValue, setSelectedValue] = useState(void 0);
93
+ const itemsRef = useRef(/* @__PURE__ */ new Map());
94
+ const [itemVersion, setItemVersion] = useState(0);
95
+ useEffect(() => {
96
+ const current = selectedValue !== void 0 ? itemsRef.current.get(selectedValue) : void 0;
97
+ const isValid = current !== void 0 && !current.disabled;
98
+ if (!isValid && itemsRef.current.size > 0) {
99
+ const entries = Array.from(itemsRef.current.entries()).filter(([, data]) => !data.disabled);
100
+ if (entries.length > 0) {
101
+ entries.sort(([, a], [, b]) => {
102
+ const position = a.element.compareDocumentPosition(b.element);
103
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
104
+ return -1;
105
+ }
106
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) {
107
+ return 1;
108
+ }
109
+ return 0;
110
+ });
111
+ const firstValue = entries[0]?.[0];
112
+ if (firstValue !== void 0 && firstValue !== selectedValue) {
113
+ setSelectedValue(firstValue);
114
+ }
115
+ } else if (selectedValue !== void 0) {
116
+ setSelectedValue(void 0);
117
+ }
118
+ }
119
+ }, [
120
+ itemVersion,
121
+ selectedValue
122
+ ]);
123
+ const registerItem = useCallback((value, element, onSelect, disabled) => {
124
+ if (element) {
125
+ itemsRef.current.set(value, {
126
+ element,
127
+ onSelect,
128
+ disabled
129
+ });
130
+ setItemVersion((v) => v + 1);
131
+ }
132
+ }, []);
133
+ const unregisterItem = useCallback((value) => {
134
+ itemsRef.current.delete(value);
135
+ setItemVersion((v) => v + 1);
136
+ }, []);
137
+ const getItemValues = useCallback(() => {
138
+ return Array.from(itemsRef.current.entries()).filter(([, data]) => !data.disabled).sort(([, a], [, b]) => {
139
+ const position = a.element.compareDocumentPosition(b.element);
140
+ return position & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : position & Node.DOCUMENT_POSITION_PRECEDING ? 1 : 0;
141
+ }).map(([value]) => value);
142
+ }, []);
143
+ const triggerSelect = useCallback(() => {
144
+ if (selectedValue !== void 0) {
145
+ const item = itemsRef.current.get(selectedValue);
146
+ item?.onSelect?.();
147
+ }
148
+ }, [
149
+ selectedValue
150
+ ]);
151
+ const itemContextValue = useMemo(() => ({
152
+ selectedValue,
153
+ onSelectedValueChange: setSelectedValue,
154
+ registerItem,
155
+ unregisterItem
156
+ }), [
157
+ selectedValue,
158
+ registerItem,
159
+ unregisterItem
160
+ ]);
161
+ const inputContextValue = useMemo(() => ({
162
+ selectedValue,
163
+ onSelectedValueChange: setSelectedValue,
164
+ getItemValues,
165
+ triggerSelect
166
+ }), [
167
+ selectedValue,
168
+ getItemValues,
169
+ triggerSelect
170
+ ]);
171
+ return /* @__PURE__ */ React3.createElement(PickerInputContextProvider, inputContextValue, /* @__PURE__ */ React3.createElement(PickerItemContextProvider, itemContextValue, children));
172
+ };
173
+ PickerRoot.displayName = "Picker.Root";
174
+ var PickerInput = /* @__PURE__ */ forwardRef(({ value, onValueChange, onChange, onKeyDown, autoFocus, ...props }, forwardedRef) => {
175
+ const { hasIosKeyboard } = useThemeContext();
176
+ const { selectedValue, onSelectedValueChange, getItemValues, triggerSelect } = usePickerInputContext("Picker.Input");
177
+ const handleChange = useCallback((event) => {
178
+ onValueChange?.(event.target.value);
179
+ onChange?.(event);
180
+ }, [
181
+ onValueChange,
182
+ onChange
183
+ ]);
184
+ const handleKeyDown = useCallback((event) => {
185
+ onKeyDown?.(event);
186
+ if (event.defaultPrevented) {
187
+ return;
188
+ }
189
+ const values = getItemValues();
190
+ if (values.length === 0) {
191
+ if (event.key === "Escape") {
192
+ onValueChange?.("");
193
+ }
194
+ return;
195
+ }
196
+ const currentIndex = selectedValue !== void 0 ? values.indexOf(selectedValue) : -1;
197
+ switch (event.key) {
198
+ case "ArrowDown": {
199
+ event.preventDefault();
200
+ const nextIndex = currentIndex === -1 ? 0 : Math.min(currentIndex + 1, values.length - 1);
201
+ const nextValue = values[nextIndex];
202
+ if (nextValue !== void 0) {
203
+ onSelectedValueChange(nextValue);
204
+ }
205
+ break;
206
+ }
207
+ case "ArrowUp": {
208
+ event.preventDefault();
209
+ const prevIndex = currentIndex === -1 ? values.length - 1 : Math.max(currentIndex - 1, 0);
210
+ const prevValue = values[prevIndex];
211
+ if (prevValue !== void 0) {
212
+ onSelectedValueChange(prevValue);
213
+ }
214
+ break;
215
+ }
216
+ case "Enter": {
217
+ if (selectedValue !== void 0) {
218
+ event.preventDefault();
219
+ triggerSelect();
220
+ }
221
+ break;
222
+ }
223
+ case "Home": {
224
+ event.preventDefault();
225
+ const firstValue = values[0];
226
+ if (firstValue !== void 0) {
227
+ onSelectedValueChange(firstValue);
228
+ }
229
+ break;
230
+ }
231
+ case "End": {
232
+ event.preventDefault();
233
+ const lastValue = values[values.length - 1];
234
+ if (lastValue !== void 0) {
235
+ onSelectedValueChange(lastValue);
236
+ }
237
+ break;
238
+ }
239
+ case "Escape": {
240
+ event.preventDefault();
241
+ if (selectedValue !== void 0) {
242
+ onSelectedValueChange(void 0);
243
+ } else {
244
+ onValueChange?.("");
245
+ }
246
+ break;
247
+ }
248
+ }
249
+ }, [
250
+ selectedValue,
251
+ onSelectedValueChange,
252
+ getItemValues,
253
+ triggerSelect,
254
+ onValueChange,
255
+ onKeyDown
256
+ ]);
257
+ return /* @__PURE__ */ React3.createElement(Input.Root, null, /* @__PURE__ */ React3.createElement(Input.TextInput, {
258
+ ...props,
259
+ autoFocus: autoFocus && !hasIosKeyboard,
260
+ ...value !== void 0 && {
261
+ value
262
+ },
263
+ onChange: handleChange,
264
+ onKeyDown: handleKeyDown,
265
+ ref: forwardedRef
266
+ }));
267
+ });
268
+ PickerInput.displayName = "Picker.Input";
269
+ var PickerItem = /* @__PURE__ */ forwardRef(({ classNames, value, onSelect, disabled, asChild, children, ...props }, forwardedRef) => {
270
+ const { selectedValue, onSelectedValueChange, registerItem, unregisterItem } = usePickerItemContext("Picker.Item");
271
+ const internalRef = useRef(null);
272
+ const isSelected = selectedValue === value && !disabled;
273
+ useEffect(() => {
274
+ const element = internalRef.current;
275
+ if (element) {
276
+ registerItem(value, element, onSelect, disabled);
277
+ }
278
+ return () => unregisterItem(value);
279
+ }, [
280
+ value,
281
+ onSelect,
282
+ disabled,
283
+ registerItem,
284
+ unregisterItem
285
+ ]);
286
+ useEffect(() => {
287
+ if (isSelected && internalRef.current) {
288
+ internalRef.current.scrollIntoView({
289
+ block: "nearest",
290
+ behavior: "smooth"
291
+ });
292
+ }
293
+ }, [
294
+ isSelected
295
+ ]);
296
+ const handleClick = useCallback(() => {
297
+ if (disabled) {
298
+ return;
299
+ }
300
+ onSelectedValueChange(value);
301
+ onSelect?.();
302
+ }, [
303
+ disabled,
304
+ value,
305
+ onSelectedValueChange,
306
+ onSelect
307
+ ]);
308
+ const handleMouseDown = useCallback((event) => {
309
+ event.preventDefault();
310
+ }, []);
311
+ const Comp = asChild ? Slot : "div";
312
+ return /* @__PURE__ */ React3.createElement(Comp, {
313
+ ...props,
314
+ ref: (node) => {
315
+ internalRef.current = node;
316
+ if (typeof forwardedRef === "function") {
317
+ forwardedRef(node);
318
+ } else if (forwardedRef) {
319
+ forwardedRef.current = node;
320
+ }
321
+ },
322
+ role: "option",
323
+ "aria-selected": isSelected,
324
+ "aria-disabled": disabled,
325
+ "data-selected": isSelected,
326
+ "data-disabled": disabled,
327
+ "data-value": value,
328
+ // Browser focus stays on the input; highlight is via `aria-selected`.
329
+ tabIndex: -1,
330
+ className: mx3("dx-hover dx-selected px-[var(--gutter,0.75rem)] py-1 cursor-pointer select-none", disabled && "opacity-50 cursor-not-allowed", classNames),
331
+ onMouseDown: handleMouseDown,
332
+ onClick: handleClick
333
+ }, children);
334
+ });
335
+ PickerItem.displayName = "Picker.Item";
336
+ var Picker = {
337
+ Root: PickerRoot,
338
+ Input: PickerInput,
339
+ Item: PickerItem
340
+ };
341
+
342
+ // src/components/Combobox/Combobox.tsx
343
+ var COMBOBOX_NAME = "Combobox";
344
+ var COMBOBOX_CONTENT_NAME = "ComboboxContent";
345
+ var COMBOBOX_ITEM_NAME = "ComboboxItem";
346
+ var COMBOBOX_TRIGGER_NAME = "ComboboxTrigger";
347
+ var [ComboboxProvider, useComboboxContext] = createContext4(COMBOBOX_NAME, {});
348
+ var ComboboxRoot = ({ children, modal, modalId: modalIdProp, open: openProp, defaultOpen, onOpenChange: propsOnOpenChange, value: valueProp, defaultValue, onValueChange: propsOnValueChange, placeholder }) => {
349
+ const modalId = useId(COMBOBOX_NAME, modalIdProp);
350
+ const [open = false, onOpenChange] = useControllableState({
351
+ prop: openProp,
352
+ defaultProp: defaultOpen,
353
+ onChange: propsOnOpenChange
354
+ });
355
+ const [value = "", onValueChange] = useControllableState({
356
+ prop: valueProp,
357
+ defaultProp: defaultValue,
358
+ onChange: propsOnValueChange
359
+ });
360
+ return /* @__PURE__ */ React4.createElement(Popover.Root, {
361
+ open,
362
+ onOpenChange,
363
+ modal
364
+ }, /* @__PURE__ */ React4.createElement(ComboboxProvider, {
365
+ isCombobox: true,
366
+ modalId,
367
+ placeholder,
368
+ open,
369
+ onOpenChange,
370
+ value,
371
+ onValueChange
372
+ }, children));
373
+ };
374
+ var ComboboxContent = composable(({ children, ...props }, forwardedRef) => {
375
+ const { modalId } = useComboboxContext(COMBOBOX_CONTENT_NAME);
376
+ return /* @__PURE__ */ React4.createElement(Popover.Content, {
377
+ ...composableProps(props, {
378
+ id: modalId
379
+ }),
380
+ ref: forwardedRef
381
+ }, /* @__PURE__ */ React4.createElement(Popover.Viewport, {
382
+ classNames: "w-(--radix-popover-trigger-width)"
383
+ }, /* @__PURE__ */ React4.createElement(Picker.Root, null, children)));
384
+ });
385
+ ComboboxContent.displayName = COMBOBOX_CONTENT_NAME;
386
+ var ComboboxTrigger = /* @__PURE__ */ forwardRef2(({ children, onClick, ...props }, forwardedRef) => {
387
+ const { modalId, open, onOpenChange, placeholder, value } = useComboboxContext(COMBOBOX_TRIGGER_NAME);
388
+ const handleClick = useCallback2((event) => {
389
+ onClick?.(event);
390
+ onOpenChange?.(true);
391
+ }, [
392
+ onClick,
393
+ onOpenChange
394
+ ]);
395
+ return /* @__PURE__ */ React4.createElement(Popover.Trigger, {
396
+ asChild: true
397
+ }, /* @__PURE__ */ React4.createElement(Button, {
398
+ ...props,
399
+ role: "combobox",
400
+ "aria-expanded": open,
401
+ "aria-controls": modalId,
402
+ "aria-haspopup": "dialog",
403
+ onClick: handleClick,
404
+ ref: forwardedRef
405
+ }, children ?? /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement("span", {
406
+ className: mx4("font-normal text-start flex-1 min-w-0 truncate me-2", !value && "text-subdued")
407
+ }, value || placeholder), /* @__PURE__ */ React4.createElement(Icon2, {
408
+ icon: "ph--caret-down--bold",
409
+ size: 3
410
+ }))));
411
+ });
412
+ ComboboxTrigger.displayName = COMBOBOX_TRIGGER_NAME;
413
+ var ComboboxVirtualTrigger = Popover.VirtualTrigger;
414
+ var ComboboxInput = /* @__PURE__ */ forwardRef2(({ classNames, ...props }, forwardedRef) => {
415
+ return /* @__PURE__ */ React4.createElement(Picker.Input, {
416
+ ...props,
417
+ classNames: [
418
+ "m-form-chrome mb-0 w-[calc(100%-2*var(--spacing-form-chrome))]",
419
+ classNames
420
+ ],
421
+ ref: forwardedRef
422
+ });
423
+ });
424
+ ComboboxInput.displayName = "Combobox.Input";
425
+ var ComboboxList = /* @__PURE__ */ forwardRef2(({ classNames, children, ...props }, forwardedRef) => {
426
+ return /* @__PURE__ */ React4.createElement(ScrollArea.Root, {
427
+ ...composableProps(props, {
428
+ classNames: [
429
+ "py-form-chrome",
430
+ classNames
431
+ ]
432
+ }),
433
+ role: "listbox",
434
+ centered: true,
435
+ padding: true,
436
+ thin: true,
437
+ ref: forwardedRef
438
+ }, /* @__PURE__ */ React4.createElement(ScrollArea.Viewport, null, children));
439
+ });
440
+ ComboboxList.displayName = "Combobox.List";
441
+ var ComboboxItem = /* @__PURE__ */ forwardRef2(({ classNames, onSelect, value, label, icon, iconClassNames, checked, suffix, disabled, closeOnSelect = true, children }, forwardedRef) => {
442
+ const { onValueChange, onOpenChange } = useComboboxContext(COMBOBOX_ITEM_NAME);
443
+ const handleSelect = useCallback2(() => {
444
+ onSelect?.();
445
+ if (value !== void 0) {
446
+ onValueChange?.(value);
447
+ }
448
+ if (closeOnSelect) {
449
+ onOpenChange?.(false);
450
+ }
451
+ }, [
452
+ onSelect,
453
+ onValueChange,
454
+ onOpenChange,
455
+ value,
456
+ closeOnSelect
457
+ ]);
458
+ return /* @__PURE__ */ React4.createElement(Picker.Item, {
459
+ value,
460
+ disabled,
461
+ onSelect: handleSelect,
462
+ ref: forwardedRef,
463
+ classNames: [
464
+ // Full width inside the viewport (no horizontal margin).
465
+ // `px-3 py-1`, `cursor-pointer`, `select-none` and the
466
+ // `dx-hover` / `dx-selected` pairing come from `Picker.Item`'s
467
+ // defaults; we only add the row-shape (flex / icons + label)
468
+ // and the disabled overrides on top.
469
+ "flex w-full gap-2 items-center",
470
+ disabled && "hover:bg-transparent data-[selected=true]:bg-transparent",
471
+ classNames
472
+ ]
473
+ }, children ?? /* @__PURE__ */ React4.createElement(React4.Fragment, null, icon && /* @__PURE__ */ React4.createElement(Icon2, {
474
+ icon,
475
+ classNames: iconClassNames
476
+ }), /* @__PURE__ */ React4.createElement("span", {
477
+ className: "w-0 grow truncate"
478
+ }, label), suffix && /* @__PURE__ */ React4.createElement("span", {
479
+ className: "shrink-0 text-description"
480
+ }, suffix), checked && /* @__PURE__ */ React4.createElement(Icon2, {
481
+ icon: "ph--check--regular"
482
+ })));
483
+ });
484
+ ComboboxItem.displayName = COMBOBOX_ITEM_NAME;
485
+ var ComboboxArrow = Popover.Arrow;
486
+ var ComboboxEmpty = /* @__PURE__ */ forwardRef2(({ classNames, children }, forwardedRef) => {
487
+ return /* @__PURE__ */ React4.createElement("div", {
488
+ ref: forwardedRef,
489
+ role: "status",
490
+ className: mx4(classNames)
491
+ }, children);
492
+ });
493
+ ComboboxEmpty.displayName = "Combobox.Empty";
494
+ var ComboboxPortal = Popover.Portal;
495
+ var Combobox = {
496
+ Root: ComboboxRoot,
497
+ Portal: ComboboxPortal,
498
+ Content: ComboboxContent,
499
+ Trigger: ComboboxTrigger,
500
+ VirtualTrigger: ComboboxVirtualTrigger,
501
+ Input: ComboboxInput,
502
+ List: ComboboxList,
503
+ Item: ComboboxItem,
504
+ Arrow: ComboboxArrow,
505
+ Empty: ComboboxEmpty
506
+ };
507
+
73
508
  // src/components/List/ListItem.tsx
509
+ import { attachClosestEdge, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
74
510
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
75
511
  import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
76
512
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
77
- import { attachClosestEdge, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
78
- import { createContext as createContext4 } from "@radix-ui/react-context";
79
- import { Slot } from "@radix-ui/react-slot";
80
- import React4, { useEffect as useEffect2, useRef, useState as useState2 } from "react";
513
+ import { createContext as createContext6 } from "@radix-ui/react-context";
514
+ import { Slot as Slot2 } from "@radix-ui/react-slot";
515
+ import React6, { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
81
516
  import { createPortal } from "react-dom";
82
517
  import { invariant } from "@dxos/invariant";
83
518
  import { IconButton, ListItem as NaturalListItem, useTranslation } from "@dxos/react-ui";
84
- import { mx as mx3, osTranslations } from "@dxos/ui-theme";
519
+ import { mx as mx5, osTranslations } from "@dxos/ui-theme";
85
520
 
86
521
  // src/components/List/ListRoot.tsx
87
- import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
88
522
  import { extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
89
523
  import { getReorderDestinationIndex } from "@atlaskit/pragmatic-drag-and-drop-hitbox/util/get-reorder-destination-index";
90
- import { createContext as createContext3 } from "@radix-ui/react-context";
91
- import React3, { useCallback, useEffect, useState } from "react";
524
+ import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
525
+ import { createContext as createContext5 } from "@radix-ui/react-context";
526
+ import React5, { useCallback as useCallback3, useEffect as useEffect2, useState as useState2 } from "react";
92
527
  var LIST_NAME = "List";
93
- var [ListProvider, useListContext] = createContext3(LIST_NAME);
528
+ var [ListProvider, useListContext] = createContext5(LIST_NAME);
94
529
  var defaultGetId2 = (item) => item?.id;
95
530
  var ListRoot = ({ children, items, isItem, getId = defaultGetId2, onMove, ...props }) => {
96
- const isEqual = useCallback((a, b) => {
531
+ const isEqual = useCallback3((a, b) => {
97
532
  const idA = getId?.(a);
98
533
  const idB = getId?.(b);
99
534
  if (idA !== void 0 && idB !== void 0) {
@@ -104,8 +539,8 @@ var ListRoot = ({ children, items, isItem, getId = defaultGetId2, onMove, ...pro
104
539
  }, [
105
540
  getId
106
541
  ]);
107
- const [state, setState] = useState(idle);
108
- useEffect(() => {
542
+ const [state, setState] = useState2(idle);
543
+ useEffect2(() => {
109
544
  if (!items) {
110
545
  return;
111
546
  }
@@ -141,7 +576,7 @@ var ListRoot = ({ children, items, isItem, getId = defaultGetId2, onMove, ...pro
141
576
  isEqual,
142
577
  onMove
143
578
  ]);
144
- return /* @__PURE__ */ React3.createElement(ListProvider, {
579
+ return /* @__PURE__ */ React5.createElement(ListProvider, {
145
580
  state,
146
581
  setState,
147
582
  isItem,
@@ -162,24 +597,16 @@ var stateStyles = {
162
597
  };
163
598
  var defaultContext = {};
164
599
  var LIST_ITEM_NAME = "ListItem";
165
- var [ListItemProvider, useListItemContext] = createContext4(LIST_ITEM_NAME, defaultContext);
600
+ var [ListItemProvider, useListItemContext] = createContext6(LIST_ITEM_NAME, defaultContext);
166
601
  var ListItem = ({ children, classNames, item, asChild, selected, ...props }) => {
167
- const Comp = asChild ? Slot : "div";
602
+ const Comp = asChild ? Slot2 : "div";
168
603
  const { isItem, readonly, dragPreview, setState: setRootState } = useListContext(LIST_ITEM_NAME);
169
- const rootRef = useRef(null);
170
- const dragHandleRef = useRef(null);
171
- const [state, setState] = useState2(idle);
172
- useEffect2(() => {
604
+ const rootRef = useRef2(null);
605
+ const dragHandleRef = useRef2(null);
606
+ const [state, setState] = useState3(idle);
607
+ useEffect3(() => {
173
608
  const element = rootRef.current;
174
- invariant(element, void 0, {
175
- F: __dxlog_file,
176
- L: 109,
177
- S: void 0,
178
- A: [
179
- "element",
180
- ""
181
- ]
182
- });
609
+ invariant(element, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 37, S: void 0, A: ["element", ""] });
183
610
  return combine(
184
611
  //
185
612
  // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about#draggable
@@ -279,23 +706,23 @@ var ListItem = ({ children, classNames, item, asChild, selected, ...props }) =>
279
706
  }, [
280
707
  item
281
708
  ]);
282
- return /* @__PURE__ */ React4.createElement(ListItemProvider, {
709
+ return /* @__PURE__ */ React6.createElement(ListItemProvider, {
283
710
  item,
284
711
  dragHandleRef
285
- }, /* @__PURE__ */ React4.createElement(Comp, {
712
+ }, /* @__PURE__ */ React6.createElement(Comp, {
286
713
  ...props,
287
714
  role: "listitem",
288
715
  "aria-selected": selected,
289
- className: mx3("relative p-1 dx-selected dx-hover", classNames, stateStyles[state.type]),
716
+ className: mx5("relative p-1 dx-selected dx-hover", classNames, stateStyles[state.type]),
290
717
  ref: rootRef
291
- }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
718
+ }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React6.createElement(NaturalListItem.DropIndicator, {
292
719
  edge: state.closestEdge
293
720
  }));
294
721
  };
295
722
  var ListItemIconButton = ({ autoHide = true, iconOnly = true, variant = "ghost", classNames, disabled, ...props }) => {
296
723
  const { state } = useListContext("ITEM_BUTTON");
297
724
  const isDisabled = state.type !== "idle" || disabled;
298
- return /* @__PURE__ */ React4.createElement(IconButton, {
725
+ return /* @__PURE__ */ React6.createElement(IconButton, {
299
726
  ...props,
300
727
  disabled: isDisabled,
301
728
  iconOnly,
@@ -310,13 +737,13 @@ var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph-
310
737
  const { state } = useListContext("DELETE_BUTTON");
311
738
  const isDisabled = state.type !== "idle" || disabled;
312
739
  const { t } = useTranslation(osTranslations);
313
- return /* @__PURE__ */ React4.createElement(IconButton, {
740
+ return /* @__PURE__ */ React6.createElement(IconButton, {
314
741
  ...props,
315
742
  variant: "ghost",
316
743
  disabled: isDisabled,
317
744
  icon,
318
745
  iconOnly: true,
319
- label: label ?? t("delete label"),
746
+ label: label ?? t("delete.label"),
320
747
  classNames: [
321
748
  classNames,
322
749
  autoHide && disabled && "hidden"
@@ -326,12 +753,12 @@ var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph-
326
753
  var ListItemDragHandle = ({ disabled }) => {
327
754
  const { dragHandleRef } = useListItemContext("DRAG_HANDLE");
328
755
  const { t } = useTranslation(osTranslations);
329
- return /* @__PURE__ */ React4.createElement(IconButton, {
756
+ return /* @__PURE__ */ React6.createElement(IconButton, {
330
757
  variant: "ghost",
331
758
  disabled,
332
759
  icon: "ph--dots-six-vertical--regular",
333
760
  iconOnly: true,
334
- label: t("drag handle label"),
761
+ label: t("drag-handle.label"),
335
762
  ref: dragHandleRef
336
763
  });
337
764
  };
@@ -341,13 +768,11 @@ var ListItemDragPreview = ({ children }) => {
341
768
  item: state.item
342
769
  }), state.container) : null;
343
770
  };
344
- var ListItemWrapper = ({ classNames, children }) => /* @__PURE__ */ React4.createElement("div", {
345
- role: "none",
346
- className: mx3("flex w-full gap-2", classNames)
771
+ var ListItemWrapper = ({ classNames, children }) => /* @__PURE__ */ React6.createElement("div", {
772
+ className: mx5("flex w-full gap-2", classNames)
347
773
  }, children);
348
- var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
349
- role: "none",
350
- className: mx3("flex grow items-center truncate", classNames),
774
+ var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React6.createElement("div", {
775
+ className: mx5("flex grow items-center truncate", classNames),
351
776
  ...props
352
777
  }, children);
353
778
 
@@ -363,28 +788,247 @@ var List = {
363
788
  ItemTitle: ListItemTitle
364
789
  };
365
790
 
791
+ // src/components/Listbox/Listbox.tsx
792
+ import { createContextScope as createContextScope2 } from "@radix-ui/react-context";
793
+ import React8, { forwardRef as forwardRef3 } from "react";
794
+ import { Icon as Icon3 } from "@dxos/react-ui";
795
+ import { mx as mx6 } from "@dxos/ui-theme";
796
+
797
+ // src/components/RowList/RowList.tsx
798
+ import { useArrowNavigationGroup } from "@fluentui/react-tabster";
799
+ import { createContextScope } from "@radix-ui/react-context";
800
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
801
+ import React7, { useCallback as useCallback4 } from "react";
802
+ import { List as List2, ListItem as ListItem2 } from "@dxos/react-list";
803
+ import { ScrollArea as ScrollArea2 } from "@dxos/react-ui";
804
+ import { composable as composable2, composableProps as composableProps2 } from "@dxos/ui-theme";
805
+ var ROW_LIST_NAME = "RowList";
806
+ var ROW_LIST_ROOT_NAME = "RowList.Root";
807
+ var ROW_LIST_VIEWPORT_NAME = "RowList.Viewport";
808
+ var ROW_LIST_CONTENT_NAME = "RowList.Content";
809
+ var ROW_NAME = "List.Row";
810
+ var [createRowListContext, createRowListScope] = createContextScope(ROW_LIST_NAME, []);
811
+ var [RowListProvider, useRowListContext] = createRowListContext(ROW_LIST_NAME);
812
+ var Root2 = ({ selectedId, defaultSelectedId, onSelectChange, children }) => {
813
+ const [resolved, setResolved] = useControllableState2({
814
+ prop: selectedId,
815
+ defaultProp: defaultSelectedId,
816
+ onChange: (next) => {
817
+ if (next !== void 0) {
818
+ onSelectChange?.(next);
819
+ }
820
+ }
821
+ });
822
+ const setSelected = useCallback4((id) => setResolved(id), [
823
+ setResolved
824
+ ]);
825
+ return /* @__PURE__ */ React7.createElement(RowListProvider, {
826
+ scope: void 0,
827
+ selectedId: resolved,
828
+ setSelected
829
+ }, children);
830
+ };
831
+ Root2.displayName = ROW_LIST_ROOT_NAME;
832
+ var Viewport = composable2((props, forwardedRef) => {
833
+ const { thin, padding, centered, children, ...rest } = props;
834
+ return /* @__PURE__ */ React7.createElement(ScrollArea2.Root, {
835
+ ...composableProps2(rest, {
836
+ classNames: "dx-container"
837
+ }),
838
+ thin,
839
+ padding,
840
+ centered,
841
+ orientation: "vertical",
842
+ ref: forwardedRef
843
+ }, /* @__PURE__ */ React7.createElement(ScrollArea2.Viewport, null, children));
844
+ });
845
+ Viewport.displayName = ROW_LIST_VIEWPORT_NAME;
846
+ var firstEnabledOption = (ul) => {
847
+ if (!ul) {
848
+ return null;
849
+ }
850
+ return ul.querySelector('[role="option"]:not([aria-disabled="true"])');
851
+ };
852
+ var Content2 = composable2((props, forwardedRef) => {
853
+ useRowListContext(ROW_LIST_CONTENT_NAME, void 0);
854
+ const arrowGroup = useArrowNavigationGroup({
855
+ axis: "vertical",
856
+ memorizeCurrent: true
857
+ });
858
+ const { children, ...rest } = props;
859
+ const handleFocus = useCallback4((event) => {
860
+ if (event.target !== event.currentTarget) {
861
+ return;
862
+ }
863
+ const ul = event.currentTarget;
864
+ const selected = ul.querySelector('[role="option"][aria-selected="true"]:not([aria-disabled="true"])');
865
+ const target = selected ?? firstEnabledOption(ul);
866
+ target?.focus();
867
+ }, []);
868
+ const composed = composableProps2(rest, {
869
+ classNames: "flex flex-col"
870
+ });
871
+ return /* @__PURE__ */ React7.createElement(List2, {
872
+ variant: "unordered",
873
+ ...composed,
874
+ ...arrowGroup,
875
+ role: "listbox",
876
+ onFocus: handleFocus,
877
+ ref: forwardedRef
878
+ }, children);
879
+ });
880
+ Content2.displayName = ROW_LIST_CONTENT_NAME;
881
+ var ROW_BASE = "dx-hover dx-selected px-3 py-2 cursor-pointer outline-none";
882
+ var Row = composable2((props, forwardedRef) => {
883
+ const { id, disabled, onClick, onFocus, children, ...rest } = props;
884
+ const { selectedId, setSelected } = useRowListContext(ROW_NAME, void 0);
885
+ const isSelected = selectedId === id;
886
+ const handleClick = useCallback4((event) => {
887
+ if (disabled) {
888
+ return;
889
+ }
890
+ setSelected(id);
891
+ onClick?.(event);
892
+ }, [
893
+ disabled,
894
+ id,
895
+ setSelected,
896
+ onClick
897
+ ]);
898
+ const handleFocus = useCallback4((event) => {
899
+ if (!disabled && selectedId !== id) {
900
+ setSelected(id);
901
+ }
902
+ onFocus?.(event);
903
+ }, [
904
+ disabled,
905
+ selectedId,
906
+ id,
907
+ setSelected,
908
+ onFocus
909
+ ]);
910
+ const composed = composableProps2(rest, {
911
+ classNames: [
912
+ ROW_BASE,
913
+ disabled && "opacity-50 cursor-not-allowed"
914
+ ]
915
+ });
916
+ return /* @__PURE__ */ React7.createElement(ListItem2, {
917
+ ...composed,
918
+ role: "option",
919
+ tabIndex: 0,
920
+ "aria-selected": isSelected,
921
+ "aria-disabled": disabled || void 0,
922
+ onClick: handleClick,
923
+ onFocus: handleFocus,
924
+ ref: forwardedRef
925
+ }, children);
926
+ });
927
+ Row.displayName = ROW_NAME;
928
+ var useRowListSelection = (id) => {
929
+ const { selectedId } = useRowListContext("useRowListSelection", void 0);
930
+ return selectedId === id;
931
+ };
932
+ var RowList = {
933
+ Root: Root2,
934
+ Viewport,
935
+ Content: Content2
936
+ };
937
+
938
+ // src/components/Listbox/Listbox.tsx
939
+ var commandItem = "flex items-center overflow-hidden";
940
+ var LISTBOX_NAME = "Listbox";
941
+ var LISTBOX_OPTION_NAME = "ListboxOption";
942
+ var LISTBOX_OPTION_LABEL_NAME = "ListboxOptionLabel";
943
+ var LISTBOX_OPTION_INDICATOR_NAME = "ListboxOptionIndicator";
944
+ var [createListboxContext, createListboxScope] = createContextScope2(LISTBOX_NAME, [
945
+ createRowListScope
946
+ ]);
947
+ var [createListboxOptionContext, createListboxOptionScope] = createContextScope2(LISTBOX_OPTION_NAME, [
948
+ createListboxScope
949
+ ]);
950
+ var [ListboxOptionProvider, useListboxOptionContext] = createListboxOptionContext(LISTBOX_OPTION_NAME);
951
+ var ListboxRoot = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
952
+ const { __listboxScope: _scope, children, classNames, value, defaultValue, onValueChange, autoFocus: _autoFocus, ...rootProps } = props;
953
+ return /* @__PURE__ */ React8.createElement(RowList.Root, {
954
+ selectedId: value,
955
+ defaultSelectedId: defaultValue,
956
+ onSelectChange: onValueChange
957
+ }, /* @__PURE__ */ React8.createElement(RowList.Content, {
958
+ ...rootProps,
959
+ classNames: mx6("w-full", classNames),
960
+ ref: forwardedRef
961
+ }, children));
962
+ });
963
+ ListboxRoot.displayName = LISTBOX_NAME;
964
+ var ListboxOption = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
965
+ const { __listboxScope, children, classNames, value, ...rootProps } = props;
966
+ return /* @__PURE__ */ React8.createElement(Row, {
967
+ id: value,
968
+ ...rootProps,
969
+ classNames: mx6("dx-focus-ring rounded-xs", commandItem, classNames),
970
+ ref: forwardedRef
971
+ }, /* @__PURE__ */ React8.createElement(ListboxOptionProviderHost, {
972
+ value
973
+ }, children));
974
+ });
975
+ ListboxOption.displayName = LISTBOX_OPTION_NAME;
976
+ var ListboxOptionProviderHost = ({ value, children }) => {
977
+ const isSelected = useRowListSelection(value);
978
+ return /* @__PURE__ */ React8.createElement(ListboxOptionProvider, {
979
+ scope: void 0,
980
+ value,
981
+ isSelected
982
+ }, children);
983
+ };
984
+ var ListboxOptionLabel = /* @__PURE__ */ forwardRef3(({ children, classNames, ...rootProps }, forwardedRef) => {
985
+ return /* @__PURE__ */ React8.createElement("span", {
986
+ ...rootProps,
987
+ className: mx6("grow truncate", classNames),
988
+ ref: forwardedRef
989
+ }, children);
990
+ });
991
+ ListboxOptionLabel.displayName = LISTBOX_OPTION_LABEL_NAME;
992
+ var ListboxOptionIndicator = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
993
+ const { __listboxOptionScope, classNames, ...rootProps } = props;
994
+ const { isSelected } = useListboxOptionContext(LISTBOX_OPTION_INDICATOR_NAME, __listboxOptionScope);
995
+ return /* @__PURE__ */ React8.createElement(Icon3, {
996
+ icon: "ph--check--regular",
997
+ ...rootProps,
998
+ classNames: mx6(!isSelected && "invisible", classNames),
999
+ ref: forwardedRef
1000
+ });
1001
+ });
1002
+ ListboxOptionIndicator.displayName = LISTBOX_OPTION_INDICATOR_NAME;
1003
+ var Listbox = {
1004
+ Root: ListboxRoot,
1005
+ Option: ListboxOption,
1006
+ OptionLabel: ListboxOptionLabel,
1007
+ OptionIndicator: ListboxOptionIndicator
1008
+ };
1009
+
366
1010
  // src/components/Tree/Tree.tsx
367
1011
  import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
368
- import React8, { useMemo as useMemo2 } from "react";
1012
+ import React12, { useMemo as useMemo3 } from "react";
369
1013
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
370
1014
 
371
1015
  // src/components/Tree/TreeContext.tsx
372
- import { createContext as createContext5, useContext } from "react";
1016
+ import { createContext as createContext7, useContext } from "react";
373
1017
  import { raise } from "@dxos/debug";
374
- var TreeContext = /* @__PURE__ */ createContext5(null);
1018
+ var TreeContext = /* @__PURE__ */ createContext7(null);
375
1019
  var TreeProvider = TreeContext.Provider;
376
1020
  var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not found"));
377
1021
 
378
1022
  // src/components/Tree/TreeItem.tsx
1023
+ import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
379
1024
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
380
1025
  import { draggable as draggable2, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
381
- import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
382
1026
  import { useAtomValue } from "@effect-atom/atom-react";
383
1027
  import * as Schema from "effect/Schema";
384
- import React7, { memo as memo3, useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
1028
+ import React11, { memo as memo3, useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
385
1029
  import { invariant as invariant2 } from "@dxos/invariant";
386
- import { TreeItem as NaturalTreeItem, Treegrid } from "@dxos/react-ui";
387
- import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx4 } from "@dxos/ui-theme";
1030
+ import { TreeItem as NaturalTreeItem, Treegrid, TREEGRID_PARENT_OF_SEPARATOR } from "@dxos/react-ui";
1031
+ import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx7 } from "@dxos/ui-theme";
388
1032
 
389
1033
  // src/components/Tree/helpers.ts
390
1034
  var DEFAULT_INDENTATION = 8;
@@ -393,19 +1037,19 @@ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
393
1037
  });
394
1038
 
395
1039
  // src/components/Tree/TreeItemHeading.tsx
396
- import React5, { forwardRef, memo, useCallback as useCallback2 } from "react";
397
- import { Button, Icon as Icon2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
1040
+ import React9, { forwardRef as forwardRef4, memo, useCallback as useCallback5 } from "react";
1041
+ import { Button as Button2, Icon as Icon4, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
398
1042
  import { TextTooltip } from "@dxos/react-ui-text-tooltip";
399
1043
  import { getStyles } from "@dxos/ui-theme";
400
- var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
1044
+ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef4(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
401
1045
  const { t } = useTranslation2();
402
1046
  const styles = iconHue ? getStyles(iconHue) : void 0;
403
- const handleSelect = useCallback2((event) => {
1047
+ const handleSelect = useCallback5((event) => {
404
1048
  onSelect?.(event.altKey);
405
1049
  }, [
406
1050
  onSelect
407
1051
  ]);
408
- const handleButtonKeydown = useCallback2((event) => {
1052
+ const handleButtonKeydown = useCallback5((event) => {
409
1053
  if (event.key === " " || event.key === "Enter") {
410
1054
  event.preventDefault();
411
1055
  event.stopPropagation();
@@ -414,17 +1058,16 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
414
1058
  }, [
415
1059
  onSelect
416
1060
  ]);
417
- return /* @__PURE__ */ React5.createElement(TextTooltip, {
1061
+ return /* @__PURE__ */ React9.createElement(TextTooltip, {
418
1062
  text: toLocalizedString(label, t),
419
1063
  side: "bottom",
420
1064
  truncateQuery: "span[data-tooltip]",
421
1065
  onlyWhenTruncating: true,
422
1066
  asChild: true,
423
1067
  ref: forwardedRef
424
- }, /* @__PURE__ */ React5.createElement(Button, {
1068
+ }, /* @__PURE__ */ React9.createElement(Button2, {
425
1069
  "data-testid": "treeItem.heading",
426
1070
  variant: "ghost",
427
- density: "fine",
428
1071
  classNames: [
429
1072
  "grow gap-2 ps-0.5 hover:bg-transparent dark:hover:bg-transparent",
430
1073
  "disabled:cursor-default disabled:opacity-100",
@@ -436,24 +1079,24 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
436
1079
  ...current && {
437
1080
  "aria-current": "location"
438
1081
  }
439
- }, icon && /* @__PURE__ */ React5.createElement(Icon2, {
440
- icon: icon ?? "ph--placeholder--regular",
1082
+ }, icon && /* @__PURE__ */ React9.createElement(Icon4, {
441
1083
  size: 5,
1084
+ icon: icon ?? "ph--placeholder--regular",
442
1085
  classNames: [
443
1086
  "my-1",
444
- styles?.surfaceText
1087
+ styles?.foreground
445
1088
  ]
446
- }), /* @__PURE__ */ React5.createElement("span", {
1089
+ }), /* @__PURE__ */ React9.createElement("span", {
447
1090
  className: "flex-1 w-0 truncate text-start font-normal",
448
1091
  "data-tooltip": true
449
1092
  }, toLocalizedString(label, t))));
450
1093
  }));
451
1094
 
452
1095
  // src/components/Tree/TreeItemToggle.tsx
453
- import React6, { forwardRef as forwardRef2, memo as memo2 } from "react";
1096
+ import React10, { forwardRef as forwardRef5, memo as memo2 } from "react";
454
1097
  import { IconButton as IconButton2 } from "@dxos/react-ui";
455
- var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open, isBranch, hidden, classNames, ...props }, forwardedRef) => {
456
- return /* @__PURE__ */ React6.createElement(IconButton2, {
1098
+ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef5(({ classNames, open, isBranch, hidden, ...props }, forwardedRef) => {
1099
+ return /* @__PURE__ */ React10.createElement(IconButton2, {
457
1100
  ref: forwardedRef,
458
1101
  "data-testid": "treeItem.toggle",
459
1102
  "aria-expanded": open,
@@ -461,8 +1104,8 @@ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open,
461
1104
  density: "fine",
462
1105
  classNames: [
463
1106
  "h-full w-6 px-0",
464
- "[&_svg]:transition-[transform] [&_svg]:duration-200",
465
- open && "[&_svg]:rotate-90",
1107
+ "[&_svg]:transition-transform [&_svg]:duration-200",
1108
+ open ? "[&_svg]:rotate-90" : "[&_svg]:rotate-0",
466
1109
  hidden ? "hidden" : !isBranch && "invisible",
467
1110
  classNames
468
1111
  ],
@@ -486,15 +1129,15 @@ var TreeDataSchema = Schema.Struct({
486
1129
  });
487
1130
  var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
488
1131
  var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: draggableProp, renderColumns: Columns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
489
- const rowRef = useRef2(null);
490
- const buttonRef = useRef2(null);
491
- const openRef = useRef2(false);
492
- const cancelExpandRef = useRef2(null);
493
- const [_state, setState] = useState3("idle");
494
- const [instruction, setInstruction] = useState3(null);
495
- const [menuOpen, setMenuOpen] = useState3(false);
1132
+ const rowRef = useRef3(null);
1133
+ const buttonRef = useRef3(null);
1134
+ const openRef = useRef3(false);
1135
+ const cancelExpandRef = useRef3(null);
1136
+ const [_state, setState] = useState4("idle");
1137
+ const [instruction, setInstruction] = useState4(null);
1138
+ const [menuOpen, setMenuOpen] = useState4(false);
496
1139
  const { itemProps: itemPropsAtom, childIds: childIdsAtom, itemOpen: itemOpenAtom, itemCurrent: itemCurrentAtom } = useTree();
497
- const path = useMemo(() => [
1140
+ const path = useMemo2(() => [
498
1141
  ...pathProp,
499
1142
  item.id
500
1143
  ], [
@@ -517,7 +1160,8 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
517
1160
  path,
518
1161
  item
519
1162
  };
520
- const cancelExpand = useCallback3(() => {
1163
+ const shouldSeedNativeDragData = typeof document !== "undefined" && document.body.hasAttribute("data-platform");
1164
+ const cancelExpand = useCallback6(() => {
521
1165
  if (cancelExpandRef.current) {
522
1166
  clearTimeout(cancelExpandRef.current);
523
1167
  cancelExpandRef.current = null;
@@ -525,22 +1169,23 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
525
1169
  }, []);
526
1170
  const isItemDraggable = draggableProp && itemDraggable !== false;
527
1171
  const isItemDroppable = itemDroppable !== false;
528
- useEffect3(() => {
1172
+ const nativeDragText = id;
1173
+ useEffect4(() => {
529
1174
  if (!draggableProp) {
530
1175
  return;
531
1176
  }
532
- invariant2(buttonRef.current, void 0, {
533
- F: __dxlog_file2,
534
- L: 148,
535
- S: void 0,
536
- A: [
537
- "buttonRef.current",
538
- ""
539
- ]
540
- });
1177
+ invariant2(buttonRef.current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 70, S: void 0, A: ["buttonRef.current", ""] });
541
1178
  const makeDraggable = () => draggable2({
542
1179
  element: buttonRef.current,
543
1180
  getInitialData: () => data,
1181
+ getInitialDataForExternal: () => {
1182
+ if (!shouldSeedNativeDragData) {
1183
+ return {};
1184
+ }
1185
+ return {
1186
+ "text/plain": nativeDragText
1187
+ };
1188
+ },
544
1189
  onDragStart: () => {
545
1190
  setState("dragging");
546
1191
  if (open) {
@@ -644,10 +1289,10 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
644
1289
  blockInstruction,
645
1290
  canDrop
646
1291
  ]);
647
- useEffect3(() => () => cancelExpand(), [
1292
+ useEffect4(() => () => cancelExpand(), [
648
1293
  cancelExpand
649
1294
  ]);
650
- const handleOpenToggle = useCallback3(() => onOpenChange?.({
1295
+ const handleOpenToggle = useCallback6(() => onOpenChange?.({
651
1296
  item,
652
1297
  path,
653
1298
  open: !open
@@ -657,7 +1302,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
657
1302
  path,
658
1303
  open
659
1304
  ]);
660
- const handleSelect = useCallback3((option = false) => {
1305
+ const handleSelect = useCallback6((option = false) => {
661
1306
  if (isBranch && (option || current)) {
662
1307
  handleOpenToggle();
663
1308
  } else if (canSelectItem) {
@@ -682,7 +1327,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
682
1327
  handleOpenToggle,
683
1328
  onSelect
684
1329
  ]);
685
- const handleKeyDown = useCallback3((event) => {
1330
+ const handleKeyDown = useCallback6((event) => {
686
1331
  switch (event.key) {
687
1332
  case "ArrowRight":
688
1333
  case "ArrowLeft":
@@ -695,7 +1340,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
695
1340
  handleOpenToggle,
696
1341
  handleSelect
697
1342
  ]);
698
- const handleItemHover = useCallback3(() => {
1343
+ const handleItemHover = useCallback6(() => {
699
1344
  onItemHover?.({
700
1345
  item
701
1346
  });
@@ -703,7 +1348,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
703
1348
  onItemHover,
704
1349
  item
705
1350
  ]);
706
- const handleContextMenu = useCallback3((event) => {
1351
+ const handleContextMenu = useCallback6((event) => {
707
1352
  event.preventDefault();
708
1353
  setMenuOpen(true);
709
1354
  }, [
@@ -719,33 +1364,32 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
719
1364
  onOpenChange,
720
1365
  onSelect
721
1366
  };
722
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
1367
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Treegrid.Row, {
723
1368
  ref: rowRef,
724
1369
  key: id,
725
1370
  id,
726
1371
  "aria-labelledby": `${id}__label`,
727
- parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
1372
+ parentOf: parentOf?.join(TREEGRID_PARENT_OF_SEPARATOR),
728
1373
  "data-object-id": id,
729
1374
  "data-testid": testId,
730
1375
  // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
731
1376
  // without alerting the user (except for in the correct link element). See also:
732
1377
  // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
733
1378
  "aria-current": current ? "" : void 0,
734
- classNames: mx4("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-active-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
1379
+ classNames: mx7("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-current-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
735
1380
  onKeyDown: handleKeyDown,
736
1381
  onMouseEnter: handleItemHover,
737
1382
  onContextMenu: handleContextMenu
738
- }, /* @__PURE__ */ React7.createElement("div", {
739
- role: "none",
1383
+ }, /* @__PURE__ */ React11.createElement("div", {
740
1384
  className: "indent relative grid grid-cols-subgrid col-[tree-row]",
741
1385
  style: paddingIndentation(level)
742
- }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
1386
+ }, /* @__PURE__ */ React11.createElement(Treegrid.Cell, {
743
1387
  classNames: "flex items-center"
744
- }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
1388
+ }, /* @__PURE__ */ React11.createElement(TreeItemToggle, {
745
1389
  isBranch,
746
1390
  open,
747
1391
  onClick: handleOpenToggle
748
- }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
1392
+ }), /* @__PURE__ */ React11.createElement(TreeItemHeading, {
749
1393
  disabled,
750
1394
  current,
751
1395
  label,
@@ -754,16 +1398,16 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
754
1398
  iconHue,
755
1399
  onSelect: handleSelect,
756
1400
  ref: buttonRef
757
- })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
1401
+ })), Columns && /* @__PURE__ */ React11.createElement(Columns, {
758
1402
  item,
759
1403
  path,
760
1404
  open,
761
1405
  menuOpen,
762
1406
  setMenuOpen
763
- }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
1407
+ }), instruction && /* @__PURE__ */ React11.createElement(NaturalTreeItem.DropIndicator, {
764
1408
  instruction,
765
1409
  gap: 2
766
- }))), open && childIds.map((childId, index) => /* @__PURE__ */ React7.createElement(TreeItemById, {
1410
+ }))), open && childIds.map((childId, index) => /* @__PURE__ */ React11.createElement(TreeItemById, {
767
1411
  key: childId,
768
1412
  id: childId,
769
1413
  path,
@@ -778,7 +1422,7 @@ var RawTreeItemById = ({ id, ...props }) => {
778
1422
  if (!item) {
779
1423
  return null;
780
1424
  }
781
- return /* @__PURE__ */ React7.createElement(TreeItem, {
1425
+ return /* @__PURE__ */ React11.createElement(TreeItem, {
782
1426
  item,
783
1427
  ...props
784
1428
  });
@@ -786,9 +1430,9 @@ var RawTreeItemById = ({ id, ...props }) => {
786
1430
  var TreeItemById = /* @__PURE__ */ memo3(RawTreeItemById);
787
1431
 
788
1432
  // src/components/Tree/Tree.tsx
789
- var Tree = ({ model, rootId, path, id, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", classNames, levelOffset, renderColumns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
1433
+ var Tree = ({ classNames, model, rootId, path, id, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", levelOffset, renderColumns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
790
1434
  const childIds = useAtomValue2(model.childIds(rootId));
791
- const treePath = useMemo2(() => path ? [
1435
+ const treePath = useMemo3(() => path ? [
792
1436
  ...path,
793
1437
  id
794
1438
  ] : [
@@ -809,12 +1453,12 @@ var Tree = ({ model, rootId, path, id, draggable: draggable3 = false, gridTempla
809
1453
  onSelect,
810
1454
  onItemHover
811
1455
  };
812
- return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
1456
+ return /* @__PURE__ */ React12.createElement(Treegrid2.Root, {
813
1457
  gridTemplateColumns,
814
1458
  classNames
815
- }, /* @__PURE__ */ React8.createElement(TreeProvider, {
1459
+ }, /* @__PURE__ */ React12.createElement(TreeProvider, {
816
1460
  value: model
817
- }, childIds.map((childId, index) => /* @__PURE__ */ React8.createElement(TreeItemById, {
1461
+ }, childIds.map((childId, index) => /* @__PURE__ */ React12.createElement(TreeItemById, {
818
1462
  key: childId,
819
1463
  id: childId,
820
1464
  last: index === childIds.length - 1,
@@ -839,17 +1483,27 @@ var Path = {
839
1483
  };
840
1484
  export {
841
1485
  Accordion,
1486
+ Combobox,
842
1487
  DEFAULT_INDENTATION,
843
1488
  List,
1489
+ Listbox,
844
1490
  Path,
1491
+ Picker,
1492
+ Row,
1493
+ RowList,
845
1494
  Tree,
846
1495
  TreeDataSchema,
847
1496
  TreeItem,
848
1497
  TreeItemById,
849
1498
  TreeItemToggle,
850
1499
  TreeProvider,
1500
+ createListboxScope,
1501
+ createRowListScope,
851
1502
  isTreeData,
852
1503
  paddingIndentation,
1504
+ usePickerInputContext,
1505
+ usePickerItemContext,
1506
+ useRowListSelection,
853
1507
  useTree
854
1508
  };
855
1509
  //# sourceMappingURL=index.mjs.map