@dxos/react-ui-list 0.8.1 → 0.8.2-main.10c050d

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 (45) hide show
  1. package/dist/lib/browser/index.mjs +684 -597
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +684 -598
  5. package/dist/lib/node/index.cjs.map +3 -3
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +684 -597
  8. package/dist/lib/node-esm/index.mjs.map +3 -3
  9. package/dist/lib/node-esm/meta.json +1 -1
  10. package/dist/types/src/components/Accordion/Accordion.d.ts +2 -2
  11. package/dist/types/src/components/Accordion/AccordionItem.d.ts.map +1 -1
  12. package/dist/types/src/components/Accordion/AccordionRoot.d.ts.map +1 -1
  13. package/dist/types/src/components/List/List.d.ts +3 -3
  14. package/dist/types/src/components/List/List.d.ts.map +1 -1
  15. package/dist/types/src/components/List/ListItem.d.ts +1 -1
  16. package/dist/types/src/components/List/ListItem.d.ts.map +1 -1
  17. package/dist/types/src/components/List/ListRoot.d.ts +1 -1
  18. package/dist/types/src/components/List/ListRoot.d.ts.map +1 -1
  19. package/dist/types/src/components/List/testing.d.ts +10 -10
  20. package/dist/types/src/components/List/testing.d.ts.map +1 -1
  21. package/dist/types/src/components/Tree/Tree.d.ts +4 -3
  22. package/dist/types/src/components/Tree/Tree.d.ts.map +1 -1
  23. package/dist/types/src/components/Tree/Tree.stories.d.ts +2 -1
  24. package/dist/types/src/components/Tree/Tree.stories.d.ts.map +1 -1
  25. package/dist/types/src/components/Tree/TreeContext.d.ts +1 -1
  26. package/dist/types/src/components/Tree/TreeItem.d.ts +9 -9
  27. package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
  28. package/dist/types/src/components/Tree/TreeItemToggle.d.ts.map +1 -1
  29. package/dist/types/src/components/Tree/helpers.d.ts.map +1 -1
  30. package/dist/types/src/components/Tree/testing.d.ts +8 -8
  31. package/dist/types/src/components/Tree/testing.d.ts.map +1 -1
  32. package/dist/types/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +19 -18
  34. package/src/components/Accordion/Accordion.stories.tsx +2 -2
  35. package/src/components/List/List.stories.tsx +5 -5
  36. package/src/components/List/ListItem.tsx +5 -8
  37. package/src/components/List/ListRoot.tsx +3 -3
  38. package/src/components/List/testing.ts +10 -8
  39. package/src/components/Tree/Tree.stories.tsx +8 -8
  40. package/src/components/Tree/Tree.tsx +11 -6
  41. package/src/components/Tree/TreeContext.tsx +1 -1
  42. package/src/components/Tree/TreeItem.tsx +23 -21
  43. package/src/components/Tree/TreeItemToggle.tsx +1 -5
  44. package/src/components/Tree/testing.ts +8 -8
  45. package/src/util/path.ts +1 -1
@@ -1,6 +1,7 @@
1
1
  import { createRequire } from 'node:module';const require = createRequire(import.meta.url);
2
2
 
3
3
  // packages/ui/react-ui-list/src/components/Accordion/AccordionItem.tsx
4
+ import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
4
5
  import * as AccordionPrimitive2 from "@radix-ui/react-accordion";
5
6
  import { createContext as createContext2 } from "@radix-ui/react-context";
6
7
  import React2 from "react";
@@ -8,6 +9,7 @@ import { Icon } from "@dxos/react-ui";
8
9
  import { mx as mx2 } from "@dxos/react-ui-theme";
9
10
 
10
11
  // packages/ui/react-ui-list/src/components/Accordion/AccordionRoot.tsx
12
+ import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
11
13
  import * as AccordionPrimitive from "@radix-ui/react-accordion";
12
14
  import { createContext } from "@radix-ui/react-context";
13
15
  import React from "react";
@@ -16,50 +18,70 @@ var ACCORDION_NAME = "Accordion";
16
18
  var [AccordionProvider, useAccordionContext] = createContext(ACCORDION_NAME);
17
19
  var defaultGetId = (item) => item?.id;
18
20
  var AccordionRoot = ({ classNames, items, getId = defaultGetId, children, value, defaultValue, onValueChange }) => {
19
- return /* @__PURE__ */ React.createElement(AccordionProvider, {
20
- getId
21
- }, /* @__PURE__ */ React.createElement(AccordionPrimitive.Root, {
22
- type: "multiple",
23
- value,
24
- defaultValue,
25
- onValueChange,
26
- className: mx(classNames)
27
- }, children?.({
28
- items: items ?? []
29
- })));
21
+ var _effect = _useSignals();
22
+ try {
23
+ return /* @__PURE__ */ React.createElement(AccordionProvider, {
24
+ getId
25
+ }, /* @__PURE__ */ React.createElement(AccordionPrimitive.Root, {
26
+ type: "multiple",
27
+ value,
28
+ defaultValue,
29
+ onValueChange,
30
+ className: mx(classNames)
31
+ }, children?.({
32
+ items: items ?? []
33
+ })));
34
+ } finally {
35
+ _effect.f();
36
+ }
30
37
  };
31
38
 
32
39
  // packages/ui/react-ui-list/src/components/Accordion/AccordionItem.tsx
33
40
  var ACCORDION_ITEM_NAME = "AccordionItem";
34
41
  var [AccordionItemProvider, useAccordionItemContext] = createContext2(ACCORDION_ITEM_NAME);
35
42
  var AccordionItem = ({ children, classNames, item }) => {
36
- const { getId } = useAccordionContext(ACCORDION_ITEM_NAME);
37
- return /* @__PURE__ */ React2.createElement(AccordionItemProvider, {
38
- item
39
- }, /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Item, {
40
- value: getId(item),
41
- className: mx2("overflow-hidden", classNames)
42
- }, children));
43
+ var _effect = _useSignals2();
44
+ try {
45
+ const { getId } = useAccordionContext(ACCORDION_ITEM_NAME);
46
+ return /* @__PURE__ */ React2.createElement(AccordionItemProvider, {
47
+ item
48
+ }, /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Item, {
49
+ value: getId(item),
50
+ className: mx2("overflow-hidden", classNames)
51
+ }, children));
52
+ } finally {
53
+ _effect.f();
54
+ }
43
55
  };
