react-native-tree-multi-select 2.0.13 → 3.0.0-beta.2

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.
Files changed (58) hide show
  1. package/README.md +151 -0
  2. package/lib/module/TreeView.js +32 -2
  3. package/lib/module/TreeView.js.map +1 -1
  4. package/lib/module/components/DragOverlay.js +104 -0
  5. package/lib/module/components/DragOverlay.js.map +1 -0
  6. package/lib/module/components/DropIndicator.js +79 -0
  7. package/lib/module/components/DropIndicator.js.map +1 -0
  8. package/lib/module/components/NodeList.js +288 -33
  9. package/lib/module/components/NodeList.js.map +1 -1
  10. package/lib/module/helpers/index.js +1 -0
  11. package/lib/module/helpers/index.js.map +1 -1
  12. package/lib/module/helpers/moveTreeNode.helper.js +96 -0
  13. package/lib/module/helpers/moveTreeNode.helper.js.map +1 -0
  14. package/lib/module/helpers/toggleCheckbox.helper.js +88 -0
  15. package/lib/module/helpers/toggleCheckbox.helper.js.map +1 -1
  16. package/lib/module/hooks/useDragDrop.js +683 -0
  17. package/lib/module/hooks/useDragDrop.js.map +1 -0
  18. package/lib/module/index.js +1 -1
  19. package/lib/module/index.js.map +1 -1
  20. package/lib/module/store/treeView.store.js +22 -1
  21. package/lib/module/store/treeView.store.js.map +1 -1
  22. package/lib/module/types/dragDrop.types.js +4 -0
  23. package/lib/module/types/dragDrop.types.js.map +1 -0
  24. package/lib/typescript/src/TreeView.d.ts.map +1 -1
  25. package/lib/typescript/src/components/DragOverlay.d.ts +13 -0
  26. package/lib/typescript/src/components/DragOverlay.d.ts.map +1 -0
  27. package/lib/typescript/src/components/DropIndicator.d.ts +13 -0
  28. package/lib/typescript/src/components/DropIndicator.d.ts.map +1 -0
  29. package/lib/typescript/src/components/NodeList.d.ts.map +1 -1
  30. package/lib/typescript/src/helpers/index.d.ts +1 -0
  31. package/lib/typescript/src/helpers/index.d.ts.map +1 -1
  32. package/lib/typescript/src/helpers/moveTreeNode.helper.d.ts +13 -0
  33. package/lib/typescript/src/helpers/moveTreeNode.helper.d.ts.map +1 -0
  34. package/lib/typescript/src/helpers/toggleCheckbox.helper.d.ts +6 -0
  35. package/lib/typescript/src/helpers/toggleCheckbox.helper.d.ts.map +1 -1
  36. package/lib/typescript/src/hooks/useDragDrop.d.ts +40 -0
  37. package/lib/typescript/src/hooks/useDragDrop.d.ts.map +1 -0
  38. package/lib/typescript/src/index.d.ts +4 -2
  39. package/lib/typescript/src/index.d.ts.map +1 -1
  40. package/lib/typescript/src/store/treeView.store.d.ts +9 -0
  41. package/lib/typescript/src/store/treeView.store.d.ts.map +1 -1
  42. package/lib/typescript/src/types/dragDrop.types.d.ts +21 -0
  43. package/lib/typescript/src/types/dragDrop.types.d.ts.map +1 -0
  44. package/lib/typescript/src/types/treeView.types.d.ts +94 -0
  45. package/lib/typescript/src/types/treeView.types.d.ts.map +1 -1
  46. package/package.json +1 -1
  47. package/src/TreeView.tsx +34 -0
  48. package/src/components/DragOverlay.tsx +114 -0
  49. package/src/components/DropIndicator.tsx +95 -0
  50. package/src/components/NodeList.tsx +327 -30
  51. package/src/helpers/index.ts +2 -1
  52. package/src/helpers/moveTreeNode.helper.ts +105 -0
  53. package/src/helpers/toggleCheckbox.helper.ts +96 -0
  54. package/src/hooks/useDragDrop.ts +835 -0
  55. package/src/index.tsx +19 -2
  56. package/src/store/treeView.store.ts +36 -0
  57. package/src/types/dragDrop.types.ts +23 -0
  58. package/src/types/treeView.types.ts +110 -0
package/src/index.tsx CHANGED
@@ -8,11 +8,21 @@ import type {
8
8
  CheckBoxViewProps,
9
9
  CheckboxValueType,
10
10
  BuiltInCheckBoxViewStyleProps,
11
- SelectionPropagation
11
+ SelectionPropagation,
12
+ DragDropCustomizations,
13
+ DragOverlayStyleProps,
14
+ DragOverlayComponentProps,
15
+ DropIndicatorStyleProps,
16
+ DropIndicatorComponentProps,
12
17
  } from "./types/treeView.types";
18
+ import type {
19
+ DragEndEvent,
20
+ DropPosition
21
+ } from "./types/dragDrop.types";
13
22
 
14
23
  export * from "./TreeView";
15
24
  export * from "./components/CheckboxView";
25
+ export { moveTreeNode } from "./helpers/moveTreeNode.helper";
16
26
 
