@dxos/react-ui-list 0.8.4-main.ef1bc66f44 → 0.8.4-main.effb148878

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 (94) hide show
  1. package/LICENSE +102 -5
  2. package/dist/lib/browser/index.mjs +957 -271
  3. package/dist/lib/browser/index.mjs.map +4 -4
  4. package/dist/lib/browser/meta.json +1 -1
  5. package/dist/lib/node-esm/index.mjs +957 -271
  6. package/dist/lib/node-esm/index.mjs.map +4 -4
  7. package/dist/lib/node-esm/meta.json +1 -1
  8. package/dist/types/src/components/Accordion/Accordion.d.ts +1 -1
  9. package/dist/types/src/components/Accordion/Accordion.d.ts.map +1 -1
  10. package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/Accordion/AccordionItem.d.ts.map +1 -1
  12. package/dist/types/src/components/Accordion/AccordionRoot.d.ts +1 -1
  13. package/dist/types/src/components/Accordion/AccordionRoot.d.ts.map +1 -1
  14. package/dist/types/src/components/Combobox/Combobox.d.ts +105 -0
  15. package/dist/types/src/components/Combobox/Combobox.d.ts.map +1 -0
  16. package/dist/types/src/components/Combobox/Combobox.stories.d.ts +12 -0
  17. package/dist/types/src/components/Combobox/Combobox.stories.d.ts.map +1 -0
  18. package/dist/types/src/components/Combobox/index.d.ts +2 -0
  19. package/dist/types/src/components/Combobox/index.d.ts.map +1 -0
  20. package/dist/types/src/components/List/List.d.ts +18 -7
  21. package/dist/types/src/components/List/List.d.ts.map +1 -1
  22. package/dist/types/src/components/List/List.stories.d.ts +2 -2
  23. package/dist/types/src/components/List/List.stories.d.ts.map +1 -1
  24. package/dist/types/src/components/List/ListItem.d.ts +10 -8
  25. package/dist/types/src/components/List/ListItem.d.ts.map +1 -1
  26. package/dist/types/src/components/List/ListRoot.d.ts.map +1 -1
  27. package/dist/types/src/components/List/testing.d.ts.map +1 -1
  28. package/dist/types/src/components/Listbox/Listbox.d.ts +27 -0
  29. package/dist/types/src/components/Listbox/Listbox.d.ts.map +1 -0
  30. package/dist/types/src/components/Listbox/Listbox.stories.d.ts +12 -0
  31. package/dist/types/src/components/Listbox/Listbox.stories.d.ts.map +1 -0
  32. package/dist/types/src/components/Listbox/index.d.ts +2 -0
  33. package/dist/types/src/components/Listbox/index.d.ts.map +1 -0
  34. package/dist/types/src/components/Picker/Picker.d.ts +49 -0
  35. package/dist/types/src/components/Picker/Picker.d.ts.map +1 -0
  36. package/dist/types/src/components/Picker/Picker.stories.d.ts +28 -0
  37. package/dist/types/src/components/Picker/Picker.stories.d.ts.map +1 -0
  38. package/dist/types/src/components/Picker/context.d.ts +29 -0
  39. package/dist/types/src/components/Picker/context.d.ts.map +1 -0
  40. package/dist/types/src/components/Picker/index.d.ts +3 -0
  41. package/dist/types/src/components/Picker/index.d.ts.map +1 -0
  42. package/dist/types/src/components/RowList/RowList.d.ts +61 -0
  43. package/dist/types/src/components/RowList/RowList.d.ts.map +1 -0
  44. package/dist/types/src/components/RowList/RowList.stories.d.ts +35 -0
  45. package/dist/types/src/components/RowList/RowList.stories.d.ts.map +1 -0
  46. package/dist/types/src/components/RowList/index.d.ts +3 -0
  47. package/dist/types/src/components/RowList/index.d.ts.map +1 -0
  48. package/dist/types/src/components/Tree/Tree.d.ts +6 -5
  49. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  50. package/dist/types/src/components/Tree/Tree.stories.d.ts +1 -1
  51. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Tree/TreeContext.d.ts +21 -10
  53. package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
  54. package/dist/types/src/components/Tree/TreeItem.d.ts +8 -0
  55. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  56. package/dist/types/src/components/Tree/TreeItemHeading.d.ts.map +1 -1
  57. package/dist/types/src/components/Tree/helpers.d.ts.map +1 -1
  58. package/dist/types/src/components/Tree/index.d.ts +2 -0
  59. package/dist/types/src/components/Tree/index.d.ts.map +1 -1
  60. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  61. package/dist/types/src/components/index.d.ts +4 -0
  62. package/dist/types/src/components/index.d.ts.map +1 -1
  63. package/dist/types/src/util/path.d.ts.map +1 -1
  64. package/dist/types/tsconfig.tsbuildinfo +1 -1
  65. package/package.json +22 -21
  66. package/src/components/Accordion/Accordion.stories.tsx +5 -5
  67. package/src/components/Accordion/AccordionItem.tsx +2 -5
  68. package/src/components/Combobox/Combobox.stories.tsx +60 -0
  69. package/src/components/Combobox/Combobox.tsx +388 -0
  70. package/src/components/Combobox/index.ts +5 -0
  71. package/src/components/List/List.stories.tsx +12 -12
  72. package/src/components/List/List.tsx +14 -10
  73. package/src/components/List/ListItem.tsx +55 -37
  74. package/src/components/List/ListRoot.tsx +1 -1
  75. package/src/components/List/testing.ts +4 -4
  76. package/src/components/Listbox/Listbox.stories.tsx +48 -0
  77. package/src/components/Listbox/Listbox.tsx +201 -0
  78. package/src/components/Listbox/index.ts +5 -0
  79. package/src/components/Picker/Picker.stories.tsx +131 -0
  80. package/src/components/Picker/Picker.tsx +368 -0
  81. package/src/components/Picker/context.ts +43 -0
  82. package/src/components/Picker/index.ts +6 -0
  83. package/src/components/RowList/RowList.stories.tsx +163 -0
  84. package/src/components/RowList/RowList.tsx +350 -0
  85. package/src/components/RowList/index.ts +6 -0
  86. package/src/components/Tree/Tree.stories.tsx +105 -30
  87. package/src/components/Tree/Tree.tsx +31 -41
  88. package/src/components/Tree/TreeContext.tsx +18 -9
  89. package/src/components/Tree/TreeItem.tsx +179 -108
  90. package/src/components/Tree/TreeItemHeading.tsx +5 -4
  91. package/src/components/Tree/TreeItemToggle.tsx +5 -5
  92. package/src/components/Tree/index.ts +2 -0
  93. package/src/components/Tree/testing.ts +5 -5
  94. 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,
