@edux-design/tree-select 0.2.3 → 0.2.4
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 +16 -1
- package/dist/index.js +42 -10
- package/dist/index.mjs +42 -10
- 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`.
|
package/dist/index.js
CHANGED
|
@@ -845,6 +845,12 @@ function TreeSelect({
|
|
|
845
845
|
},
|
|
846
846
|
[expandedIds, isExpandedControlled, onExpandedChange]
|
|
847
847
|
);
|
|
848
|
+
const emitDataChange = (0, import_react3.useCallback)(
|
|
849
|
+
(nextTree, meta) => {
|
|
850
|
+
onDataChange == null ? void 0 : onDataChange(nextTree, meta);
|
|
851
|
+
},
|
|
852
|
+
[onDataChange]
|
|
853
|
+
);
|
|
848
854
|
const toggleExpanded = (0, import_react3.useCallback)((id) => {
|
|
849
855
|
updateExpandedIds((prev) => {
|
|
850
856
|
if (prev.has(id)) {
|
|
@@ -954,6 +960,7 @@ function TreeSelect({
|
|
|
954
960
|
}
|
|
955
961
|
}, []);
|
|
956
962
|
const handleDragEnd = (0, import_react3.useCallback)(() => {
|
|
963
|
+
var _a2;
|
|
957
964
|
const projection = getDropProjection({
|
|
958
965
|
items: visibleItems,
|
|
959
966
|
activeId,
|
|
@@ -969,6 +976,7 @@ function TreeSelect({
|
|
|
969
976
|
return;
|
|
970
977
|
}
|
|
971
978
|
const { parentId, siblingIndex, projectedDepth } = projection;
|
|
979
|
+
const sourceParentId = ((_a2 = itemById.get(draggedRootIds[0] ?? activeId)) == null ? void 0 : _a2.parentId) ?? null;
|
|
972
980
|
const { nextNodes, removedNodes } = removeNodes(treeData, draggedRootIds);
|
|
973
981
|
if (!removedNodes.length) {
|
|
974
982
|
setActiveId(null);
|
|
@@ -980,7 +988,16 @@ function TreeSelect({
|
|
|
980
988
|
removedNodes.forEach((node, index) => {
|
|
981
989
|
nextTree = insertNode(nextTree, parentId, siblingIndex + index, node);
|
|
982
990
|
});
|
|
983
|
-
|
|
991
|
+
emitDataChange(nextTree, {
|
|
992
|
+
reason: "drag",
|
|
993
|
+
activeId,
|
|
994
|
+
draggedRootIds,
|
|
995
|
+
draggedIds: Array.from(draggedIds),
|
|
996
|
+
sourceParentId,
|
|
997
|
+
targetParentId: parentId ?? null,
|
|
998
|
+
targetSiblingIndex: siblingIndex,
|
|
999
|
+
projectedDepth
|
|
1000
|
+
});
|
|
984
1001
|
if (parentId && projectedDepth > 0) {
|
|
985
1002
|
updateExpandedIds((prev) => {
|
|
986
1003
|
prev.add(parentId);
|
|
@@ -994,8 +1011,9 @@ function TreeSelect({
|
|
|
994
1011
|
activeId,
|
|
995
1012
|
draggedIds,
|
|
996
1013
|
draggedRootIds,
|
|
1014
|
+
emitDataChange,
|
|
997
1015
|
horizontalOffset,
|
|
998
|
-
|
|
1016
|
+
itemById,
|
|
999
1017
|
overId,
|
|
1000
1018
|
treeData,
|
|
1001
1019
|
updateExpandedIds,
|
|
@@ -1018,29 +1036,40 @@ function TreeSelect({
|
|
|
1018
1036
|
(parentId) => {
|
|
1019
1037
|
const newNode = createNewNode();
|
|
1020
1038
|
const nextTree = addChildNode(treeData, parentId, newNode);
|
|
1021
|
-
|
|
1039
|
+
emitDataChange(nextTree, {
|
|
1040
|
+
reason: "add-child",
|
|
1041
|
+
activeId: newNode.id,
|
|
1042
|
+
targetParentId: parentId
|
|
1043
|
+
});
|
|
1022
1044
|
updateExpandedIds((prev) => {
|
|
1023
1045
|
prev.add(parentId);
|
|
1024
1046
|
return prev;
|
|
1025
1047
|
});
|
|
1026
1048
|
},
|
|
1027
|
-
[createNewNode,
|
|
1049
|
+
[createNewNode, emitDataChange, treeData, updateExpandedIds]
|
|
1028
1050
|
);
|
|
1029
1051
|
const handleAddSibling = (0, import_react3.useCallback)(
|
|
1030
1052
|
(targetId) => {
|
|
1031
1053
|
const newNode = createNewNode();
|
|
1032
1054
|
const { nextNodes, inserted } = addSiblingNode(treeData, targetId, newNode);
|
|
1033
1055
|
if (!inserted) return;
|
|
1034
|
-
|
|
1056
|
+
emitDataChange(nextNodes, {
|
|
1057
|
+
reason: "add-sibling",
|
|
1058
|
+
activeId: newNode.id
|
|
1059
|
+
});
|
|
1035
1060
|
},
|
|
1036
|
-
[createNewNode,
|
|
1061
|
+
[createNewNode, emitDataChange, treeData]
|
|
1037
1062
|
);
|
|
1038
1063
|
const handleDelete = (0, import_react3.useCallback)(
|
|
1039
1064
|
(targetId) => {
|
|
1040
1065
|
const { nextNodes, removed } = removeNode(treeData, targetId);
|
|
1041
1066
|
if (!removed) return;
|
|
1042
1067
|
const removedIds = collectNodeIds(removed);
|
|
1043
|
-
|
|
1068
|
+
emitDataChange(nextNodes, {
|
|
1069
|
+
reason: "delete",
|
|
1070
|
+
activeId: targetId,
|
|
1071
|
+
draggedIds: Array.from(removedIds)
|
|
1072
|
+
});
|
|
1044
1073
|
updateExpandedIds((prev) => {
|
|
1045
1074
|
removedIds.forEach((id) => prev.delete(id));
|
|
1046
1075
|
return prev;
|
|
@@ -1056,7 +1085,7 @@ function TreeSelect({
|
|
|
1056
1085
|
);
|
|
1057
1086
|
setEditingId((prev) => prev && removedIds.has(prev) ? null : prev);
|
|
1058
1087
|
},
|
|
1059
|
-
[
|
|
1088
|
+
[emitDataChange, treeData, updateExpandedIds]
|
|
1060
1089
|
);
|
|
1061
1090
|
const startEdit = (0, import_react3.useCallback)(
|
|
1062
1091
|
(id) => {
|
|
@@ -1080,9 +1109,12 @@ function TreeSelect({
|
|
|
1080
1109
|
return;
|
|
1081
1110
|
}
|
|
1082
1111
|
const nextTree = updateNodeLabel(treeData, editingId, nextLabel);
|
|
1083
|
-
|
|
1112
|
+
emitDataChange(nextTree, {
|
|
1113
|
+
reason: "edit",
|
|
1114
|
+
activeId: editingId
|
|
1115
|
+
});
|
|
1084
1116
|
setEditingId(null);
|
|
1085
|
-
}, [draftLabel, editingId,
|
|
1117
|
+
}, [draftLabel, editingId, emitDataChange, onLabelChange, treeData]);
|
|
1086
1118
|
const cancelEdit = (0, import_react3.useCallback)(() => {
|
|
1087
1119
|
setEditingId(null);
|
|
1088
1120
|
}, []);
|
package/dist/index.mjs
CHANGED
|
@@ -828,6 +828,12 @@ function TreeSelect({
|
|
|
828
828
|
},
|
|
829
829
|
[expandedIds, isExpandedControlled, onExpandedChange]
|
|
830
830
|
);
|
|
831
|
+
const emitDataChange = useCallback2(
|
|
832
|
+
(nextTree, meta) => {
|
|
833
|
+
onDataChange == null ? void 0 : onDataChange(nextTree, meta);
|
|
834
|
+
},
|
|
835
|
+
[onDataChange]
|
|
836
|
+
);
|
|
831
837
|
const toggleExpanded = useCallback2((id) => {
|
|
832
838
|
updateExpandedIds((prev) => {
|
|
833
839
|
if (prev.has(id)) {
|
|
@@ -937,6 +943,7 @@ function TreeSelect({
|
|
|
937
943
|
}
|
|
938
944
|
}, []);
|
|
939
945
|
const handleDragEnd = useCallback2(() => {
|
|
946
|
+
var _a2;
|
|
940
947
|
const projection = getDropProjection({
|
|
941
948
|
items: visibleItems,
|
|
942
949
|
activeId,
|
|
@@ -952,6 +959,7 @@ function TreeSelect({
|
|
|
952
959
|
return;
|
|
953
960
|
}
|
|
954
961
|
const { parentId, siblingIndex, projectedDepth } = projection;
|
|
962
|
+
const sourceParentId = ((_a2 = itemById.get(draggedRootIds[0] ?? activeId)) == null ? void 0 : _a2.parentId) ?? null;
|
|
955
963
|
const { nextNodes, removedNodes } = removeNodes(treeData, draggedRootIds);
|
|
956
964
|
if (!removedNodes.length) {
|
|
957
965
|
setActiveId(null);
|
|
@@ -963,7 +971,16 @@ function TreeSelect({
|
|
|
963
971
|
removedNodes.forEach((node, index) => {
|
|
964
972
|
nextTree = insertNode(nextTree, parentId, siblingIndex + index, node);
|
|
965
973
|
});
|
|
966
|
-
|
|
974
|
+
emitDataChange(nextTree, {
|
|
975
|
+
reason: "drag",
|
|
976
|
+
activeId,
|
|
977
|
+
draggedRootIds,
|
|
978
|
+
draggedIds: Array.from(draggedIds),
|
|
979
|
+
sourceParentId,
|
|
980
|
+
targetParentId: parentId ?? null,
|
|
981
|
+
targetSiblingIndex: siblingIndex,
|
|
982
|
+
projectedDepth
|
|
983
|
+
});
|
|
967
984
|
if (parentId && projectedDepth > 0) {
|
|
968
985
|
updateExpandedIds((prev) => {
|
|
969
986
|
prev.add(parentId);
|
|
@@ -977,8 +994,9 @@ function TreeSelect({
|
|
|
977
994
|
activeId,
|
|
978
995
|
draggedIds,
|
|
979
996
|
draggedRootIds,
|
|
997
|
+
emitDataChange,
|
|
980
998
|
horizontalOffset,
|
|
981
|
-
|
|
999
|
+
itemById,
|
|
982
1000
|
overId,
|
|
983
1001
|
treeData,
|
|
984
1002
|
updateExpandedIds,
|
|
@@ -1001,29 +1019,40 @@ function TreeSelect({
|
|
|
1001
1019
|
(parentId) => {
|
|
1002
1020
|
const newNode = createNewNode();
|
|
1003
1021
|
const nextTree = addChildNode(treeData, parentId, newNode);
|
|
1004
|
-
|
|
1022
|
+
emitDataChange(nextTree, {
|
|
1023
|
+
reason: "add-child",
|
|
1024
|
+
activeId: newNode.id,
|
|
1025
|
+
targetParentId: parentId
|
|
1026
|
+
});
|
|
1005
1027
|
updateExpandedIds((prev) => {
|
|
1006
1028
|
prev.add(parentId);
|
|
1007
1029
|
return prev;
|
|
1008
1030
|
});
|
|
1009
1031
|
},
|
|
1010
|
-
[createNewNode,
|
|
1032
|
+
[createNewNode, emitDataChange, treeData, updateExpandedIds]
|
|
1011
1033
|
);
|
|
1012
1034
|
const handleAddSibling = useCallback2(
|
|
1013
1035
|
(targetId) => {
|
|
1014
1036
|
const newNode = createNewNode();
|
|
1015
1037
|
const { nextNodes, inserted } = addSiblingNode(treeData, targetId, newNode);
|
|
1016
1038
|
if (!inserted) return;
|
|
1017
|
-
|
|
1039
|
+
emitDataChange(nextNodes, {
|
|
1040
|
+
reason: "add-sibling",
|
|
1041
|
+
activeId: newNode.id
|
|
1042
|
+
});
|
|
1018
1043
|
},
|
|
1019
|
-
[createNewNode,
|
|
1044
|
+
[createNewNode, emitDataChange, treeData]
|
|
1020
1045
|
);
|
|
1021
1046
|
const handleDelete = useCallback2(
|
|
1022
1047
|
(targetId) => {
|
|
1023
1048
|
const { nextNodes, removed } = removeNode(treeData, targetId);
|
|
1024
1049
|
if (!removed) return;
|
|
1025
1050
|
const removedIds = collectNodeIds(removed);
|
|
1026
|
-
|
|
1051
|
+
emitDataChange(nextNodes, {
|
|
1052
|
+
reason: "delete",
|
|
1053
|
+
activeId: targetId,
|
|
1054
|
+
draggedIds: Array.from(removedIds)
|
|
1055
|
+
});
|
|
1027
1056
|
updateExpandedIds((prev) => {
|
|
1028
1057
|
removedIds.forEach((id) => prev.delete(id));
|
|
1029
1058
|
return prev;
|
|
@@ -1039,7 +1068,7 @@ function TreeSelect({
|
|
|
1039
1068
|
);
|
|
1040
1069
|
setEditingId((prev) => prev && removedIds.has(prev) ? null : prev);
|
|
1041
1070
|
},
|
|
1042
|
-
[
|
|
1071
|
+
[emitDataChange, treeData, updateExpandedIds]
|
|
1043
1072
|
);
|
|
1044
1073
|
const startEdit = useCallback2(
|
|
1045
1074
|
(id) => {
|
|
@@ -1063,9 +1092,12 @@ function TreeSelect({
|
|
|
1063
1092
|
return;
|
|
1064
1093
|
}
|
|
1065
1094
|
const nextTree = updateNodeLabel(treeData, editingId, nextLabel);
|
|
1066
|
-
|
|
1095
|
+
emitDataChange(nextTree, {
|
|
1096
|
+
reason: "edit",
|
|
1097
|
+
activeId: editingId
|
|
1098
|
+
});
|
|
1067
1099
|
setEditingId(null);
|
|
1068
|
-
}, [draftLabel, editingId,
|
|
1100
|
+
}, [draftLabel, editingId, emitDataChange, onLabelChange, treeData]);
|
|
1069
1101
|
const cancelEdit = useCallback2(() => {
|
|
1070
1102
|
setEditingId(null);
|
|
1071
1103
|
}, []);
|