44
56
  var AccordionItemHeader = ({ classNames, children, ...props }) => {
45
- return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Header, {
46
- ...props,
47
- className: mx2(classNames)
48
- }, /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Trigger, {
49
- className: "group flex items-center p-2 dx-focus-ring-inset is-full text-start"
50
- }, children, /* @__PURE__ */ React2.createElement(Icon, {
51
- icon: "ph--caret-right--regular",
52
- size: 4,
53
- classNames: "transition-transform duration-200 group-data-[state=open]:rotate-90"
54
- })));
57
+ var _effect = _useSignals2();
58
+ try {
59
+ return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Header, {
60
+ ...props,
61
+ className: mx2(classNames)
62
+ }, /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Trigger, {
63
+ className: "group flex items-center p-2 dx-focus-ring-inset is-full text-start"
64
+ }, children, /* @__PURE__ */ React2.createElement(Icon, {
65
+ icon: "ph--caret-right--regular",
66
+ size: 4,
67
+ classNames: "transition-transform duration-200 group-data-[state=open]:rotate-90"
68
+ })));
69
+ } finally {
70
+ _effect.f();
71
+ }
55
72
  };
56
73
  var AccordionItemBody = ({ children, classNames }) => {
57
- return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Content, {
58
- className: "overflow-hidden data-[state=closed]:animate-slideUp data-[state=open]:animate-slideDown"
59
- }, /* @__PURE__ */ React2.createElement("div", {
60
- role: "none",
61
- className: mx2("p-2", classNames)
62
- }, children));
74
+ var _effect = _useSignals2();
75
+ try {
76
+ return /* @__PURE__ */ React2.createElement(AccordionPrimitive2.Content, {
77
+ className: "overflow-hidden data-[state=closed]:animate-slideUp data-[state=open]:animate-slideDown"
78
+ }, /* @__PURE__ */ React2.createElement("div", {
79
+ role: "none",
80
+ className: mx2("p-2", classNames)
81
+ }, children));
82
+ } finally {
83
+ _effect.f();
84
+ }
63
85
  };
64
86
 
65
87
  // packages/ui/react-ui-list/src/components/Accordion/Accordion.tsx
@@ -71,6 +93,7 @@ var Accordion = {
71
93
  };
72
94
 
73
95
  // packages/ui/react-ui-list/src/components/List/ListItem.tsx
96
+ import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
74
97
  import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