@@ -55,7 +55,6 @@ var AccordionItemBody = ({ children, classNames }) => {
55
55
  return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Content, {
56
56
  className: "overflow-hidden data-[state=closed]:animate-slide-up data-[state=open]:animate-slide-down"
57
57
  }, /* @__PURE__ */ React2.createElement("div", {
58
- role: "none",
59
58
  className: mx2("p-2", classNames)
60
59
  }, children));
61
60
  };
@@ -68,29 +67,467 @@ var Accordion = {
68
67
  ItemBody: AccordionItemBody
69
68
  };
70
69
 
70
+ // src/components/Combobox/Combobox.tsx
71
+ import { createContext as createContext4 } from "@radix-ui/react-context";
72
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
73
+ import React4, { forwardRef as forwardRef2, useCallback as useCallback2 } from "react";
74
+ import { Button, Icon as Icon2, Popover, ScrollArea, useId } from "@dxos/react-ui";
75
+ import { composable, composableProps } from "@dxos/react-ui";
76
+ import { 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,11 @@ 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
+ className: mx5("flex w-full gap-2", classNames)
341
772
  }, children);
342
- var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
343
- className: mx3("flex grow items-center truncate", classNames),
773
+ var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React6.createElement("div", {
774
+ className: mx5("flex grow items-center truncate", classNames),
344
775
  ...props
345
776
  }, children);
346
777
 
@@ -351,31 +782,252 @@ var List = {
351
782
  ItemDragPreview: ListItemDragPreview,
352
783
  ItemWrapper: ListItemWrapper,
353
784
  ItemDragHandle: ListItemDragHandle,
785
+ ItemIconButton: ListItemIconButton,
354
786
  ItemDeleteButton: ListItemDeleteButton,
355
- ItemButton: ListItemButton,
356
787
  ItemTitle: ListItemTitle
357
788
  };
358
789
 
