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