75
98
  import { draggable, dropTargetForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
76
99
  import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
@@ -83,6 +106,7 @@ import { Icon as Icon2, ListItem as NaturalListItem } from "@dxos/react-ui";
83
106
  import { mx as mx3 } from "@dxos/react-ui-theme";
84
107
 
85
108
  // packages/ui/react-ui-list/src/components/List/ListRoot.tsx
109
+ import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
86
110
  import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
87
111
  import { extractClosestEdge } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
88
112
  import { getReorderDestinationIndex } from "@atlaskit/pragmatic-drag-and-drop-hitbox/util/get-reorder-destination-index";
@@ -92,63 +116,68 @@ var LIST_NAME = "List";
92
116
  var [ListProvider, useListContext] = createContext3(LIST_NAME);
93
117
  var defaultGetId2 = (item) => item?.id;
94
118
  var ListRoot = ({ children, items, isItem, getId = defaultGetId2, onMove, ...props }) => {
95
- const isEqual = useCallback((a, b) => {
96
- const idA = getId?.(a);
97
- const idB = getId?.(b);
98
- if (idA !== void 0 && idB !== void 0) {
99
- return idA === idB;
100
- } else {
101
- return a === b;
102
- }
103
- }, [
104
- getId
105
- ]);
106
- const [state, setState] = useState(idle);
107
- useEffect(() => {
108
- if (!items) {
109
- return;
110
- }
111
- return monitorForElements({
112
- canMonitor: ({ source }) => isItem(source.data),
113
- onDrop: ({ location, source }) => {
114
- const target = location.current.dropTargets[0];
115
- if (!target) {
116
- return;
117
- }
118
- const sourceData = source.data;
119
- const targetData = target.data;
120
- if (!isItem(sourceData) || !isItem(targetData)) {
121
- return;
122
- }
123
- const sourceIdx = items.findIndex((item) => isEqual(item, sourceData));
124
- const targetIdx = items.findIndex((item) => isEqual(item, targetData));
125
- if (targetIdx < 0 || sourceIdx < 0) {
126
- return;
127
- }
128
- const closestEdgeOfTarget = extractClosestEdge(targetData);
129
- const destinationIndex = getReorderDestinationIndex({
130
- closestEdgeOfTarget,
131
- startIndex: sourceIdx,
132
- indexOfTarget: targetIdx,
133
- axis: "vertical"
134
- });
135
- onMove?.(sourceIdx, destinationIndex);
119
+ var _effect = _useSignals3();
120
+ try {
121
+ const isEqual = useCallback((a, b) => {
122
+ const idA = getId?.(a);
123
+ const idB = getId?.(b);
124
+ if (idA !== void 0 && idB !== void 0) {
125
+ return idA === idB;
126
+ } else {
127
+ return a === b;
136
128
  }
137
- });
138
- }, [
139
- items,
140
- isEqual,
141
- onMove
142
- ]);
143
- return /* @__PURE__ */ React3.createElement(ListProvider, {
144
- state,
145
- setState,
146
- isItem,
147
- ...props
148
- }, children?.({
149
- state,
150
- items: items ?? []
151
- }));
129
+ }, [
130
+ getId
131
+ ]);
132
+ const [state, setState] = useState(idle);
133
+ useEffect(() => {
134
+ if (!items) {
135
+ return;
136
+ }
137
+ return monitorForElements({
138
+ canMonitor: ({ source }) => isItem?.(source.data) ?? false,
139
+ onDrop: ({ location, source }) => {
140
+ const target = location.current.dropTargets[0];
141
+ if (!target) {
142
+ return;
143
+ }
144
+ const sourceData = source.data;
145
+ const targetData = target.data;
146
+ if (!isItem?.(sourceData) || !isItem?.(targetData)) {
147
+ return;
148
+ }
149
+ const sourceIdx = items.findIndex((item) => isEqual(item, sourceData));
150
+ const targetIdx = items.findIndex((item) => isEqual(item, targetData));
151
+ if (targetIdx < 0 || sourceIdx < 0) {
152
+ return;
153
+ }
154
+ const closestEdgeOfTarget = extractClosestEdge(targetData);
155
+ const destinationIndex = getReorderDestinationIndex({
156
+ closestEdgeOfTarget,
157
+ startIndex: sourceIdx,
158
+ indexOfTarget: targetIdx,
159
+ axis: "vertical"
160
+ });
161
+ onMove?.(sourceIdx, destinationIndex);
162
+ }
163
+ });
164
+ }, [
165
+ items,
166
+ isEqual,
167
+ onMove
168
+ ]);
169
+ return /* @__PURE__ */ React3.createElement(ListProvider, {
170
+ state,
171
+ setState,
172
+ isItem,
173
+ ...props
174
+ }, children?.({
175
+ state,
176
+ items: items ?? []
177
+ }));
178
+ } finally {
179
+ _effect.f();
180
+ }
152
181
  };
153
182
 
154
183
  // packages/ui/react-ui-list/src/components/List/ListItem.tsx
@@ -163,176 +192,201 @@ var defaultContext = {};
163
192
  var LIST_ITEM_NAME = "ListItem";
164
193
  var [ListItemProvider, useListItemContext] = createContext4(LIST_ITEM_NAME, defaultContext);
165
194
  var ListItem = ({ children, classNames, item, ...props }) => {
166
- const { isItem, 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: 91,
175
- S: void 0,
176
- A: [
177
- "element",
178
- ""
179
- ]
180
- });
181
- return combine(
182
- //
183
- // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about#draggable
184
- //
185
- draggable({
186
- element,
187
- dragHandle: dragHandleRef.current,
188
- getInitialData: () => item,
189
- onGenerateDragPreview: dragPreview ? ({ nativeSetDragImage, source }) => {
190
- const rect = source.element.getBoundingClientRect();
191
- setCustomNativeDragPreview({
192
- nativeSetDragImage,
193
- getOffset: ({ container }) => {
194
- const { height } = container.getBoundingClientRect();
195
- return {
196
- x: 20,
197
- y: height / 2
198
- };
199
- },
200
- render: ({ container }) => {
201
- container.style.width = rect.width + "px";
202
- setState({
203
- type: "preview",
204
- container
205
- });
206
- setRootState({
207
- type: "preview",
208
- container,
209
- item
210
- });
211
- return () => {
212
- };
213
- }
214
- });
215
- } : void 0,
216
- onDragStart: () => {
217
- setState({
218
- type: "is-dragging"
219
- });
220
- setRootState({
221
- type: "is-dragging",
222
- item
223
- });
224
- },
225
- onDrop: () => {
226
- setState(idle);
227
- setRootState(idle);
228
- }
229
- }),
230
- //
231
- // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about#drop-target-for-elements
232
- //
233
- dropTargetForElements({
234
- element,
235
- canDrop: ({ source }) => {
236
- return source.element !== element && isItem(source.data);
237
- },
238
- getData: ({ input }) => {
239
- return attachClosestEdge(item, {
240
- element,
241
- input,
242
- allowedEdges: [
243
- "top",
244
- "bottom"
245
- ]
246
- });
247
- },
248
- getIsSticky: () => true,
249
- onDragEnter: ({ self }) => {
250
- const closestEdge = extractClosestEdge2(self.data);
251
- setState({
252
- type: "is-dragging-over",
253
- closestEdge
254
- });
255
- },
256
- onDrag: ({ self }) => {
257
- const closestEdge = extractClosestEdge2(self.data);
258
- setState((current) => {
259
- if (current.type === "is-dragging-over" && current.closestEdge === closestEdge) {
260
- return current;
261
- }
262
- return {
195
+ var _effect = _useSignals4();
196
+ try {
197
+ const { isItem, dragPreview, setState: setRootState } = useListContext(LIST_ITEM_NAME);
198
+ const ref = useRef(null);
199
+ const dragHandleRef = useRef(null);
200
+ const [state, setState] = useState2(idle);
201
+ useEffect2(() => {
202
+ const element = ref.current;
203
+ invariant(element, void 0, {
204
+ F: __dxlog_file,
205
+ L: 91,
206
+ S: void 0,
207
+ A: [
208
+ "element",
209
+ ""
210
+ ]
211
+ });
212
+ return combine(
213
+ //
214
+ // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about#draggable
215
+ //
216
+ draggable({
217
+ element,
218
+ dragHandle: dragHandleRef.current,
219
+ getInitialData: () => item,
220
+ onGenerateDragPreview: dragPreview ? ({ nativeSetDragImage, source }) => {
221
+ const rect = source.element.getBoundingClientRect();
222
+ setCustomNativeDragPreview({
223
+ nativeSetDragImage,
224
+ getOffset: ({ container }) => {
225
+ const { height } = container.getBoundingClientRect();
226
+ return {
227
+ x: 20,
228
+ y: height / 2
229
+ };
230
+ },
231
+ render: ({ container }) => {
232
+ container.style.width = rect.width + "px";
233
+ setState({
234
+ type: "preview",
235
+ container
236
+ });
237
+ setRootState({
238
+ type: "preview",
239
+ container,
240
+ item
241
+ });
242
+ return () => {
243
+ };
244
+ }
245
+ });
246
+ } : void 0,
247
+ onDragStart: () => {
248
+ setState({
249
+ type: "is-dragging"
250
+ });
251
+ setRootState({
252
+ type: "is-dragging",
253
+ item
254
+ });
255
+ },
256
+ onDrop: () => {
257
+ setState(idle);
258
+ setRootState(idle);
259
+ }
260
+ }),
261
+ //
262
+ // https://atlassian.design/components/pragmatic-drag-and-drop/core-package/adapters/element/about#drop-target-for-elements
263
+ //
264
+ dropTargetForElements({
265
+ element,
266
+ canDrop: ({ source }) => {
267
+ return (source.element !== element && isItem?.(source.data)) ?? false;
268
+ },
269
+ getData: ({ input }) => {
270
+ return attachClosestEdge(item, {
271
+ element,
272
+ input,
273
+ allowedEdges: [
274
+ "top",
275
+ "bottom"
276
+ ]
277
+ });
278
+ },
279
+ getIsSticky: () => true,
280
+ onDragEnter: ({ self }) => {
281
+ const closestEdge = extractClosestEdge2(self.data);
282
+ setState({
263
283
  type: "is-dragging-over",
264
284
  closestEdge
265
- };
266
- });
267
- },
268
- onDragLeave: () => {
269
- setState(idle);
270
- },
271
- onDrop: () => {
272
- setState(idle);
273
- }
274
- })
275
- );
276
- }, [
277
- item
278
- ]);
279
- return /* @__PURE__ */ React4.createElement(ListItemProvider, {
280
- item,
281
- dragHandleRef
282
- }, /* @__PURE__ */ React4.createElement("div", {
283
- role: "none",
284
- className: "relative"
285
- }, /* @__PURE__ */ React4.createElement("div", {
286
- ref,
287
- role: "listitem",
288
- className: mx3("flex overflow-hidden", classNames, stateStyles[state.type]),
289
- ...props
290
- }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
291
- edge: state.closestEdge
292
- })));
285
+ });
286
+ },
287
+ onDrag: ({ self }) => {
288
+ const closestEdge = extractClosestEdge2(self.data);
289
+ setState((current) => {
290
+ if (current.type === "is-dragging-over" && current.closestEdge === closestEdge) {
291
+ return current;
292
+ }
293
+ return {
294
+ type: "is-dragging-over",
295
+ closestEdge
296
+ };
297
+ });
298
+ },
299
+ onDragLeave: () => {
300
+ setState(idle);
301
+ },
302
+ onDrop: () => {
303
+ setState(idle);
304
+ }
305
+ })
306
+ );
307
+ }, [
308
+ item
309
+ ]);
310
+ return /* @__PURE__ */ React4.createElement(ListItemProvider, {
311
+ item,
312
+ dragHandleRef
313
+ }, /* @__PURE__ */ React4.createElement("div", {
314
+ role: "none",
315
+ className: "relative"
316
+ }, /* @__PURE__ */ React4.createElement("div", {
317
+ ref,
318
+ role: "listitem",
319
+ className: mx3("flex overflow-hidden", classNames, stateStyles[state.type]),
320
+ ...props
321
+ }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
322
+ edge: state.closestEdge
323
+ })));
324
+ } finally {
325
+ _effect.f();
326
+ }
293
327
  };
