react-native-swappable-grid 1.0.0

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 (44) hide show
  1. package/README.md +284 -0
  2. package/lib/commonjs/ChildWrapper.js +320 -0
  3. package/lib/commonjs/ChildWrapper.js.map +1 -0
  4. package/lib/commonjs/SwappableGrid.js +378 -0
  5. package/lib/commonjs/SwappableGrid.js.map +1 -0
  6. package/lib/commonjs/index.js +14 -0
  7. package/lib/commonjs/index.js.map +1 -0
  8. package/lib/commonjs/utils/helpers/computerMinHeight.js +11 -0
  9. package/lib/commonjs/utils/helpers/computerMinHeight.js.map +1 -0
  10. package/lib/commonjs/utils/helpers/gestures/PanWithLongPress.js +249 -0
  11. package/lib/commonjs/utils/helpers/gestures/PanWithLongPress.js.map +1 -0
  12. package/lib/commonjs/utils/helpers/indexCalculations.js +73 -0
  13. package/lib/commonjs/utils/helpers/indexCalculations.js.map +1 -0
  14. package/lib/commonjs/utils/useGridLayout.js +205 -0
  15. package/lib/commonjs/utils/useGridLayout.js.map +1 -0
  16. package/lib/module/ChildWrapper.js +313 -0
  17. package/lib/module/ChildWrapper.js.map +1 -0
  18. package/lib/module/SwappableGrid.js +370 -0
  19. package/lib/module/SwappableGrid.js.map +1 -0
  20. package/lib/module/index.js +2 -0
  21. package/lib/module/index.js.map +1 -0
  22. package/lib/module/utils/helpers/computerMinHeight.js +5 -0
  23. package/lib/module/utils/helpers/computerMinHeight.js.map +1 -0
  24. package/lib/module/utils/helpers/gestures/PanWithLongPress.js +242 -0
  25. package/lib/module/utils/helpers/gestures/PanWithLongPress.js.map +1 -0
  26. package/lib/module/utils/helpers/indexCalculations.js +64 -0
  27. package/lib/module/utils/helpers/indexCalculations.js.map +1 -0
  28. package/lib/module/utils/useGridLayout.js +199 -0
  29. package/lib/module/utils/useGridLayout.js.map +1 -0
  30. package/lib/typescript/ChildWrapper.d.ts +23 -0
  31. package/lib/typescript/SwappableGrid.d.ts +85 -0
  32. package/lib/typescript/index.d.ts +2 -0
  33. package/lib/typescript/utils/helpers/computerMinHeight.d.ts +1 -0
  34. package/lib/typescript/utils/helpers/gestures/PanWithLongPress.d.ts +40 -0
  35. package/lib/typescript/utils/helpers/indexCalculations.d.ts +28 -0
  36. package/lib/typescript/utils/useGridLayout.d.ts +46 -0
  37. package/package.json +68 -0
  38. package/src/ChildWrapper.tsx +376 -0
  39. package/src/SwappableGrid.tsx +492 -0
  40. package/src/index.ts +2 -0
  41. package/src/utils/helpers/computerMinHeight.ts +9 -0
  42. package/src/utils/helpers/gestures/PanWithLongPress.ts +304 -0
  43. package/src/utils/helpers/indexCalculations.ts +91 -0
  44. package/src/utils/useGridLayout.ts +236 -0
