@dxos/react-ui-list 0.8.4-main.d05673bc65 → 0.8.4-main.dfabb4ec29

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 (83) hide show
  1. package/dist/lib/browser/index.mjs +778 -121
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node-esm/index.mjs +778 -121
  5. package/dist/lib/node-esm/index.mjs.map +4 -4
  6. package/dist/lib/node-esm/meta.json +1 -1
  7. package/dist/types/src/components/Accordion/Accordion.d.ts +1 -1
  8. package/dist/types/src/components/Accordion/Accordion.d.ts.map +1 -1
  9. package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/Accordion/AccordionItem.d.ts.map +1 -1
  11. package/dist/types/src/components/Accordion/AccordionRoot.d.ts +1 -1
  12. package/dist/types/src/components/Accordion/AccordionRoot.d.ts.map +1 -1
  13. package/dist/types/src/components/Combobox/Combobox.d.ts +105 -0
  14. package/dist/types/src/components/Combobox/Combobox.d.ts.map +1 -0
  15. package/dist/types/src/components/Combobox/Combobox.stories.d.ts +12 -0
  16. package/dist/types/src/components/Combobox/Combobox.stories.d.ts.map +1 -0
  17. package/dist/types/src/components/Combobox/index.d.ts +2 -0
  18. package/dist/types/src/components/Combobox/index.d.ts.map +1 -0
  19. package/dist/types/src/components/List/List.d.ts +15 -4
  20. package/dist/types/src/components/List/List.d.ts.map +1 -1
  21. package/dist/types/src/components/List/List.stories.d.ts +2 -2
  22. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  23. package/dist/types/src/components/List/ListItem.d.ts +7 -7
  24. package/dist/types/src/components/List/ListItem.d.ts.map +1 -1
  25. package/dist/types/src/components/List/ListRoot.d.ts.map +1 -1
  26. package/dist/types/src/components/List/testing.d.ts.map +1 -1
  27. package/dist/types/src/components/Listbox/Listbox.d.ts +27 -0
  28. package/dist/types/src/components/Listbox/Listbox.d.ts.map +1 -0
  29. package/dist/types/src/components/Listbox/Listbox.stories.d.ts +12 -0
  30. package/dist/types/src/components/Listbox/Listbox.stories.d.ts.map +1 -0
  31. package/dist/types/src/components/Listbox/index.d.ts +2 -0
  32. package/dist/types/src/components/Listbox/index.d.ts.map +1 -0
  33. package/dist/types/src/components/Picker/Picker.d.ts +49 -0
  34. package/dist/types/src/components/Picker/Picker.d.ts.map +1 -0
  35. package/dist/types/src/components/Picker/Picker.stories.d.ts +28 -0
  36. package/dist/types/src/components/Picker/Picker.stories.d.ts.map +1 -0
  37. package/dist/types/src/components/Picker/context.d.ts +29 -0
  38. package/dist/types/src/components/Picker/context.d.ts.map +1 -0
  39. package/dist/types/src/components/Picker/index.d.ts +3 -0
  40. package/dist/types/src/components/Picker/index.d.ts.map +1 -0
  41. package/dist/types/src/components/RowList/RowList.d.ts +61 -0
  42. package/dist/types/src/components/RowList/RowList.d.ts.map +1 -0
  43. package/dist/types/src/components/RowList/RowList.stories.d.ts +35 -0
  44. package/dist/types/src/components/RowList/RowList.stories.d.ts.map +1 -0
  45. package/dist/types/src/components/RowList/index.d.ts +3 -0
  46. package/dist/types/src/components/RowList/index.d.ts.map +1 -0
  47. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  48. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  49. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  50. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  51. package/dist/types/src/components/Tree/helpers.d.ts.map +1 -1
  52. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  53. package/dist/types/src/components/index.d.ts +4 -0
  54. package/dist/types/src/components/index.d.ts.map +1 -1
  55. package/dist/types/src/util/path.d.ts.map +1 -1
  56. package/dist/types/tsconfig.tsbuildinfo +1 -1
  57. package/package.json +20 -20
  58. package/src/components/Accordion/Accordion.stories.tsx +3 -3
  59. package/src/components/Accordion/AccordionItem.tsx +1 -4
  60. package/src/components/Combobox/Combobox.stories.tsx +60 -0
  61. package/src/components/Combobox/Combobox.tsx +387 -0
  62. package/src/components/Combobox/index.ts +5 -0
  63. package/src/components/List/List.stories.tsx +5 -5
  64. package/src/components/List/List.tsx +12 -8
  65. package/src/components/List/ListItem.tsx +28 -28
  66. package/src/components/List/ListRoot.tsx +1 -1
  67. package/src/components/List/testing.ts +4 -4
  68. package/src/components/Listbox/Listbox.stories.tsx +48 -0
  69. package/src/components/Listbox/Listbox.tsx +201 -0
  70. package/src/components/Listbox/index.ts +5 -0
  71. package/src/components/Picker/Picker.stories.tsx +131 -0
  72. package/src/components/Picker/Picker.tsx +368 -0
  73. package/src/components/Picker/context.ts +43 -0
  74. package/src/components/Picker/index.ts +6 -0
  75. package/src/components/RowList/RowList.stories.tsx +163 -0
  76. package/src/components/RowList/RowList.tsx +353 -0
  77. package/src/components/RowList/index.ts +6 -0
  78. package/src/components/Tree/Tree.stories.tsx +4 -5
  79. package/src/components/Tree/TreeItem.tsx +13 -9
  80. package/src/components/Tree/TreeItemHeading.tsx +1 -2
  81. package/src/components/Tree/TreeItemToggle.tsx +3 -3
  82. package/src/components/Tree/testing.ts +5 -5
  83. 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,
