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

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 (55) hide show
  1. package/dist/lib/browser/index.mjs +675 -730
  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 +675 -730
  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 +5 -8
  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 -30
  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 +43 -29
  42. package/src/components/List/List.tsx +2 -5
  43. package/src/components/List/ListItem.tsx +49 -35
  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 +102 -85
  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 +66 -54
  50. package/src/components/Tree/TreeItemHeading.tsx +11 -9
  51. package/src/components/Tree/TreeItemToggle.tsx +29 -19
  52. package/src/components/Tree/testing.ts +5 -4
  53. package/dist/lib/node/index.cjs +0 -886
  54. package/dist/lib/node/index.cjs.map +0 -7
  55. package/dist/lib/node/meta.json +0 -1
@@ -1,88 +1,66 @@
1
- // packages/ui/react-ui-list/src/components/Accordion/AccordionItem.tsx
2
- import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
1
+ // src/components/Accordion/AccordionItem.tsx
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
- // packages/ui/react-ui-list/src/components/Accordion/AccordionRoot.tsx
10
- import { useSignals as _useSignals } from "@preact-signals/safe-react/tracking";
8
+ // src/components/Accordion/AccordionRoot.tsx
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
- // packages/ui/react-ui-list/src/components/Accordion/AccordionItem.tsx
30
+ // src/components/Accordion/AccordionItem.tsx
38
31
  var ACCORDION_ITEM_NAME = "AccordionItem";
39
- var [AccordionItemProvider, useAccordionItemContext] = createContext2(ACCORDION_ITEM_NAME);
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
- // packages/ui/react-ui-list/src/components/Accordion/Accordion.tsx
63
+ // src/components/Accordion/Accordion.tsx
86
64
  var Accordion = {
87
65
  Root: AccordionRoot,
88
66
  Item: AccordionItem,
@@ -90,21 +68,19 @@ var Accordion = {
90
68
  ItemBody: AccordionItemBody
91
69
  };
92
70
 
93
- // packages/ui/react-ui-list/src/components/List/ListItem.tsx
94
- import { useSignals as _useSignals4 } from "@preact-signals/safe-react/tracking";
71
+ // src/components/List/ListItem.tsx
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";
98
75
  import { attachClosestEdge, extractClosestEdge as extractClosestEdge2 } from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
99
76
  import { createContext as createContext4 } from "@radix-ui/react-context";
100
- import React4, { forwardRef, useEffect as useEffect2, useRef, useState as useState2 } from "react";
77
+ import React4, { useEffect as useEffect2, useRef, useState as useState2 } from "react";
101
78
  import { createPortal } from "react-dom";
102
79
  import { invariant } from "@dxos/invariant";
103
- import { Icon as Icon2, ListItem as NaturalListItem } from "@dxos/react-ui";
104
- import { mx as mx3 } from "@dxos/react-ui-theme";
80
+ import { IconButton, ListItem as NaturalListItem, useTranslation } from "@dxos/react-ui";
81
+ import { mx as mx3, osTranslations } from "@dxos/ui-theme";
105
82
 
106
- // packages/ui/react-ui-list/src/components/List/ListRoot.tsx
107
- import { useSignals as _useSignals3 } from "@preact-signals/safe-react/tracking";
83
+ // src/components/List/ListRoot.tsx
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,72 +90,67 @@ 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
- // packages/ui/react-ui-list/src/components/List/ListItem.tsx
182
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-list/src/components/List/ListItem.tsx";
152
+ // src/components/List/ListItem.tsx
153
+ var __dxlog_file = "/__w/dxos/dxos/packages/ui/react-ui-list/src/components/List/ListItem.tsx";
183
154
  var idle = {
184
155
  type: "idle"
185
156
  };
@@ -190,203 +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: 91,
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
- onDrag: ({ self }) => {
287
- const closestEdge = extractClosestEdge2(self.data);
288
- setState((current) => {
289
- if (current.type === "is-dragging-over" && current.closestEdge === closestEdge) {
290
- return current;
291
- }
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();
292
194
  return {
293
- type: "is-dragging-over",
294
- closestEdge
195
+ x: 20,
196
+ y: height / 2
295
197
  };
296
- });
297
- },
298
- onDragLeave: () => {
299
- setState(idle);
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
- role: "none",
314
- className: "relative"
315
- }, /* @__PURE__ */ React4.createElement("div", {
316
- ref,
317
- role: "listitem",
318
- className: mx3("flex overflow-hidden", classNames, stateStyles[state.type]),
319
- ...props
320
- }, children), state.type === "is-dragging-over" && state.closestEdge && /* @__PURE__ */ React4.createElement(NaturalListItem.DropIndicator, {
321
- edge: state.closestEdge
322
- })));
323
- } finally {
324
- _effect.f();
325
- }
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
+ })));
326
289
  };
