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