@@ -158,28 +593,20 @@ var idle = {
158
593
  type: "idle"
159
594
  };
160
595
  var stateStyles = {
161
- "w-dragging": "opacity-50"
596
+ "is-dragging": "opacity-50"
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 ref = useRef(null);
170
- const dragHandleRef = useRef(null);
171
- const [state, setState] = useState2(idle);
172
- useEffect2(() => {
173
- const element = ref.current;
174
- invariant(element, void 0, {
175
- F: __dxlog_file,
176
- L: 109,
177
- S: void 0,
178
- A: [
179
- "element",
180
- ""
181
- ]
182
- });
604
+ const rootRef = useRef2(null);
605
+ const dragHandleRef = useRef2(null);
606
+ const [state, setState] = useState3(idle);
607
+ useEffect3(() => {
608
+ const element = rootRef.current;
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
@@ -218,10 +645,10 @@ var ListItem = ({ children, classNames, item, asChild, selected, ...props }) =>
218
645
  } : void 0,
219
646
  onDragStart: () => {
220
647
  setState({
221
- type: "w-dragging"
648
+ type: "is-dragging"
222
649
  });
223
650
  setRootState({
224
- type: "w-dragging",
651
+ type: "is-dragging",
225
652
  item
226
653
  });
227
654
  },
@@ -252,7 +679,7 @@ var ListItem = ({ children, classNames, item, asChild, selected, ...props }) =>
252
679
  onDragEnter: ({ self }) => {
253
680
  const closestEdge = extractClosestEdge2(self.data);
254
681
  setState({
255
- type: "w-dragging-over",
682
+ type: "is-dragging-over",
256
683
  closestEdge
257
684
  });
258
685
  },
@@ -262,11 +689,11 @@ var ListItem = ({ children, classNames, item, asChild, selected, ...props }) =>
262
689
  onDrag: ({ self }) => {
263
690
  const closestEdge = extractClosestEdge2(self.data);
264
691
  setState((current) => {
265
- if (current.type === "w-dragging-over" && current.closestEdge === closestEdge) {
692
+ if (current.type === "is-dragging-over" && current.closestEdge === closestEdge) {
266
693
  return current;
267
694
  }
268
695
  return {
269
- type: "w-dragging-over",
696
+ type: "is-dragging-over",
270
697
  closestEdge
271
698
  };
272
699
  });
@@ -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, {
286
- ref,
712
+ }, /* @__PURE__ */ React6.createElement(Comp, {
713
+ ...props,
287
714
  role: "listitem",
288
715
  "aria-selected": selected,
289
- className: mx3("relative dx-selected", classNames, stateStyles[state.type]),
290
- ...props
291
- }, children), state.type === "w-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
716
+ className: mx5("relative p-1 dx-selected dx-hover", classNames, stateStyles[state.type]),
717
+ ref: rootRef
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, {
314
- iconOnly: true,
315
- variant: "ghost",
740
+ return /* @__PURE__ */ React6.createElement(IconButton, {
316
741
  ...props,
317
- icon,
742
+ variant: "ghost",
318
743
  disabled: isDisabled,
319
- label: label ?? t("delete label"),
744
+ icon,
745
+ iconOnly: true,
746
+ label: label ?? t("delete.label"),
320
747
  classNames: [
321
748
  classNames,
322
749
  autoHide && disabled && "hidden"
@@ -326,13 +753,13 @@ 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, {
330
- iconOnly: true,
756
+ return /* @__PURE__ */ React6.createElement(IconButton, {
331
757
  variant: "ghost",
332
- label: t("drag handle label"),
333
- ref: dragHandleRef,
758
+ disabled,
334
759
  icon: "ph--dots-six-vertical--regular",
335
- disabled
760
+ iconOnly: true,
761
+ label: t("drag-handle.label"),
762
+ ref: dragHandleRef
336
763
  });
337
764
  };
338
765
  var ListItemDragPreview = ({ children }) => {
@@ -341,11 +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
- 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)
346
773
  }, children);
347
- var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
348
- 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),
349
776
  ...props
350
777
  }, children);
351
778
 
@@ -361,28 +788,248 @@ var List = {
361
788
  ItemTitle: ListItemTitle
362
789
  };
363
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
+ const composed = composableProps2(rest, {
835
+ classNames: "dx-container"
836
+ });
837
+ return /* @__PURE__ */ React7.createElement(ScrollArea2.Root, {
838
+ orientation: "vertical",
839
+ thin,
840
+ padding,
841
+ centered,
842
+ ...composed,
843
+ ref: forwardedRef
844
+ }, /* @__PURE__ */ React7.createElement(ScrollArea2.Viewport, null, children));
845
+ });
846
+ Viewport.displayName = ROW_LIST_VIEWPORT_NAME;
847
+ var firstEnabledOption = (ul) => {
848
+ if (!ul) {
849
+ return null;
850
+ }
851
+ return ul.querySelector('[role="option"]:not([aria-disabled="true"])');
852
+ };
853
+ var Content2 = composable2((props, forwardedRef) => {
854
+ useRowListContext(ROW_LIST_CONTENT_NAME, void 0);
855
+ const arrowGroup = useArrowNavigationGroup({
856
+ axis: "vertical",
857
+ memorizeCurrent: true
858
+ });
859
+ const { children, ...rest } = props;
860
+ const handleFocus = useCallback4((event) => {
861
+ if (event.target !== event.currentTarget) {
862
+ return;
863
+ }
864
+ const ul = event.currentTarget;
865
+ const selected = ul.querySelector('[role="option"][aria-selected="true"]:not([aria-disabled="true"])');
866
+ const target = selected ?? firstEnabledOption(ul);
867
+ target?.focus();
868
+ }, []);
869
+ const composed = composableProps2(rest, {
870
+ classNames: "flex flex-col"
871
+ });
872
+ return /* @__PURE__ */ React7.createElement(List2, {
873
+ variant: "unordered",
874
+ ...composed,
875
+ ...arrowGroup,
876
+ role: "listbox",
877
+ onFocus: handleFocus,
878
+ ref: forwardedRef
879
+ }, children);
880
+ });
881
+ Content2.displayName = ROW_LIST_CONTENT_NAME;
882
+ var ROW_BASE = "dx-hover dx-selected px-3 py-2 cursor-pointer outline-none border-b border-separator last:border-b-0";
883
+ var Row = composable2((props, forwardedRef) => {
884
+ const { id, disabled, onClick, onFocus, children, ...rest } = props;
885
+ const { selectedId, setSelected } = useRowListContext(ROW_NAME, void 0);
886
+ const isSelected = selectedId === id;
887
+ const handleClick = useCallback4((event) => {
888
+ if (disabled) {
889
+ return;
890
+ }
891
+ setSelected(id);
892
+ onClick?.(event);
893
+ }, [
894
+ disabled,
895
+ id,
896
+ setSelected,
897
+ onClick
898
+ ]);
899
+ const handleFocus = useCallback4((event) => {
900
+ if (!disabled && selectedId !== id) {
901
+ setSelected(id);
902
+ }
903
+ onFocus?.(event);
904
+ }, [
905
+ disabled,
906
+ selectedId,
907
+ id,
908
+ setSelected,
909
+ onFocus
910
+ ]);
911
+ const composed = composableProps2(rest, {
912
+ classNames: [
913
+ ROW_BASE,
914
+ disabled && "opacity-50 cursor-not-allowed"
915
+ ]
916
+ });
917
+ return /* @__PURE__ */ React7.createElement(ListItem2, {
918
+ ...composed,
919
+ role: "option",
920
+ tabIndex: 0,
921
+ "aria-selected": isSelected,
922
+ "aria-disabled": disabled || void 0,
923
+ onClick: handleClick,
924
+ onFocus: handleFocus,
925
+ ref: forwardedRef
926
+ }, children);
927
+ });
928
+ Row.displayName = ROW_NAME;
929
+ var useRowListSelection = (id) => {
930
+ const { selectedId } = useRowListContext("useRowListSelection", void 0);
931
+ return selectedId === id;
932
+ };
933
+ var RowList = {
934
+ Root: Root2,
935
+ Viewport,
936
+ Content: Content2
937
+ };
938
+
939
+ // src/components/Listbox/Listbox.tsx
940
+ var commandItem = "flex items-center overflow-hidden";
941
+ var LISTBOX_NAME = "Listbox";
942
+ var LISTBOX_OPTION_NAME = "ListboxOption";
943
+ var LISTBOX_OPTION_LABEL_NAME = "ListboxOptionLabel";
944
+ var LISTBOX_OPTION_INDICATOR_NAME = "ListboxOptionIndicator";
945
+ var [createListboxContext, createListboxScope] = createContextScope2(LISTBOX_NAME, [
946
+ createRowListScope
947
+ ]);
948
+ var [createListboxOptionContext, createListboxOptionScope] = createContextScope2(LISTBOX_OPTION_NAME, [
949
+ createListboxScope
950
+ ]);
951
+ var [ListboxOptionProvider, useListboxOptionContext] = createListboxOptionContext(LISTBOX_OPTION_NAME);
952
+ var ListboxRoot = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
953
+ const { __listboxScope: _scope, children, classNames, value, defaultValue, onValueChange, autoFocus: _autoFocus, ...rootProps } = props;
954
+ return /* @__PURE__ */ React8.createElement(RowList.Root, {
955
+ selectedId: value,
956
+ defaultSelectedId: defaultValue,
957
+ onSelectChange: onValueChange
958
+ }, /* @__PURE__ */ React8.createElement(RowList.Content, {
959
+ ...rootProps,
960
+ classNames: mx6("w-full", classNames),
961
+ ref: forwardedRef
962
+ }, children));
963
+ });
964
+ ListboxRoot.displayName = LISTBOX_NAME;
965
+ var ListboxOption = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
966
+ const { __listboxScope, children, classNames, value, ...rootProps } = props;
967
+ return /* @__PURE__ */ React8.createElement(Row, {
968
+ id: value,
969
+ ...rootProps,
970
+ classNames: mx6("dx-focus-ring rounded-xs", commandItem, classNames),
971
+ ref: forwardedRef
972
+ }, /* @__PURE__ */ React8.createElement(ListboxOptionProviderHost, {
973
+ value
974
+ }, children));
975
+ });
976
+ ListboxOption.displayName = LISTBOX_OPTION_NAME;
977
+ var ListboxOptionProviderHost = ({ value, children }) => {
978
+ const isSelected = useRowListSelection(value);
979
+ return /* @__PURE__ */ React8.createElement(ListboxOptionProvider, {
980
+ scope: void 0,
981
+ value,
982
+ isSelected
983
+ }, children);
984
+ };
985
+ var ListboxOptionLabel = /* @__PURE__ */ forwardRef3(({ children, classNames, ...rootProps }, forwardedRef) => {
986
+ return /* @__PURE__ */ React8.createElement("span", {
987
+ ...rootProps,
988
+ className: mx6("grow truncate", classNames),
989
+ ref: forwardedRef
990
+ }, children);
991
+ });
992
+ ListboxOptionLabel.displayName = LISTBOX_OPTION_LABEL_NAME;
993
+ var ListboxOptionIndicator = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
994
+ const { __listboxOptionScope, classNames, ...rootProps } = props;
995
+ const { isSelected } = useListboxOptionContext(LISTBOX_OPTION_INDICATOR_NAME, __listboxOptionScope);
996
+ return /* @__PURE__ */ React8.createElement(Icon3, {
997
+ icon: "ph--check--regular",
998
+ ...rootProps,
999
+ classNames: mx6(!isSelected && "invisible", classNames),
1000
+ ref: forwardedRef
1001
+ });
1002
+ });
1003
+ ListboxOptionIndicator.displayName = LISTBOX_OPTION_INDICATOR_NAME;
1004
+ var Listbox = {
1005
+ Root: ListboxRoot,
1006
+ Option: ListboxOption,
1007
+ OptionLabel: ListboxOptionLabel,
1008
+ OptionIndicator: ListboxOptionIndicator
1009
+ };
1010
+
364
1011
  // src/components/Tree/Tree.tsx
