react-native-tree-multi-select 2.0.11 → 3.0.0-beta.1
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 +151 -0
- package/lib/module/TreeView.js +32 -2
- package/lib/module/TreeView.js.map +1 -1
- package/lib/module/components/DragOverlay.js +101 -0
- package/lib/module/components/DragOverlay.js.map +1 -0
- package/lib/module/components/DropIndicator.js +79 -0
- package/lib/module/components/DropIndicator.js.map +1 -0
- package/lib/module/components/NodeList.js +258 -32
- package/lib/module/components/NodeList.js.map +1 -1
- package/lib/module/helpers/index.js +1 -0
- package/lib/module/helpers/index.js.map +1 -1
- package/lib/module/helpers/moveTreeNode.helper.js +96 -0
- package/lib/module/helpers/moveTreeNode.helper.js.map +1 -0
- package/lib/module/helpers/toggleCheckbox.helper.js +88 -0
- package/lib/module/helpers/toggleCheckbox.helper.js.map +1 -1
- package/lib/module/hooks/useDragDrop.js +511 -0
- package/lib/module/hooks/useDragDrop.js.map +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/store/treeView.store.js +19 -1
- package/lib/module/store/treeView.store.js.map +1 -1
- package/lib/module/types/dragDrop.types.js +4 -0
- package/lib/module/types/dragDrop.types.js.map +1 -0
- package/lib/typescript/src/TreeView.d.ts.map +1 -1
- package/lib/typescript/src/components/DragOverlay.d.ts +12 -0
- package/lib/typescript/src/components/DragOverlay.d.ts.map +1 -0
- package/lib/typescript/src/components/DropIndicator.d.ts +13 -0
- package/lib/typescript/src/components/DropIndicator.d.ts.map +1 -0
- package/lib/typescript/src/components/NodeList.d.ts.map +1 -1
- package/lib/typescript/src/helpers/index.d.ts +1 -0
- package/lib/typescript/src/helpers/index.d.ts.map +1 -1
- package/lib/typescript/src/helpers/moveTreeNode.helper.d.ts +13 -0
- package/lib/typescript/src/helpers/moveTreeNode.helper.d.ts.map +1 -0
- package/lib/typescript/src/helpers/toggleCheckbox.helper.d.ts +6 -0
- package/lib/typescript/src/helpers/toggleCheckbox.helper.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useDragDrop.d.ts +35 -0
- package/lib/typescript/src/hooks/useDragDrop.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +4 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/store/treeView.store.d.ts +8 -0
- package/lib/typescript/src/store/treeView.store.d.ts.map +1 -1
- package/lib/typescript/src/types/dragDrop.types.d.ts +21 -0
- package/lib/typescript/src/types/dragDrop.types.d.ts.map +1 -0
- package/lib/typescript/src/types/treeView.types.d.ts +90 -0
- package/lib/typescript/src/types/treeView.types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/TreeView.tsx +34 -0
- package/src/components/DragOverlay.tsx +112 -0
- package/src/components/DropIndicator.tsx +95 -0
- package/src/components/NodeList.tsx +302 -30
- package/src/helpers/index.ts +2 -1
- package/src/helpers/moveTreeNode.helper.ts +105 -0
- package/src/helpers/toggleCheckbox.helper.ts +96 -0
- package/src/hooks/useDragDrop.ts +643 -0
- package/src/index.tsx +19 -2
- package/src/store/treeView.store.ts +32 -0
- package/src/types/dragDrop.types.ts +23 -0
- package/src/types/treeView.types.ts +106 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SelectionPropagation, TreeNode } from "../types/treeView.types";
|
|
2
|
+
import type { DropPosition } from "../types/dragDrop.types";
|
|
2
3
|
import { create, type StoreApi, type UseBoundStore } from "zustand";
|
|
3
4
|
|
|
4
5
|
export type TreeViewState<ID> = {
|
|
@@ -43,6 +44,18 @@ export type TreeViewState<ID> = {
|
|
|
43
44
|
selectionPropagation: SelectionPropagation
|
|
44
45
|
) => void;
|
|
45
46
|
|
|
47
|
+
// Drag-and-drop state
|
|
48
|
+
draggedNodeId: ID | null;
|
|
49
|
+
updateDraggedNodeId: (draggedNodeId: ID | null) => void;
|
|
50
|
+
|
|
51
|
+
invalidDragTargetIds: Set<ID>;
|
|
52
|
+
updateInvalidDragTargetIds: (invalidDragTargetIds: Set<ID>) => void;
|
|
53
|
+
|
|
54
|
+
// Drop target state (used by nodes to render their own indicator)
|
|
55
|
+
dropTargetNodeId: ID | null;
|
|
56
|
+
dropPosition: DropPosition | null;
|
|
57
|
+
updateDropTarget: (nodeId: ID | null, position: DropPosition | null) => void;
|
|
58
|
+
|
|
46
59
|
// Cleanup all states in this store
|
|
47
60
|
cleanUpTreeViewStore: () => void;
|
|
48
61
|
};
|
|
@@ -97,6 +110,21 @@ export function getTreeViewStore<ID>(id: string): UseBoundStore<StoreApi<TreeVie
|
|
|
97
110
|
}
|
|
98
111
|
}),
|
|
99
112
|
|
|
113
|
+
draggedNodeId: null,
|
|
114
|
+
updateDraggedNodeId: (draggedNodeId) => set({ draggedNodeId }),
|
|
115
|
+
|
|
116
|
+
invalidDragTargetIds: new Set<ID>(),
|
|
117
|
+
updateInvalidDragTargetIds: (invalidDragTargetIds) => set({
|
|
118
|
+
invalidDragTargetIds
|
|
119
|
+
}),
|
|
120
|
+
|
|
121
|
+
dropTargetNodeId: null,
|
|
122
|
+
dropPosition: null,
|
|
123
|
+
updateDropTarget: (nodeId, position) => set({
|
|
124
|
+
dropTargetNodeId: nodeId,
|
|
125
|
+
dropPosition: position,
|
|
126
|
+
}),
|
|
127
|
+
|
|
100
128
|
cleanUpTreeViewStore: () =>
|
|
101
129
|
set({
|
|
102
130
|
checked: new Set(),
|
|
@@ -109,6 +137,10 @@ export function getTreeViewStore<ID>(id: string): UseBoundStore<StoreApi<TreeVie
|
|
|
109
137
|
searchKeys: [""],
|
|
110
138
|
innerMostChildrenIds: [],
|
|
111
139
|
selectionPropagation: { toChildren: true, toParents: true },
|
|
140
|
+
draggedNodeId: null,
|
|
141
|
+
invalidDragTargetIds: new Set<ID>(),
|
|
142
|
+
dropTargetNodeId: null,
|
|
143
|
+
dropPosition: null,
|
|
112
144
|
}),
|
|
113
145
|
}));
|
|
114
146
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TreeNode } from "./treeView.types";
|
|
2
|
+
|
|
3
|
+
export type DropPosition = "above" | "below" | "inside";
|
|
4
|
+
|
|
5
|
+
export interface DragEndEvent<ID = string> {
|
|
6
|
+
/** The id of the node that was dragged */
|
|
7
|
+
draggedNodeId: ID;
|
|
8
|
+
/** The id of the target node where the dragged node was dropped */
|
|
9
|
+
targetNodeId: ID;
|
|
10
|
+
/** Where relative to the target: above/below = sibling, inside = child */
|
|
11
|
+
position: DropPosition;
|
|
12
|
+
/** The reordered tree data after the move */
|
|
13
|
+
newTreeData: TreeNode<ID>[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface DropTarget<ID = string> {
|
|
17
|
+
targetNodeId: ID;
|
|
18
|
+
targetIndex: number;
|
|
19
|
+
position: DropPosition;
|
|
20
|
+
isValid: boolean;
|
|
21
|
+
targetLevel: number;
|
|
22
|
+
indicatorTop: number;
|
|
23
|
+
}
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
import type {
|
|
13
13
|
CheckboxProps as _CheckboxProps
|
|
14
14
|
} from "@futurejj/react-native-checkbox";
|
|
15
|
+
import type { DragEndEvent, DropPosition } from "./dragDrop.types";
|
|
15
16
|
|
|
16
17
|
export type CheckboxValueType = boolean | "indeterminate";
|
|
17
18
|
|
|
@@ -46,6 +47,10 @@ export interface NodeRowProps<ID = string> {
|
|
|
46
47
|
|
|
47
48
|
onCheck: () => void;
|
|
48
49
|
onExpand: () => void;
|
|
50
|
+
|
|
51
|
+
isDragTarget?: boolean;
|
|
52
|
+
isDragging?: boolean;
|
|
53
|
+
isDraggedNode?: boolean;
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
export interface TreeItemCustomizations<ID> {
|
|
@@ -64,6 +69,20 @@ export interface NodeProps<ID> extends TreeItemCustomizations<ID> {
|
|
|
64
69
|
node: __FlattenedTreeNode__<ID>;
|
|
65
70
|
level: number;
|
|
66
71
|
storeId: string;
|
|
72
|
+
|
|
73
|
+
nodeIndex?: number;
|
|
74
|
+
dragEnabled?: boolean;
|
|
75
|
+
isDragging?: boolean;
|
|
76
|
+
onNodeTouchStart?: (
|
|
77
|
+
nodeId: ID,
|
|
78
|
+
pageY: number,
|
|
79
|
+
locationY: number,
|
|
80
|
+
nodeIndex: number
|
|
81
|
+
) => void;
|
|
82
|
+
onNodeTouchEnd?: () => void;
|
|
83
|
+
longPressDuration?: number;
|
|
84
|
+
onItemLayout?: (height: number) => void;
|
|
85
|
+
dragDropCustomizations?: DragDropCustomizations<ID>;
|
|
67
86
|
}
|
|
68
87
|
|
|
69
88
|
export interface NodeListProps<ID> extends TreeItemCustomizations<ID> {
|
|
@@ -73,6 +92,18 @@ export interface NodeListProps<ID> extends TreeItemCustomizations<ID> {
|
|
|
73
92
|
initialScrollNodeID?: ID;
|
|
74
93
|
|
|
75
94
|
storeId: string;
|
|
95
|
+
|
|
96
|
+
dragEnabled?: boolean;
|
|
97
|
+
onDragEnd?: (event: DragEndEvent<ID>) => void;
|
|
98
|
+
longPressDuration?: number;
|
|
99
|
+
autoScrollThreshold?: number;
|
|
100
|
+
autoScrollSpeed?: number;
|
|
101
|
+
/** Offset of the dragged overlay from the finger, in item-height units. Default: -1 (one item above finger) */
|
|
102
|
+
dragOverlayOffset?: number;
|
|
103
|
+
/** Delay in ms before auto-expanding a collapsed node during drag hover. Default: 800 */
|
|
104
|
+
autoExpandDelay?: number;
|
|
105
|
+
/** Customizations for drag-and-drop visuals (overlay, indicator, opacity) */
|
|
106
|
+
dragDropCustomizations?: DragDropCustomizations<ID>;
|
|
76
107
|
}
|
|
77
108
|
|
|
78
109
|
export interface TreeViewProps<ID = string> extends Omit<
|
|
@@ -88,6 +119,21 @@ export interface TreeViewProps<ID = string> extends Omit<
|
|
|
88
119
|
preExpandedIds?: ID[];
|
|
89
120
|
|
|
90
121
|
selectionPropagation?: SelectionPropagation;
|
|
122
|
+
|
|
123
|
+
/** Enable drag-and-drop reordering */
|
|
124
|
+
dragEnabled?: boolean;
|
|
125
|
+
/** Callback fired after a node is dropped at a new position */
|
|
126
|
+
onDragEnd?: (event: DragEndEvent<ID>) => void;
|
|
127
|
+
/** Long press duration in ms to start drag. Default: 400 */
|
|
128
|
+
longPressDuration?: number;
|
|
129
|
+
/** Distance from edge (px) to trigger auto-scroll. Default: 60 */
|
|
130
|
+
autoScrollThreshold?: number;
|
|
131
|
+
/** Speed multiplier for auto-scroll. Default: 1.0 */
|
|
132
|
+
autoScrollSpeed?: number;
|
|
133
|
+
/** Offset of the dragged overlay from the finger, in item-height units. Default: -1 (one item above finger) */
|
|
134
|
+
dragOverlayOffset?: number;
|
|
135
|
+
/** Delay in ms before auto-expanding a collapsed node during drag hover. Default: 800 */
|
|
136
|
+
autoExpandDelay?: number;
|
|
91
137
|
}
|
|
92
138
|
|
|
93
139
|
type CheckboxProps = Omit<_CheckboxProps, "onPress" | "status">;
|
|
@@ -141,3 +187,63 @@ export interface SelectionPropagation {
|
|
|
141
187
|
toChildren?: boolean;
|
|
142
188
|
toParents?: boolean;
|
|
143
189
|
}
|
|
190
|
+
|
|
191
|
+
// --- Drag-and-drop customization types ---
|
|
192
|
+
|
|
193
|
+
/** Props for the drop indicator rendered on the target node during drag */
|
|
194
|
+
export interface DropIndicatorComponentProps {
|
|
195
|
+
/** Whether the indicator is above, below, or inside the target node */
|
|
196
|
+
position: DropPosition;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Style props for customizing the built-in drop indicator appearance */
|
|
200
|
+
export interface DropIndicatorStyleProps {
|
|
201
|
+
/** Color of the line indicator (above/below). Default: "#0078FF" */
|
|
202
|
+
lineColor?: string;
|
|
203
|
+
/** Thickness of the line indicator. Default: 3 */
|
|
204
|
+
lineThickness?: number;
|
|
205
|
+
/** Diameter of the circle at the line's start. Default: 10 */
|
|
206
|
+
circleSize?: number;
|
|
207
|
+
/** Background color of the "inside" highlight. Default: "rgba(0, 120, 255, 0.15)" */
|
|
208
|
+
highlightColor?: string;
|
|
209
|
+
/** Border color of the "inside" highlight. Default: "rgba(0, 120, 255, 0.5)" */
|
|
210
|
+
highlightBorderColor?: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** Style props for customizing the drag overlay (the "lifted" node ghost) */
|
|
214
|
+
export interface DragOverlayStyleProps {
|
|
215
|
+
/** Background color of the overlay. Default: "rgba(255, 255, 255, 0.95)" */
|
|
216
|
+
backgroundColor?: string;
|
|
217
|
+
/** Shadow color. Default: "#000" */
|
|
218
|
+
shadowColor?: string;
|
|
219
|
+
/** Shadow opacity. Default: 0.25 */
|
|
220
|
+
shadowOpacity?: number;
|
|
221
|
+
/** Shadow radius. Default: 4 */
|
|
222
|
+
shadowRadius?: number;
|
|
223
|
+
/** Android elevation. Default: 10 */
|
|
224
|
+
elevation?: number;
|
|
225
|
+
/** Custom style applied to the overlay container */
|
|
226
|
+
style?: StyleProp<ViewStyle>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/** Combined drag-and-drop customization props */
|
|
230
|
+
export interface DragDropCustomizations<ID = string> {
|
|
231
|
+
/** Opacity applied to the dragged node and its invalid drop targets. Default: 0.3 */
|
|
232
|
+
draggedNodeOpacity?: number;
|
|
233
|
+
/** Style props for the built-in drop indicator */
|
|
234
|
+
dropIndicatorStyleProps?: DropIndicatorStyleProps;
|
|
235
|
+
/** Style props for the drag overlay (lifted node ghost) */
|
|
236
|
+
dragOverlayStyleProps?: DragOverlayStyleProps;
|
|
237
|
+
/** Fully custom drop indicator component — replaces the built-in line/highlight */
|
|
238
|
+
CustomDropIndicatorComponent?: React.ComponentType<DropIndicatorComponentProps>;
|
|
239
|
+
/** Fully custom drag overlay component — replaces the built-in ghost node */
|
|
240
|
+
CustomDragOverlayComponent?: React.ComponentType<DragOverlayComponentProps<ID>>;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** Props passed to a custom drag overlay component */
|
|
244
|
+
export interface DragOverlayComponentProps<ID = string> {
|
|
245
|
+
/** The node being dragged */
|
|
246
|
+
node: __FlattenedTreeNode__<ID>;
|
|
247
|
+
/** The nesting level of the dragged node */
|
|
248
|
+
level: number;
|
|
249
|
+
}
|