294
328
  var IconButton = /* @__PURE__ */ forwardRef(({ classNames, icon, ...props }, forwardedRef) => {
295
- return /* @__PURE__ */ React4.createElement("button", {
296
- ref: forwardedRef,
297
- className: mx3("flex items-center justify-center", classNames),
298
- ...props
299
- }, /* @__PURE__ */ React4.createElement(Icon2, {
300
- icon,
301
- classNames: "cursor-pointer",
302
- size: 4
303
- }));
329
+ var _effect = _useSignals4();
330
+ try {
331
+ return /* @__PURE__ */ React4.createElement("button", {
332
+ ref: forwardedRef,
333
+ className: mx3("flex items-center justify-center", classNames),
334
+ ...props
335
+ }, /* @__PURE__ */ React4.createElement(Icon2, {
336
+ icon,
337
+ classNames: "cursor-pointer",
338
+ size: 4
339
+ }));
340
+ } finally {
341
+ _effect.f();
342
+ }
304
343
  });
305
344
  var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph--x--regular", ...props }) => {
306
- const { state } = useListContext("DELETE_BUTTON");
307
- const isDisabled = state.type !== "idle" || disabled;
308
- return /* @__PURE__ */ React4.createElement(IconButton, {
309
- icon,
310
- disabled: isDisabled,
311
- classNames: [
312
- classNames,
313
- autoHide && disabled && "hidden"
314
- ],
315
- ...props
316
- });
345
+ var _effect = _useSignals4();
346
+ try {
347
+ const { state } = useListContext("DELETE_BUTTON");
348
+ const isDisabled = state.type !== "idle" || disabled;
349
+ return /* @__PURE__ */ React4.createElement(IconButton, {
350
+ icon,
351
+ disabled: isDisabled,
352
+ classNames: [
353
+ classNames,
354
+ autoHide && disabled && "hidden"
355
+ ],
356
+ ...props
357
+ });
358
+ } finally {
359
+ _effect.f();
360
+ }
317
361
  };
318
362
  var ListItemButton = ({ autoHide = true, classNames, disabled, ...props }) => {
319
- const { state } = useListContext("ITEM_BUTTON");
320
- const isDisabled = state.type !== "idle" || disabled;
321
- return /* @__PURE__ */ React4.createElement(IconButton, {
322
- disabled: isDisabled,
323
- classNames: [
324
- classNames,
325
- autoHide && disabled && "hidden"
326
- ],
327
- ...props
328
- });
363
+ var _effect = _useSignals4();
364
+ try {
365
+ const { state } = useListContext("ITEM_BUTTON");
366
+ const isDisabled = state.type !== "idle" || disabled;
367
+ return /* @__PURE__ */ React4.createElement(IconButton, {
368
+ disabled: isDisabled,
369
+ classNames: [
370
+ classNames,
371
+ autoHide && disabled && "hidden"
372
+ ],
373
+ ...props
374
+ });
375
+ } finally {
376
+ _effect.f();
377
+ }
329
378
  };
330
379
  var ListItemDragHandle = () => {
331
- const { dragHandleRef } = useListItemContext("DRAG_HANDLE");
332
- return /* @__PURE__ */ React4.createElement(IconButton, {
333
- ref: dragHandleRef,
334
- icon: "ph--dots-six-vertical--regular"
335
- });
380
+ var _effect = _useSignals4();
381
+ try {
382
+ const { dragHandleRef } = useListItemContext("DRAG_HANDLE");
383
+ return /* @__PURE__ */ React4.createElement(IconButton, {
384
+ ref: dragHandleRef,
385
+ icon: "ph--dots-six-vertical--regular"
386
+ });
387
+ } finally {
388
+ _effect.f();
389
+ }
336
390
  };
337
391
  var ListItemDragPreview = ({ children }) => {
338
392
  const { state } = useListContext("DRAG_PREVIEW");
@@ -340,13 +394,27 @@ var ListItemDragPreview = ({ children }) => {
340
394
  item: state.item
341
395
  }), state.container) : null;
342
396
  };
343
- var ListItemWrapper = ({ classNames, children }) => /* @__PURE__ */ React4.createElement("div", {
344
- className: mx3("flex is-full gap-2", classNames)
345
- }, children);
346
- var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
347
- className: mx3("flex grow items-center truncate", classNames),
348
- ...props
349
- }, children);
397
+ var ListItemWrapper = ({ classNames, children }) => {
398
+ var _effect = _useSignals4();
399
+ try {
400
+ return /* @__PURE__ */ React4.createElement("div", {
401
+ className: mx3("flex is-full gap-2", classNames)
402
+ }, children);
403
+ } finally {
404
+ _effect.f();
405
+ }
406
+ };
407
+ var ListItemTitle = ({ classNames, children, ...props }) => {
408
+ var _effect = _useSignals4();
409
+ try {
410
+ return /* @__PURE__ */ React4.createElement("div", {
411
+ className: mx3("flex grow items-center truncate", classNames),
412
+ ...props
413
+ }, children);
414
+ } finally {
415
+ _effect.f();
416
+ }
417
+ };
350
418
 