790
+ // src/components/Listbox/Listbox.tsx
791
+ import { createContextScope as createContextScope2 } from "@radix-ui/react-context";
792
+ import React8, { forwardRef as forwardRef3 } from "react";
793
+ import { Icon as Icon3 } from "@dxos/react-ui";
794
+ import { mx as mx6 } from "@dxos/ui-theme";
795
+
796
+ // src/components/RowList/RowList.tsx
797
+ import { useArrowNavigationGroup } from "@fluentui/react-tabster";
798
+ import { createContextScope } from "@radix-ui/react-context";
799
+ import { useControllableState as useControllableState2 } from "@radix-ui/react-use-controllable-state";
800
+ import React7, { useCallback as useCallback4 } from "react";
801
+ import { List as List2, ListItem as ListItem2 } from "@dxos/react-list";
802
+ import { ScrollArea as ScrollArea2 } from "@dxos/react-ui";
803
+ import { composable as composable2, composableProps as composableProps2 } from "@dxos/react-ui";
804
+ var ROW_LIST_NAME = "RowList";
805
+ var ROW_LIST_ROOT_NAME = "RowList.Root";
806
+ var ROW_LIST_VIEWPORT_NAME = "RowList.Viewport";
807
+ var ROW_LIST_CONTENT_NAME = "RowList.Content";
808
+ var ROW_NAME = "List.Row";
809
+ var [createRowListContext, createRowListScope] = createContextScope(ROW_LIST_NAME, []);
810
+ var [RowListProvider, useRowListContext] = createRowListContext(ROW_LIST_NAME);
811
+ var Root2 = ({ selectedId, defaultSelectedId, onSelectChange, children }) => {
812
+ const [resolved, setResolved] = useControllableState2({
813
+ prop: selectedId,
814
+ defaultProp: defaultSelectedId,
815
+ onChange: (next) => {
816
+ if (next !== void 0) {
817
+ onSelectChange?.(next);
818
+ }
819
+ }
820
+ });
821
+ const setSelected = useCallback4((id) => setResolved(id), [
822
+ setResolved
823
+ ]);
824
+ return /* @__PURE__ */ React7.createElement(RowListProvider, {
825
+ scope: void 0,
826
+ selectedId: resolved,
827
+ setSelected
828
+ }, children);
829
+ };
830
+ Root2.displayName = ROW_LIST_ROOT_NAME;
831
+ var Viewport = composable2((props, forwardedRef) => {
832
+ const { thin, padding, centered, children, ...rest } = props;
833
+ return /* @__PURE__ */ React7.createElement(ScrollArea2.Root, {
834
+ ...composableProps2(rest, {
835
+ classNames: "dx-container"
836
+ }),
837
+ thin,
838
+ padding,
839
+ centered,
840
+ orientation: "vertical",
841
+ ref: forwardedRef
842
+ }, /* @__PURE__ */ React7.createElement(ScrollArea2.Viewport, null, children));
843
+ });
844
+ Viewport.displayName = ROW_LIST_VIEWPORT_NAME;
845
+ var firstEnabledOption = (ul) => {
846
+ if (!ul) {
847
+ return null;
848
+ }
849
+ return ul.querySelector('[role="option"]:not([aria-disabled="true"])');
850
+ };
851
+ var Content2 = composable2((props, forwardedRef) => {
852
+ useRowListContext(ROW_LIST_CONTENT_NAME, void 0);
853
+ const arrowGroup = useArrowNavigationGroup({
854
+ axis: "vertical",
855
+ memorizeCurrent: true
856
+ });
857
+ const { children, ...rest } = props;
858
+ const handleFocus = useCallback4((event) => {
859
+ if (event.target !== event.currentTarget) {
860
+ return;
861
+ }
862
+ const ul = event.currentTarget;
863
+ const selected = ul.querySelector('[role="option"][aria-selected="true"]:not([aria-disabled="true"])');
864
+ const target = selected ?? firstEnabledOption(ul);
865
+ target?.focus();
866
+ }, []);
867
+ const composed = composableProps2(rest, {
868
+ classNames: "flex flex-col"
869
+ });
870
+ return /* @__PURE__ */ React7.createElement(List2, {
871
+ variant: "unordered",
872
+ ...composed,
873
+ ...arrowGroup,
874
+ role: "listbox",
875
+ onFocus: handleFocus,
876
+ ref: forwardedRef
877
+ }, children);
878
+ });
879
+ Content2.displayName = ROW_LIST_CONTENT_NAME;
880
+ var ROW_BASE = "dx-hover dx-selected px-3 py-2 cursor-pointer outline-none";
881
+ var Row = composable2((props, forwardedRef) => {
882
+ const { id, disabled, onClick, onFocus, children, ...rest } = props;
883
+ const { selectedId, setSelected } = useRowListContext(ROW_NAME, void 0);
884
+ const isSelected = selectedId === id;
885
+ const handleClick = useCallback4((event) => {
886
+ if (disabled) {
887
+ return;
888
+ }
889
+ setSelected(id);
890
+ onClick?.(event);
891
+ }, [
892
+ disabled,
893
+ id,
894
+ setSelected,
895
+ onClick
896
+ ]);
897
+ const handleFocus = useCallback4((event) => {
898
+ if (!disabled && selectedId !== id) {
899
+ setSelected(id);
900
+ }
901
+ onFocus?.(event);
902
+ }, [
903
+ disabled,
904
+ selectedId,
905
+ id,
906
+ setSelected,
907
+ onFocus
908
+ ]);
909
+ const composed = composableProps2(rest, {
910
+ classNames: [
911
+ ROW_BASE,
912
+ disabled && "opacity-50 cursor-not-allowed"
913
+ ]
914
+ });
915
+ return /* @__PURE__ */ React7.createElement(ListItem2, {
916
+ ...composed,
917
+ role: "option",
918
+ tabIndex: 0,
919
+ "aria-selected": isSelected,
920
+ "aria-disabled": disabled || void 0,
921
+ onClick: handleClick,
922
+ onFocus: handleFocus,
923
+ ref: forwardedRef
924
+ }, children);
925
+ });
926
+ Row.displayName = ROW_NAME;
927
+ var useRowListSelection = (id) => {
928
+ const { selectedId } = useRowListContext("useRowListSelection", void 0);
929
+ return selectedId === id;
930
+ };
931
+ var RowList = {
932
+ Root: Root2,
933
+ Viewport,
934
+ Content: Content2
935
+ };
936
+
937
+ // src/components/Listbox/Listbox.tsx
938
+ var commandItem = "flex items-center overflow-hidden";
939
+ var LISTBOX_NAME = "Listbox";
940
+ var LISTBOX_OPTION_NAME = "ListboxOption";
941
+ var LISTBOX_OPTION_LABEL_NAME = "ListboxOptionLabel";
942
+ var LISTBOX_OPTION_INDICATOR_NAME = "ListboxOptionIndicator";
943
+ var [createListboxContext, createListboxScope] = createContextScope2(LISTBOX_NAME, [
944
+ createRowListScope
945
+ ]);
946
+ var [createListboxOptionContext, createListboxOptionScope] = createContextScope2(LISTBOX_OPTION_NAME, [
947
+ createListboxScope
948
+ ]);
949
+ var [ListboxOptionProvider, useListboxOptionContext] = createListboxOptionContext(LISTBOX_OPTION_NAME);
950
+ var ListboxRoot = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
951
+ const { __listboxScope: _scope, children, classNames, value, defaultValue, onValueChange, autoFocus: _autoFocus, ...rootProps } = props;
952
+ return /* @__PURE__ */ React8.createElement(RowList.Root, {
953
+ selectedId: value,
954
+ defaultSelectedId: defaultValue,
955
+ onSelectChange: onValueChange
956
+ }, /* @__PURE__ */ React8.createElement(RowList.Content, {
957
+ ...rootProps,
958
+ classNames: mx6("w-full", classNames),
959
+ ref: forwardedRef
960
+ }, children));
961
+ });
962
+ ListboxRoot.displayName = LISTBOX_NAME;
963
+ var ListboxOption = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
964
+ const { __listboxScope, children, classNames, value, ...rootProps } = props;
965
+ return /* @__PURE__ */ React8.createElement(Row, {
966
+ id: value,
967
+ ...rootProps,
968
+ classNames: mx6("dx-focus-ring rounded-xs", commandItem, classNames),
969
+ ref: forwardedRef
970
+ }, /* @__PURE__ */ React8.createElement(ListboxOptionProviderHost, {
971
+ value
972
+ }, children));
973
+ });
974
+ ListboxOption.displayName = LISTBOX_OPTION_NAME;
975
+ var ListboxOptionProviderHost = ({ value, children }) => {
976
+ const isSelected = useRowListSelection(value);
977
+ return /* @__PURE__ */ React8.createElement(ListboxOptionProvider, {
978
+ scope: void 0,
979
+ value,
980
+ isSelected
981
+ }, children);
982
+ };
983
+ var ListboxOptionLabel = /* @__PURE__ */ forwardRef3(({ children, classNames, ...rootProps }, forwardedRef) => {
984
+ return /* @__PURE__ */ React8.createElement("span", {
985
+ ...rootProps,
986
+ className: mx6("grow truncate", classNames),
987
+ ref: forwardedRef
988
+ }, children);
989
+ });
990
+ ListboxOptionLabel.displayName = LISTBOX_OPTION_LABEL_NAME;
991
+ var ListboxOptionIndicator = /* @__PURE__ */ forwardRef3((props, forwardedRef) => {
992
+ const { __listboxOptionScope, classNames, ...rootProps } = props;
993
+ const { isSelected } = useListboxOptionContext(LISTBOX_OPTION_INDICATOR_NAME, __listboxOptionScope);
994
+ return /* @__PURE__ */ React8.createElement(Icon3, {
995
+ icon: "ph--check--regular",
996
+ ...rootProps,
997
+ classNames: mx6(!isSelected && "invisible", classNames),
998
+ ref: forwardedRef
999
+ });
1000
+ });
1001
+ ListboxOptionIndicator.displayName = LISTBOX_OPTION_INDICATOR_NAME;
1002
+ var Listbox = {
1003
+ Root: ListboxRoot,
1004
+ Option: ListboxOption,
1005
+ OptionLabel: ListboxOptionLabel,
1006
+ OptionIndicator: ListboxOptionIndicator
1007
+ };
1008
+
359
1009
  // src/components/Tree/Tree.tsx
