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