351
419
  // packages/ui/react-ui-list/src/components/List/List.tsx
352
420
  var List = {
@@ -362,6 +430,7 @@ var List = {
362
430
  };
363
431
 
364
432
  // packages/ui/react-ui-list/src/components/Tree/Tree.tsx
433
+ import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
365
434
  import React8, { useMemo as useMemo2 } from "react";
366
435
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
367
436
 
@@ -373,82 +442,95 @@ var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not
373
442
  var TreeProvider = TreeContext.Provider;
374
443
 
375
444
  // packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx
445
+ import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
376
446
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
377
447
  import { draggable as draggable2, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
378
448
  import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
449
+ import { Schema } from "effect";
379
450
  import React7, { memo as memo3, useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
380
- import { S } from "@dxos/echo-schema";
381
451
  import { invariant as invariant2 } from "@dxos/invariant";
382
452
  import { Treegrid, TreeItem as NaturalTreeItem } from "@dxos/react-ui";
383
453
  import { ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx6 } from "@dxos/react-ui-theme";
384
454
 
385
455
  // packages/ui/react-ui-list/src/components/Tree/TreeItemHeading.tsx
456
+ import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
386
457
  import React5, { forwardRef as forwardRef2, memo, useCallback as useCallback2 } from "react";
387
458
  import { Button, Icon as Icon3, toLocalizedString, useTranslation } from "@dxos/react-ui";
388
459
  import { TextTooltip } from "@dxos/react-ui-text-tooltip";
389
460
  import { mx as mx4 } from "@dxos/react-ui-theme";
390
461
  var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ label, icon, className, disabled, current, onSelect }, forwardedRef) => {
391
- const { t } = useTranslation();
392
- const handleSelect = useCallback2((event) => {
393
- onSelect?.(event.altKey);
394
- }, [
395
- onSelect
396
- ]);
397
- const handleButtonKeydown = useCallback2((event) => {
398
- if (event.key === " " || event.key === "Enter") {
399
- event.preventDefault();
400
- event.stopPropagation();
462
+ var _effect = _useSignals5();
463
+ try {
464
+ const { t } = useTranslation();
465
+ const handleSelect = useCallback2((event) => {
401
466
  onSelect?.(event.altKey);
402
- }
403
- }, [
404
- onSelect
405
- ]);
406
- return /* @__PURE__ */ React5.createElement(TextTooltip, {
407
- text: toLocalizedString(label, t),
408
- side: "bottom",
409
- truncateQuery: "span[data-tooltip]",
410
- onlyWhenTruncating: true,
411
- asChild: true,
412
- ref: forwardedRef
413
- }, /* @__PURE__ */ React5.createElement(Button, {
414
- "data-testid": "treeItem.heading",
415
- variant: "ghost",
416
- density: "fine",
417
- classNames: mx4("grow gap-2 pis-0.5 hover:bg-transparent dark:hover:bg-transparent", "disabled:cursor-default disabled:opacity-100", className),
418
- disabled,
419
- onClick: handleSelect,
420
- onKeyDown: handleButtonKeydown,
421
- ...current && {
422
- "aria-current": "location"
423
- }
424
- }, icon && /* @__PURE__ */ React5.createElement(Icon3, {
425
- icon: icon ?? "ph--placeholder--regular",
426
- size: 5,
427
- classNames: "mlb-1"
428
- }), /* @__PURE__ */ React5.createElement("span", {
429
- className: "flex-1 is-0 truncate text-start text-sm font-normal",
430
- "data-tooltip": true
431
- }, toLocalizedString(label, t))));
467
+ }, [
468
+ onSelect
469
+ ]);
470
+ const handleButtonKeydown = useCallback2((event) => {
471
+ if (event.key === " " || event.key === "Enter") {
472
+ event.preventDefault();
473
+ event.stopPropagation();
474
+ onSelect?.(event.altKey);
475
+ }
476
+ }, [
477
+ onSelect
478
+ ]);
479
+ return /* @__PURE__ */ React5.createElement(TextTooltip, {
480
+ text: toLocalizedString(label, t),
481
+ side: "bottom",
482
+ truncateQuery: "span[data-tooltip]",
483
+ onlyWhenTruncating: true,
484
+ asChild: true,
485
+ ref: forwardedRef
486
+ }, /* @__PURE__ */ React5.createElement(Button, {
487
+ "data-testid": "treeItem.heading",
488
+ variant: "ghost",
489
+ density: "fine",
490
+ classNames: mx4("grow gap-2 pis-0.5 hover:bg-transparent dark:hover:bg-transparent", "disabled:cursor-default disabled:opacity-100", className),
491
+ disabled,
492
+ onClick: handleSelect,
493
+ onKeyDown: handleButtonKeydown,
494
+ ...current && {
495
+ "aria-current": "location"
496
+ }
497
+ }, icon && /* @__PURE__ */ React5.createElement(Icon3, {
498
+ icon: icon ?? "ph--placeholder--regular",
499
+ size: 5,
500
+ classNames: "mlb-1"
501
+ }), /* @__PURE__ */ React5.createElement("span", {
502
+ className: "flex-1 is-0 truncate text-start text-sm font-normal",
503
+ "data-tooltip": true
504
+ }, toLocalizedString(label, t))));
505
+ } finally {
506
+ _effect.f();
507
+ }
432
508
  }));
433
509
 
434
510
  // packages/ui/react-ui-list/src/components/Tree/TreeItemToggle.tsx
511
+ import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
435
512
  import React6, { forwardRef as forwardRef3, memo as memo2 } from "react";
436
513
  import { Button as Button2, Icon as Icon4 } from "@dxos/react-ui";
437
514
  import { mx as mx5 } from "@dxos/react-ui-theme";
438
515
  var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef3(({ open, isBranch, hidden, onToggle }, forwardedRef) => {
439
- return /* @__PURE__ */ React6.createElement(Button2, {
440
- ref: forwardedRef,
441
- "data-testid": "treeItem.toggle",
442
- "aria-expanded": open,
443
- variant: "ghost",
444
- density: "fine",
445
- classNames: mx5("is-6 pli-0 dx-focus-ring-inset", hidden ? "hidden" : !isBranch && "invisible"),
446
- onClick: onToggle
447
- }, /* @__PURE__ */ React6.createElement(Icon4, {
448
- icon: "ph--caret-right--regular",
449
- size: 3,
450
- classNames: mx5("transition duration-200", open && "rotate-90")
451
- }));
516
+ var _effect = _useSignals6();
517
+ try {
518
+ return /* @__PURE__ */ React6.createElement(Button2, {
519
+ ref: forwardedRef,
520
+ "data-testid": "treeItem.toggle",
521
+ "aria-expanded": open,
522
+ variant: "ghost",
523
+ density: "fine",
524
+ classNames: mx5("is-6 pli-0 dx-focus-ring-inset", hidden ? "hidden" : !isBranch && "invisible"),
525
+ onClick: onToggle
526
+ }, /* @__PURE__ */ React6.createElement(Icon4, {
527
+ icon: "ph--caret-right--bold",
528
+ size: 3,
529
+ classNames: mx5("transition duration-200", open && "rotate-90")
530
+ }));
531
+ } finally {
532
+ _effect.f();
533
+ }
452
534
  }));