360
- import React8, { useMemo as useMemo2 } from "react";
1010
+ import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
1011
+ import React12, { useMemo as useMemo3 } from "react";
361
1012
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
362
1013
 
363
1014
  // src/components/Tree/TreeContext.tsx
364
- import { createContext as createContext5, useContext } from "react";
1015
+ import { createContext as createContext7, useContext } from "react";
365
1016
  import { raise } from "@dxos/debug";
366
- var TreeContext = /* @__PURE__ */ createContext5(null);
1017
+ var TreeContext = /* @__PURE__ */ createContext7(null);
367
1018
  var TreeProvider = TreeContext.Provider;
368
1019
  var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not found"));
369
1020
 
370
1021
  // src/components/Tree/TreeItem.tsx
1022
+ import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
371
1023
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
372
1024
  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";
1025
+ import { useAtomValue } from "@effect-atom/atom-react";
374
1026
  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";
1027
+ import React11, { memo as memo3, useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState4 } from "react";
376
1028
  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";
1029
+ import { TreeItem as NaturalTreeItem, Treegrid, TREEGRID_PARENT_OF_SEPARATOR } from "@dxos/react-ui";
1030
+ import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx7 } from "@dxos/ui-theme";
379
1031
 
380
1032
  // src/components/Tree/helpers.ts