365
1012
  import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
366
- import React8, { useMemo as useMemo2 } from "react";
1013
+ import React12, { useMemo as useMemo3 } from "react";
367
1014
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
368
1015
 
369
1016
  // src/components/Tree/TreeContext.tsx
370
- import { createContext as createContext5, useContext } from "react";
1017
+ import { createContext as createContext7, useContext } from "react";
371
1018
  import { raise } from "@dxos/debug";
372
- var TreeContext = /* @__PURE__ */ createContext5(null);
1019
+ var TreeContext = /* @__PURE__ */ createContext7(null);
373
1020
  var TreeProvider = TreeContext.Provider;
374
1021
  var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not found"));
375
1022
 
376
1023
  // src/components/Tree/TreeItem.tsx
1024
+ import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
377
1025
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
378
1026
  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
1027
  import { useAtomValue } from "@effect-atom/atom-react";
381
1028
  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";
1029
+ import React11, { memo as memo3, useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
383
1030
  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";
1031
+ import { TreeItem as NaturalTreeItem, Treegrid, TREEGRID_PARENT_OF_SEPARATOR } from "@dxos/react-ui";
1032
+ import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx7 } from "@dxos/ui-theme";
386
1033
 
387
1034
  // src/components/Tree/helpers.ts
388
1035
  var DEFAULT_INDENTATION = 8;