327
- var IconButton = /* @__PURE__ */ forwardRef(({ classNames, icon, ...props }, forwardedRef) => {
328
- var _effect = _useSignals4();
329
- try {
330
- return /* @__PURE__ */ React4.createElement("button", {
331
- ref: forwardedRef,
332
- className: mx3("flex items-center justify-center", classNames),
333
- ...props
334
- }, /* @__PURE__ */ React4.createElement(Icon2, {
335
- icon,
336
- classNames: "cursor-pointer",
337
- size: 4
338
- }));
339
- } finally {
340
- _effect.f();
341
- }
342
- });
343
- var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph--x--regular", ...props }) => {
344
- var _effect = _useSignals4();
345
- try {
346
- const { state } = useListContext("DELETE_BUTTON");
347
- const isDisabled = state.type !== "idle" || disabled;
348
- return /* @__PURE__ */ React4.createElement(IconButton, {
349
- icon,
350
- disabled: isDisabled,
351
- classNames: [
352
- classNames,
353
- autoHide && disabled && "hidden"
354
- ],
355
- ...props
356
- });
357
- } finally {
358
- _effect.f();
359
- }
290
+ var ListItemDeleteButton = ({ autoHide = true, classNames, disabled, icon = "ph--x--regular", label, ...props }) => {
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
+ });
360
306
  };
361
- var ListItemButton = ({ autoHide = true, classNames, disabled, ...props }) => {
362
- var _effect = _useSignals4();
363
- try {
364
- const { state } = useListContext("ITEM_BUTTON");
365
- const isDisabled = state.type !== "idle" || disabled;
366
- return /* @__PURE__ */ React4.createElement(IconButton, {
367
- disabled: isDisabled,
368
- classNames: [
369
- classNames,
370
- autoHide && disabled && "hidden"
371
- ],
372
- ...props
373
- });
374
- } finally {
375
- _effect.f();
376
- }
307
+ var ListItemButton = ({ autoHide = true, iconOnly = true, variant = "ghost", classNames, disabled, ...props }) => {
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
+ });
377
320
  };
378
321
  var ListItemDragHandle = ({ disabled }) => {
379
- var _effect = _useSignals4();
380
- try {
381
- const { dragHandleRef } = useListItemContext("DRAG_HANDLE");
382
- return /* @__PURE__ */ React4.createElement(IconButton, {
383
- ref: dragHandleRef,
384
- icon: "ph--dots-six-vertical--regular",
385
- disabled
386
- });
387
- } finally {
388
- _effect.f();
389
- }
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
+ });
390
332
  };
391
333
  var ListItemDragPreview = ({ children }) => {
392
334
  const { state } = useListContext("DRAG_PREVIEW");
@@ -394,29 +336,15 @@ var ListItemDragPreview = ({ children }) => {
394
336
  item: state.item
395
337
  }), state.container) : null;
396
338
  };
397
- var ListItemWrapper = ({ classNames, children }) => {
398
- var _effect = _useSignals4();
399
- try {
400
- return /* @__PURE__ */ React4.createElement("div", {
401
- className: mx3("flex is-full gap-2", classNames)
402
- }, children);
403
- } finally {
404
- _effect.f();
405
- }
406
- };
407
- var ListItemTitle = ({ classNames, children, ...props }) => {
408
- var _effect = _useSignals4();
409
- try {
410
- return /* @__PURE__ */ React4.createElement("div", {
411
- className: mx3("flex grow items-center truncate", classNames),
412
- ...props
413
- }, children);
414
- } finally {
415
- _effect.f();
416
- }
417
- };
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);
418
346
 
