@dxos/react-ui-list 0.8.4-main.b97322e → 0.8.4-main.bc674ce

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