381
1033
  var DEFAULT_INDENTATION = 8;
@@ -384,19 +1036,19 @@ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
384
1036
  });
385
1037
 
386
1038
  // 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";
1039
+ import React9, { forwardRef as forwardRef4, memo, useCallback as useCallback5 } from "react";
1040
+ import { Button as Button2, Icon as Icon4, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
389
1041
  import { TextTooltip } from "@dxos/react-ui-text-tooltip";
390
1042
  import { getStyles } from "@dxos/ui-theme";
391
- var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
1043
+ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef4(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
392
1044
  const { t } = useTranslation2();
393
1045
  const styles = iconHue ? getStyles(iconHue) : void 0;
394
- const handleSelect = useCallback2((event) => {
1046
+ const handleSelect = useCallback5((event) => {
395
1047
  onSelect?.(event.altKey);
396
1048
  }, [
397
1049
  onSelect
398
1050
  ]);
399
- const handleButtonKeydown = useCallback2((event) => {
1051
+ const handleButtonKeydown = useCallback5((event) => {
400
1052
  if (event.key === " " || event.key === "Enter") {
401
1053
  event.preventDefault();
402
1054
  event.stopPropagation();
@@ -405,19 +1057,18 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
405
1057
  }, [
406
1058
  onSelect
407
1059
  ]);
408
- return /* @__PURE__ */ React5.createElement(TextTooltip, {
1060
+ return /* @__PURE__ */ React9.createElement(TextTooltip, {
409
1061
  text: toLocalizedString(label, t),
410
1062
  side: "bottom",
411
1063
  truncateQuery: "span[data-tooltip]",
412
1064
  onlyWhenTruncating: true,
413
1065
  asChild: true,
414
1066
  ref: forwardedRef
415
- }, /* @__PURE__ */ React5.createElement(Button, {
1067
+ }, /* @__PURE__ */ React9.createElement(Button2, {
416
1068
  "data-testid": "treeItem.heading",
417
1069
  variant: "ghost",
418
- density: "fine",
419
1070
  classNames: [
420
- "grow gap-2 pis-0.5 hover:bg-transparent dark:hover:bg-transparent",
1071
+ "grow gap-2 ps-0.5 hover:bg-transparent dark:hover:bg-transparent",
421
1072
  "disabled:cursor-default disabled:opacity-100",
422
1073
  className
423
1074
  ],
@@ -427,33 +1078,33 @@ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label,
427
1078
  ...current && {
428
1079
  "aria-current": "location"
429
1080
  }
430
- }, icon && /* @__PURE__ */ React5.createElement(Icon2, {
431
- icon: icon ?? "ph--placeholder--regular",
1081
+ }, icon && /* @__PURE__ */ React9.createElement(Icon4, {
432
1082
  size: 5,
1083
+ icon: icon ?? "ph--circle-dashed--regular",
433
1084
  classNames: [
434
- "mlb-1",
435
- styles?.icon
1085
+ "my-1",
1086
+ styles?.foreground
436
1087
  ]
437
- }), /* @__PURE__ */ React5.createElement("span", {
438
- className: "flex-1 is-0 truncate text-start text-sm font-normal",
1088
+ }), /* @__PURE__ */ React9.createElement("span", {
1089
+ className: "flex-1 w-0 truncate text-start font-normal",
439
1090
  "data-tooltip": true
440
1091
  }, toLocalizedString(label, t))));
441
1092
  }));
442
1093
 
443
1094
  // src/components/Tree/TreeItemToggle.tsx
444
- import React6, { forwardRef as forwardRef2, memo as memo2 } from "react";
1095
+ import React10, { forwardRef as forwardRef5, memo as memo2 } from "react";
445
1096
  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, {
1097
+ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef5(({ classNames, open, isBranch, hidden, ...props }, forwardedRef) => {
1098
+ return /* @__PURE__ */ React10.createElement(IconButton2, {
448
1099
  ref: forwardedRef,
449
1100
  "data-testid": "treeItem.toggle",
450
1101
  "aria-expanded": open,
451
1102
  variant: "ghost",
452
- density: "fine",
1103
+ density: "md",
453
1104
  classNames: [
454
- "bs-full is-6 pli-0",
455
- "[&_svg]:transition-[transform] [&_svg]:duration-200",
456
- open && "[&_svg]:rotate-90",
1105
+ "h-full w-6 px-0",
1106
+ "[&_svg]:transition-transform [&_svg]:duration-200",
1107
+ open ? "[&_svg]:rotate-90" : "[&_svg]:rotate-0",
457
1108
  hidden ? "hidden" : !isBranch && "invisible",
458
1109
  classNames
459
1110
  ],
@@ -476,26 +1127,26 @@ var TreeDataSchema = Schema.Struct({
476
1127
  item: Schema.Any
477
1128
  });
478
1129
  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
1130
+ var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: draggableProp, renderColumns: Columns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
1131
+ const rowRef = useRef3(null);
1132
+ const buttonRef = useRef3(null);
1133
+ const openRef = useRef3(false);
1134
+ const cancelExpandRef = useRef3(null);
1135
+ const [_state, setState] = useState4("idle");
1136
+ const [instruction, setInstruction] = useState4(null);
1137
+ const [menuOpen, setMenuOpen] = useState4(false);
1138
+ const { itemProps: itemPropsAtom, childIds: childIdsAtom, itemOpen: itemOpenAtom, itemCurrent: itemCurrentAtom } = useTree();
1139
+ const path = useMemo2(() => [
1140
+ ...pathProp,
1141
+ item.id
493
1142
  ], [
494
- _path,
495
- id
1143
+ pathProp,
1144
+ item.id
496
1145
  ]);
497
- const open = useIsOpen(path, item);
498
- const current = useIsCurrent(path, item);
1146
+ const { id, parentOf, draggable: itemDraggable, droppable: itemDroppable, label, className, headingClassName, icon, iconHue, disabled, testId } = useAtomValue(itemPropsAtom(path));
1147
+ const childIds = useAtomValue(childIdsAtom(item.id));
1148
+ const open = useAtomValue(itemOpenAtom(path));
1149
+ const current = useAtomValue(itemCurrentAtom(path));
499
1150
  const level = path.length - levelOffset;
500
1151
  const isBranch = !!parentOf;
501
1152
  const mode = last ? "last-in-group" : open ? "expanded" : "standard";
@@ -503,122 +1154,132 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
503
1154
  item,
504
1155
  path
505
1156
  }) ?? true;
506
- const cancelExpand = useCallback3(() => {
1157
+ const data = {
1158
+ id,
1159
+ path,
1160
+ item
1161
+ };
1162
+ const shouldSeedNativeDragData = typeof document !== "undefined" && document.body.hasAttribute("data-platform");
1163
+ const cancelExpand = useCallback6(() => {
507
1164
  if (cancelExpandRef.current) {
508
1165
  clearTimeout(cancelExpandRef.current);
509
1166
  cancelExpandRef.current = null;
510
1167
  }
511
1168
  }, []);
512
- useEffect3(() => {
513
- if (!_draggable) {
1169
+ const isItemDraggable = draggableProp && itemDraggable !== false;
1170
+ const isItemDroppable = itemDroppable !== false;
1171
+ const nativeDragText = id;
1172
+ useEffect4(() => {
1173
+ if (!draggableProp) {
514
1174
  return;
515
1175
  }
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
- }
1176
+ invariant2(buttonRef.current, void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file2, L: 70, S: void 0, A: ["buttonRef.current", ""] });
1177
+ const makeDraggable = () => draggable2({
1178
+ element: buttonRef.current,
1179
+ getInitialData: () => data,
1180
+ getInitialDataForExternal: () => {
1181
+ if (!shouldSeedNativeDragData) {
1182
+ return {};
554
1183
  }
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
1184
+ return {
1185
+ "text/plain": nativeDragText
1186
+ };
1187
+ },
1188
+ onDragStart: () => {
1189
+ setState("dragging");
1190
+ if (open) {
1191
+ openRef.current = true;
1192
+ onOpenChange?.({
1193
+ item,
1194
+ path,
1195
+ open: false
576
1196
  });
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
1197
+ }
1198
+ },
1199
+ onDrop: () => {
1200
+ setState("idle");
1201
+ if (openRef.current) {
1202
+ onOpenChange?.({
1203
+ item,
1204
+ path,
1205
+ open: true
585
1206
  });
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);
1207
+ }
1208
+ }
1209
+ });
1210
+ if (!isItemDroppable) {
1211
+ return isItemDraggable ? makeDraggable() : void 0;
1212
+ }
1213
+ const dropTarget = dropTargetForElements2({
1214
+ element: buttonRef.current,
1215
+ getData: ({ input, element }) => {
1216
+ return attachInstruction(data, {
1217
+ input,
1218
+ element,
1219
+ indentPerLevel: DEFAULT_INDENTATION,
1220
+ currentLevel: level,
1221
+ mode,
1222
+ block: isBranch ? [] : [
1223
+ "make-child"
1224
+ ]
1225
+ });
1226
+ },
1227
+ canDrop: ({ source }) => {
1228
+ const _canDrop = canDrop ?? (() => true);
1229
+ return source.element !== buttonRef.current && _canDrop({
1230
+ source: source.data,
1231
+ target: data
1232
+ });
1233
+ },
1234
+ getIsSticky: () => true,
1235
+ onDrag: ({ self, source }) => {
1236
+ const desired = extractInstruction(self.data);
1237
+ const block = desired && blockInstruction?.({
1238
+ instruction: desired,
1239
+ source: source.data,
1240
+ target: data
1241
+ });
1242
+ const instruction2 = block && desired.type !== "instruction-blocked" ? {
1243
+ type: "instruction-blocked",
1244
+ desired
1245
+ } : desired;
1246
+ if (source.data.id !== id) {
1247
+ if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
1248
+ cancelExpandRef.current = setTimeout(() => {
1249
+ onOpenChange?.({
1250
+ item,
1251
+ path,
1252
+ open: true
1253
+ });
1254
+ }, 500);
608
1255
  }
609
- },
610
- onDragLeave: () => {
611
- cancelExpand();
612
- setInstruction(null);
613
- },
614
- onDrop: () => {
615
- cancelExpand();
1256
+ if (instruction2?.type !== "make-child") {
1257
+ cancelExpand();
1258
+ }
1259
+ setInstruction(instruction2);
1260
+ } else if (instruction2?.type === "reparent") {
1261
+ setInstruction(instruction2);
1262
+ } else {
616
1263
  setInstruction(null);
617
1264
  }
618
- })
619
- );
1265
+ },
1266
+ onDragLeave: () => {
1267
+ cancelExpand();
1268
+ setInstruction(null);
1269
+ },
1270
+ onDrop: () => {
1271
+ cancelExpand();
1272
+ setInstruction(null);
1273
+ }
1274
+ });
1275
+ if (!isItemDraggable) {
1276
+ return dropTarget;
1277
+ }
1278
+ return combine2(makeDraggable(), dropTarget);
620
1279
  }, [
621
- _draggable,
1280
+ draggableProp,
1281
+ isItemDraggable,
1282
+ isItemDroppable,
622
1283
  item,
623
1284
  id,
624
1285
  mode,
@@ -627,10 +1288,10 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
627
1288
  blockInstruction,
628
1289
  canDrop
629
1290
  ]);
630
- useEffect3(() => () => cancelExpand(), [
1291
+ useEffect4(() => () => cancelExpand(), [
631
1292
  cancelExpand
632
1293
  ]);
633
- const handleOpenToggle = useCallback3(() => onOpenChange?.({
1294
+ const handleOpenToggle = useCallback6(() => onOpenChange?.({
634
1295
  item,
635
1296
  path,
636
1297
  open: !open
@@ -640,7 +1301,7 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
640
1301
  path,
641
1302
  open
642
1303
  ]);
643
- const handleSelect = useCallback3((option = false) => {
1304
+ const handleSelect = useCallback6((option = false) => {
644
1305
  if (isBranch && (option || current)) {
645
1306
  handleOpenToggle();
646
1307
  } else if (canSelectItem) {
@@ -665,7 +1326,7 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
665
1326
  handleOpenToggle,
666
1327
  onSelect
667
1328
  ]);
668
- const handleKeyDown = useCallback3((event) => {
1329
+ const handleKeyDown = useCallback6((event) => {
669
1330
  switch (event.key) {
670
1331
  case "ArrowRight":
671
1332
  case "ArrowLeft":
@@ -678,44 +1339,56 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
678
1339
  handleOpenToggle,
679
1340
  handleSelect
680
1341
  ]);
681
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
1342
+ const handleItemHover = useCallback6(() => {
1343
+ onItemHover?.({
1344
+ item
1345
+ });
1346
+ }, [
1347
+ onItemHover,
1348
+ item
1349
+ ]);
1350
+ const handleContextMenu = useCallback6((event) => {
1351
+ event.preventDefault();
1352
+ setMenuOpen(true);
1353
+ }, [
1354
+ setMenuOpen
1355
+ ]);
1356
+ const childProps = {
1357
+ draggable: draggableProp,
1358
+ renderColumns: Columns,
1359
+ blockInstruction,
1360
+ canDrop,
1361
+ canSelect,
1362
+ onItemHover,
1363
+ onOpenChange,
1364
+ onSelect
1365
+ };
1366
+ return /* @__PURE__ */ React11.createElement(React11.Fragment, null, /* @__PURE__ */ React11.createElement(Treegrid.Row, {
682
1367
  ref: rowRef,
683
1368
  key: id,
684
1369
  id,
685
1370
  "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
- ],
1371
+ parentOf: parentOf?.join(TREEGRID_PARENT_OF_SEPARATOR),
697
1372
  "data-object-id": id,
698
1373
  "data-testid": testId,
699
1374
  // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
700
1375
  // without alerting the user (except for in the correct link element). See also:
701
1376
  // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
702
1377
  "aria-current": current ? "" : void 0,
1378
+ classNames: mx7("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-current-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
703
1379
  onKeyDown: handleKeyDown,
704
- onContextMenu: (event) => {
705
- event.preventDefault();
706
- setMenuOpen(true);
707
- }
708
- }, /* @__PURE__ */ React7.createElement("div", {
709
- role: "none",
1380
+ onMouseEnter: handleItemHover,
1381
+ onContextMenu: handleContextMenu
1382
+ }, /* @__PURE__ */ React11.createElement("div", {
710
1383
  className: "indent relative grid grid-cols-subgrid col-[tree-row]",
711
1384
  style: paddingIndentation(level)
712
- }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
1385
+ }, /* @__PURE__ */ React11.createElement(Treegrid.Cell, {
713
1386
  classNames: "flex items-center"
714
- }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
1387
+ }, /* @__PURE__ */ React11.createElement(TreeItemToggle, {
715
1388
  isBranch,
716
1389
  open,
717
1390
  onClick: handleOpenToggle
718
- }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
1391
+ }), /* @__PURE__ */ React11.createElement(TreeItemHeading, {
719
1392
  disabled,
720
1393
  current,
721
1394
  label,
@@ -724,46 +1397,41 @@ var RawTreeItem = ({ item, path: _path, levelOffset = 2, last, draggable: _dragg
724
1397
  iconHue,
725
1398
  onSelect: handleSelect,
726
1399
  ref: buttonRef
727
- })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
1400
+ })), Columns && /* @__PURE__ */ React11.createElement(Columns, {
728
1401
  item,
729
1402
  path,
730
1403
  open,
731
1404
  menuOpen,
732
1405
  setMenuOpen
733
- }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
1406
+ }), instruction && /* @__PURE__ */ React11.createElement(NaturalTreeItem.DropIndicator, {
734
1407
  instruction,
735
1408
  gap: 2
736
- }))), open && items.map((item2, index) => /* @__PURE__ */ React7.createElement(TreeItem, {
737
- key: item2.id,
738
- item: item2,
1409
+ }))), open && childIds.map((childId, index) => /* @__PURE__ */ React11.createElement(TreeItemById, {
1410
+ key: childId,
1411
+ id: childId,
739
1412
  path,
740
- last: index === items.length - 1,
741
- draggable: _draggable,
742
- renderColumns: Columns,
743
- blockInstruction,
744
- canDrop,
745
- canSelect,
746
- onOpenChange,
747
- onSelect
1413
+ last: index === childIds.length - 1,
1414
+ ...childProps
748
1415
  })));
749
1416
  };
750
1417
  var TreeItem = /* @__PURE__ */ memo3(RawTreeItem);
1418
+ var RawTreeItemById = ({ id, ...props }) => {
1419
+ const { item: itemAtom } = useTree();
1420
+ const item = useAtomValue(itemAtom(id));
1421
+ if (!item) {
1422
+ return null;
1423
+ }
1424
+ return /* @__PURE__ */ React11.createElement(TreeItem, {
1425
+ item,
1426
+ ...props
1427
+ });
1428
+ };
1429
+ var TreeItemById = /* @__PURE__ */ memo3(RawTreeItemById);
751
1430
 
752
1431
  // 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 ? [
1432
+ var Tree = ({ classNames, model, rootId, path, id, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", levelOffset, renderColumns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
1433
+ const childIds = useAtomValue2(model.childIds(rootId));
1434
+ const treePath = useMemo3(() => path ? [
767
1435
  ...path,
768
1436
  id
769
1437
  ] : [
@@ -772,15 +1440,7 @@ var Tree = ({ root, path, id, useItems, getProps, useIsOpen, useIsCurrent, dragg
772
1440
  id,
773
1441
  path
774
1442
  ]);
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,
1443
+ const childProps = {
784
1444
  path: treePath,
785
1445
  levelOffset,
786
1446
  draggable: draggable3,
@@ -789,7 +1449,19 @@ var Tree = ({ root, path, id, useItems, getProps, useIsOpen, useIsCurrent, dragg
789
1449
  canDrop,
790
1450
  canSelect,
791
1451
  onOpenChange,
792
- onSelect
1452
+ onSelect,
1453
+ onItemHover
1454
+ };
1455
+ return /* @__PURE__ */ React12.createElement(Treegrid2.Root, {
1456
+ gridTemplateColumns,
1457
+ classNames
1458
+ }, /* @__PURE__ */ React12.createElement(TreeProvider, {
1459
+ value: model
1460
+ }, childIds.map((childId, index) => /* @__PURE__ */ React12.createElement(TreeItemById, {
1461
+ key: childId,
1462
+ id: childId,
1463
+ last: index === childIds.length - 1,
1464
+ ...childProps
793
1465
  }))));
794
1466
  };
795
1467
 
@@ -810,13 +1482,27 @@ var Path = {
810
1482
  };
811
1483
  export {
812
1484
  Accordion,
1485
+ Combobox,
1486
+ DEFAULT_INDENTATION,
813
1487
  List,
1488
+ Listbox,
814
1489
  Path,
1490
+ Picker,
1491
+ Row,
1492
+ RowList,
815
1493
  Tree,
816
1494
  TreeDataSchema,
817
1495
  TreeItem,
1496
+ TreeItemById,
1497
+ TreeItemToggle,
818
1498
  TreeProvider,
1499
+ createListboxScope,
1500
+ createRowListScope,
819
1501
  isTreeData,
1502
+ paddingIndentation,
1503
+ usePickerInputContext,
1504
+ usePickerItemContext,
1505
+ useRowListSelection,
820
1506
  useTree
821
1507
  };
822
1508
  //# sourceMappingURL=index.mjs.map