419
- // packages/ui/react-ui-list/src/components/List/List.tsx
347
+ // src/components/List/List.tsx
420
348
  var List = {
421
349
  Root: ListRoot,
422
350
  Item: ListItem,
@@ -425,122 +353,122 @@ var List = {
425
353
  ItemDragHandle: ListItemDragHandle,
426
354
  ItemDeleteButton: ListItemDeleteButton,
427
355
  ItemButton: ListItemButton,
428
- ItemTitle: ListItemTitle,
429
- IconButton
356
+ ItemTitle: ListItemTitle
430
357
  };
431
358
 
432
- // packages/ui/react-ui-list/src/components/Tree/Tree.tsx
433
- import { useSignals as _useSignals8 } from "@preact-signals/safe-react/tracking";
359
+ // src/components/Tree/Tree.tsx
434
360
  import React8, { useMemo as useMemo2 } from "react";
435
361
  import { Treegrid as Treegrid2 } from "@dxos/react-ui";
436
362
 
437
- // packages/ui/react-ui-list/src/components/Tree/TreeContext.tsx
363
+ // src/components/Tree/TreeContext.tsx
438
364
  import { createContext as createContext5, useContext } from "react";
439
365
  import { raise } from "@dxos/debug";
440
366
  var TreeContext = /* @__PURE__ */ createContext5(null);
441
367
  var TreeProvider = TreeContext.Provider;
442
368
  var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not found"));
443
369
 
444
- // packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx
445
- import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
370
+ // src/components/Tree/TreeItem.tsx
446
371
  import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
447
372
  import { draggable as draggable2, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
448
373
  import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
449
- import { Schema } from "effect";
374
+ import * as Schema from "effect/Schema";
450
375
  import React7, { memo as memo3, useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
451
376
  import { invariant as invariant2 } from "@dxos/invariant";
452
- import { Treegrid, TreeItem as NaturalTreeItem } from "@dxos/react-ui";
453
- import { ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx6 } from "@dxos/react-ui-theme";
377
+ import { TreeItem as NaturalTreeItem, Treegrid } from "@dxos/react-ui";
378
+ import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls } from "@dxos/ui-theme";
379
+
380
+ // src/components/Tree/helpers.ts
381
+ var DEFAULT_INDENTATION = 8;
382
+ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
383
+ paddingInlineStart: `${(level - 1) * indentation}px`
384
+ });
454
385
 
455
- // packages/ui/react-ui-list/src/components/Tree/TreeItemHeading.tsx
456
- import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
457
- import React5, { forwardRef as forwardRef2, memo, useCallback as useCallback2 } from "react";
458
- import { Button, Icon as Icon3, toLocalizedString, useTranslation } from "@dxos/react-ui";
386
+ // src/components/Tree/TreeItemHeading.tsx
387
+ import React5, { forwardRef, memo, useCallback as useCallback2 } from "react";
388
+ import { Button, Icon as Icon2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
459
389
  import { TextTooltip } from "@dxos/react-ui-text-tooltip";
460
- import { mx as mx4 } from "@dxos/react-ui-theme";
461
- var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef2(({ label, icon, className, disabled, current, onSelect }, forwardedRef) => {
462
- var _effect = _useSignals5();
463
- try {
464
- const { t } = useTranslation();
465
- const handleSelect = useCallback2((event) => {
390
+ import { getStyles } from "@dxos/ui-theme";
391
+ var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
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();
466
403
  onSelect?.(event.altKey);
467
- }, [
468
- onSelect
469
- ]);
470
- const handleButtonKeydown = useCallback2((event) => {
471
- if (event.key === " " || event.key === "Enter") {
472
- event.preventDefault();
473
- event.stopPropagation();
474
- onSelect?.(event.altKey);
475
- }
476
- }, [
477
- onSelect
478
- ]);
479
- return /* @__PURE__ */ React5.createElement(TextTooltip, {
480
- text: toLocalizedString(label, t),
481
- side: "bottom",
482
- truncateQuery: "span[data-tooltip]",
483
- onlyWhenTruncating: true,
484
- asChild: true,
485
- ref: forwardedRef
486
- }, /* @__PURE__ */ React5.createElement(Button, {
487
- "data-testid": "treeItem.heading",
488
- variant: "ghost",
489
- density: "fine",
490
- classNames: mx4("grow gap-2 pis-0.5 hover:bg-transparent dark:hover:bg-transparent", "disabled:cursor-default disabled:opacity-100", className),
491
- disabled,
492
- onClick: handleSelect,
493
- onKeyDown: handleButtonKeydown,
494
- ...current && {
495
- "aria-current": "location"
496
- }
497
- }, icon && /* @__PURE__ */ React5.createElement(Icon3, {
498
- icon: icon ?? "ph--placeholder--regular",
499
- size: 5,
500
- classNames: "mlb-1"
501
- }), /* @__PURE__ */ React5.createElement("span", {
502
- className: "flex-1 is-0 truncate text-start text-sm font-normal",
503
- "data-tooltip": true
504
- }, toLocalizedString(label, t))));
505
- } finally {
506
- _effect.f();
507
- }
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))));
508
441
  }));