453
535
 
454
536
  // packages/ui/react-ui-list/src/components/Tree/helpers.ts
@@ -460,305 +542,311 @@ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
460
542
  // packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx
461
543
  var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx";
462
544
  var hoverableDescriptionIcons = "[--icons-color:inherit] hover-hover:[--icons-color:var(--description-text)] hover-hover:hover:[--icons-color:inherit] focus-within:[--icons-color:inherit]";
463
- var TreeDataSchema = S.Struct({
464
- id: S.String,
465
- path: S.Array(S.String),
466
- item: S.Any
545
+ var TreeDataSchema = Schema.Struct({
546
+ id: Schema.String,
547
+ path: Schema.Array(Schema.String),
548
+ item: Schema.Any
467
549
  });
468
- var isTreeData = (data) => S.is(TreeDataSchema)(data);
550
+ var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
469
551
  var RawTreeItem = ({ item, path: _path, last, draggable: _draggable, renderColumns: Columns, canDrop, onOpenChange, onSelect, levelOffset = 2 }) => {
470
- const { getItems, getProps, isOpen, isCurrent } = useTree();
471
- const items = getItems(item);
472
- const { id, label, parentOf, icon, disabled, className, headingClassName, testId } = getProps(item, _path);
473
- const path = useMemo(() => [
474
- ..._path,
475
- id
476
- ], [
477
- _path,
478
- id
479
- ]);
480
- const open = isOpen(path, item);
481
- const current = isCurrent(path, item);
482
- const level = path.length - levelOffset;
483
- const isBranch = !!parentOf;
484
- const mode = last ? "last-in-group" : open ? "expanded" : "standard";
485
- const data = useMemo(() => ({
486
- id,
487
- path,
488
- item
489
- }), [
490
- id,
491
- path,
492
- item
493
- ]);
494
- const rowRef = useRef2(null);
495
- const buttonRef = useRef2(null);
496
- const openRef = useRef2(false);
497
- const cancelExpandRef = useRef2(null);
498
- const [_state, setState] = useState3("idle");
499
- const [instruction, setInstruction] = useState3(null);
500
- const [menuOpen, setMenuOpen] = useState3(false);
501
- const cancelExpand = useCallback3(() => {
502
- if (cancelExpandRef.current) {
503
- clearTimeout(cancelExpandRef.current);
504
- cancelExpandRef.current = null;
505
- }
506
- }, []);
507
- useEffect3(() => {
508
- if (!_draggable) {
509
- return;
510
- }
511
- invariant2(buttonRef.current, void 0, {
512
- F: __dxlog_file2,
513
- L: 106,
514
- S: void 0,
515
- A: [
516
- "buttonRef.current",
517
- ""
518
- ]
519
- });
520
- return combine2(
521
- draggable2({
522
- element: buttonRef.current,
523
- getInitialData: () => data,
524
- onDragStart: () => {
525
- setState("dragging");
526
- if (open) {
527
- openRef.current = true;
528
- onOpenChange?.({
529
- item,
530
- path,
531
- open: false
532
- });
552
+ var _effect = _useSignals7();
553
+ try {
554
+ const rowRef = useRef2(null);
555
+ const buttonRef = useRef2(null);
556
+ const openRef = useRef2(false);
557
+ const cancelExpandRef = useRef2(null);
558
+ const [_state, setState] = useState3("idle");
559
+ const [instruction, setInstruction] = useState3(null);
560
+ const [menuOpen, setMenuOpen] = useState3(false);
561
+ const { useItems, getProps, isOpen, isCurrent } = useTree();
562
+ const items = useItems(item);
563
+ const { id, label, parentOf, icon, disabled, className, headingClassName, testId } = getProps(item, _path);
564
+ const path = useMemo(() => [
565
+ ..._path,
566
+ id
567
+ ], [
568
+ _path,
569
+ id
570
+ ]);
571
+ const open = isOpen(path, item);
572
+ const current = isCurrent(path, item);
573
+ const level = path.length - levelOffset;
574
+ const isBranch = !!parentOf;
575
+ const mode = last ? "last-in-group" : open ? "expanded" : "standard";
576
+ const cancelExpand = useCallback3(() => {
577
+ if (cancelExpandRef.current) {
578
+ clearTimeout(cancelExpandRef.current);
579
+ cancelExpandRef.current = null;
580
+ }
581
+ }, []);
582
+ useEffect3(() => {
583
+ if (!_draggable) {
584
+ return;
585
+ }
586
+ invariant2(buttonRef.current, void 0, {
587
+ F: __dxlog_file2,
588
+ L: 106,
589
+ S: void 0,
590
+ A: [
591
+ "buttonRef.current",
592
+ ""
593
+ ]
594
+ });
595
+ const data = {
596
+ id,
597
+ path,
598
+ item
599
+ };
600
+ return combine2(
601
+ draggable2({
602
+ element: buttonRef.current,
603
+ getInitialData: () => data,
604
+ onDragStart: () => {
605
+ setState("dragging");
606
+ if (open) {
607
+ openRef.current = true;
608
+ onOpenChange?.({
609
+ item,
610
+ path,
611
+ open: false
612
+ });
613
+ }
614
+ },
615
+ onDrop: () => {
616
+ setState("idle");
617
+ if (openRef.current) {
618
+ onOpenChange?.({
619
+ item,
620
+ path,
621
+ open: true
622
+ });
623
+ }
533
624
  }
534
- },
535
- onDrop: () => {
536
- setState("idle");
537
- if (openRef.current) {
538
- onOpenChange?.({
539
- item,
540
- path,
541
- open: true
625
+ }),
626
+ // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
627
+ dropTargetForElements2({
628
+ element: buttonRef.current,
629
+ getData: ({ input, element }) => {
630
+ return attachInstruction(data, {
631
+ input,
632
+ element,
633
+ indentPerLevel: DEFAULT_INDENTATION,
634
+ currentLevel: level,
635
+ mode,
636
+ block: isBranch ? [] : [
637
+ "make-child"
638
+ ]
542
639
  });
543
- }
544
- }
545
- }),
546
- // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
547
- dropTargetForElements2({
548
- element: buttonRef.current,
549
- getData: ({ input, element }) => {
550
- return attachInstruction(data, {
551
- input,
552
- element,
553
- indentPerLevel: DEFAULT_INDENTATION,
554
- currentLevel: level,
555
- mode,
556
- block: isBranch ? [] : [
557
- "make-child"
558
- ]
559
- });
560
- },
561
- canDrop: ({ source }) => {
562
- const _canDrop = canDrop ?? (() => true);
563
- return source.element !== buttonRef.current && _canDrop(source.data, data);
564
- },
565
- getIsSticky: () => true,
566
- onDrag: ({ self, source }) => {
567
- const instruction2 = extractInstruction(self.data);
568
- if (source.data.id !== id) {
569
- if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
570
- cancelExpandRef.current = setTimeout(() => {
571
- onOpenChange?.({
572
- item,
573
- path,
574
- open: true
575
- });
576
- }, 500);
577
- }
578
- if (instruction2?.type !== "make-child") {
579
- cancelExpand();
640
+ },
641
+ canDrop: ({ source }) => {
642
+ const _canDrop = canDrop ?? (() => true);
643
+ return source.element !== buttonRef.current && _canDrop(source.data, data);
644
+ },
645
+ getIsSticky: () => true,
646
+ onDrag: ({ self, source }) => {
647
+ const instruction2 = extractInstruction(self.data);
648
+ if (source.data.id !== id) {
649
+ if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
650
+ cancelExpandRef.current = setTimeout(() => {
651
+ onOpenChange?.({
652
+ item,
653
+ path,
654
+ open: true
655
+ });
656
+ }, 500);
657
+ }
658
+ if (instruction2?.type !== "make-child") {
659
+ cancelExpand();
660
+ }
661
+ setInstruction(instruction2);
662
+ } else if (instruction2?.type === "reparent") {
663
+ setInstruction(instruction2);
664
+ } else {
665
+ setInstruction(null);
580
666
  }
581
- setInstruction(instruction2);
582
- } else if (instruction2?.type === "reparent") {
583
- setInstruction(instruction2);
584
- } else {
667
+ },
668
+ onDragLeave: () => {
669
+ cancelExpand();
670
+ setInstruction(null);
671
+ },
672
+ onDrop: () => {
673
+ cancelExpand();
585
674
  setInstruction(null);
586
675
  }
587
- },
588
- onDragLeave: () => {
589
- cancelExpand();
590
- setInstruction(null);
591
- },
592
- onDrop: () => {
593
- cancelExpand();
594
- setInstruction(null);
595
- }
596
- })
597
- );
598
- }, [
599
- _draggable,
600
- item,
601
- id,
602
- mode,
603
- path,
604
- open,
605
- canDrop
606
- ]);
607
- useEffect3(() => () => cancelExpand(), [
608
- cancelExpand
609
- ]);
610
- const handleOpenChange = useCallback3(() => onOpenChange?.({
611
- item,
612
- path,
613
- open: !open
614
- }), [
615
- onOpenChange,
616
- item,
617
- path,
618
- open
619
- ]);
620
- const handleSelect = useCallback3((option = false) => {
621
- if (isBranch) {
622
- handleOpenChange();
623
- } else {
624
- rowRef.current?.focus();
625
- onSelect?.({
626
- item,
627
- path,
628
- current: !current,
629
- option
630
- });
631
- }
632
- }, [
633
- item,
634
- path,
635
- current,
636
- isBranch,
637
- handleOpenChange,
638
- onSelect
639
- ]);
640
- const handleKeyDown = useCallback3((event) => {
641
- switch (event.key) {
642
- case "ArrowRight":
643
- isBranch && !open && handleOpenChange();
644
- break;
645
- case "ArrowLeft":
646
- isBranch && open && handleOpenChange();
647
- break;
648
- case " ":
649
- handleSelect(event.altKey);
650
- break;
651
- }
652
- }, [
653
- isBranch,
654
- open,
655
- handleOpenChange,
656
- handleSelect
657
- ]);
658
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
659
- ref: rowRef,
660
- key: id,
661
- id,
662
- "aria-labelledby": `${id}__label`,
663
- parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
664
- classNames: mx6("grid grid-cols-subgrid col-[tree-row] mbs-0.5 aria-[current]:bg-groupSurface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostHover, className),
665
- "data-itemid": id,
666
- "data-testid": testId,
667
- // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
668
- // without alerting the user (except for in the correct link element). See also:
669
- // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
670
- "aria-current": current ? "" : void 0,
671
- onKeyDown: handleKeyDown,
672
- onContextMenu: (event) => {
673
- event.preventDefault();
674
- setMenuOpen(true);
675
- }
676
- }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
677
- indent: true,
678
- classNames: "relative grid grid-cols-subgrid col-[tree-row]",
679
- style: paddingIndentation(level)
680
- }, /* @__PURE__ */ React7.createElement("div", {
681
- role: "none",
682
- className: "flex items-center"
683
- }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
684
- isBranch,
685
- open,
686
- onToggle: handleOpenChange
687
- }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
688
- ref: buttonRef,
689
- label,
690
- icon,
691
- className: headingClassName,
692
- disabled,
693
- current,
694
- onSelect: handleSelect
695
- })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
696
- item,
697
- path,
698
- open,
699
- menuOpen,
700
- setMenuOpen
701
- }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
702
- instruction,
703
- gap: 2
704
- }))), open && items.map((item2, index) => /* @__PURE__ */ React7.createElement(TreeItem, {
705
- key: item2.id,
706
- item: item2,
707
- path,
708
- last: index === items.length - 1,
709
- draggable: _draggable,
710
- renderColumns: Columns,
711
- canDrop,
712
- onOpenChange,
713
- onSelect
714
- })));
676
+ })
677
+ );
678
+ }, [
679
+ _draggable,
680
+ item,
681
+ id,
682
+ mode,
683
+ path,
684
+ open,
685
+ canDrop
686
+ ]);
687
+ useEffect3(() => () => cancelExpand(), [
688
+ cancelExpand
689
+ ]);
690
+ const handleOpenChange = useCallback3(() => onOpenChange?.({
691
+ item,
692
+ path,
693
+ open: !open
694
+ }), [
695
+ onOpenChange,
696
+ item,
697
+ path,
698
+ open
699
+ ]);
700
+ const handleSelect = useCallback3((option = false) => {
701
+ if (isBranch) {
702
+ handleOpenChange();
703
+ } else {
704
+ rowRef.current?.focus();
705
+ onSelect?.({
706
+ item,
707
+ path,
708
+ current: !current,
709
+ option
710
+ });
711
+ }
712
+ }, [
713
+ item,
714
+ path,
715
+ current,
716
+ isBranch,
717
+ handleOpenChange,
718
+ onSelect
719
+ ]);
720
+ const handleKeyDown = useCallback3((event) => {
721
+ switch (event.key) {
722
+ case "ArrowRight":
723
+ isBranch && !open && handleOpenChange();
724
+ break;
725
+ case "ArrowLeft":
726
+ isBranch && open && handleOpenChange();
727
+ break;
728
+ case " ":
729
+ handleSelect(event.altKey);
730
+ break;
731
+ }
732
+ }, [
733
+ isBranch,
734
+ open,
735
+ handleOpenChange,
736
+ handleSelect
737
+ ]);
738
+ return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
739
+ ref: rowRef,
740
+ key: id,
741
+ id,
742
+ "aria-labelledby": `${id}__label`,
743
+ parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
744
+ classNames: mx6("grid grid-cols-subgrid col-[tree-row] mbs-0.5 aria-[current]:bg-activeSurface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostHover, className),
745
+ "data-itemid": id,
746
+ "data-testid": testId,
747
+ // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
748
+ // without alerting the user (except for in the correct link element). See also:
749
+ // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
750
+ "aria-current": current ? "" : void 0,
751
+ onKeyDown: handleKeyDown,
752
+ onContextMenu: (event) => {
753
+ event.preventDefault();
754
+ setMenuOpen(true);
755
+ }
756
+ }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
757
+ indent: true,
758
+ classNames: "relative grid grid-cols-subgrid col-[tree-row]",
759
+ style: paddingIndentation(level)
760
+ }, /* @__PURE__ */ React7.createElement("div", {
761
+ role: "none",
762
+ className: "flex items-center"
763
+ }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
764
+ isBranch,
765
+ open,
766
+ onToggle: handleOpenChange
767
+ }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
768
+ ref: buttonRef,
769
+ label,
770
+ icon,
771
+ className: headingClassName,
772
+ disabled,
773
+ current,
774
+ onSelect: handleSelect
775
+ })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
776
+ item,
777
+ path,
778
+ open,
779
+ menuOpen,
780
+ setMenuOpen
781
+ }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
782
+ instruction,
783
+ gap: 2
784
+ }))), open && items.map((item2, index) => /* @__PURE__ */ React7.createElement(TreeItem, {
785
+ key: item2.id,
786
+ item: item2,
787
+ path,
788
+ last: index === items.length - 1,
789
+ draggable: _draggable,
790
+ renderColumns: Columns,
791
+ canDrop,
792
+ onOpenChange,
793
+ onSelect
794
+ })));
795
+ } finally {
796
+ _effect.f();
797
+ }
715
798
  };
