@dxos/react-ui-list 0.8.4-main.1068cf700f → 0.8.4-main.1c7ec43d41

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