509
442
 
510
- // packages/ui/react-ui-list/src/components/Tree/TreeItemToggle.tsx
511
- import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
512
- import React6, { forwardRef as forwardRef3, memo as memo2 } from "react";
513
- import { Button as Button2, Icon as Icon4 } from "@dxos/react-ui";
514
- import { mx as mx5 } from "@dxos/react-ui-theme";
515
- var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef3(({ open, isBranch, hidden, onToggle }, forwardedRef) => {
516
- var _effect = _useSignals6();
517
- try {
518
- return /* @__PURE__ */ React6.createElement(Button2, {
519
- ref: forwardedRef,
520
- "data-testid": "treeItem.toggle",
521
- "aria-expanded": open,
522
- variant: "ghost",
523
- density: "fine",
524
- classNames: mx5("is-6 pli-0 dx-focus-ring-inset", hidden ? "hidden" : !isBranch && "invisible"),
525
- onClick: onToggle
526
- }, /* @__PURE__ */ React6.createElement(Icon4, {
527
- icon: "ph--caret-right--bold",
528
- size: 3,
529
- classNames: mx5("transition duration-200", open && "rotate-90")
530
- }));
531
- } finally {
532
- _effect.f();
533
- }
443
+ // src/components/Tree/TreeItemToggle.tsx
444
+ import React6, { forwardRef as forwardRef2, memo as memo2 } from "react";
445
+ import { IconButton as IconButton2 } from "@dxos/react-ui";
446
+ var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open, isBranch, hidden, classNames, ...props }, forwardedRef) => {
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
+ });
534
468
  }));
535
469
 
536
- // packages/ui/react-ui-list/src/components/Tree/helpers.ts
537
- var DEFAULT_INDENTATION = 8;
538
- var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
539
- paddingInlineStart: `${(level - 1) * indentation}px`
540
- });
541
-
542
- // packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx
543
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx";
470
+ // src/components/Tree/TreeItem.tsx
471
+ var __dxlog_file2 = "/__w/dxos/dxos/packages/ui/react-ui-list/src/components/Tree/TreeItem.tsx";
544
472
  var hoverableDescriptionIcons = "[--icons-color:inherit] hover-hover:[--icons-color:var(--description-text)] hover-hover:hover:[--icons-color:inherit] focus-within:[--icons-color:inherit]";
