@edux-design/tree-select 0.2.3 → 0.2.5
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/README.md +40 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +108 -32
- package/dist/index.mjs +108 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -123,7 +123,22 @@ export function ChevronExample() {
|
|
|
123
123
|
Tree data to render. This component is controlled; updates are emitted through `onDataChange`.
|
|
124
124
|
|
|
125
125
|
### `onDataChange` (function)
|
|
126
|
-
Called with
|
|
126
|
+
Called with `(nextTree, meta?)` when edits, add actions, deletes, or drag-and-drop reordering occur.
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
type TreeSelectChangeMeta = {
|
|
130
|
+
reason: "drag" | "edit" | "add-child" | "add-sibling" | "delete";
|
|
131
|
+
activeId?: string | null;
|
|
132
|
+
draggedRootIds?: string[];
|
|
133
|
+
draggedIds?: string[];
|
|
134
|
+
sourceParentId?: string | null;
|
|
135
|
+
targetParentId?: string | null;
|
|
136
|
+
targetSiblingIndex?: number | null;
|
|
137
|
+
projectedDepth?: number | null;
|
|
138
|
+
};
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
For drag-and-drop, `meta.draggedRootIds` identifies the exact root nodes that moved, which removes ambiguity when multiple reorder outcomes can produce the same final tree shape.
|
|
127
142
|
|
|
128
143
|
### `onLabelChange` (function)
|
|
129
144
|
Called with `(id, nextLabel)` when a label edit is committed. When provided, label edits do not emit `onDataChange`.
|
|
@@ -164,6 +179,29 @@ import { MenuList, MenuItem } from "@edux-design/menus";
|
|
|
164
179
|
/>;
|
|
165
180
|
```
|
|
166
181
|
|
|
182
|
+
### `renderLabel` (function)
|
|
183
|
+
Renders custom inline content where the label normally appears. This is the supported way to compose metadata like `Tag` elements next to the item title.
|
|
184
|
+
|
|
185
|
+
```jsx
|
|
186
|
+
import { Tag } from "@edux-design/tags";
|
|
187
|
+
|
|
188
|
+
<TreeSelect
|
|
189
|
+
data={data}
|
|
190
|
+
renderLabel={({ id, node, hasChildren }) => (
|
|
191
|
+
<>
|
|
192
|
+
<span>{node.label ?? id}</span>
|
|
193
|
+
<Tag
|
|
194
|
+
size="small"
|
|
195
|
+
tone="subtle"
|
|
196
|
+
variant={hasChildren ? "information" : "neutral"}
|
|
197
|
+
>
|
|
198
|
+
{hasChildren ? "Group" : "Leaf"}
|
|
199
|
+
</Tag>
|
|
200
|
+
</>
|
|
201
|
+
)}
|
|
202
|
+
/>;
|
|
203
|
+
```
|
|
204
|
+
|
|
167
205
|
### `maxLabelLength` (number)
|
|
168
206
|
Limits label width by character count and truncates with an ellipsis when exceeded.
|
|
169
207
|
|
|
@@ -229,6 +267,7 @@ levelConfig={{
|
|
|
229
267
|
- `levelConfig` can override editability, actions, and tooltips per depth.
|
|
230
268
|
- Drag-and-drop supports reordering within a level and moving items between levels.
|
|
231
269
|
- Drag handle alignment is set so child handles align under the parent toggle.
|
|
270
|
+
- `renderLabel` customizes both the row content and the single-item drag overlay.
|
|
232
271
|
|
|
233
272
|
---
|
|
234
273
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
|
-
declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDrag, isEditable, allowDelete, useChevron, actionButtonsPosition, maxLabelLength, maxDepth, addChildTooltip, addSiblingTooltip, deleteTooltip, onLabelChange, levelConfig, defaultExpanded, expanded, onExpandedChange, renderAdditionalActionsMenu, }: {
|
|
3
|
+
declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDrag, isEditable, allowDelete, useChevron, actionButtonsPosition, maxLabelLength, maxDepth, addChildTooltip, addSiblingTooltip, deleteTooltip, onLabelChange, levelConfig, defaultExpanded, expanded, onExpandedChange, renderAdditionalActionsMenu, renderLabel, }: {
|
|
4
4
|
data: any;
|
|
5
5
|
onDataChange: any;
|
|
6
6
|
allowDragAndDrop?: boolean;
|
|
@@ -20,6 +20,7 @@ declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDr
|
|
|
20
20
|
expanded: any;
|
|
21
21
|
onExpandedChange: any;
|
|
22
22
|
renderAdditionalActionsMenu: any;
|
|
23
|
+
renderLabel: any;
|
|
23
24
|
}): react_jsx_runtime.JSX.Element;
|
|
24
25
|
|
|
25
26
|
export { TreeSelect };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
|
-
declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDrag, isEditable, allowDelete, useChevron, actionButtonsPosition, maxLabelLength, maxDepth, addChildTooltip, addSiblingTooltip, deleteTooltip, onLabelChange, levelConfig, defaultExpanded, expanded, onExpandedChange, renderAdditionalActionsMenu, }: {
|
|
3
|
+
declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDrag, isEditable, allowDelete, useChevron, actionButtonsPosition, maxLabelLength, maxDepth, addChildTooltip, addSiblingTooltip, deleteTooltip, onLabelChange, levelConfig, defaultExpanded, expanded, onExpandedChange, renderAdditionalActionsMenu, renderLabel, }: {
|
|
4
4
|
data: any;
|
|
5
5
|
onDataChange: any;
|
|
6
6
|
allowDragAndDrop?: boolean;
|
|
@@ -20,6 +20,7 @@ declare function TreeSelect({ data, onDataChange, allowDragAndDrop, allowMultiDr
|
|
|
20
20
|
expanded: any;
|
|
21
21
|
onExpandedChange: any;
|
|
22
22
|
renderAdditionalActionsMenu: any;
|
|
23
|
+
renderLabel: any;
|
|
23
24
|
}): react_jsx_runtime.JSX.Element;
|
|
24
25
|
|
|
25
26
|
export { TreeSelect };
|
package/dist/index.js
CHANGED
|
@@ -87,10 +87,19 @@ var TreeRow = ({
|
|
|
87
87
|
canDelete,
|
|
88
88
|
onDelete,
|
|
89
89
|
deleteTooltip,
|
|
90
|
-
additionalActionsMenu
|
|
90
|
+
additionalActionsMenu,
|
|
91
|
+
renderLabel
|
|
91
92
|
}) => {
|
|
92
93
|
const toggleLabel = isExpanded ? "Collapse item" : "Expand item";
|
|
93
94
|
const label = item.node.label ?? item.node.id;
|
|
95
|
+
const labelContent = renderLabel ? renderLabel({
|
|
96
|
+
id: item.id,
|
|
97
|
+
node: item.node,
|
|
98
|
+
depth,
|
|
99
|
+
parentId: item.parentId,
|
|
100
|
+
hasChildren: item.hasChildren,
|
|
101
|
+
isExpanded
|
|
102
|
+
}) : label;
|
|
94
103
|
const showToggle = item.hasChildren;
|
|
95
104
|
const [additionalMenuOpen, setAdditionalMenuOpen] = import_react.default.useState(false);
|
|
96
105
|
const rowBackground = isDragging ? "rgba(0, 0, 0, 0.04)" : isSelected ? "rgba(15, 98, 254, 0.08)" : void 0;
|
|
@@ -217,9 +226,13 @@ var TreeRow = ({
|
|
|
217
226
|
style: {
|
|
218
227
|
fontSize: 14,
|
|
219
228
|
cursor: isEditable ? "pointer" : "default",
|
|
220
|
-
...
|
|
229
|
+
...renderLabel ? {
|
|
230
|
+
display: "inline-flex",
|
|
231
|
+
alignItems: "center",
|
|
232
|
+
gap: 6
|
|
233
|
+
} : labelStyle
|
|
221
234
|
},
|
|
222
|
-
children:
|
|
235
|
+
children: labelContent
|
|
223
236
|
}
|
|
224
237
|
),
|
|
225
238
|
showActions ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
@@ -326,7 +339,8 @@ var TreeSortableRow = ({
|
|
|
326
339
|
canDelete,
|
|
327
340
|
onDelete,
|
|
328
341
|
deleteTooltip,
|
|
329
|
-
additionalActionsMenu
|
|
342
|
+
additionalActionsMenu,
|
|
343
|
+
renderLabel
|
|
330
344
|
}) => {
|
|
331
345
|
const {
|
|
332
346
|
attributes,
|
|
@@ -390,7 +404,8 @@ var TreeSortableRow = ({
|
|
|
390
404
|
canDelete,
|
|
391
405
|
onDelete,
|
|
392
406
|
deleteTooltip,
|
|
393
|
-
additionalActionsMenu
|
|
407
|
+
additionalActionsMenu,
|
|
408
|
+
renderLabel
|
|
394
409
|
}
|
|
395
410
|
);
|
|
396
411
|
};
|
|
@@ -765,9 +780,9 @@ function TreeSelect({
|
|
|
765
780
|
defaultExpanded,
|
|
766
781
|
expanded,
|
|
767
782
|
onExpandedChange,
|
|
768
|
-
renderAdditionalActionsMenu
|
|
783
|
+
renderAdditionalActionsMenu,
|
|
784
|
+
renderLabel
|
|
769
785
|
}) {
|
|
770
|
-
var _a, _b;
|
|
771
786
|
const [uncontrolledExpandedIds, setExpandedIds] = (0, import_react3.useState)(
|
|
772
787
|
() => getExpandedIds(data ?? [], defaultExpanded)
|
|
773
788
|
);
|
|
@@ -806,12 +821,12 @@ function TreeSelect({
|
|
|
806
821
|
}, [maxDepth]);
|
|
807
822
|
const resolvedLevelConfig = (0, import_react3.useCallback)(
|
|
808
823
|
(depth) => {
|
|
809
|
-
var
|
|
824
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
810
825
|
const defaults = (levelConfig == null ? void 0 : levelConfig.default) ?? {};
|
|
811
|
-
const perLevel = ((
|
|
826
|
+
const perLevel = ((_a = levelConfig == null ? void 0 : levelConfig.levels) == null ? void 0 : _a[depth]) ?? {};
|
|
812
827
|
const editable = perLevel.editable ?? defaults.editable ?? isEditable;
|
|
813
828
|
const actions = {
|
|
814
|
-
addChild: ((
|
|
829
|
+
addChild: ((_b = perLevel.actions) == null ? void 0 : _b.addChild) ?? ((_c = defaults.actions) == null ? void 0 : _c.addChild) ?? editable,
|
|
815
830
|
addSibling: ((_d = perLevel.actions) == null ? void 0 : _d.addSibling) ?? ((_e = defaults.actions) == null ? void 0 : _e.addSibling) ?? editable,
|
|
816
831
|
delete: ((_f = perLevel.actions) == null ? void 0 : _f.delete) ?? ((_g = defaults.actions) == null ? void 0 : _g.delete) ?? (editable && allowDelete)
|
|
817
832
|
};
|
|
@@ -845,6 +860,12 @@ function TreeSelect({
|
|
|
845
860
|
},
|
|
846
861
|
[expandedIds, isExpandedControlled, onExpandedChange]
|
|
847
862
|
);
|
|
863
|
+
const emitDataChange = (0, import_react3.useCallback)(
|
|
864
|
+
(nextTree, meta) => {
|
|
865
|
+
onDataChange == null ? void 0 : onDataChange(nextTree, meta);
|
|
866
|
+
},
|
|
867
|
+
[onDataChange]
|
|
868
|
+
);
|
|
848
869
|
const toggleExpanded = (0, import_react3.useCallback)((id) => {
|
|
849
870
|
updateExpandedIds((prev) => {
|
|
850
871
|
if (prev.has(id)) {
|
|
@@ -857,15 +878,15 @@ function TreeSelect({
|
|
|
857
878
|
}, [updateExpandedIds]);
|
|
858
879
|
const handleRowClick = (0, import_react3.useCallback)(
|
|
859
880
|
(event, id) => {
|
|
860
|
-
var
|
|
881
|
+
var _a, _b;
|
|
861
882
|
if (!allowMultiDrag) return;
|
|
862
883
|
const hasMultiKey = event.metaKey || event.ctrlKey;
|
|
863
|
-
const parentId = ((
|
|
884
|
+
const parentId = ((_a = itemById.get(id)) == null ? void 0 : _a.parentId) ?? null;
|
|
864
885
|
const siblingOrder = siblingOrderMap.get(parentId) ?? [];
|
|
865
886
|
if (event.shiftKey) {
|
|
866
887
|
const anchorIndex = siblingOrder.indexOf(lastSelectedId);
|
|
867
888
|
const targetIndex = siblingOrder.indexOf(id);
|
|
868
|
-
if (anchorIndex < 0 || targetIndex < 0 || (((
|
|
889
|
+
if (anchorIndex < 0 || targetIndex < 0 || (((_b = itemById.get(lastSelectedId ?? "")) == null ? void 0 : _b.parentId) ?? null) !== parentId) {
|
|
869
890
|
setSelectedIds(/* @__PURE__ */ new Set([id]));
|
|
870
891
|
setLastSelectedId(id);
|
|
871
892
|
return;
|
|
@@ -887,10 +908,10 @@ function TreeSelect({
|
|
|
887
908
|
return;
|
|
888
909
|
}
|
|
889
910
|
setSelectedIds((prev) => {
|
|
890
|
-
var
|
|
911
|
+
var _a2;
|
|
891
912
|
if (prev.size) {
|
|
892
913
|
const firstSelected = prev.values().next().value;
|
|
893
|
-
const selectedParent = ((
|
|
914
|
+
const selectedParent = ((_a2 = itemById.get(firstSelected)) == null ? void 0 : _a2.parentId) ?? null;
|
|
894
915
|
if (selectedParent !== parentId) {
|
|
895
916
|
return /* @__PURE__ */ new Set([id]);
|
|
896
917
|
}
|
|
@@ -948,12 +969,13 @@ function TreeSelect({
|
|
|
948
969
|
setHorizontalOffset(event.delta.x);
|
|
949
970
|
}, []);
|
|
950
971
|
const handleDragOver = (0, import_react3.useCallback)((event) => {
|
|
951
|
-
var
|
|
952
|
-
if ((
|
|
972
|
+
var _a;
|
|
973
|
+
if ((_a = event.over) == null ? void 0 : _a.id) {
|
|
953
974
|
setOverId(normaliseId(event.over.id));
|
|
954
975
|
}
|
|
955
976
|
}, []);
|
|
956
977
|
const handleDragEnd = (0, import_react3.useCallback)(() => {
|
|
978
|
+
var _a;
|
|
957
979
|
const projection = getDropProjection({
|
|
958
980
|
items: visibleItems,
|
|
959
981
|
activeId,
|
|
@@ -969,6 +991,7 @@ function TreeSelect({
|
|
|
969
991
|
return;
|
|
970
992
|
}
|
|
971
993
|
const { parentId, siblingIndex, projectedDepth } = projection;
|
|
994
|
+
const sourceParentId = ((_a = itemById.get(draggedRootIds[0] ?? activeId)) == null ? void 0 : _a.parentId) ?? null;
|
|
972
995
|
const { nextNodes, removedNodes } = removeNodes(treeData, draggedRootIds);
|
|
973
996
|
if (!removedNodes.length) {
|
|
974
997
|
setActiveId(null);
|
|
@@ -980,7 +1003,16 @@ function TreeSelect({
|
|
|
980
1003
|
removedNodes.forEach((node, index) => {
|
|
981
1004
|
nextTree = insertNode(nextTree, parentId, siblingIndex + index, node);
|
|
982
1005
|
});
|
|
983
|
-
|
|
1006
|
+
emitDataChange(nextTree, {
|
|
1007
|
+
reason: "drag",
|
|
1008
|
+
activeId,
|
|
1009
|
+
draggedRootIds,
|
|
1010
|
+
draggedIds: Array.from(draggedIds),
|
|
1011
|
+
sourceParentId,
|
|
1012
|
+
targetParentId: parentId ?? null,
|
|
1013
|
+
targetSiblingIndex: siblingIndex,
|
|
1014
|
+
projectedDepth
|
|
1015
|
+
});
|
|
984
1016
|
if (parentId && projectedDepth > 0) {
|
|
985
1017
|
updateExpandedIds((prev) => {
|
|
986
1018
|
prev.add(parentId);
|
|
@@ -994,8 +1026,9 @@ function TreeSelect({
|
|
|
994
1026
|
activeId,
|
|
995
1027
|
draggedIds,
|
|
996
1028
|
draggedRootIds,
|
|
1029
|
+
emitDataChange,
|
|
997
1030
|
horizontalOffset,
|
|
998
|
-
|
|
1031
|
+
itemById,
|
|
999
1032
|
overId,
|
|
1000
1033
|
treeData,
|
|
1001
1034
|
updateExpandedIds,
|
|
@@ -1018,29 +1051,40 @@ function TreeSelect({
|
|
|
1018
1051
|
(parentId) => {
|
|
1019
1052
|
const newNode = createNewNode();
|
|
1020
1053
|
const nextTree = addChildNode(treeData, parentId, newNode);
|
|
1021
|
-
|
|
1054
|
+
emitDataChange(nextTree, {
|
|
1055
|
+
reason: "add-child",
|
|
1056
|
+
activeId: newNode.id,
|
|
1057
|
+
targetParentId: parentId
|
|
1058
|
+
});
|
|
1022
1059
|
updateExpandedIds((prev) => {
|
|
1023
1060
|
prev.add(parentId);
|
|
1024
1061
|
return prev;
|
|
1025
1062
|
});
|
|
1026
1063
|
},
|
|
1027
|
-
[createNewNode,
|
|
1064
|
+
[createNewNode, emitDataChange, treeData, updateExpandedIds]
|
|
1028
1065
|
);
|
|
1029
1066
|
const handleAddSibling = (0, import_react3.useCallback)(
|
|
1030
1067
|
(targetId) => {
|
|
1031
1068
|
const newNode = createNewNode();
|
|
1032
1069
|
const { nextNodes, inserted } = addSiblingNode(treeData, targetId, newNode);
|
|
1033
1070
|
if (!inserted) return;
|
|
1034
|
-
|
|
1071
|
+
emitDataChange(nextNodes, {
|
|
1072
|
+
reason: "add-sibling",
|
|
1073
|
+
activeId: newNode.id
|
|
1074
|
+
});
|
|
1035
1075
|
},
|
|
1036
|
-
[createNewNode,
|
|
1076
|
+
[createNewNode, emitDataChange, treeData]
|
|
1037
1077
|
);
|
|
1038
1078
|
const handleDelete = (0, import_react3.useCallback)(
|
|
1039
1079
|
(targetId) => {
|
|
1040
1080
|
const { nextNodes, removed } = removeNode(treeData, targetId);
|
|
1041
1081
|
if (!removed) return;
|
|
1042
1082
|
const removedIds = collectNodeIds(removed);
|
|
1043
|
-
|
|
1083
|
+
emitDataChange(nextNodes, {
|
|
1084
|
+
reason: "delete",
|
|
1085
|
+
activeId: targetId,
|
|
1086
|
+
draggedIds: Array.from(removedIds)
|
|
1087
|
+
});
|
|
1044
1088
|
updateExpandedIds((prev) => {
|
|
1045
1089
|
removedIds.forEach((id) => prev.delete(id));
|
|
1046
1090
|
return prev;
|
|
@@ -1056,12 +1100,12 @@ function TreeSelect({
|
|
|
1056
1100
|
);
|
|
1057
1101
|
setEditingId((prev) => prev && removedIds.has(prev) ? null : prev);
|
|
1058
1102
|
},
|
|
1059
|
-
[
|
|
1103
|
+
[emitDataChange, treeData, updateExpandedIds]
|
|
1060
1104
|
);
|
|
1061
1105
|
const startEdit = (0, import_react3.useCallback)(
|
|
1062
1106
|
(id) => {
|
|
1063
|
-
var
|
|
1064
|
-
const currentLabel = ((
|
|
1107
|
+
var _a, _b, _c, _d;
|
|
1108
|
+
const currentLabel = ((_b = (_a = itemById.get(id)) == null ? void 0 : _a.node) == null ? void 0 : _b.label) ?? ((_d = (_c = itemById.get(id)) == null ? void 0 : _c.node) == null ? void 0 : _d.id) ?? "";
|
|
1065
1109
|
setEditingId(id);
|
|
1066
1110
|
setDraftLabel(String(currentLabel));
|
|
1067
1111
|
},
|
|
@@ -1080,12 +1124,30 @@ function TreeSelect({
|
|
|
1080
1124
|
return;
|
|
1081
1125
|
}
|
|
1082
1126
|
const nextTree = updateNodeLabel(treeData, editingId, nextLabel);
|
|
1083
|
-
|
|
1127
|
+
emitDataChange(nextTree, {
|
|
1128
|
+
reason: "edit",
|
|
1129
|
+
activeId: editingId
|
|
1130
|
+
});
|
|
1084
1131
|
setEditingId(null);
|
|
1085
|
-
}, [draftLabel, editingId,
|
|
1132
|
+
}, [draftLabel, editingId, emitDataChange, onLabelChange, treeData]);
|
|
1086
1133
|
const cancelEdit = (0, import_react3.useCallback)(() => {
|
|
1087
1134
|
setEditingId(null);
|
|
1088
1135
|
}, []);
|
|
1136
|
+
const renderLabelContent = (0, import_react3.useCallback)(
|
|
1137
|
+
(item) => {
|
|
1138
|
+
if (!item) return null;
|
|
1139
|
+
if (!renderLabel) return item.node.label ?? item.id;
|
|
1140
|
+
return renderLabel({
|
|
1141
|
+
id: item.id,
|
|
1142
|
+
node: item.node,
|
|
1143
|
+
depth: item.depth,
|
|
1144
|
+
parentId: item.parentId,
|
|
1145
|
+
hasChildren: item.hasChildren,
|
|
1146
|
+
isExpanded: expandedIds.has(item.id)
|
|
1147
|
+
});
|
|
1148
|
+
},
|
|
1149
|
+
[expandedIds, renderLabel]
|
|
1150
|
+
);
|
|
1089
1151
|
const indicator = (0, import_react3.useMemo)(() => {
|
|
1090
1152
|
if (!allowDragAndDrop) return null;
|
|
1091
1153
|
return getDropIndicator({
|
|
@@ -1174,7 +1236,8 @@ function TreeSelect({
|
|
|
1174
1236
|
canDelete: levelSettings.actions.delete,
|
|
1175
1237
|
onDelete: handleDelete,
|
|
1176
1238
|
deleteTooltip: levelSettings.tooltips.delete,
|
|
1177
|
-
additionalActionsMenu
|
|
1239
|
+
additionalActionsMenu,
|
|
1240
|
+
renderLabel
|
|
1178
1241
|
},
|
|
1179
1242
|
item.id
|
|
1180
1243
|
);
|
|
@@ -1189,7 +1252,19 @@ function TreeSelect({
|
|
|
1189
1252
|
borderRadius: 6,
|
|
1190
1253
|
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.12)"
|
|
1191
1254
|
},
|
|
1192
|
-
children: draggedRootIds.length > 1 ? `${draggedRootIds.length} items` :
|
|
1255
|
+
children: draggedRootIds.length > 1 ? `${draggedRootIds.length} items` : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1256
|
+
"span",
|
|
1257
|
+
{
|
|
1258
|
+
style: {
|
|
1259
|
+
display: "inline-flex",
|
|
1260
|
+
alignItems: "center",
|
|
1261
|
+
gap: 6
|
|
1262
|
+
},
|
|
1263
|
+
children: renderLabelContent(
|
|
1264
|
+
visibleItems.find((item) => item.id === activeId)
|
|
1265
|
+
) ?? activeId
|
|
1266
|
+
}
|
|
1267
|
+
)
|
|
1193
1268
|
}
|
|
1194
1269
|
) : null })
|
|
1195
1270
|
]
|
|
@@ -1234,7 +1309,8 @@ function TreeSelect({
|
|
|
1234
1309
|
canDelete: levelSettings.actions.delete,
|
|
1235
1310
|
onDelete: handleDelete,
|
|
1236
1311
|
deleteTooltip: levelSettings.tooltips.delete,
|
|
1237
|
-
additionalActionsMenu
|
|
1312
|
+
additionalActionsMenu,
|
|
1313
|
+
renderLabel
|
|
1238
1314
|
},
|
|
1239
1315
|
item.id
|
|
1240
1316
|
);
|
package/dist/index.mjs
CHANGED
|
@@ -70,10 +70,19 @@ var TreeRow = ({
|
|
|
70
70
|
canDelete,
|
|
71
71
|
onDelete,
|
|
72
72
|
deleteTooltip,
|
|
73
|
-
additionalActionsMenu
|
|
73
|
+
additionalActionsMenu,
|
|
74
|
+
renderLabel
|
|
74
75
|
}) => {
|
|
75
76
|
const toggleLabel = isExpanded ? "Collapse item" : "Expand item";
|
|
76
77
|
const label = item.node.label ?? item.node.id;
|
|
78
|
+
const labelContent = renderLabel ? renderLabel({
|
|
79
|
+
id: item.id,
|
|
80
|
+
node: item.node,
|
|
81
|
+
depth,
|
|
82
|
+
parentId: item.parentId,
|
|
83
|
+
hasChildren: item.hasChildren,
|
|
84
|
+
isExpanded
|
|
85
|
+
}) : label;
|
|
77
86
|
const showToggle = item.hasChildren;
|
|
78
87
|
const [additionalMenuOpen, setAdditionalMenuOpen] = React.useState(false);
|
|
79
88
|
const rowBackground = isDragging ? "rgba(0, 0, 0, 0.04)" : isSelected ? "rgba(15, 98, 254, 0.08)" : void 0;
|
|
@@ -200,9 +209,13 @@ var TreeRow = ({
|
|
|
200
209
|
style: {
|
|
201
210
|
fontSize: 14,
|
|
202
211
|
cursor: isEditable ? "pointer" : "default",
|
|
203
|
-
...
|
|
212
|
+
...renderLabel ? {
|
|
213
|
+
display: "inline-flex",
|
|
214
|
+
alignItems: "center",
|
|
215
|
+
gap: 6
|
|
216
|
+
} : labelStyle
|
|
204
217
|
},
|
|
205
|
-
children:
|
|
218
|
+
children: labelContent
|
|
206
219
|
}
|
|
207
220
|
),
|
|
208
221
|
showActions ? /* @__PURE__ */ jsxs(
|
|
@@ -309,7 +322,8 @@ var TreeSortableRow = ({
|
|
|
309
322
|
canDelete,
|
|
310
323
|
onDelete,
|
|
311
324
|
deleteTooltip,
|
|
312
|
-
additionalActionsMenu
|
|
325
|
+
additionalActionsMenu,
|
|
326
|
+
renderLabel
|
|
313
327
|
}) => {
|
|
314
328
|
const {
|
|
315
329
|
attributes,
|
|
@@ -373,7 +387,8 @@ var TreeSortableRow = ({
|
|
|
373
387
|
canDelete,
|
|
374
388
|
onDelete,
|
|
375
389
|
deleteTooltip,
|
|
376
|
-
additionalActionsMenu
|
|
390
|
+
additionalActionsMenu,
|
|
391
|
+
renderLabel
|
|
377
392
|
}
|
|
378
393
|
);
|
|
379
394
|
};
|
|
@@ -748,9 +763,9 @@ function TreeSelect({
|
|
|
748
763
|
defaultExpanded,
|
|
749
764
|
expanded,
|
|
750
765
|
onExpandedChange,
|
|
751
|
-
renderAdditionalActionsMenu
|
|
766
|
+
renderAdditionalActionsMenu,
|
|
767
|
+
renderLabel
|
|
752
768
|
}) {
|
|
753
|
-
var _a, _b;
|
|
754
769
|
const [uncontrolledExpandedIds, setExpandedIds] = useState(
|
|
755
770
|
() => getExpandedIds(data ?? [], defaultExpanded)
|
|
756
771
|
);
|
|
@@ -789,12 +804,12 @@ function TreeSelect({
|
|
|
789
804
|
}, [maxDepth]);
|
|
790
805
|
const resolvedLevelConfig = useCallback2(
|
|
791
806
|
(depth) => {
|
|
792
|
-
var
|
|
807
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
793
808
|
const defaults = (levelConfig == null ? void 0 : levelConfig.default) ?? {};
|
|
794
|
-
const perLevel = ((
|
|
809
|
+
const perLevel = ((_a = levelConfig == null ? void 0 : levelConfig.levels) == null ? void 0 : _a[depth]) ?? {};
|
|
795
810
|
const editable = perLevel.editable ?? defaults.editable ?? isEditable;
|
|
796
811
|
const actions = {
|
|
797
|
-
addChild: ((
|
|
812
|
+
addChild: ((_b = perLevel.actions) == null ? void 0 : _b.addChild) ?? ((_c = defaults.actions) == null ? void 0 : _c.addChild) ?? editable,
|
|
798
813
|
addSibling: ((_d = perLevel.actions) == null ? void 0 : _d.addSibling) ?? ((_e = defaults.actions) == null ? void 0 : _e.addSibling) ?? editable,
|
|
799
814
|
delete: ((_f = perLevel.actions) == null ? void 0 : _f.delete) ?? ((_g = defaults.actions) == null ? void 0 : _g.delete) ?? (editable && allowDelete)
|
|
800
815
|
};
|
|
@@ -828,6 +843,12 @@ function TreeSelect({
|
|
|
828
843
|
},
|
|
829
844
|
[expandedIds, isExpandedControlled, onExpandedChange]
|
|
830
845
|
);
|
|
846
|
+
const emitDataChange = useCallback2(
|
|
847
|
+
(nextTree, meta) => {
|
|
848
|
+
onDataChange == null ? void 0 : onDataChange(nextTree, meta);
|
|
849
|
+
},
|
|
850
|
+
[onDataChange]
|
|
851
|
+
);
|
|
831
852
|
const toggleExpanded = useCallback2((id) => {
|
|
832
853
|
updateExpandedIds((prev) => {
|
|
833
854
|
if (prev.has(id)) {
|
|
@@ -840,15 +861,15 @@ function TreeSelect({
|
|
|
840
861
|
}, [updateExpandedIds]);
|
|
841
862
|
const handleRowClick = useCallback2(
|
|
842
863
|
(event, id) => {
|
|
843
|
-
var
|
|
864
|
+
var _a, _b;
|
|
844
865
|
if (!allowMultiDrag) return;
|
|
845
866
|
const hasMultiKey = event.metaKey || event.ctrlKey;
|
|
846
|
-
const parentId = ((
|
|
867
|
+
const parentId = ((_a = itemById.get(id)) == null ? void 0 : _a.parentId) ?? null;
|
|
847
868
|
const siblingOrder = siblingOrderMap.get(parentId) ?? [];
|
|
848
869
|
if (event.shiftKey) {
|
|
849
870
|
const anchorIndex = siblingOrder.indexOf(lastSelectedId);
|
|
850
871
|
const targetIndex = siblingOrder.indexOf(id);
|
|
851
|
-
if (anchorIndex < 0 || targetIndex < 0 || (((
|
|
872
|
+
if (anchorIndex < 0 || targetIndex < 0 || (((_b = itemById.get(lastSelectedId ?? "")) == null ? void 0 : _b.parentId) ?? null) !== parentId) {
|
|
852
873
|
setSelectedIds(/* @__PURE__ */ new Set([id]));
|
|
853
874
|
setLastSelectedId(id);
|
|
854
875
|
return;
|
|
@@ -870,10 +891,10 @@ function TreeSelect({
|
|
|
870
891
|
return;
|
|
871
892
|
}
|
|
872
893
|
setSelectedIds((prev) => {
|
|
873
|
-
var
|
|
894
|
+
var _a2;
|
|
874
895
|
if (prev.size) {
|
|
875
896
|
const firstSelected = prev.values().next().value;
|
|
876
|
-
const selectedParent = ((
|
|
897
|
+
const selectedParent = ((_a2 = itemById.get(firstSelected)) == null ? void 0 : _a2.parentId) ?? null;
|
|
877
898
|
if (selectedParent !== parentId) {
|
|
878
899
|
return /* @__PURE__ */ new Set([id]);
|
|
879
900
|
}
|
|
@@ -931,12 +952,13 @@ function TreeSelect({
|
|
|
931
952
|
setHorizontalOffset(event.delta.x);
|
|
932
953
|
}, []);
|
|
933
954
|
const handleDragOver = useCallback2((event) => {
|
|
934
|
-
var
|
|
935
|
-
if ((
|
|
955
|
+
var _a;
|
|
956
|
+
if ((_a = event.over) == null ? void 0 : _a.id) {
|
|
936
957
|
setOverId(normaliseId(event.over.id));
|
|
937
958
|
}
|
|
938
959
|
}, []);
|
|
939
960
|
const handleDragEnd = useCallback2(() => {
|
|
961
|
+
var _a;
|
|
940
962
|
const projection = getDropProjection({
|
|
941
963
|
items: visibleItems,
|
|
942
964
|
activeId,
|
|
@@ -952,6 +974,7 @@ function TreeSelect({
|
|
|
952
974
|
return;
|
|
953
975
|
}
|
|
954
976
|
const { parentId, siblingIndex, projectedDepth } = projection;
|
|
977
|
+
const sourceParentId = ((_a = itemById.get(draggedRootIds[0] ?? activeId)) == null ? void 0 : _a.parentId) ?? null;
|
|
955
978
|
const { nextNodes, removedNodes } = removeNodes(treeData, draggedRootIds);
|
|
956
979
|
if (!removedNodes.length) {
|
|
957
980
|
setActiveId(null);
|
|
@@ -963,7 +986,16 @@ function TreeSelect({
|
|
|
963
986
|
removedNodes.forEach((node, index) => {
|
|
964
987
|
nextTree = insertNode(nextTree, parentId, siblingIndex + index, node);
|
|
965
988
|
});
|
|
966
|
-
|
|
989
|
+
emitDataChange(nextTree, {
|
|
990
|
+
reason: "drag",
|
|
991
|
+
activeId,
|
|
992
|
+
draggedRootIds,
|
|
993
|
+
draggedIds: Array.from(draggedIds),
|
|
994
|
+
sourceParentId,
|
|
995
|
+
targetParentId: parentId ?? null,
|
|
996
|
+
targetSiblingIndex: siblingIndex,
|
|
997
|
+
projectedDepth
|
|
998
|
+
});
|
|
967
999
|
if (parentId && projectedDepth > 0) {
|
|
968
1000
|
updateExpandedIds((prev) => {
|
|
969
1001
|
prev.add(parentId);
|
|
@@ -977,8 +1009,9 @@ function TreeSelect({
|
|
|
977
1009
|
activeId,
|
|
978
1010
|
draggedIds,
|
|
979
1011
|
draggedRootIds,
|
|
1012
|
+
emitDataChange,
|
|
980
1013
|
horizontalOffset,
|
|
981
|
-
|
|
1014
|
+
itemById,
|
|
982
1015
|
overId,
|
|
983
1016
|
treeData,
|
|
984
1017
|
updateExpandedIds,
|
|
@@ -1001,29 +1034,40 @@ function TreeSelect({
|
|
|
1001
1034
|
(parentId) => {
|
|
1002
1035
|
const newNode = createNewNode();
|
|
1003
1036
|
const nextTree = addChildNode(treeData, parentId, newNode);
|
|
1004
|
-
|
|
1037
|
+
emitDataChange(nextTree, {
|
|
1038
|
+
reason: "add-child",
|
|
1039
|
+
activeId: newNode.id,
|
|
1040
|
+
targetParentId: parentId
|
|
1041
|
+
});
|
|
1005
1042
|
updateExpandedIds((prev) => {
|
|
1006
1043
|
prev.add(parentId);
|
|
1007
1044
|
return prev;
|
|
1008
1045
|
});
|
|
1009
1046
|
},
|
|
1010
|
-
[createNewNode,
|
|
1047
|
+
[createNewNode, emitDataChange, treeData, updateExpandedIds]
|
|
1011
1048
|
);
|
|
1012
1049
|
const handleAddSibling = useCallback2(
|
|
1013
1050
|
(targetId) => {
|
|
1014
1051
|
const newNode = createNewNode();
|
|
1015
1052
|
const { nextNodes, inserted } = addSiblingNode(treeData, targetId, newNode);
|
|
1016
1053
|
if (!inserted) return;
|
|
1017
|
-
|
|
1054
|
+
emitDataChange(nextNodes, {
|
|
1055
|
+
reason: "add-sibling",
|
|
1056
|
+
activeId: newNode.id
|
|
1057
|
+
});
|
|
1018
1058
|
},
|
|
1019
|
-
[createNewNode,
|
|
1059
|
+
[createNewNode, emitDataChange, treeData]
|
|
1020
1060
|
);
|
|
1021
1061
|
const handleDelete = useCallback2(
|
|
1022
1062
|
(targetId) => {
|
|
1023
1063
|
const { nextNodes, removed } = removeNode(treeData, targetId);
|
|
1024
1064
|
if (!removed) return;
|
|
1025
1065
|
const removedIds = collectNodeIds(removed);
|
|
1026
|
-
|
|
1066
|
+
emitDataChange(nextNodes, {
|
|
1067
|
+
reason: "delete",
|
|
1068
|
+
activeId: targetId,
|
|
1069
|
+
draggedIds: Array.from(removedIds)
|
|
1070
|
+
});
|
|
1027
1071
|
updateExpandedIds((prev) => {
|
|
1028
1072
|
removedIds.forEach((id) => prev.delete(id));
|
|
1029
1073
|
return prev;
|
|
@@ -1039,12 +1083,12 @@ function TreeSelect({
|
|
|
1039
1083
|
);
|
|
1040
1084
|
setEditingId((prev) => prev && removedIds.has(prev) ? null : prev);
|
|
1041
1085
|
},
|
|
1042
|
-
[
|
|
1086
|
+
[emitDataChange, treeData, updateExpandedIds]
|
|
1043
1087
|
);
|
|
1044
1088
|
const startEdit = useCallback2(
|
|
1045
1089
|
(id) => {
|
|
1046
|
-
var
|
|
1047
|
-
const currentLabel = ((
|
|
1090
|
+
var _a, _b, _c, _d;
|
|
1091
|
+
const currentLabel = ((_b = (_a = itemById.get(id)) == null ? void 0 : _a.node) == null ? void 0 : _b.label) ?? ((_d = (_c = itemById.get(id)) == null ? void 0 : _c.node) == null ? void 0 : _d.id) ?? "";
|
|
1048
1092
|
setEditingId(id);
|
|
1049
1093
|
setDraftLabel(String(currentLabel));
|
|
1050
1094
|
},
|
|
@@ -1063,12 +1107,30 @@ function TreeSelect({
|
|
|
1063
1107
|
return;
|
|
1064
1108
|
}
|
|
1065
1109
|
const nextTree = updateNodeLabel(treeData, editingId, nextLabel);
|
|
1066
|
-
|
|
1110
|
+
emitDataChange(nextTree, {
|
|
1111
|
+
reason: "edit",
|
|
1112
|
+
activeId: editingId
|
|
1113
|
+
});
|
|
1067
1114
|
setEditingId(null);
|
|
1068
|
-
}, [draftLabel, editingId,
|
|
1115
|
+
}, [draftLabel, editingId, emitDataChange, onLabelChange, treeData]);
|
|
1069
1116
|
const cancelEdit = useCallback2(() => {
|
|
1070
1117
|
setEditingId(null);
|
|
1071
1118
|
}, []);
|
|
1119
|
+
const renderLabelContent = useCallback2(
|
|
1120
|
+
(item) => {
|
|
1121
|
+
if (!item) return null;
|
|
1122
|
+
if (!renderLabel) return item.node.label ?? item.id;
|
|
1123
|
+
return renderLabel({
|
|
1124
|
+
id: item.id,
|
|
1125
|
+
node: item.node,
|
|
1126
|
+
depth: item.depth,
|
|
1127
|
+
parentId: item.parentId,
|
|
1128
|
+
hasChildren: item.hasChildren,
|
|
1129
|
+
isExpanded: expandedIds.has(item.id)
|
|
1130
|
+
});
|
|
1131
|
+
},
|
|
1132
|
+
[expandedIds, renderLabel]
|
|
1133
|
+
);
|
|
1072
1134
|
const indicator = useMemo2(() => {
|
|
1073
1135
|
if (!allowDragAndDrop) return null;
|
|
1074
1136
|
return getDropIndicator({
|
|
@@ -1157,7 +1219,8 @@ function TreeSelect({
|
|
|
1157
1219
|
canDelete: levelSettings.actions.delete,
|
|
1158
1220
|
onDelete: handleDelete,
|
|
1159
1221
|
deleteTooltip: levelSettings.tooltips.delete,
|
|
1160
|
-
additionalActionsMenu
|
|
1222
|
+
additionalActionsMenu,
|
|
1223
|
+
renderLabel
|
|
1161
1224
|
},
|
|
1162
1225
|
item.id
|
|
1163
1226
|
);
|
|
@@ -1172,7 +1235,19 @@ function TreeSelect({
|
|
|
1172
1235
|
borderRadius: 6,
|
|
1173
1236
|
boxShadow: "0 8px 24px rgba(0, 0, 0, 0.12)"
|
|
1174
1237
|
},
|
|
1175
|
-
children: draggedRootIds.length > 1 ? `${draggedRootIds.length} items` :
|
|
1238
|
+
children: draggedRootIds.length > 1 ? `${draggedRootIds.length} items` : /* @__PURE__ */ jsx3(
|
|
1239
|
+
"span",
|
|
1240
|
+
{
|
|
1241
|
+
style: {
|
|
1242
|
+
display: "inline-flex",
|
|
1243
|
+
alignItems: "center",
|
|
1244
|
+
gap: 6
|
|
1245
|
+
},
|
|
1246
|
+
children: renderLabelContent(
|
|
1247
|
+
visibleItems.find((item) => item.id === activeId)
|
|
1248
|
+
) ?? activeId
|
|
1249
|
+
}
|
|
1250
|
+
)
|
|
1176
1251
|
}
|
|
1177
1252
|
) : null })
|
|
1178
1253
|
]
|
|
@@ -1217,7 +1292,8 @@ function TreeSelect({
|
|
|
1217
1292
|
canDelete: levelSettings.actions.delete,
|
|
1218
1293
|
onDelete: handleDelete,
|
|
1219
1294
|
deleteTooltip: levelSettings.tooltips.delete,
|
|
1220
|
-
additionalActionsMenu
|
|
1295
|
+
additionalActionsMenu,
|
|
1296
|
+
renderLabel
|
|
1221
1297
|
},
|
|
1222
1298
|
item.id
|
|
1223
1299
|
);
|