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

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