545
473
  var TreeDataSchema = Schema.Struct({
546
474
  id: Schema.String,
@@ -548,307 +476,324 @@ var TreeDataSchema = Schema.Struct({
548
476
  item: Schema.Any
549
477
  });
550
478
  var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
551
- var RawTreeItem = ({ item, path: _path, last, draggable: _draggable, renderColumns: Columns, canDrop, onOpenChange, onSelect, levelOffset = 2 }) => {
552
- var _effect = _useSignals7();
553
- try {
554
- const rowRef = useRef2(null);
555
- const buttonRef = useRef2(null);
556
- const openRef = useRef2(false);
557
- const cancelExpandRef = useRef2(null);
558
- const [_state, setState] = useState3("idle");
559
- const [instruction, setInstruction] = useState3(null);
560
- const [menuOpen, setMenuOpen] = useState3(false);
561
- const { useItems, getProps, isOpen, isCurrent } = useTree();
562
- const items = useItems(item);
563
- const { id, label, parentOf, icon, disabled, className, headingClassName, testId } = getProps(item, _path);
564
- const path = useMemo(() => [
565
- ..._path,
566
- id
567
- ], [
568
- _path,
569
- id
570
- ]);
571
- const open = isOpen(path, item);
572
- const current = isCurrent(path, item);
573
- const level = path.length - levelOffset;
574
- const isBranch = !!parentOf;
575
- const mode = last ? "last-in-group" : open ? "expanded" : "standard";
576
- const cancelExpand = useCallback3(() => {
577
- if (cancelExpandRef.current) {
578
- clearTimeout(cancelExpandRef.current);
579
- cancelExpandRef.current = null;
580
- }
581
- }, []);
582
- useEffect3(() => {
583
- if (!_draggable) {
584
- return;
585
- }
586
- invariant2(buttonRef.current, void 0, {
587
- F: __dxlog_file2,
588
- L: 106,
589
- S: void 0,
590
- A: [
591
- "buttonRef.current",
592
- ""
593
- ]
594
- });
595
- const data = {
596
- id,
597
- path,
598
- item
599
- };
600
- return combine2(
601
- draggable2({
602
- element: buttonRef.current,
603
- getInitialData: () => data,
604
- onDragStart: () => {
605
- setState("dragging");
606
- if (open) {
607
- openRef.current = true;
608
- onOpenChange?.({
609
- item,
610
- path,
611
- open: false
612
- });
613
- }
614
- },
615
- onDrop: () => {
616
- setState("idle");
617
- if (openRef.current) {
618
- onOpenChange?.({
619
- item,
620
- path,
621
- open: true
622
- });
623
- }
624
- }
625
- }),
626
- // https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
627
- dropTargetForElements2({
628
- element: buttonRef.current,
629
- getData: ({ input, element }) => {
630
- return attachInstruction(data, {
631
- input,
632
- element,
633
- indentPerLevel: DEFAULT_INDENTATION,
634
- currentLevel: level,
635
- mode,
636
- block: isBranch ? [] : [
637
- "make-child"
638
- ]
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
639
542
  });
640
- },
641
- canDrop: ({ source }) => {
642
- const _canDrop = canDrop ?? (() => true);
643
- return source.element !== buttonRef.current && _canDrop({
644
- source: source.data,
645
- target: data
543
+ }
544
+ },
545
+ onDrop: () => {
546
+ setState("idle");
547
+ if (openRef.current) {
548
+ onOpenChange?.({
549
+ item,
550
+ path,
551
+ open: true
646
552
  });
647
- },
648
- getIsSticky: () => true,
649
- onDrag: ({ self, source }) => {
650
- const instruction2 = extractInstruction(self.data);
651
- if (source.data.id !== id) {
652
- if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
653
- cancelExpandRef.current = setTimeout(() => {
654
- onOpenChange?.({
655
- item,
656
- path,
657
- open: true
658
- });
659
- }, 500);
660
- }
661
- if (instruction2?.type !== "make-child") {
662
- cancelExpand();
663
- }
664
- setInstruction(instruction2);
665
- } else if (instruction2?.type === "reparent") {
666
- setInstruction(instruction2);
667
- } else {
668
- 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);
669
599
  }
670
- },
671
- onDragLeave: () => {
672
- cancelExpand();
673
- setInstruction(null);
674
- },
675
- onDrop: () => {
676
- cancelExpand();
600
+ if (instruction2?.type !== "make-child") {
601
+ cancelExpand();
602
+ }
603
+ setInstruction(instruction2);
604
+ } else if (instruction2?.type === "reparent") {
605
+ setInstruction(instruction2);
606
+ } else {
677
607
  setInstruction(null);
678
608
  }
679
- })
680
- );
681
- }, [
682
- _draggable,
683
- item,
684
- id,
685
- mode,
686
- path,
687
- open,
688
- canDrop
689
- ]);
690
- useEffect3(() => () => cancelExpand(), [
691
- cancelExpand
692
- ]);
693
- const handleOpenChange = useCallback3(() => onOpenChange?.({
694
- item,
695
- path,
696
- open: !open
697
- }), [
698
- onOpenChange,
699
- item,
700
- path,
701
- open
702
- ]);
703
- const handleSelect = useCallback3((option = false) => {
704
- if (isBranch) {
705
- handleOpenChange();
706
- } else {
707
- rowRef.current?.focus();
708
- onSelect?.({
709
- item,
710
- path,
711
- current: !current,
712
- option
713
- });
714
- }
715
- }, [
716
- item,
717
- path,
718
- current,
719
- isBranch,
720
- handleOpenChange,
721
- onSelect
722
- ]);
723
- const handleKeyDown = useCallback3((event) => {
724
- switch (event.key) {
725
- case "ArrowRight":
726
- isBranch && !open && handleOpenChange();
727
- break;
728
- case "ArrowLeft":
729
- isBranch && open && handleOpenChange();
730
- break;
731
- case " ":
732
- handleSelect(event.altKey);
733
- break;
734
- }
735
- }, [
736
- isBranch,
737
- open,
738
- handleOpenChange,
739
- handleSelect
740
- ]);
741
- return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
742
- ref: rowRef,
743
- key: id,
744
- id,
745
- "aria-labelledby": `${id}__label`,
746
- parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
747
- classNames: mx6("grid grid-cols-subgrid col-[tree-row] mbs-0.5 aria-[current]:bg-activeSurface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostHover, className),
748
- "data-itemid": id,
749
- "data-testid": testId,
750
- // NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
751
- // without alerting the user (except for in the correct link element). See also:
752
- // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
753
- "aria-current": current ? "" : void 0,
754
- onKeyDown: handleKeyDown,
755
- onContextMenu: (event) => {
756
- event.preventDefault();
757
- setMenuOpen(true);
758
- }
759
- }, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
760
- indent: true,
761
- classNames: "relative grid grid-cols-subgrid col-[tree-row]",
762
- style: paddingIndentation(level)
763
- }, /* @__PURE__ */ React7.createElement("div", {
764
- role: "none",
765
- className: "flex items-center"
766
- }, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
767
- isBranch,
768
- open,
769
- onToggle: handleOpenChange
770
- }), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
771
- ref: buttonRef,
772
- label,
773
- icon,
774
- className: headingClassName,
775
- disabled,
776
- current,
777
- onSelect: handleSelect
778
- })), Columns && /* @__PURE__ */ React7.createElement(Columns, {
779
- item,
780
- path,
781
- open,
782
- menuOpen,
783
- setMenuOpen
784
- }), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
785
- instruction,
786
- gap: 2
787
- }))), open && items.map((item2, index) => /* @__PURE__ */ React7.createElement(TreeItem, {
788
- key: item2.id,
789
- item: item2,
790
- path,
791
- last: index === items.length - 1,
792
- draggable: _draggable,
793
- renderColumns: Columns,
794
- canDrop,
795
- onOpenChange,
796
- onSelect
797
- })));
798
- } finally {
799
- _effect.f();
800
- }
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
+ })));
801
749
  };