716
799
  var TreeItem = /* @__PURE__ */ memo3(RawTreeItem);
717
800
 
718
801
  // packages/ui/react-ui-list/src/components/Tree/Tree.tsx
719
- var Tree = ({ root, path, id, getItems, getProps, isOpen, isCurrent, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", classNames, renderColumns, canDrop, onOpenChange, onSelect, levelOffset }) => {
720
- const context = useMemo2(() => ({
721
- getItems,
722
- getProps,
723
- isOpen,
724
- isCurrent
725
- }), [
726
- getItems,
727
- getProps,
728
- isOpen,
729
- isCurrent
730
- ]);
731
- const items = getItems(root);
732
- const treePath = useMemo2(() => path ? [
733
- ...path,
734
- id
735
- ] : [
736
- id
737
- ], [
738
- id,
739
- path
740
- ]);
741
- return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
742
- gridTemplateColumns,
743
- classNames
744
- }, /* @__PURE__ */ React8.createElement(TreeProvider, {
745
- value: context
746
- }, items.map((item, index) => /* @__PURE__ */ React8.createElement(TreeItem, {
747
- key: item.id,
748
- item,
749
- last: index === items.length - 1,
750
- path: treePath,
751
- levelOffset,
752
- draggable: draggable3,
753
- renderColumns,
754
- canDrop,
755
- onOpenChange,
756
- onSelect
757
- }))));
802
+ var Tree = ({ root, path, id, useItems, getProps, isOpen, isCurrent, draggable: draggable3 = false, gridTemplateColumns = "[tree-row-start] 1fr min-content [tree-row-end]", classNames, renderColumns, canDrop, onOpenChange, onSelect, levelOffset }) => {
803
+ var _effect = _useSignals8();
804
+ try {
805
+ const context = useMemo2(() => ({
806
+ useItems,
807
+ getProps,
808
+ isOpen,
809
+ isCurrent
810
+ }), [
811
+ useItems,
812
+ getProps,
813
+ isOpen,
814
+ isCurrent
815
+ ]);
816
+ const items = useItems(root);
817
+ const treePath = useMemo2(() => path ? [
818
+ ...path,
819
+ id
820
+ ] : [
821
+ id
822
+ ], [
823
+ id,
824
+ path
825
+ ]);
826
+ return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
827
+ gridTemplateColumns,
828
+ classNames
829
+ }, /* @__PURE__ */ React8.createElement(TreeProvider, {
830
+ value: context
831
+ }, items.map((item, index) => /* @__PURE__ */ React8.createElement(TreeItem, {
832
+ key: item.id,
833
+ item,
834
+ last: index === items.length - 1,
835
+ path: treePath,
836
+ levelOffset,
837
+ draggable: draggable3,
838
+ renderColumns,
839
+ canDrop,
840
+ onOpenChange,
841
+ onSelect
842
+ }))));
843
+ } finally {
844
+ _effect.f();
845
+ }
758
846
  };
759
847
 
760
848
  // packages/ui/react-ui-list/src/util/path.ts
761
- var SEPARATOR = "~";
849
+ var SEPARATOR = "+";
762
850
  var Path = {
763
851
  create: (...args) => args.join(SEPARATOR),
764
852
  parts: (path) => path.split(SEPARATOR),
@@ -776,7 +864,6 @@ export {
776
864
  Accordion,
777
865
  List,
778
866
  Path,
779
- RawTreeItem,
780
867
  Tree,
781
868
  TreeDataSchema,
782
869
  TreeItem,