@dxos/react-ui-list 0.8.4-main.c4373fc → 0.8.4-main.d05673bc65
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 -711
- 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 -711
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/src/components/Accordion/Accordion.stories.d.ts +0 -3
- package/dist/types/src/components/Accordion/Accordion.stories.d.ts.map +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 +22 -9
- package/dist/types/src/components/Tree/TreeContext.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeItem.d.ts +20 -3
- package/dist/types/src/components/Tree/TreeItem.d.ts.map +1 -1
- package/dist/types/src/components/Tree/TreeItemHeading.d.ts +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 +2 -5
- package/src/components/Accordion/AccordionItem.tsx +3 -3
- package/src/components/Accordion/AccordionRoot.tsx +1 -1
- package/src/components/List/List.stories.tsx +31 -19
- package/src/components/List/List.tsx +2 -2
- package/src/components/List/ListItem.tsx +53 -35
- package/src/components/List/ListRoot.tsx +2 -2
- package/src/components/List/testing.ts +2 -2
- package/src/components/Tree/Tree.stories.tsx +150 -60
- package/src/components/Tree/Tree.tsx +39 -41
- package/src/components/Tree/TreeContext.tsx +19 -8
- package/src/components/Tree/TreeItem.tsx +173 -103
- package/src/components/Tree/TreeItemHeading.tsx +9 -5
- package/src/components/Tree/TreeItemToggle.tsx +1 -1
- package/src/components/Tree/index.ts +2 -0
- package/src/components/Tree/testing.ts +4 -3
|
@@ -1,85 +1,63 @@
|
|
|
1
1
|
// src/components/Accordion/AccordionItem.tsx
|
|
2
|
-
import { useSignals as _useSignals2 } from "@preact-signals/safe-react/tracking";
|
|
3
2
|
import * as AccordionPrimitive2 from "@radix-ui/react-accordion";
|
|
4
3
|
import { createContext as createContext2 } from "@radix-ui/react-context";
|
|
5
4
|
import React2 from "react";
|
|
6
5
|
import { Icon } from "@dxos/react-ui";
|
|
7
|
-
import { mx as mx2 } from "@dxos/
|
|
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
|
|
@@ -184,200 +156,182 @@ var idle = {
|
|
|
184
156
|
type: "idle"
|
|
185
157
|
};
|
|
186
158
|
var stateStyles = {
|
|
187
|
-
"
|
|
159
|
+
"w-dragging": "opacity-50"
|
|
188
160
|
};
|
|
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 ref = useRef(null);
|
|
168
|
+
const dragHandleRef = useRef(null);
|
|
169
|
+
const [state, setState] = useState2(idle);
|
|
170
|
+
useEffect2(() => {
|
|
171
|
+
const element = ref.current;
|
|
172
|
+
invariant(element, void 0, {
|
|
173
|
+
F: __dxlog_file,
|
|
174
|
+
L: 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: "w-dragging"
|
|
220
|
+
});
|
|
221
|
+
setRootState({
|
|
222
|
+
type: "w-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: "w-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 === "w-dragging-over" && current.closestEdge === closestEdge) {
|
|
264
|
+
return current;
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
type: "w-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
|
+
ref,
|
|
285
|
+
role: "listitem",
|
|
286
|
+
"aria-selected": selected,
|
|
287
|
+
className: mx3("relative dx-selected", classNames, stateStyles[state.type]),
|
|
288
|
+
...props
|
|
289
|
+
}, children), state.type === "w-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
|
+
iconOnly: true,
|
|
313
|
+
variant: "ghost",
|
|
314
|
+
...props,
|
|
315
|
+
icon,
|
|
316
|
+
disabled: isDisabled,
|
|
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
|
+
iconOnly: true,
|
|
329
|
+
variant: "ghost",
|
|
330
|
+
label: t("drag handle label"),
|
|
331
|
+
ref: dragHandleRef,
|
|
332
|
+
icon: "ph--dots-six-vertical--regular",
|
|
333
|
+
disabled
|
|
334
|
+
});
|
|
381
335
|
};
|
|
382
336
|
var ListItemDragPreview = ({ children }) => {
|
|
383
337
|
const { state } = useListContext("DRAG_PREVIEW");
|
|
@@ -385,27 +339,13 @@ 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
|
-
_effect.f();
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
var ListItemTitle = ({ classNames, children, ...props }) => {
|
|
399
|
-
var _effect = _useSignals4();
|
|
400
|
-
try {
|
|
401
|
-
return /* @__PURE__ */ React4.createElement("div", {
|
|
402
|
-
className: mx3("flex grow items-center truncate", classNames),
|
|
403
|
-
...props
|
|
404
|
-
}, children);
|
|
405
|
-
} finally {
|
|
406
|
-
_effect.f();
|
|
407
|
-
}
|
|
408
|
-
};
|
|
342
|
+
var ListItemWrapper = ({ classNames, children }) => /* @__PURE__ */ React4.createElement("div", {
|
|
343
|
+
className: mx3("flex w-full gap-2", classNames)
|
|
344
|
+
}, children);
|
|
345
|
+
var ListItemTitle = ({ classNames, children, ...props }) => /* @__PURE__ */ React4.createElement("div", {
|
|
346
|
+
className: mx3("flex grow items-center truncate", classNames),
|
|
347
|
+
...props
|
|
348
|
+
}, children);
|
|
409
349
|
|
|
410
350
|
// src/components/List/List.tsx
|
|
411
351
|
var List = {
|
|
@@ -414,13 +354,13 @@ var List = {
|
|
|
414
354
|
ItemDragPreview: ListItemDragPreview,
|
|
415
355
|
ItemWrapper: ListItemWrapper,
|
|
416
356
|
ItemDragHandle: ListItemDragHandle,
|
|
357
|
+
ItemIconButton: ListItemIconButton,
|
|
417
358
|
ItemDeleteButton: ListItemDeleteButton,
|
|
418
|
-
ItemButton: ListItemButton,
|
|
419
359
|
ItemTitle: ListItemTitle
|
|
420
360
|
};
|
|
421
361
|
|
|
422
362
|
// src/components/Tree/Tree.tsx
|
|
423
|
-
import {
|
|
363
|
+
import { useAtomValue as useAtomValue2 } from "@effect-atom/atom-react";
|
|
424
364
|
import React8, { useMemo as useMemo2 } from "react";
|
|
425
365
|
import { Treegrid as Treegrid2 } from "@dxos/react-ui";
|
|
426
366
|
|
|
@@ -432,15 +372,15 @@ var TreeProvider = TreeContext.Provider;
|
|
|
432
372
|
var useTree = () => useContext(TreeContext) ?? raise(new Error("TreeContext not found"));
|
|
433
373
|
|
|
434
374
|
// src/components/Tree/TreeItem.tsx
|
|
435
|
-
import { useSignals as _useSignals7 } from "@preact-signals/safe-react/tracking";
|
|
436
375
|
import { combine as combine2 } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
|
437
376
|
import { draggable as draggable2, dropTargetForElements as dropTargetForElements2 } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
438
377
|
import { attachInstruction, extractInstruction } from "@atlaskit/pragmatic-drag-and-drop-hitbox/tree-item";
|
|
378
|
+
import { useAtomValue } from "@effect-atom/atom-react";
|
|
439
379
|
import * as Schema from "effect/Schema";
|
|
440
380
|
import React7, { memo as memo3, useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
|
|
441
381
|
import { invariant as invariant2 } from "@dxos/invariant";
|
|
442
382
|
import { TreeItem as NaturalTreeItem, Treegrid } from "@dxos/react-ui";
|
|
443
|
-
import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls } from "@dxos/
|
|
383
|
+
import { ghostFocusWithin, ghostHover, hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, mx as mx4 } from "@dxos/ui-theme";
|
|
444
384
|
|
|
445
385
|
// src/components/Tree/helpers.ts
|
|
446
386
|
var DEFAULT_INDENTATION = 8;
|
|
@@ -449,97 +389,87 @@ var paddingIndentation = (level, indentation = DEFAULT_INDENTATION) => ({
|
|
|
449
389
|
});
|
|
450
390
|
|
|
451
391
|
// src/components/Tree/TreeItemHeading.tsx
|
|
452
|
-
import { useSignals as _useSignals5 } from "@preact-signals/safe-react/tracking";
|
|
453
392
|
import React5, { forwardRef, memo, useCallback as useCallback2 } from "react";
|
|
454
393
|
import { Button, Icon as Icon2, toLocalizedString, useTranslation as useTranslation2 } from "@dxos/react-ui";
|
|
455
394
|
import { TextTooltip } from "@dxos/react-ui-text-tooltip";
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
395
|
+
import { getStyles } from "@dxos/ui-theme";
|
|
396
|
+
var TreeItemHeading = /* @__PURE__ */ memo(/* @__PURE__ */ forwardRef(({ label, className, icon, iconHue, disabled, current, onSelect }, forwardedRef) => {
|
|
397
|
+
const { t } = useTranslation2();
|
|
398
|
+
const styles = iconHue ? getStyles(iconHue) : void 0;
|
|
399
|
+
const handleSelect = useCallback2((event) => {
|
|
400
|
+
onSelect?.(event.altKey);
|
|
401
|
+
}, [
|
|
402
|
+
onSelect
|
|
403
|
+
]);
|
|
404
|
+
const handleButtonKeydown = useCallback2((event) => {
|
|
405
|
+
if (event.key === " " || event.key === "Enter") {
|
|
406
|
+
event.preventDefault();
|
|
407
|
+
event.stopPropagation();
|
|
461
408
|
onSelect?.(event.altKey);
|
|
462
|
-
}
|
|
463
|
-
|
|
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
|
-
classNames: [
|
|
500
|
-
"mlb-1",
|
|
501
|
-
iconClassName
|
|
502
|
-
]
|
|
503
|
-
}), /* @__PURE__ */ React5.createElement("span", {
|
|
504
|
-
className: "flex-1 is-0 truncate text-start text-sm font-normal",
|
|
505
|
-
"data-tooltip": true
|
|
506
|
-
}, toLocalizedString(label, t))));
|
|
507
|
-
} finally {
|
|
508
|
-
_effect.f();
|
|
509
|
-
}
|
|
409
|
+
}
|
|
410
|
+
}, [
|
|
411
|
+
onSelect
|
|
412
|
+
]);
|
|
413
|
+
return /* @__PURE__ */ React5.createElement(TextTooltip, {
|
|
414
|
+
text: toLocalizedString(label, t),
|
|
415
|
+
side: "bottom",
|
|
416
|
+
truncateQuery: "span[data-tooltip]",
|
|
417
|
+
onlyWhenTruncating: true,
|
|
418
|
+
asChild: true,
|
|
419
|
+
ref: forwardedRef
|
|
420
|
+
}, /* @__PURE__ */ React5.createElement(Button, {
|
|
421
|
+
"data-testid": "treeItem.heading",
|
|
422
|
+
variant: "ghost",
|
|
423
|
+
density: "fine",
|
|
424
|
+
classNames: [
|
|
425
|
+
"grow gap-2 ps-0.5 hover:bg-transparent dark:hover:bg-transparent",
|
|
426
|
+
"disabled:cursor-default disabled:opacity-100",
|
|
427
|
+
className
|
|
428
|
+
],
|
|
429
|
+
disabled,
|
|
430
|
+
onClick: handleSelect,
|
|
431
|
+
onKeyDown: handleButtonKeydown,
|
|
432
|
+
...current && {
|
|
433
|
+
"aria-current": "location"
|
|
434
|
+
}
|
|
435
|
+
}, icon && /* @__PURE__ */ React5.createElement(Icon2, {
|
|
436
|
+
icon: icon ?? "ph--placeholder--regular",
|
|
437
|
+
size: 5,
|
|
438
|
+
classNames: [
|
|
439
|
+
"my-1",
|
|
440
|
+
styles?.surfaceText
|
|
441
|
+
]
|
|
442
|
+
}), /* @__PURE__ */ React5.createElement("span", {
|
|
443
|
+
className: "flex-1 w-0 truncate text-start font-normal",
|
|
444
|
+
"data-tooltip": true
|
|
445
|
+
}, toLocalizedString(label, t))));
|
|
510
446
|
}));
|
|
511
447
|
|
|
512
448
|
// src/components/Tree/TreeItemToggle.tsx
|
|
513
|
-
import { useSignals as _useSignals6 } from "@preact-signals/safe-react/tracking";
|
|
514
449
|
import React6, { forwardRef as forwardRef2, memo as memo2 } from "react";
|
|
515
450
|
import { IconButton as IconButton2 } from "@dxos/react-ui";
|
|
516
451
|
var TreeItemToggle = /* @__PURE__ */ memo2(/* @__PURE__ */ forwardRef2(({ open, isBranch, hidden, classNames, ...props }, forwardedRef) => {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
...props
|
|
539
|
-
});
|
|
540
|
-
} finally {
|
|
541
|
-
_effect.f();
|
|
542
|
-
}
|
|
452
|
+
return /* @__PURE__ */ React6.createElement(IconButton2, {
|
|
453
|
+
ref: forwardedRef,
|
|
454
|
+
"data-testid": "treeItem.toggle",
|
|
455
|
+
"aria-expanded": open,
|
|
456
|
+
variant: "ghost",
|
|
457
|
+
density: "fine",
|
|
458
|
+
classNames: [
|
|
459
|
+
"h-full w-6 px-0",
|
|
460
|
+
"[&_svg]:transition-[transform] [&_svg]:duration-200",
|
|
461
|
+
open && "[&_svg]:rotate-90",
|
|
462
|
+
hidden ? "hidden" : !isBranch && "invisible",
|
|
463
|
+
classNames
|
|
464
|
+
],
|
|
465
|
+
size: 3,
|
|
466
|
+
icon: "ph--caret-right--bold",
|
|
467
|
+
iconOnly: true,
|
|
468
|
+
noTooltip: true,
|
|
469
|
+
label: open ? "Click to close" : "Click to open",
|
|
470
|
+
tabIndex: -1,
|
|
471
|
+
...props
|
|
472
|
+
});
|
|
543
473
|
}));
|
|
544
474
|
|
|
545
475
|
// src/components/Tree/TreeItem.tsx
|
|
@@ -551,319 +481,341 @@ var TreeDataSchema = Schema.Struct({
|
|
|
551
481
|
item: Schema.Any
|
|
552
482
|
});
|
|
553
483
|
var isTreeData = (data) => Schema.is(TreeDataSchema)(data);
|
|
554
|
-
var RawTreeItem = ({ item, path:
|
|
555
|
-
|
|
556
|
-
|
|
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
|
-
|
|
484
|
+
var RawTreeItem = ({ item, path: pathProp, levelOffset = 2, last, draggable: draggableProp, renderColumns: Columns, blockInstruction, canDrop, canSelect, onOpenChange, onSelect, onItemHover }) => {
|
|
485
|
+
const rowRef = useRef2(null);
|
|
486
|
+
const buttonRef = useRef2(null);
|
|
487
|
+
const openRef = useRef2(false);
|
|
488
|
+
const cancelExpandRef = useRef2(null);
|
|
489
|
+
const [_state, setState] = useState3("idle");
|
|
490
|
+
const [instruction, setInstruction] = useState3(null);
|
|
491
|
+
const [menuOpen, setMenuOpen] = useState3(false);
|
|
492
|
+
const { itemProps: itemPropsAtom, childIds: childIdsAtom, itemOpen: itemOpenAtom, itemCurrent: itemCurrentAtom } = useTree();
|
|
493
|
+
const path = useMemo(() => [
|
|
494
|
+
...pathProp,
|
|
495
|
+
item.id
|
|
496
|
+
], [
|
|
497
|
+
pathProp,
|
|
498
|
+
item.id
|
|
499
|
+
]);
|
|
500
|
+
const { id, parentOf, draggable: itemDraggable, droppable: itemDroppable, label, className, headingClassName, icon, iconHue, disabled, testId } = useAtomValue(itemPropsAtom(path));
|
|
501
|
+
const childIds = useAtomValue(childIdsAtom(item.id));
|
|
502
|
+
const open = useAtomValue(itemOpenAtom(path));
|
|
503
|
+
const current = useAtomValue(itemCurrentAtom(path));
|
|
504
|
+
const level = path.length - levelOffset;
|
|
505
|
+
const isBranch = !!parentOf;
|
|
506
|
+
const mode = last ? "last-in-group" : open ? "expanded" : "standard";
|
|
507
|
+
const canSelectItem = canSelect?.({
|
|
508
|
+
item,
|
|
509
|
+
path
|
|
510
|
+
}) ?? true;
|
|
511
|
+
const data = {
|
|
512
|
+
id,
|
|
513
|
+
path,
|
|
514
|
+
item
|
|
515
|
+
};
|
|
516
|
+
const cancelExpand = useCallback3(() => {
|
|
517
|
+
if (cancelExpandRef.current) {
|
|
518
|
+
clearTimeout(cancelExpandRef.current);
|
|
519
|
+
cancelExpandRef.current = null;
|
|
520
|
+
}
|
|
521
|
+
}, []);
|
|
522
|
+
const isItemDraggable = draggableProp && itemDraggable !== false;
|
|
523
|
+
const isItemDroppable = itemDroppable !== false;
|
|
524
|
+
useEffect3(() => {
|
|
525
|
+
if (!draggableProp) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
invariant2(buttonRef.current, void 0, {
|
|
529
|
+
F: __dxlog_file2,
|
|
530
|
+
L: 148,
|
|
531
|
+
S: void 0,
|
|
532
|
+
A: [
|
|
533
|
+
"buttonRef.current",
|
|
534
|
+
""
|
|
535
|
+
]
|
|
536
|
+
});
|
|
537
|
+
const makeDraggable = () => draggable2({
|
|
538
|
+
element: buttonRef.current,
|
|
539
|
+
getInitialData: () => data,
|
|
540
|
+
onDragStart: () => {
|
|
541
|
+
setState("dragging");
|
|
542
|
+
if (open) {
|
|
543
|
+
openRef.current = true;
|
|
544
|
+
onOpenChange?.({
|
|
545
|
+
item,
|
|
546
|
+
path,
|
|
547
|
+
open: false
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
},
|
|
551
|
+
onDrop: () => {
|
|
552
|
+
setState("idle");
|
|
553
|
+
if (openRef.current) {
|
|
554
|
+
onOpenChange?.({
|
|
555
|
+
item,
|
|
556
|
+
path,
|
|
557
|
+
open: true
|
|
558
|
+
});
|
|
559
|
+
}
|
|
592
560
|
}
|
|
593
|
-
|
|
594
|
-
|
|
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
|
-
|
|
561
|
+
});
|
|
562
|
+
if (!isItemDroppable) {
|
|
563
|
+
return isItemDraggable ? makeDraggable() : void 0;
|
|
564
|
+
}
|
|
565
|
+
const dropTarget = dropTargetForElements2({
|
|
566
|
+
element: buttonRef.current,
|
|
567
|
+
getData: ({ input, element }) => {
|
|
568
|
+
return attachInstruction(data, {
|
|
569
|
+
input,
|
|
570
|
+
element,
|
|
571
|
+
indentPerLevel: DEFAULT_INDENTATION,
|
|
572
|
+
currentLevel: level,
|
|
573
|
+
mode,
|
|
574
|
+
block: isBranch ? [] : [
|
|
575
|
+
"make-child"
|
|
576
|
+
]
|
|
577
|
+
});
|
|
578
|
+
},
|
|
579
|
+
canDrop: ({ source }) => {
|
|
580
|
+
const _canDrop = canDrop ?? (() => true);
|
|
581
|
+
return source.element !== buttonRef.current && _canDrop({
|
|
582
|
+
source: source.data,
|
|
583
|
+
target: data
|
|
584
|
+
});
|
|
585
|
+
},
|
|
586
|
+
getIsSticky: () => true,
|
|
587
|
+
onDrag: ({ self, source }) => {
|
|
588
|
+
const desired = extractInstruction(self.data);
|
|
589
|
+
const block = desired && blockInstruction?.({
|
|
590
|
+
instruction: desired,
|
|
591
|
+
source: source.data,
|
|
592
|
+
target: data
|
|
593
|
+
});
|
|
594
|
+
const instruction2 = block && desired.type !== "instruction-blocked" ? {
|
|
595
|
+
type: "instruction-blocked",
|
|
596
|
+
desired
|
|
597
|
+
} : desired;
|
|
598
|
+
if (source.data.id !== id) {
|
|
599
|
+
if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
|
|
600
|
+
cancelExpandRef.current = setTimeout(() => {
|
|
625
601
|
onOpenChange?.({
|
|
626
602
|
item,
|
|
627
603
|
path,
|
|
628
604
|
open: true
|
|
629
605
|
});
|
|
630
|
-
}
|
|
606
|
+
}, 500);
|
|
631
607
|
}
|
|
632
|
-
|
|
633
|
-
// https://github.com/atlassian/pragmatic-drag-and-drop/blob/main/packages/hitbox/constellation/index/about.mdx
|
|
634
|
-
dropTargetForElements2({
|
|
635
|
-
element: buttonRef.current,
|
|
636
|
-
getData: ({ input, element }) => {
|
|
637
|
-
return attachInstruction(data, {
|
|
638
|
-
input,
|
|
639
|
-
element,
|
|
640
|
-
indentPerLevel: DEFAULT_INDENTATION,
|
|
641
|
-
currentLevel: level,
|
|
642
|
-
mode,
|
|
643
|
-
block: isBranch ? [] : [
|
|
644
|
-
"make-child"
|
|
645
|
-
]
|
|
646
|
-
});
|
|
647
|
-
},
|
|
648
|
-
canDrop: ({ source }) => {
|
|
649
|
-
const _canDrop = canDrop ?? (() => true);
|
|
650
|
-
return source.element !== buttonRef.current && _canDrop({
|
|
651
|
-
source: source.data,
|
|
652
|
-
target: data
|
|
653
|
-
});
|
|
654
|
-
},
|
|
655
|
-
getIsSticky: () => true,
|
|
656
|
-
onDrag: ({ self, source }) => {
|
|
657
|
-
const instruction2 = extractInstruction(self.data);
|
|
658
|
-
if (source.data.id !== id) {
|
|
659
|
-
if (instruction2?.type === "make-child" && isBranch && !open && !cancelExpandRef.current) {
|
|
660
|
-
cancelExpandRef.current = setTimeout(() => {
|
|
661
|
-
onOpenChange?.({
|
|
662
|
-
item,
|
|
663
|
-
path,
|
|
664
|
-
open: true
|
|
665
|
-
});
|
|
666
|
-
}, 500);
|
|
667
|
-
}
|
|
668
|
-
if (instruction2?.type !== "make-child") {
|
|
669
|
-
cancelExpand();
|
|
670
|
-
}
|
|
671
|
-
setInstruction(instruction2);
|
|
672
|
-
} else if (instruction2?.type === "reparent") {
|
|
673
|
-
setInstruction(instruction2);
|
|
674
|
-
} else {
|
|
675
|
-
setInstruction(null);
|
|
676
|
-
}
|
|
677
|
-
},
|
|
678
|
-
onDragLeave: () => {
|
|
679
|
-
cancelExpand();
|
|
680
|
-
setInstruction(null);
|
|
681
|
-
},
|
|
682
|
-
onDrop: () => {
|
|
608
|
+
if (instruction2?.type !== "make-child") {
|
|
683
609
|
cancelExpand();
|
|
684
|
-
setInstruction(null);
|
|
685
610
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
const handleOpenToggle = useCallback3(() => onOpenChange?.({
|
|
701
|
-
item,
|
|
702
|
-
path,
|
|
703
|
-
open: !open
|
|
704
|
-
}), [
|
|
705
|
-
onOpenChange,
|
|
706
|
-
item,
|
|
707
|
-
path,
|
|
708
|
-
open
|
|
709
|
-
]);
|
|
710
|
-
const handleSelect = useCallback3((option = false) => {
|
|
711
|
-
if (isBranch && (option || current)) {
|
|
712
|
-
handleOpenToggle();
|
|
713
|
-
} else if (canSelectItem) {
|
|
714
|
-
canSelect?.({
|
|
715
|
-
item,
|
|
716
|
-
path
|
|
717
|
-
});
|
|
718
|
-
rowRef.current?.focus();
|
|
719
|
-
onSelect?.({
|
|
720
|
-
item,
|
|
721
|
-
path,
|
|
722
|
-
current: !current,
|
|
723
|
-
option
|
|
724
|
-
});
|
|
725
|
-
}
|
|
726
|
-
}, [
|
|
727
|
-
item,
|
|
728
|
-
path,
|
|
729
|
-
current,
|
|
730
|
-
isBranch,
|
|
731
|
-
canSelectItem,
|
|
732
|
-
handleOpenToggle,
|
|
733
|
-
onSelect
|
|
734
|
-
]);
|
|
735
|
-
const handleKeyDown = useCallback3((event) => {
|
|
736
|
-
switch (event.key) {
|
|
737
|
-
case "ArrowRight":
|
|
738
|
-
case "ArrowLeft":
|
|
739
|
-
isBranch && handleOpenToggle();
|
|
740
|
-
break;
|
|
741
|
-
}
|
|
742
|
-
}, [
|
|
743
|
-
isBranch,
|
|
744
|
-
open,
|
|
745
|
-
handleOpenToggle,
|
|
746
|
-
handleSelect
|
|
747
|
-
]);
|
|
748
|
-
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
|
|
749
|
-
ref: rowRef,
|
|
750
|
-
key: id,
|
|
751
|
-
id,
|
|
752
|
-
"aria-labelledby": `${id}__label`,
|
|
753
|
-
parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
|
|
754
|
-
classNames: [
|
|
755
|
-
"grid grid-cols-subgrid col-[tree-row] mbs-0.5 aria-[current]:bg-activeSurface",
|
|
756
|
-
hoverableControls,
|
|
757
|
-
hoverableFocusedKeyboardControls,
|
|
758
|
-
hoverableFocusedWithinControls,
|
|
759
|
-
hoverableDescriptionIcons,
|
|
760
|
-
ghostHover,
|
|
761
|
-
ghostFocusWithin,
|
|
762
|
-
className
|
|
763
|
-
],
|
|
764
|
-
"data-itemid": id,
|
|
765
|
-
"data-testid": testId,
|
|
766
|
-
// NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
|
|
767
|
-
// without alerting the user (except for in the correct link element). See also:
|
|
768
|
-
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
|
|
769
|
-
"aria-current": current ? "" : void 0,
|
|
770
|
-
onKeyDown: handleKeyDown,
|
|
771
|
-
onContextMenu: (event) => {
|
|
772
|
-
event.preventDefault();
|
|
773
|
-
setMenuOpen(true);
|
|
611
|
+
setInstruction(instruction2);
|
|
612
|
+
} else if (instruction2?.type === "reparent") {
|
|
613
|
+
setInstruction(instruction2);
|
|
614
|
+
} else {
|
|
615
|
+
setInstruction(null);
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
onDragLeave: () => {
|
|
619
|
+
cancelExpand();
|
|
620
|
+
setInstruction(null);
|
|
621
|
+
},
|
|
622
|
+
onDrop: () => {
|
|
623
|
+
cancelExpand();
|
|
624
|
+
setInstruction(null);
|
|
774
625
|
}
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
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
|
-
|
|
626
|
+
});
|
|
627
|
+
if (!isItemDraggable) {
|
|
628
|
+
return dropTarget;
|
|
629
|
+
}
|
|
630
|
+
return combine2(makeDraggable(), dropTarget);
|
|
631
|
+
}, [
|
|
632
|
+
draggableProp,
|
|
633
|
+
isItemDraggable,
|
|
634
|
+
isItemDroppable,
|
|
635
|
+
item,
|
|
636
|
+
id,
|
|
637
|
+
mode,
|
|
638
|
+
path,
|
|
639
|
+
open,
|
|
640
|
+
blockInstruction,
|
|
641
|
+
canDrop
|
|
642
|
+
]);
|
|
643
|
+
useEffect3(() => () => cancelExpand(), [
|
|
644
|
+
cancelExpand
|
|
645
|
+
]);
|
|
646
|
+
const handleOpenToggle = useCallback3(() => onOpenChange?.({
|
|
647
|
+
item,
|
|
648
|
+
path,
|
|
649
|
+
open: !open
|
|
650
|
+
}), [
|
|
651
|
+
onOpenChange,
|
|
652
|
+
item,
|
|
653
|
+
path,
|
|
654
|
+
open
|
|
655
|
+
]);
|
|
656
|
+
const handleSelect = useCallback3((option = false) => {
|
|
657
|
+
if (isBranch && (option || current)) {
|
|
658
|
+
handleOpenToggle();
|
|
659
|
+
} else if (canSelectItem) {
|
|
660
|
+
canSelect?.({
|
|
661
|
+
item,
|
|
662
|
+
path
|
|
663
|
+
});
|
|
664
|
+
rowRef.current?.focus();
|
|
665
|
+
onSelect?.({
|
|
666
|
+
item,
|
|
667
|
+
path,
|
|
668
|
+
current: !current,
|
|
669
|
+
option
|
|
670
|
+
});
|
|
671
|
+
}
|
|
672
|
+
}, [
|
|
673
|
+
item,
|
|
674
|
+
path,
|
|
675
|
+
current,
|
|
676
|
+
isBranch,
|
|
677
|
+
canSelectItem,
|
|
678
|
+
handleOpenToggle,
|
|
679
|
+
onSelect
|
|
680
|
+
]);
|
|
681
|
+
const handleKeyDown = useCallback3((event) => {
|
|
682
|
+
switch (event.key) {
|
|
683
|
+
case "ArrowRight":
|
|
684
|
+
case "ArrowLeft":
|
|
685
|
+
isBranch && handleOpenToggle();
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
}, [
|
|
689
|
+
isBranch,
|
|
690
|
+
open,
|
|
691
|
+
handleOpenToggle,
|
|
692
|
+
handleSelect
|
|
693
|
+
]);
|
|
694
|
+
const handleItemHover = useCallback3(() => {
|
|
695
|
+
onItemHover?.({
|
|
696
|
+
item
|
|
697
|
+
});
|
|
698
|
+
}, [
|
|
699
|
+
onItemHover,
|
|
700
|
+
item
|
|
701
|
+
]);
|
|
702
|
+
const handleContextMenu = useCallback3((event) => {
|
|
703
|
+
event.preventDefault();
|
|
704
|
+
setMenuOpen(true);
|
|
705
|
+
}, [
|
|
706
|
+
setMenuOpen
|
|
707
|
+
]);
|
|
708
|
+
const childProps = {
|
|
709
|
+
draggable: draggableProp,
|
|
710
|
+
renderColumns: Columns,
|
|
711
|
+
blockInstruction,
|
|
712
|
+
canDrop,
|
|
713
|
+
canSelect,
|
|
714
|
+
onItemHover,
|
|
715
|
+
onOpenChange,
|
|
716
|
+
onSelect
|
|
717
|
+
};
|
|
718
|
+
return /* @__PURE__ */ React7.createElement(React7.Fragment, null, /* @__PURE__ */ React7.createElement(Treegrid.Row, {
|
|
719
|
+
ref: rowRef,
|
|
720
|
+
key: id,
|
|
721
|
+
id,
|
|
722
|
+
"aria-labelledby": `${id}__label`,
|
|
723
|
+
parentOf: parentOf?.join(Treegrid.PARENT_OF_SEPARATOR),
|
|
724
|
+
"data-object-id": id,
|
|
725
|
+
"data-testid": testId,
|
|
726
|
+
// NOTE(thure): This is intentionally an empty string to for descendents to select by in the CSS
|
|
727
|
+
// without alerting the user (except for in the correct link element). See also:
|
|
728
|
+
// https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-current#description
|
|
729
|
+
"aria-current": current ? "" : void 0,
|
|
730
|
+
classNames: mx4("grid grid-cols-subgrid col-[tree-row] mt-0.5 is-current:bg-active-surface", hoverableControls, hoverableFocusedKeyboardControls, hoverableFocusedWithinControls, hoverableDescriptionIcons, ghostFocusWithin, ghostHover, className),
|
|
731
|
+
onKeyDown: handleKeyDown,
|
|
732
|
+
onMouseEnter: handleItemHover,
|
|
733
|
+
onContextMenu: handleContextMenu
|
|
734
|
+
}, /* @__PURE__ */ React7.createElement("div", {
|
|
735
|
+
role: "none",
|
|
736
|
+
className: "indent relative grid grid-cols-subgrid col-[tree-row]",
|
|
737
|
+
style: paddingIndentation(level)
|
|
738
|
+
}, /* @__PURE__ */ React7.createElement(Treegrid.Cell, {
|
|
739
|
+
classNames: "flex items-center"
|
|
740
|
+
}, /* @__PURE__ */ React7.createElement(TreeItemToggle, {
|
|
741
|
+
isBranch,
|
|
742
|
+
open,
|
|
743
|
+
onClick: handleOpenToggle
|
|
744
|
+
}), /* @__PURE__ */ React7.createElement(TreeItemHeading, {
|
|
745
|
+
disabled,
|
|
746
|
+
current,
|
|
747
|
+
label,
|
|
748
|
+
className: headingClassName,
|
|
749
|
+
icon,
|
|
750
|
+
iconHue,
|
|
751
|
+
onSelect: handleSelect,
|
|
752
|
+
ref: buttonRef
|
|
753
|
+
})), Columns && /* @__PURE__ */ React7.createElement(Columns, {
|
|
754
|
+
item,
|
|
755
|
+
path,
|
|
756
|
+
open,
|
|
757
|
+
menuOpen,
|
|
758
|
+
setMenuOpen
|
|
759
|
+
}), instruction && /* @__PURE__ */ React7.createElement(NaturalTreeItem.DropIndicator, {
|
|
760
|
+
instruction,
|
|
761
|
+
gap: 2
|
|
762
|
+
}))), open && childIds.map((childId, index) => /* @__PURE__ */ React7.createElement(TreeItemById, {
|
|
763
|
+
key: childId,
|
|
764
|
+
id: childId,
|
|
765
|
+
path,
|
|
766
|
+
last: index === childIds.length - 1,
|
|
767
|
+
...childProps
|
|
768
|
+
})));
|
|
818
769
|
};
|
|
819
770
|
var TreeItem = /* @__PURE__ */ memo3(RawTreeItem);
|
|
771
|
+
var RawTreeItemById = ({ id, ...props }) => {
|
|
772
|
+
const { item: itemAtom } = useTree();
|
|
773
|
+
const item = useAtomValue(itemAtom(id));
|
|
774
|
+
if (!item) {
|
|
775
|
+
return null;
|
|
776
|
+
}
|
|
777
|
+
return /* @__PURE__ */ React7.createElement(TreeItem, {
|
|
778
|
+
item,
|
|
779
|
+
...props
|
|
780
|
+
});
|
|
781
|
+
};
|
|
782
|
+
var TreeItemById = /* @__PURE__ */ memo3(RawTreeItemById);
|
|
820
783
|
|
|
821
784
|
// src/components/Tree/Tree.tsx
|
|
822
|
-
var Tree = ({
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
levelOffset,
|
|
857
|
-
draggable: draggable3,
|
|
858
|
-
renderColumns,
|
|
859
|
-
canDrop,
|
|
860
|
-
canSelect,
|
|
861
|
-
onOpenChange,
|
|
862
|
-
onSelect
|
|
863
|
-
}))));
|
|
864
|
-
} finally {
|
|
865
|
-
_effect.f();
|
|
866
|
-
}
|
|
785
|
+
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 }) => {
|
|
786
|
+
const childIds = useAtomValue2(model.childIds(rootId));
|
|
787
|
+
const treePath = useMemo2(() => path ? [
|
|
788
|
+
...path,
|
|
789
|
+
id
|
|
790
|
+
] : [
|
|
791
|
+
id
|
|
792
|
+
], [
|
|
793
|
+
id,
|
|
794
|
+
path
|
|
795
|
+
]);
|
|
796
|
+
const childProps = {
|
|
797
|
+
path: treePath,
|
|
798
|
+
levelOffset,
|
|
799
|
+
draggable: draggable3,
|
|
800
|
+
renderColumns,
|
|
801
|
+
blockInstruction,
|
|
802
|
+
canDrop,
|
|
803
|
+
canSelect,
|
|
804
|
+
onOpenChange,
|
|
805
|
+
onSelect,
|
|
806
|
+
onItemHover
|
|
807
|
+
};
|
|
808
|
+
return /* @__PURE__ */ React8.createElement(Treegrid2.Root, {
|
|
809
|
+
gridTemplateColumns,
|
|
810
|
+
classNames
|
|
811
|
+
}, /* @__PURE__ */ React8.createElement(TreeProvider, {
|
|
812
|
+
value: model
|
|
813
|
+
}, childIds.map((childId, index) => /* @__PURE__ */ React8.createElement(TreeItemById, {
|
|
814
|
+
key: childId,
|
|
815
|
+
id: childId,
|
|
816
|
+
last: index === childIds.length - 1,
|
|
817
|
+
...childProps
|
|
818
|
+
}))));
|
|
867
819
|
};
|
|
868
820
|
|
|
869
821
|
// src/util/path.ts
|
|
@@ -883,13 +835,17 @@ var Path = {
|
|
|
883
835
|
};
|
|
884
836
|
export {
|
|
885
837
|
Accordion,
|
|
838
|
+
DEFAULT_INDENTATION,
|
|
886
839
|
List,
|
|
887
840
|
Path,
|
|
888
841
|
Tree,
|
|
889
842
|
TreeDataSchema,
|
|
890
843
|
TreeItem,
|
|
844
|
+
TreeItemById,
|
|
845
|
+
TreeItemToggle,
|
|
891
846
|
TreeProvider,
|
|
892
847
|
isTreeData,
|
|
848
|
+
paddingIndentation,
|
|
893
849
|
useTree
|
|
894
850
|
};
|
|
895
851
|
//# sourceMappingURL=index.mjs.map
|