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

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