17
27
  export type {
18
28
  TreeNode,
@@ -24,5 +34,12 @@ export type {
24
34
  CheckBoxViewProps,
25
35
  CheckboxValueType,
26
36
  BuiltInCheckBoxViewStyleProps,
27
- SelectionPropagation
37
+ SelectionPropagation,
38
+ DragEndEvent,
39
+ DropPosition,
40
+ DragDropCustomizations,
41
+ DragOverlayStyleProps,
42
+ DragOverlayComponentProps,
43
+ DropIndicatorStyleProps,
44
+ DropIndicatorComponentProps,
28
45
  };
@@ -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,19 @@ 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
+ dropLevel: number | null;
58
+ updateDropTarget: (nodeId: ID | null, position: DropPosition | null, level?: number | null) => void;
59
+
46
60
  // Cleanup all states in this store
47
61
  cleanUpTreeViewStore: () => void;
48
62
  };
@@ -97,6 +111,23 @@ export function getTreeViewStore<ID>(id: string): UseBoundStore<StoreApi<TreeVie
97
111
  }
98
112
  }),
99
113
 
114
+ draggedNodeId: null,
115
+ updateDraggedNodeId: (draggedNodeId) => set({ draggedNodeId }),
116
+
117
+ invalidDragTargetIds: new Set<ID>(),
118
+ updateInvalidDragTargetIds: (invalidDragTargetIds) => set({
119
+ invalidDragTargetIds
120
+ }),
121
+
122
+ dropTargetNodeId: null,
123
+ dropPosition: null,
124
+ dropLevel: null,
125
+ updateDropTarget: (nodeId, position, level) => set({
126
+ dropTargetNodeId: nodeId,
127
+ dropPosition: position,
128
+ dropLevel: level ?? null,
129
+ }),
130
+
100
131
  cleanUpTreeViewStore: () =>
101
132
  set({
102
133
  checked: new Set(),
@@ -109,6 +140,11 @@ export function getTreeViewStore<ID>(id: string): UseBoundStore<StoreApi<TreeVie
109
140
  searchKeys: [""],
110
141
  innerMostChildrenIds: [],
111
142
  selectionPropagation: { toChildren: true, toParents: true },
143
+ draggedNodeId: null,
144
+ invalidDragTargetIds: new Set<ID>(),
145
+ dropTargetNodeId: null,
146
+ dropPosition: null,
147
+ dropLevel: null,
112
148
  }),
113
149
  }));
114
150
 
@@ -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,67 @@ 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
+ /** The nesting level of the target node (useful for indenting the indicator) */
198
+ level: number;
199
+ /** The indentation multiplier used for each level (pixels per level) */
200
+ indentationMultiplier: number;
201
+ }
202
+
203
+ /** Style props for customizing the built-in drop indicator appearance */
204
+ export interface DropIndicatorStyleProps {
205
+ /** Color of the line indicator (above/below). Default: "#0078FF" */
206
+ lineColor?: string;
207
+ /** Thickness of the line indicator. Default: 3 */
208
+ lineThickness?: number;
209
+ /** Diameter of the circle at the line's start. Default: 10 */
210
+ circleSize?: number;
211
+ /** Background color of the "inside" highlight. Default: "rgba(0, 120, 255, 0.15)" */
212
+ highlightColor?: string;
213
+ /** Border color of the "inside" highlight. Default: "rgba(0, 120, 255, 0.5)" */
214
+ highlightBorderColor?: string;
215
+ }
216
+
217
+ /** Style props for customizing the drag overlay (the "lifted" node ghost) */
218
+ export interface DragOverlayStyleProps {
219
+ /** Background color of the overlay. Default: "rgba(255, 255, 255, 0.95)" */
220
+ backgroundColor?: string;
221
+ /** Shadow color. Default: "#000" */
222
+ shadowColor?: string;
223
+ /** Shadow opacity. Default: 0.25 */
224
+ shadowOpacity?: number;
225
+ /** Shadow radius. Default: 4 */
226
+ shadowRadius?: number;
227
+ /** Android elevation. Default: 10 */
228
+ elevation?: number;
229
+ /** Custom style applied to the overlay container */
230
+ style?: StyleProp<ViewStyle>;
231
+ }
232
+
233
+ /** Combined drag-and-drop customization props */
234
+ export interface DragDropCustomizations<ID = string> {
235
+ /** Opacity applied to the dragged node and its invalid drop targets. Default: 0.3 */
236
+ draggedNodeOpacity?: number;
237
+ /** Style props for the built-in drop indicator */
238
+ dropIndicatorStyleProps?: DropIndicatorStyleProps;
239
+ /** Style props for the drag overlay (lifted node ghost) */
240
+ dragOverlayStyleProps?: DragOverlayStyleProps;
241
+ /** Fully custom drop indicator component — replaces the built-in line/highlight */
242
+ CustomDropIndicatorComponent?: React.ComponentType<DropIndicatorComponentProps>;
243
+ /** Fully custom drag overlay component — replaces the built-in ghost node */
244
+ CustomDragOverlayComponent?: React.ComponentType<DragOverlayComponentProps<ID>>;
245
+ }
246
+
247
+ /** Props passed to a custom drag overlay component */
248
+ export interface DragOverlayComponentProps<ID = string> {
249
+ /** The node being dragged */
250
+ node: __FlattenedTreeNode__<ID>;
251
+ /** The nesting level of the dragged node */
252
+ level: number;
253
+ }