@@ -391,19 +1038,19 @@ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
391
1038
  });
392
1039
 
393
1040
  // 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";
1041
+ import React9, { forwardRef as forwardRef4, memo, useCallback as useCallback5 } from "react";
1042
+ import { Button as Button2, Icon as Icon4, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
396
1043
  import { TextTooltip } from "@dxos/react-ui-text-tooltip";
397
1044
  import { getStyles } from "@dxos/ui-theme";
398
- var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
1045
+ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef4(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
399
1046
  const { t } = useTranslation2();
400
1047
  const styles = iconHue ? getStyles(iconHue) : void 0;
401
- const handleSelect = useCallback2((event) => {
1048
+ const handleSelect = useCallback5((event) => {
402
1049
  onSelect?.(event.altKey);
403
1050
  }, [
404
1051
  onSelect
405
1052
  ]);
406
- const handleButtonKeydown = useCallback2((event) => {
1053
+ const handleButtonKeydown = useCallback5((event) => {
407
1054
  if (event.key === " " || event.key === "Enter") {
408
1055
  event.preventDefault();
409
1056
  event.stopPropagation();
@@ -412,17 +1059,16 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
412
1059
  }, [
413
1060
  onSelect
414
1061
  ]);
415
- return /* @__PURE__ */ React5.createElement(TextTooltip, {
1062
+ return /* @__PURE__ */ React9.createElement(TextTooltip, {
416
1063
  text: toLocalizedString(label, t),
417
1064
  side: "bottom",
418
1065
  truncateQuery: "span[data-tooltip]",
419
1066
  onlyWhenTruncating: true,
420
1067
  asChild: true,
421
1068
  ref: forwardedRef
422
- }, /* @__PURE__ */ React5.createElement(Button, {
1069
+ }, /* @__PURE__ */ React9.createElement(Button2, {
423
1070
  "data-testid": "treeItem.heading",
424
1071
  variant: "ghost",
425
- density: "fine",
426
1072
  classNames: [
427
1073
  "grow gap-2 ps-0.5 hover:bg-transparent dark:hover:bg-transparent",
428
1074
  "disabled:cursor-default disabled:opacity-100",
@@ -434,24 +1080,24 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
434
1080
  ...current && {
435
1081
  "aria-current": "location"
436
1082
  }
437
- }, icon && /* @__PURE__ */ React5.createElement(Icon2, {
438
- icon: icon ?? "ph--placeholder--regular",
1083
+ }, icon && /* @__PURE__ */ React9.createElement(Icon4, {
439
1084
  size: 5,
1085
+ icon: icon ?? "ph--placeholder--regular",
440
1086
  classNames: [
441
1087
  "my-1",
442
1088
  styles?.surfaceText
443
1089
  ]
444
- }), /* @__PURE__ */ React5.createElement("span", {
1090
+ }), /* @__PURE__ */ React9.createElement("span", {
445
1091
  className: "flex-1 w-0 truncate text-start font-normal",
446
1092
  "data-tooltip": true
447
1093
  }, toLocalizedString(label, t))));
448
1094
  }));
449
1095
 
450
1096
  // src/components/Tree/TreeItemToggle.tsx
451
- import React6, { forwardRef as forwardRef2, memo as memo2 } from "react";
1097
+ import React10, { forwardRef as forwardRef5, memo as memo2 } from "react";
452
1098
  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, {
1099
+ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef5(({ classNames, open, isBranch, hidden, ...props }, forwardedRef) => {
1100
+ return /* @__PURE__ */ React10.createElement(IconButton2, {
455
1101
  ref: forwardedRef,
456
1102
  "data-testid": "treeItem.toggle",
457
1103
  "aria-expanded": open,
@@ -459,8 +1105,8 @@ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open,
459
1105
  density: "fine",
460
1106
  classNames: [
461
1107
  "h-full w-6 px-0",
462
- "[&_svg]:transition-[transform] [&_svg]:duration-200",
463
- open && "[&_svg]:rotate-90",
1108
+ "[&_svg]:transition-transform [&_svg]:duration-200",
1109
+ open ? "[&_svg]:rotate-90" : "[&_svg]:rotate-0",
464
1110
  hidden ? "hidden" : !isBranch && "invisible",
465
1111
  classNames
466
1112
  ],
@@ -484,15 +1130,15 @@ var TreeDataSchema = Schema.Struct({
484
1130
  });
485
1131
  var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
486
1132
  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);
1133
+ const rowRef = useRef3(null);
1134
+ const buttonRef = useRef3(null);
1135
+ const openRef = useRef3(false);
1136
+ const cancelExpandRef = useRef3(null);
1137
+ const [_state, setState] = useState4("idle");
1138
+ const [instruction, setInstruction] = useState4(null);
1139
+ const [menuOpen, setMenuOpen] = useState4(false);
494
1140
  const { itemProps: itemPropsAtom, childIds: childIdsAtom, itemOpen: itemOpenAtom, itemCurrent: itemCurrentAtom } = useTree();
495
- const path = useMemo(() => [
1141
+ const path = useMemo2(() => [
496
1142
  ...pathProp,
497
1143
  item.id
498
1144
  ], [
@@ -515,7 +1161,8 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
515
1161
  path,
516
1162
  item
517
1163
  };
518
- const cancelExpand = useCallback3(() => {
1164
+ const shouldSeedNativeDragData = typeof document !== "undefined" && document.body.hasAttribute("data-platform");
1165
+ const cancelExpand = useCallback6(() => {
519
1166
  if (cancelExpandRef.current) {
520
1167
  clearTimeout(cancelExpandRef.current);
521
1168
  cancelExpandRef.current = null;
@@ -523,22 +1170,23 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
523
1170
  }, []);
524
1171
  const isItemDraggable = draggableProp && itemDraggable !== false;
525
1172
  const isItemDroppable = itemDroppable !== false;
526
- useEffect3(() => {
1173
+ const nativeDragText = id;
1174
+ useEffect4(() => {
527
1175
  if (!draggableProp) {
528
1176
  return;
529
1177
  }
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
- });
1178
+ invariant2(buttonRef.current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 70, S: void 0, A: ["buttonRef.current", ""] });
539
1179
  const makeDraggable = () => draggable2({
540
1180
  element: buttonRef.current,
541
1181
  getInitialData: () => data,
1182
+ getInitialDataForExternal: () => {
1183
+ if (!shouldSeedNativeDragData) {
1184
+ return {};
1185
+ }
1186
+ return {
1187
+ "text/plain": nativeDragText
1188
+ };
1189
+ },
542
1190
  onDragStart: () => {
543
1191
  setState("dragging");
544
1192
  if (open) {
@@ -642,10 +1290,10 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
642
1290
  blockInstruction,
643
1291
  canDrop
644
1292
  ]);
645
- useEffect3(() => () => cancelExpand(), [
1293
+ useEffect4(() => () => cancelExpand(), [
646
1294
  cancelExpand
647
1295
  ]);
648
- const handleOpenToggle = useCallback3(() => onOpenChange?.({
1296
+ const handleOpenToggle = useCallback6(() => onOpenChange?.({
649
1297
  item,
650
1298
  path,
651
1299
  open: !open
@@ -655,7 +1303,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
655
1303
  path,
656
1304
  open
657
1305
  ]);
658
- const handleSelect = useCallback3((option = false) => {
1306
+ const handleSelect = useCallback6((option = false) => {
659
1307
  if (isBranch && (option || current)) {
660
1308
  handleOpenToggle();
661
1309
  } else if (canSelectItem) {
@@ -680,7 +1328,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
680
1328
  handleOpenToggle,
681
1329
  onSelect
682
1330
  ]);
683
- const handleKeyDown = useCallback3((event) => {
1331
+ const handleKeyDown = useCallback6((event) => {
684
1332
  switch (event.key) {
685
1333
  case "ArrowRight":
686
1334
  case "ArrowLeft":
@@ -693,7 +1341,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
693
1341
  handleOpenToggle,
694
1342
  handleSelect
695
1343
  ]);
696
- const handleItemHover = useCallback3(() => {
1344
+ const handleItemHover = useCallback6(() => {
697
1345
  onItemHover?.({
698
1346
  item
699
1347
  });
@@ -701,7 +1349,7 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
701
1349
  onItemHover,
702
1350
  item
703
1351
  ]);
704
- const handleContextMenu = useCallback3((event) => {
1352
+ const handleContextMenu = useCallback6((event) => {
705
1353
  event.preventDefault();
706
1354
  setMenuOpen(true);
707
1355
  }, [
@@ -717,33 +1365,32 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
717
1365
  onOpenChange,
718
1366
  onSelect
719
1367
  };
720
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
1368
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Treegrid.Row, {
721
1369
  ref: rowRef,
722
1370
  key: id,
723
1371
  id,
724
1372
  "aria-labelledby": `${id}__label`,
725
- parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
1373
+ parentOf: parentOf?.join(TREEGRID_PARENT_OF_SEPARATOR),
726
1374
  "data-object-id": id,
727
1375
  "data-testid": testId,
728
1376
  // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
729
1377
  // without alerting the user (except for in the correct link element). See also:
730
1378
  // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
731
1379
  "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),
1380
+ classNames: mx7("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-active-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
733
1381
  onKeyDown: handleKeyDown,
734
1382
  onMouseEnter: handleItemHover,
735
1383
  onContextMenu: handleContextMenu
736
- }, /* @__PURE__ */ React7.createElement("div", {
737
- role: "none",
1384
+ }, /* @__PURE__ */ React11.createElement("div", {
738
1385
  className: "indent relative grid grid-cols-subgrid col-[tree-row]",
739
1386
  style: paddingIndentation(level)
740
- }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
1387
+ }, /* @__PURE__ */ React11.createElement(Treegrid.Cell, {
741
1388
  classNames: "flex items-center"
742
- }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
1389
+ }, /* @__PURE__ */ React11.createElement(TreeItemToggle, {
743
1390
  isBranch,
744
1391
  open,
745
1392
  onClick: handleOpenToggle
746
- }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
1393
+ }), /* @__PURE__ */ React11.createElement(TreeItemHeading, {
747
1394
  disabled,
748
1395
  current,
749
1396
  label,
@@ -752,16 +1399,16 @@ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: dra
752
1399
  iconHue,
753
1400
  onSelect: handleSelect,
754
1401
  ref: buttonRef
755
- })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
1402
+ })), Columns && /* @__PURE__ */ React11.createElement(Columns, {
756
1403
  item,
757
1404
  path,
758
1405
  open,
759
1406
  menuOpen,
760
1407
  setMenuOpen
761
- }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
1408
+ }), instruction && /* @__PURE__ */ React11.createElement(NaturalTreeItem.DropIndicator, {
762
1409
  instruction,
763
1410
  gap: 2
764
- }))), open && childIds.map((childId, index) => /* @__PURE__ */ React7.createElement(TreeItemById, {
1411
+ }))), open && childIds.map((childId, index) => /* @__PURE__ */ React11.createElement(TreeItemById, {
765
1412
  key: childId,
766
1413
  id: childId,
767
1414
  path,
@@ -776,7 +1423,7 @@ var RawTreeItemById = ({ id, ...props }) => {
776
1423
  if (!item) {
777
1424
  return null;
778
1425
  }
779
- return /* @__PURE__ */ React7.createElement(TreeItem, {
1426
+ return /* @__PURE__ */ React11.createElement(TreeItem, {
780
1427
  item,
781
1428
  ...props
782
1429
  });
@@ -786,7 +1433,7 @@ var TreeItemById = /* @__PURE__ */ memo3(RawTreeItemById);
786
1433
  // src/components/Tree/Tree.tsx
787
1434
  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 }) => {
788
1435
  const childIds = useAtomValue2(model.childIds(rootId));
789
- const treePath = useMemo2(() => path ? [
1436
+ const treePath = useMemo3(() => path ? [
790
1437
  ...path,
791
1438
  id
792
1439
  ] : [
@@ -807,12 +1454,12 @@ var Tree = ({ model, rootId, path, id, draggable: draggable3 = false, gridTempla
807
1454
  onSelect,
808
1455
  onItemHover
809
1456
  };
810
- return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
1457
+ return /* @__PURE__ */ React12.createElement(Treegrid2.Root, {
811
1458
  gridTemplateColumns,
812
1459
  classNames
813
- }, /* @__PURE__ */ React8.createElement(TreeProvider, {
1460
+ }, /* @__PURE__ */ React12.createElement(TreeProvider, {
814
1461
  value: model
815
- }, childIds.map((childId, index) => /* @__PURE__ */ React8.createElement(TreeItemById, {
1462
+ }, childIds.map((childId, index) => /* @__PURE__ */ React12.createElement(TreeItemById, {
816
1463
  key: childId,
817
1464
  id: childId,
818
1465
  last: index === childIds.length - 1,
@@ -837,17 +1484,27 @@ var Path = {
837
1484
  };
838
1485
  export {
839
1486
  Accordion,
1487
+ Combobox,
840
1488
  DEFAULT_INDENTATION,
841
1489
  List,
1490
+ Listbox,
842
1491
  Path,
1492
+ Picker,
1493
+ Row,
1494
+ RowList,
843
1495
  Tree,
844
1496
  TreeDataSchema,
845
1497
  TreeItem,
846
1498
  TreeItemById,
847
1499
  TreeItemToggle,
848
1500
  TreeProvider,
1501
+ createListboxScope,
1502
+ createRowListScope,
849
1503
  isTreeData,
850
1504
  paddingIndentation,
1505
+ usePickerInputContext,
1506
+ usePickerItemContext,
1507
+ useRowListSelection,
851
1508
  useTree
852
1509
  };
853
1510
  //# sourceMappingURL=index.mjs.map