@@ -0,0 +1,242 @@
1
+ import { Gesture } from "react-native-gesture-handler";
2
+ import { runOnJS, withSpring, withTiming, scrollTo, useSharedValue, useDerivedValue } from "react-native-reanimated";
3
+ import { indexToXY, toIndex1ColFromLiveMidlines, xyToIndex } from "../indexCalculations";
4
+ export const PanWithLongPress = props => {
5
+ const {
6
+ order,
7
+ dynamicNumColumns,
8
+ activeKey,
9
+ offsetX,
10
+ offsetY,
11
+ startX,
12
+ startY,
13
+ dragMode,
14
+ positions,
15
+ itemsByKey,
16
+ itemWidth,
17
+ itemHeight,
18
+ containerPadding,
19
+ gap,
20
+ setOrderState,
21
+ onDragEnd,
22
+ onOrderChange,
23
+ scrollSpeed,
24
+ scrollThreshold,
25
+ scrollViewRef,
26
+ scrollOffset,
27
+ viewportH,
28
+ longPressMs,
29
+ contentH,
30
+ reverse = false,
31
+ deleteComponentPosition,
32
+ deleteItem,
33
+ contentPaddingBottom = 0
34
+ } = props;
35
+ const scrollDir = useSharedValue(0); // -1 = up, 1 = down, 0 = none
36
+ const initialScrollOffset = useSharedValue(0);
37
+ useDerivedValue(() => {
38
+ if (!dragMode.value || !activeKey.value) return;
39
+ if (viewportH.value <= 0 || contentH.value <= 0) return;
40
+ const key = activeKey.value;
41
+ const p = positions[key];
42
+ if (!p) return;
43
+
44
+ // 1. Clamp scroll offset
45
+ const maxScroll = contentH.value - viewportH.value;
46
+ const newScroll = Math.max(0, Math.min(scrollOffset.value + scrollDir.value * scrollSpeed, maxScroll));
47
+ scrollTo(scrollViewRef, 0, newScroll, false);
48
+ const scrollDelta = newScroll - initialScrollOffset.value;
49
+ scrollOffset.value = newScroll;
50
+
51
+ // 2. Clamp item position
52
+ // Allow dragging into padding area (paddingBottom from style prop)
53
+ const minY = 0;
54
+ // Add paddingBottom to maxY to allow dragging into the padding area
55
+ const maxY = contentH.value - itemHeight + contentPaddingBottom;
56
+ const proposedY = startY.value + offsetY.value + scrollDelta;
57
+ p.y.value = Math.max(minY, Math.min(proposedY, maxY));
58
+
59
+ // X stays normal
60
+ p.x.value = startX.value + offsetX.value;
61
+
62
+ // Keep loop alive
63
+ requestAnimationFrame(() => {
64
+ scrollDir.value = scrollDir.value;
65
+ });
66
+ });
67
+ const getIndexOfKey = key => {
68
+ "worklet";
69
+
70
+ return order.value.findIndex(x => x === key);
71
+ };
72
+ return Gesture.Pan().minDistance(10).activateAfterLongPress(longPressMs).onStart(({
73
+ x,
74
+ y
75
+ }) => {
76
+ initialScrollOffset.value = scrollOffset.value;
77
+ dragMode.value = true;
78
+ let bestKey = null;
79
+ let bestDist = Number.MAX_VALUE;
80
+ order.value.forEach(key => {
81
+ const p = positions[key];
82
+ if (!p) return;
83
+ const cx = p.x.value + itemWidth / 2;
84
+ const cy = p.y.value + itemHeight / 2;
85
+ const dx = cx - x;
86
+ const dy = cy - y;
87
+ const dist2 = dx * dx + dy * dy;
88
+ if (dist2 < bestDist) {
89
+ bestDist = dist2;
90
+ bestKey = key;
91
+ }
92
+ });
93
+ if (!bestKey) return;
94
+ activeKey.value = bestKey;
95
+ const p = positions[bestKey];
96
+ p.active.value = withTiming(1, {
97
+ duration: 120
98
+ });
99
+ startX.value = p.x.value;
100
+ startY.value = p.y.value;
101
+ offsetX.value = 0;
102
+ offsetY.value = 0;
103
+ }).onUpdate(({
104
+ translationX,
105
+ translationY
106
+ }) => {
107
+ if (!dragMode.value) return;
108
+ const key = activeKey.value;
109
+ if (!key) return;
110
+ const p = positions[key];
111
+ const scrollDelta = scrollOffset.value - initialScrollOffset.value;
112
+
113
+ // Update active (top-left)
114
+ offsetX.value = translationX;
115
+ offsetY.value = translationY;
116
+ p.x.value = startX.value + offsetX.value;
117
+ p.y.value = startY.value + offsetY.value + scrollDelta;
118
+
119
+ // Auto-scroll (unchanged)
120
+ const pointerYInViewport = p.y.value - scrollOffset.value;
121
+ if (pointerYInViewport > viewportH.value - scrollThreshold) {
122
+ scrollDir.value = 1;
123
+ } else if (pointerYInViewport < scrollThreshold) {
124
+ scrollDir.value = -1;
125
+ } else {
126
+ scrollDir.value = 0;
127
+ }
128
+
129
+ // Compute target index from the active tile's **center**
130
+ const centerY = p.y.value + itemHeight / 2;
131
+ const fromIndex = getIndexOfKey(key);
132
+ let toIndex;
133
+ if (dynamicNumColumns.value === 1) {
134
+ toIndex = toIndex1ColFromLiveMidlines(order, positions, activeKey, itemHeight, centerY, reverse // ← pass your prop
135
+ );
136
+ } else {
137
+ // unchanged multi-column path
138
+ const centerX = p.x.value + itemWidth / 2;
139
+ toIndex = xyToIndex({
140
+ order,
141
+ x: centerX,
142
+ y: centerY,
143
+ itemWidth,
144
+ itemHeight,
145
+ dynamicNumColumns,
146
+ containerPadding,
147
+ gap
148
+ });
149
+ }
150
+ if (toIndex !== fromIndex && toIndex >= 0 && toIndex <= order.value.length - 1) {
151
+ const next = [...order.value];
152
+ next.splice(fromIndex, 1);
153
+ next.splice(toIndex, 0, key);
154
+ order.value = next;
155
+ }
156
+ }).onEnd(() => {
157
+ scrollDir.value = 0; // stop auto-scroll
158
+ if (!dragMode.value) return;
159
+ const key = activeKey.value;
160
+ if (!key) {
161
+ dragMode.value = false;
162
+ return;
163
+ }
164
+ const p = positions[key];
165
+
166
+ // Check if item was dropped into delete component
167
+ if (deleteComponentPosition !== null && deleteComponentPosition !== void 0 && deleteComponentPosition.value && deleteItem) {
168
+ const deletePos = deleteComponentPosition.value;
169
+
170
+ // Add tolerance/padding to make it easier to hit (20% of item size)
171
+ const tolerance = Math.min(itemWidth, itemHeight) * 0.2;
172
+ const expandedDeleteX = deletePos.x - tolerance;
173
+ const expandedDeleteY = deletePos.y - tolerance;
174
+ const expandedDeleteWidth = deletePos.width + tolerance * 2;
175
+ const expandedDeleteHeight = deletePos.height + tolerance * 2;
176
+
177
+ // Check if item bounding box overlaps with expanded delete component bounds
178
+ // This is more forgiving than checking just the center point
179
+ const itemLeft = p.x.value;
180
+ const itemRight = p.x.value + itemWidth;
181
+ const itemTop = p.y.value;
182
+ const itemBottom = p.y.value + itemHeight;
183
+
184
+ // Bounding box intersection check
185
+ const overlaps = itemLeft < expandedDeleteX + expandedDeleteWidth && itemRight > expandedDeleteX && itemTop < expandedDeleteY + expandedDeleteHeight && itemBottom > expandedDeleteY;
186
+ if (overlaps) {
187
+ // Item was dropped into delete component - delete it
188
+ runOnJS(deleteItem)(key);
189
+ // Note: deleteItem will handle calling onDelete callback if provided
190
+ p.active.value = withTiming(0, {
191
+ duration: 120
192
+ });
193
+ activeKey.value = null;
194
+ dragMode.value = false;
195
+ return;
196
+ }
197
+ }
198
+
199
+ // Normal drop - return to grid position
200
+ const idx = getIndexOfKey(key);
201
+ const {
202
+ x,
203
+ y
204
+ } = indexToXY({
205
+ index: idx,
206
+ itemWidth,
207
+ itemHeight,
208
+ dynamicNumColumns,
209
+ containerPadding,
210
+ gap
211
+ });
212
+ const scale = Math.min(itemWidth, itemHeight) / 200; // 100px baseline
213
+
214
+ const damping = 18 * scale;
215
+ const stiffness = 240 * scale;
216
+ const mass = Math.max(0.05, scale); // helps stability for tiny items
217
+
218
+ p.x.value = withSpring(x, {
219
+ damping,
220
+ stiffness,
221
+ mass
222
+ });
223
+ p.y.value = withSpring(y, {
224
+ damping,
225
+ stiffness,
226
+ mass
227
+ });
228
+ p.active.value = withTiming(0, {
229
+ duration: 120
230
+ });
231
+ runOnJS(setOrderState)(order.value);
232
+ if (onDragEnd) {
233
+ runOnJS(onDragEnd)(order.value.map(key => itemsByKey[key]));
234
+ }
235
+ if (onOrderChange) {
236
+ runOnJS(onOrderChange)([...order.value]);
237
+ }
238
+ activeKey.value = null;
239
+ dragMode.value = false;
240
+ });
241
+ };
242
+ //# sourceMappingURL=PanWithLongPress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Gesture","runOnJS","withSpring","withTiming","scrollTo","useSharedValue","useDerivedValue","indexToXY","toIndex1ColFromLiveMidlines","xyToIndex","PanWithLongPress","props","order","dynamicNumColumns","activeKey","offsetX","offsetY","startX","startY","dragMode","positions","itemsByKey","itemWidth","itemHeight","containerPadding","gap","setOrderState","onDragEnd","onOrderChange","scrollSpeed","scrollThreshold","scrollViewRef","scrollOffset","viewportH","longPressMs","contentH","reverse","deleteComponentPosition","deleteItem","contentPaddingBottom","scrollDir","initialScrollOffset","value","key","p","maxScroll","newScroll","Math","max","min","scrollDelta","minY","maxY","proposedY","y","x","requestAnimationFrame","getIndexOfKey","findIndex","Pan","minDistance","activateAfterLongPress","onStart","bestKey","bestDist","Number","MAX_VALUE","forEach","cx","cy","dx","dy","dist2","active","duration","onUpdate","translationX","translationY","pointerYInViewport","centerY","fromIndex","toIndex","centerX","length","next","splice","onEnd","deletePos","tolerance","expandedDeleteX","expandedDeleteY","expandedDeleteWidth","width","expandedDeleteHeight","height","itemLeft","itemRight","itemTop","itemBottom","overlaps","idx","index","scale","damping","stiffness","mass","map"],"sources":["PanWithLongPress.ts"],"sourcesContent":["import { Gesture } from \"react-native-gesture-handler\";\nimport {\n runOnJS,\n SharedValue,\n withSpring,\n withTiming,\n scrollTo,\n AnimatedRef,\n useSharedValue,\n useDerivedValue,\n} from \"react-native-reanimated\";\nimport {\n indexToXY,\n toIndex1ColFromLiveMidlines,\n xyToIndex,\n} from \"../indexCalculations\";\n\ninterface PanProps {\n order: SharedValue<string[]>;\n dynamicNumColumns: SharedValue<number>;\n activeKey: SharedValue<string | null>;\n offsetX: SharedValue<number>;\n offsetY: SharedValue<number>;\n startX: SharedValue<number>;\n startY: SharedValue<number>;\n dragMode: SharedValue<boolean>;\n positions: any;\n itemsByKey: any;\n itemWidth: number;\n itemHeight: number;\n containerPadding: number;\n gap: number;\n setOrderState: React.Dispatch<React.SetStateAction<string[]>>;\n onDragEnd?: (ordered: ChildNode[]) => void;\n onOrderChange?: (keys: string[]) => void;\n\n // scrolling\n scrollSpeed: number;\n scrollThreshold: number;\n scrollViewRef: AnimatedRef<any>;\n scrollOffset: SharedValue<number>;\n viewportH: SharedValue<number>;\n longPressMs: number;\n contentH: SharedValue<number>;\n reverse?: boolean;\n deleteComponentPosition?: SharedValue<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>;\n deleteItem?: (key: string) => void;\n contentPaddingBottom?: number; // Padding bottom from style prop to allow dragging into padding area\n}\n\nexport const PanWithLongPress = (props: PanProps & { longPressMs: number }) => {\n const {\n order,\n dynamicNumColumns,\n activeKey,\n offsetX,\n offsetY,\n startX,\n startY,\n dragMode,\n positions,\n itemsByKey,\n itemWidth,\n itemHeight,\n containerPadding,\n gap,\n setOrderState,\n onDragEnd,\n onOrderChange,\n scrollSpeed,\n scrollThreshold,\n scrollViewRef,\n scrollOffset,\n viewportH,\n longPressMs,\n contentH,\n reverse = false,\n deleteComponentPosition,\n deleteItem,\n contentPaddingBottom = 0,\n } = props;\n\n const scrollDir = useSharedValue(0); // -1 = up, 1 = down, 0 = none\n const initialScrollOffset = useSharedValue(0);\n\n useDerivedValue(() => {\n if (!dragMode.value || !activeKey.value) return;\n\n if (viewportH.value <= 0 || contentH.value <= 0) return;\n\n const key = activeKey.value;\n const p = positions[key];\n if (!p) return;\n\n // 1. Clamp scroll offset\n const maxScroll = contentH.value - viewportH.value;\n const newScroll = Math.max(\n 0,\n Math.min(scrollOffset.value + scrollDir.value * scrollSpeed, maxScroll)\n );\n\n scrollTo(scrollViewRef, 0, newScroll, false);\n const scrollDelta = newScroll - initialScrollOffset.value;\n scrollOffset.value = newScroll;\n\n // 2. Clamp item position\n // Allow dragging into padding area (paddingBottom from style prop)\n const minY = 0;\n // Add paddingBottom to maxY to allow dragging into the padding area\n const maxY = contentH.value - itemHeight + contentPaddingBottom;\n const proposedY = startY.value + offsetY.value + scrollDelta;\n p.y.value = Math.max(minY, Math.min(proposedY, maxY));\n\n // X stays normal\n p.x.value = startX.value + offsetX.value;\n\n // Keep loop alive\n requestAnimationFrame(() => {\n scrollDir.value = scrollDir.value;\n });\n });\n\n const getIndexOfKey = (key: string) => {\n \"worklet\";\n return order.value.findIndex((x) => x === key);\n };\n\n return Gesture.Pan()\n .minDistance(10)\n .activateAfterLongPress(longPressMs)\n .onStart(({ x, y }) => {\n initialScrollOffset.value = scrollOffset.value;\n dragMode.value = true;\n let bestKey: string | null = null;\n let bestDist = Number.MAX_VALUE;\n order.value.forEach((key) => {\n const p = positions[key];\n if (!p) return;\n const cx = p.x.value + itemWidth / 2;\n const cy = p.y.value + itemHeight / 2;\n const dx = cx - x;\n const dy = cy - y;\n const dist2 = dx * dx + dy * dy;\n if (dist2 < bestDist) {\n bestDist = dist2;\n bestKey = key;\n }\n });\n if (!bestKey) return;\n activeKey.value = bestKey;\n const p = positions[bestKey]!;\n p.active.value = withTiming(1, { duration: 120 });\n startX.value = p.x.value;\n startY.value = p.y.value;\n offsetX.value = 0;\n offsetY.value = 0;\n })\n .onUpdate(({ translationX, translationY }) => {\n if (!dragMode.value) return;\n const key = activeKey.value;\n if (!key) return;\n\n const p = positions[key]!;\n const scrollDelta = scrollOffset.value - initialScrollOffset.value;\n\n // Update active (top-left)\n offsetX.value = translationX;\n offsetY.value = translationY;\n p.x.value = startX.value + offsetX.value;\n p.y.value = startY.value + offsetY.value + scrollDelta;\n\n // Auto-scroll (unchanged)\n const pointerYInViewport = p.y.value - scrollOffset.value;\n if (pointerYInViewport > viewportH.value - scrollThreshold) {\n scrollDir.value = 1;\n } else if (pointerYInViewport < scrollThreshold) {\n scrollDir.value = -1;\n } else {\n scrollDir.value = 0;\n }\n\n // Compute target index from the active tile's **center**\n const centerY = p.y.value + itemHeight / 2;\n const fromIndex = getIndexOfKey(key);\n\n let toIndex: number;\n if (dynamicNumColumns.value === 1) {\n toIndex = toIndex1ColFromLiveMidlines(\n order,\n positions,\n activeKey,\n itemHeight,\n centerY,\n reverse // ← pass your prop\n );\n } else {\n // unchanged multi-column path\n const centerX = p.x.value + itemWidth / 2;\n toIndex = xyToIndex({\n order,\n x: centerX,\n y: centerY,\n itemWidth,\n itemHeight,\n dynamicNumColumns,\n containerPadding,\n gap,\n });\n }\n\n if (\n toIndex !== fromIndex &&\n toIndex >= 0 &&\n toIndex <= order.value.length - 1\n ) {\n const next = [...order.value];\n next.splice(fromIndex, 1);\n next.splice(toIndex, 0, key);\n order.value = next;\n }\n })\n .onEnd(() => {\n scrollDir.value = 0; // stop auto-scroll\n if (!dragMode.value) return;\n const key = activeKey.value;\n if (!key) {\n dragMode.value = false;\n return;\n }\n const p = positions[key]!;\n\n // Check if item was dropped into delete component\n if (deleteComponentPosition?.value && deleteItem) {\n const deletePos = deleteComponentPosition.value;\n\n // Add tolerance/padding to make it easier to hit (20% of item size)\n const tolerance = Math.min(itemWidth, itemHeight) * 0.2;\n const expandedDeleteX = deletePos.x - tolerance;\n const expandedDeleteY = deletePos.y - tolerance;\n const expandedDeleteWidth = deletePos.width + tolerance * 2;\n const expandedDeleteHeight = deletePos.height + tolerance * 2;\n\n // Check if item bounding box overlaps with expanded delete component bounds\n // This is more forgiving than checking just the center point\n const itemLeft = p.x.value;\n const itemRight = p.x.value + itemWidth;\n const itemTop = p.y.value;\n const itemBottom = p.y.value + itemHeight;\n\n // Bounding box intersection check\n const overlaps =\n itemLeft < expandedDeleteX + expandedDeleteWidth &&\n itemRight > expandedDeleteX &&\n itemTop < expandedDeleteY + expandedDeleteHeight &&\n itemBottom > expandedDeleteY;\n\n if (overlaps) {\n // Item was dropped into delete component - delete it\n runOnJS(deleteItem)(key);\n // Note: deleteItem will handle calling onDelete callback if provided\n p.active.value = withTiming(0, { duration: 120 });\n activeKey.value = null;\n dragMode.value = false;\n return;\n }\n }\n\n // Normal drop - return to grid position\n const idx = getIndexOfKey(key);\n const { x, y } = indexToXY({\n index: idx,\n itemWidth,\n itemHeight,\n dynamicNumColumns,\n containerPadding,\n gap,\n });\n const scale = Math.min(itemWidth, itemHeight) / 200; // 100px baseline\n\n const damping = 18 * scale;\n const stiffness = 240 * scale;\n const mass = Math.max(0.05, scale); // helps stability for tiny items\n\n p.x.value = withSpring(x, { damping, stiffness, mass });\n p.y.value = withSpring(y, { damping, stiffness, mass });\n\n p.active.value = withTiming(0, { duration: 120 });\n\n runOnJS(setOrderState)(order.value);\n if (onDragEnd) {\n runOnJS(onDragEnd)(order.value.map((key) => itemsByKey[key]));\n }\n if (onOrderChange) {\n runOnJS(onOrderChange)([...order.value]);\n }\n activeKey.value = null;\n dragMode.value = false;\n });\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,64 @@
1
+ export const indexToXY = ({
2
+ index,
3
+ itemHeight,
4
+ itemWidth,
5
+ dynamicNumColumns,
6
+ containerPadding,
7
+ gap
8
+ }) => {
9
+ "worklet";
10
+
11
+ const cols = dynamicNumColumns.value;
12
+ const col = index % cols;
13
+ const row = Math.floor(index / cols);
14
+ const x = containerPadding + col * (itemWidth + gap);
15
+ const y = containerPadding + row * (itemHeight + gap);
16
+ return {
17
+ x,
18
+ y
19
+ };
20
+ };
21
+ export const xyToIndex = ({
22
+ order,
23
+ x,
24
+ y,
25
+ itemHeight,
26
+ itemWidth,
27
+ dynamicNumColumns,
28
+ gap,
29
+ containerPadding
30
+ }) => {
31
+ "worklet";
32
+
33
+ const cols = dynamicNumColumns.value;
34
+
35
+ // Work with CENTER coordinates relative to the content box
36
+ const relX = x - containerPadding;
37
+ const relY = y - containerPadding;
38
+ const col = Math.floor(relX / (itemWidth + gap));
39
+ const row = Math.floor(relY / (itemHeight + gap));
40
+ const clampedCol = Math.max(0, Math.min(cols - 1, col));
41
+ const maxRows = Math.max(1, Math.ceil(order.value.length / cols));
42
+ const clampedRow = Math.max(0, Math.min(maxRows - 1, row));
43
+ return clampedRow * cols + clampedCol;
44
+ };
45
+ export const toIndex1ColFromLiveMidlines = (order, positions, activeKey, itemHeight, centerY, reverse) => {
46
+ "worklet";
47
+
48
+ const list = order.value.filter(k => k !== activeKey.value);
49
+
50
+ // Sort by actual on-screen Y (top → bottom)
51
+ list.sort((a, b) => positions[a].y.value - positions[b].y.value);
52
+
53
+ // Find visual slot v (0..list.length)
54
+ let v = 0;
55
+ for (; v < list.length; v++) {
56
+ const mid = positions[list[v]].y.value + itemHeight / 2;
57
+ if (centerY < mid) break;
58
+ }
59
+
60
+ // Map visual slot → array index AFTER removal (reverse aware)
61
+ const afterRemovalLen = list.length;
62
+ return reverse ? afterRemovalLen - v : v;
63
+ };
64
+ //# sourceMappingURL=indexCalculations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["indexToXY","index","itemHeight","itemWidth","dynamicNumColumns","containerPadding","gap","cols","value","col","row","Math","floor","x","y","xyToIndex","order","relX","relY","clampedCol","max","min","maxRows","ceil","length","clampedRow","toIndex1ColFromLiveMidlines","positions","activeKey","centerY","reverse","list","filter","k","sort","a","b","v","mid","afterRemovalLen"],"sources":["indexCalculations.ts"],"sourcesContent":["import { SharedValue } from \"react-native-reanimated\";\n\ninterface IndexToXYProps {\n index: number;\n itemHeight: number;\n itemWidth: number;\n dynamicNumColumns: SharedValue<number>;\n containerPadding: number;\n gap: number;\n}\n\nexport const indexToXY = ({\n index,\n itemHeight,\n itemWidth,\n dynamicNumColumns,\n containerPadding,\n gap,\n}: IndexToXYProps) => {\n \"worklet\";\n const cols = dynamicNumColumns.value;\n const col = index % cols;\n const row = Math.floor(index / cols);\n const x = containerPadding + col * (itemWidth + gap);\n const y = containerPadding + row * (itemHeight + gap);\n return { x, y };\n};\n\ninterface XYToIndexProps {\n order: SharedValue<string[]>;\n x: number;\n y: number;\n itemHeight: number;\n itemWidth: number;\n dynamicNumColumns: SharedValue<number>;\n containerPadding: number;\n gap: number;\n}\n\nexport const xyToIndex = ({\n order,\n x,\n y,\n itemHeight,\n itemWidth,\n dynamicNumColumns,\n gap,\n containerPadding,\n}: XYToIndexProps) => {\n \"worklet\";\n const cols = dynamicNumColumns.value;\n\n // Work with CENTER coordinates relative to the content box\n const relX = x - containerPadding;\n const relY = y - containerPadding;\n\n const col = Math.floor(relX / (itemWidth + gap));\n const row = Math.floor(relY / (itemHeight + gap));\n\n const clampedCol = Math.max(0, Math.min(cols - 1, col));\n const maxRows = Math.max(1, Math.ceil(order.value.length / cols));\n const clampedRow = Math.max(0, Math.min(maxRows - 1, row));\n\n return clampedRow * cols + clampedCol;\n};\n\nexport const toIndex1ColFromLiveMidlines = (\n order: SharedValue<string[]>,\n positions: Record<string, { y: SharedValue<number> }>,\n activeKey: SharedValue<string | null>,\n itemHeight: number,\n centerY: number,\n reverse: boolean\n) => {\n \"worklet\";\n const list = order.value.filter((k) => k !== activeKey.value);\n\n // Sort by actual on-screen Y (top → bottom)\n list.sort((a, b) => positions[a].y.value - positions[b].y.value);\n\n // Find visual slot v (0..list.length)\n let v = 0;\n for (; v < list.length; v++) {\n const mid = positions[list[v]].y.value + itemHeight / 2;\n if (centerY < mid) break;\n }\n\n // Map visual slot → array index AFTER removal (reverse aware)\n const afterRemovalLen = list.length;\n return reverse ? afterRemovalLen - v : v;\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,199 @@
1
+ import { Children, isValidElement, useMemo, useState } from "react";
2
+ import { Gesture } from "react-native-gesture-handler";
3
+ import { useAnimatedScrollHandler, useDerivedValue, useSharedValue, withSpring } from "react-native-reanimated";
4
+ import { indexToXY } from "./helpers/indexCalculations";
5
+ import { PanWithLongPress } from "./helpers/gestures/PanWithLongPress";
6
+ export function useGridLayout({
7
+ reverse,
8
+ children,
9
+ itemWidth,
10
+ itemHeight,
11
+ gap,
12
+ containerPadding,
13
+ longPressMs,
14
+ numColumns,
15
+ onDragEnd,
16
+ onOrderChange,
17
+ onDelete,
18
+ scrollViewRef,
19
+ scrollSpeed,
20
+ scrollThreshold,
21
+ contentPaddingBottom = 0
22
+ }) {
23
+ const childArray = Children.toArray(children).filter(isValidElement);
24
+ const keys = childArray.map(child => {
25
+ if (!("key" in child) || child.key == null) {
26
+ throw new Error("All children must have a unique 'key' prop.");
27
+ }
28
+ return String(child.key);
29
+ });
30
+ const [orderState, setOrderState] = useState(keys);
31
+ const itemsByKey = useMemo(() => {
32
+ const map = {};
33
+ childArray.forEach(child => {
34
+ map[String(child.key)] = child;
35
+ });
36
+ return map;
37
+ }, [children]);
38
+ const dynamicNumColumns = useSharedValue(numColumns ? numColumns : 1);
39
+ const order = useSharedValue(orderState);
40
+ const contentW = useSharedValue(0);
41
+ const viewportH = useSharedValue(0); // **visible height of ScrollView**
42
+ const activeKey = useSharedValue(null);
43
+ const offsetX = useSharedValue(0);
44
+ const offsetY = useSharedValue(0);
45
+ const startX = useSharedValue(0);
46
+ const startY = useSharedValue(0);
47
+ const dragMode = useSharedValue(false);
48
+ const anyItemInDeleteMode = useSharedValue(false); // Global delete mode state
49
+ const contentH = useSharedValue(0);
50
+ const scrollOffset = useSharedValue(0);
51
+ const onScroll = useAnimatedScrollHandler({
52
+ onScroll: e => {
53
+ scrollOffset.value = e.contentOffset.y;
54
+ }
55
+ });
56
+
57
+ // initial positions (create shared values consistently by data length)
58
+ const positionsArray = childArray.map((d, i) => {
59
+ const {
60
+ x,
61
+ y
62
+ } = indexToXY({
63
+ index: i,
64
+ itemWidth,
65
+ itemHeight,
66
+ dynamicNumColumns,
67
+ containerPadding,
68
+ gap
69
+ });
70
+ return {
71
+ key: d.key,
72
+ pos: {
73
+ x: useSharedValue(x),
74
+ y: useSharedValue(y),
75
+ active: useSharedValue(0)
76
+ }
77
+ };
78
+ });
79
+ const positions = useMemo(() => {
80
+ const obj = {};
81
+ positionsArray.forEach(({
82
+ key,
83
+ pos
84
+ }) => {
85
+ obj[key ?? `key-${Math.random().toString(36).slice(2)}`] = pos;
86
+ });
87
+ return obj;
88
+ }, [positionsArray]);
89
+ const deleteItem = key => {
90
+ setOrderState(prev => prev.filter(k => k !== key));
91
+ order.value = order.value.filter(k => k !== key);
92
+ onOrderChange === null || onOrderChange === void 0 || onOrderChange([...order.value]);
93
+ // Call onDelete callback if provided (for both delete button and drop-to-delete)
94
+ if (onDelete) {
95
+ onDelete(key);
96
+ }
97
+ };
98
+ useDerivedValue(() => {
99
+ order.value.forEach((key, i) => {
100
+ if (activeKey.value === key) return; // ⬅️ do not layout the active tile
101
+
102
+ const p = positions[key];
103
+ if (!p) return;
104
+ const displayIndex = reverse ? order.value.length - 1 - i : i;
105
+ const {
106
+ x,
107
+ y
108
+ } = indexToXY({
109
+ index: displayIndex,
110
+ itemWidth,
111
+ itemHeight,
112
+ dynamicNumColumns,
113
+ containerPadding,
114
+ gap
115
+ });
116
+ const scale = Math.min(itemWidth, itemHeight) / 100; // 100px baseline
117
+
118
+ const damping = 18 * scale;
119
+ const stiffness = 240 * scale;
120
+ const mass = Math.max(0.1, scale); // helps stability for tiny items
121
+
122
+ p.x.value = withSpring(x, {
123
+ damping,
124
+ stiffness,
125
+ mass
126
+ });
127
+ p.y.value = withSpring(y, {
128
+ damping,
129
+ stiffness,
130
+ mass
131
+ });
132
+ });
133
+ });
134
+
135
+ // Layout of the ScrollView (viewport) — height we compare against for edge-scrolling
136
+ const onLayoutScrollView = e => {
137
+ viewportH.value = e.nativeEvent.layout.height;
138
+ };
139
+
140
+ // Layout of the content view — width used to compute columns
141
+ const onLayoutContent = e => {
142
+ contentW.value = e.nativeEvent.layout.width;
143
+ contentH.value = e.nativeEvent.layout.height;
144
+ if (numColumns) {
145
+ dynamicNumColumns.value = numColumns;
146
+ } else {
147
+ const possibleCols = Math.floor((e.nativeEvent.layout.width - containerPadding * 2 + gap) / (itemWidth + gap));
148
+ dynamicNumColumns.value = Math.max(1, possibleCols);
149
+ }
150
+ };
151
+ const deleteComponentPosition = useSharedValue(null);
152
+ const composed = Gesture.Simultaneous(PanWithLongPress({
153
+ contentH,
154
+ order,
155
+ dynamicNumColumns,
156
+ activeKey,
157
+ offsetX,
158
+ offsetY,
159
+ startX,
160
+ startY,
161
+ dragMode,
162
+ positions,
163
+ itemsByKey,
164
+ itemWidth,
165
+ itemHeight,
166
+ containerPadding,
167
+ gap,
168
+ setOrderState,
169
+ onDragEnd,
170
+ onOrderChange,
171
+ scrollViewRef,
172
+ scrollOffset,
173
+ viewportH,
174
+ longPressMs,
175
+ scrollSpeed,
176
+ scrollThreshold,
177
+ reverse,
178
+ deleteComponentPosition,
179
+ deleteItem,
180
+ contentPaddingBottom
181
+ }));
182
+ return {
183
+ itemsByKey,
184
+ orderState,
185
+ dragMode,
186
+ anyItemInDeleteMode,
187
+ composed,
188
+ dynamicNumColumns,
189
+ onLayoutContent,
190
+ onLayoutScrollView,
191
+ positions,
192
+ onScroll,
193
+ childArray,
194
+ order,
195
+ deleteItem,
196
+ deleteComponentPosition
197
+ };
198
+ }
199
+ //# sourceMappingURL=useGridLayout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Children","isValidElement","useMemo","useState","Gesture","useAnimatedScrollHandler","useDerivedValue","useSharedValue","withSpring","indexToXY","PanWithLongPress","useGridLayout","reverse","children","itemWidth","itemHeight","gap","containerPadding","longPressMs","numColumns","onDragEnd","onOrderChange","onDelete","scrollViewRef","scrollSpeed","scrollThreshold","contentPaddingBottom","childArray","toArray","filter","keys","map","child","key","Error","String","orderState","setOrderState","itemsByKey","forEach","dynamicNumColumns","order","contentW","viewportH","activeKey","offsetX","offsetY","startX","startY","dragMode","anyItemInDeleteMode","contentH","scrollOffset","onScroll","e","value","contentOffset","y","positionsArray","d","i","x","index","pos","active","positions","obj","Math","random","toString","slice","deleteItem","prev","k","p","displayIndex","length","scale","min","damping","stiffness","mass","max","onLayoutScrollView","nativeEvent","layout","height","onLayoutContent","width","possibleCols","floor","deleteComponentPosition","composed","Simultaneous"],"sources":["useGridLayout.ts"],"sourcesContent":["import { Children, isValidElement, ReactNode, useMemo, useState } from \"react\";\nimport { LayoutChangeEvent } from \"react-native\";\nimport { Gesture } from \"react-native-gesture-handler\";\nimport {\n AnimatedRef,\n SharedValue,\n useAnimatedScrollHandler,\n useDerivedValue,\n useSharedValue,\n withSpring,\n} from \"react-native-reanimated\";\nimport { indexToXY } from \"./helpers/indexCalculations\";\nimport { PanWithLongPress } from \"./helpers/gestures/PanWithLongPress\";\n\ninterface useGridLayoutProps {\n reverse?: boolean;\n children: ReactNode;\n itemWidth: number;\n itemHeight: number;\n gap: number;\n containerPadding: number;\n longPressMs: number;\n numColumns?: number;\n onDragEnd?: (ordered: ChildNode[]) => void;\n onOrderChange?: (keys: string[]) => void;\n onDelete?: (key: string) => void;\n scrollViewRef: AnimatedRef<any>;\n scrollSpeed: number;\n scrollThreshold: number;\n contentPaddingBottom?: number;\n}\n\nexport function useGridLayout({\n reverse,\n children,\n itemWidth,\n itemHeight,\n gap,\n containerPadding,\n longPressMs,\n numColumns,\n onDragEnd,\n onOrderChange,\n onDelete,\n scrollViewRef,\n scrollSpeed,\n scrollThreshold,\n contentPaddingBottom = 0,\n}: useGridLayoutProps) {\n const childArray = Children.toArray(children).filter(isValidElement);\n const keys = childArray.map((child) => {\n if (!(\"key\" in child) || child.key == null) {\n throw new Error(\"All children must have a unique 'key' prop.\");\n }\n return String(child.key);\n });\n\n const [orderState, setOrderState] = useState(keys);\n\n const itemsByKey = useMemo(() => {\n const map: Record<string, ReactNode> = {};\n childArray.forEach((child) => {\n map[String(child.key)] = child;\n });\n return map;\n }, [children]);\n\n const dynamicNumColumns: SharedValue<number> = useSharedValue(\n numColumns ? numColumns : 1\n );\n const order = useSharedValue<string[]>(orderState);\n const contentW = useSharedValue(0);\n const viewportH = useSharedValue(0); // **visible height of ScrollView**\n const activeKey = useSharedValue<string | null>(null);\n const offsetX = useSharedValue(0);\n const offsetY = useSharedValue(0);\n const startX = useSharedValue(0);\n const startY = useSharedValue(0);\n const dragMode = useSharedValue(false);\n const anyItemInDeleteMode = useSharedValue(false); // Global delete mode state\n const contentH = useSharedValue(0);\n const scrollOffset = useSharedValue(0);\n\n const onScroll = useAnimatedScrollHandler({\n onScroll: (e) => {\n scrollOffset.value = e.contentOffset.y;\n },\n });\n\n // initial positions (create shared values consistently by data length)\n const positionsArray = childArray.map((d, i) => {\n const { x, y } = indexToXY({\n index: i,\n itemWidth,\n itemHeight,\n dynamicNumColumns,\n containerPadding,\n gap,\n });\n return {\n key: d.key,\n pos: {\n x: useSharedValue(x),\n y: useSharedValue(y),\n active: useSharedValue(0),\n },\n };\n });\n\n const positions = useMemo(() => {\n const obj: Record<string, (typeof positionsArray)[number][\"pos\"]> = {};\n\n positionsArray.forEach(({ key, pos }) => {\n obj[key ?? `key-${Math.random().toString(36).slice(2)}`] = pos;\n });\n\n return obj;\n }, [positionsArray]);\n\n const deleteItem = (key: string) => {\n setOrderState((prev) => prev.filter((k) => k !== key));\n order.value = order.value.filter((k) => k !== key);\n onOrderChange?.([...order.value]);\n // Call onDelete callback if provided (for both delete button and drop-to-delete)\n if (onDelete) {\n onDelete(key);\n }\n };\n\n useDerivedValue(() => {\n order.value.forEach((key, i) => {\n if (activeKey.value === key) return; // ⬅️ do not layout the active tile\n\n const p = positions[key];\n if (!p) return;\n\n const displayIndex = reverse ? order.value.length - 1 - i : i;\n\n const { x, y } = indexToXY({\n index: displayIndex,\n itemWidth,\n itemHeight,\n dynamicNumColumns,\n containerPadding,\n gap,\n });\n\n const scale = Math.min(itemWidth, itemHeight) / 100; // 100px baseline\n\n const damping = 18 * scale;\n const stiffness = 240 * scale;\n const mass = Math.max(0.1, scale); // helps stability for tiny items\n\n p.x.value = withSpring(x, { damping, stiffness, mass });\n p.y.value = withSpring(y, { damping, stiffness, mass });\n });\n });\n\n // Layout of the ScrollView (viewport) — height we compare against for edge-scrolling\n const onLayoutScrollView = (e: LayoutChangeEvent) => {\n viewportH.value = e.nativeEvent.layout.height;\n };\n\n // Layout of the content view — width used to compute columns\n const onLayoutContent = (e: LayoutChangeEvent) => {\n contentW.value = e.nativeEvent.layout.width;\n contentH.value = e.nativeEvent.layout.height;\n\n if (numColumns) {\n dynamicNumColumns.value = numColumns;\n } else {\n const possibleCols = Math.floor(\n (e.nativeEvent.layout.width - containerPadding * 2 + gap) /\n (itemWidth + gap)\n );\n dynamicNumColumns.value = Math.max(1, possibleCols);\n }\n };\n\n const deleteComponentPosition = useSharedValue<{\n x: number;\n y: number;\n width: number;\n height: number;\n } | null>(null);\n\n const composed = Gesture.Simultaneous(\n PanWithLongPress({\n contentH,\n order,\n dynamicNumColumns,\n activeKey,\n offsetX,\n offsetY,\n startX,\n startY,\n dragMode,\n positions,\n itemsByKey,\n itemWidth,\n itemHeight,\n containerPadding,\n gap,\n setOrderState,\n onDragEnd,\n onOrderChange,\n scrollViewRef,\n scrollOffset,\n viewportH,\n longPressMs,\n scrollSpeed,\n scrollThreshold,\n reverse,\n deleteComponentPosition,\n deleteItem,\n contentPaddingBottom,\n })\n );\n\n return {\n itemsByKey,\n orderState,\n dragMode,\n anyItemInDeleteMode,\n composed,\n dynamicNumColumns,\n onLayoutContent,\n onLayoutScrollView,\n positions,\n onScroll,\n childArray,\n order,\n deleteItem,\n deleteComponentPosition,\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+ import { SharedValue } from "react-native-reanimated";
3
+ type Props = {
4
+ position: {
5
+ x: SharedValue<number>;
6
+ y: SharedValue<number>;
7
+ active: SharedValue<number>;
8
+ };
9
+ itemWidth: number;
10
+ itemHeight: number;
11
+ dragMode: SharedValue<boolean>;
12
+ anyItemInDeleteMode: SharedValue<boolean>;
13
+ children: React.ReactNode;
14
+ wiggle?: {
15
+ duration: number;
16
+ degrees: number;
17
+ };
18
+ dragSizeIncreaseFactor: number;
19
+ onDelete?: () => void;
20
+ disableHoldToDelete?: boolean;
21
+ };
22
+ export default function ChildWrapper({ position, itemWidth, itemHeight, dragMode, anyItemInDeleteMode, children, wiggle, dragSizeIncreaseFactor, onDelete, disableHoldToDelete, }: Props): React.JSX.Element;
23
+ export {};