802
750
  var TreeItem = /* @__PURE__ */ memo3(RawTreeItem);
803
751
 
804
- // packages/ui/react-ui-list/src/components/Tree/Tree.tsx
805
- 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 }) => {
806
- var _effect = _useSignals8();
807
- try {
808
- const context = useMemo2(() => ({
809
- useItems,
810
- getProps,
811
- isOpen,
812
- isCurrent
813
- }), [
814
- useItems,
815
- getProps,
816
- isOpen,
817
- isCurrent
818
- ]);
819
- const items = useItems(root);
820
- const treePath = useMemo2(() => path ? [
821
- ...path,
822
- id
823
- ] : [
824
- id
825
- ], [
826
- id,
827
- path
828
- ]);
829
- return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
830
- gridTemplateColumns,
831
- classNames
832
- }, /* @__PURE__ */ React8.createElement(TreeProvider, {
833
- value: context
834
- }, items.map((item, index) => /* @__PURE__ */ React8.createElement(TreeItem, {
835
- key: item.id,
836
- item,
837
- last: index === items.length - 1,
838
- path: treePath,
839
- levelOffset,
840
- draggable: draggable3,
841
- renderColumns,
842
- canDrop,
843
- onOpenChange,
844
- onSelect
845
- }))));
846
- } finally {
847
- _effect.f();
848
- }
752
+ // src/components/Tree/Tree.tsx
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
+ }))));
849
794
  };
850
795
 
851
- // packages/ui/react-ui-list/src/util/path.ts
796
+ // src/util/path.ts
852
797
  var SEPARATOR = "+";
853
798
  var Path = {
854
799
  create: (...args) => args.join(SEPARATOR),