react-native-sortable-dynamic 0.3.3 → 0.4.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.
- package/lib/commonjs/Config.js +6 -23
- package/lib/commonjs/Config.js.map +1 -1
- package/lib/commonjs/SortableItemWrapper.js +65 -70
- package/lib/commonjs/SortableItemWrapper.js.map +1 -1
- package/lib/module/Config.js +7 -24
- package/lib/module/Config.js.map +1 -1
- package/lib/module/SortableItemWrapper.js +68 -73
- package/lib/module/SortableItemWrapper.js.map +1 -1
- package/package.json +1 -1
- package/src/Config.js +8 -21
- package/src/SortableItemWrapper.js +24 -24
package/lib/commonjs/Config.js
CHANGED
|
@@ -10,18 +10,13 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
10
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
11
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
12
12
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
13
|
-
//
|
|
14
|
-
const {
|
|
15
|
-
width
|
|
16
|
-
} = _reactNative.Dimensions.get('window');
|
|
17
|
-
|
|
18
|
-
// Default configuration for the sortable grid/list
|
|
13
|
+
// Default configuration for the sortable grid/list (static fallback values)
|
|
19
14
|
const defaultConfig = {
|
|
20
15
|
MARGIN: 10,
|
|
21
16
|
// Default margin between items
|
|
22
17
|
COL: 2,
|
|
23
18
|
// Default number of columns
|
|
24
|
-
SIZE:
|
|
19
|
+
SIZE: 100 // Temporary fallback size
|
|
25
20
|
};
|
|
26
21
|
|
|
27
22
|
// Create a Context for the sortable grid/list configuration
|
|
@@ -38,11 +33,9 @@ const animationConfig = exports.animationConfig = {
|
|
|
38
33
|
};
|
|
39
34
|
|
|
40
35
|
// Helper function to calculate the item's position based on its index
|
|
41
|
-
// Used to position items in a grid layout
|
|
42
36
|
const getPosition = (position, COL, SIZE) => {
|
|
43
37
|
'worklet';
|
|
44
38
|
|
|
45
|
-
// Necessary for Reanimated 2 to run this function on the UI thread
|
|
46
39
|
return {
|
|
47
40
|
x: position % COL === 0 ? 0 : SIZE * (position % COL),
|
|
48
41
|
y: Math.floor(position / COL) * SIZE
|
|
@@ -54,7 +47,6 @@ exports.getPosition = getPosition;
|
|
|
54
47
|
const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
55
48
|
'worklet';
|
|
56
49
|
|
|
57
|
-
// Necessary for Reanimated 2 to run this function on the UI thread
|
|
58
50
|
const x = Math.round(tx / SIZE) * SIZE;
|
|
59
51
|
const y = Math.round(ty / SIZE) * SIZE;
|
|
60
52
|
const row = Math.max(y, 0) / SIZE;
|
|
@@ -65,32 +57,23 @@ const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
|
65
57
|
/**
|
|
66
58
|
* SortableConfigProvider component
|
|
67
59
|
*
|
|
68
|
-
* Wrap your sortable grid/list components with this provider to set custom configuration.
|
|
69
|
-
* This provider allows for overriding default settings like margin and the number of columns.
|
|
70
|
-
*
|
|
71
60
|
* @param {Object} config - Custom configuration to override the default settings.
|
|
72
61
|
* @param {number} config.MARGIN - Margin between items.
|
|
73
62
|
* @param {number} config.COL - Number of columns in the grid.
|
|
74
63
|
* @param {React.ReactNode} children - Child components that will use this configuration.
|
|
75
|
-
*
|
|
76
|
-
* Usage:
|
|
77
|
-
*
|
|
78
|
-
* <SortableConfigProvider config={{ MARGIN: 15, COL: 3 }}>
|
|
79
|
-
* <YourSortableComponent />
|
|
80
|
-
* </SortableConfigProvider>
|
|
81
64
|
*/
|
|
82
65
|
exports.getOrder = getOrder;
|
|
83
66
|
const SortableConfigProvider = ({
|
|
84
67
|
children,
|
|
85
|
-
config
|
|
68
|
+
config = {}
|
|
86
69
|
}) => {
|
|
87
|
-
|
|
70
|
+
const {
|
|
71
|
+
width
|
|
72
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
88
73
|
const mergedConfig = {
|
|
89
74
|
...defaultConfig,
|
|
90
75
|
...config
|
|
91
76
|
};
|
|
92
|
-
|
|
93
|
-
// Recalculate SIZE based on COL and MARGIN
|
|
94
77
|
mergedConfig.SIZE = width / mergedConfig.COL - mergedConfig.MARGIN;
|
|
95
78
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ConfigContext.Provider, {
|
|
96
79
|
value: mergedConfig,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","_reactNativeReanimated","_react","_interopRequireWildcard","_jsxRuntime","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","_reactNativeReanimated","_react","_interopRequireWildcard","_jsxRuntime","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","defaultConfig","MARGIN","COL","SIZE","ConfigContext","createContext","useSortableConfig","useContext","exports","animationConfig","easing","Easing","inOut","ease","duration","getPosition","position","x","y","Math","floor","getOrder","tx","ty","max","round","row","col","min","SortableConfigProvider","children","config","width","useWindowDimensions","mergedConfig","jsx","Provider","value","_default"],"sourceRoot":"../../src","sources":["Config.js"],"mappings":"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","ignoreList":[]}
|
|
@@ -57,7 +57,10 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
57
57
|
}) => {
|
|
58
58
|
// Get safe area insets for accurate height calculation
|
|
59
59
|
const inset = (0, _reactNativeSafeAreaContext.useSafeAreaInsets)();
|
|
60
|
-
const
|
|
60
|
+
const {
|
|
61
|
+
height
|
|
62
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
63
|
+
const containerHeight = height - inset.top - inset.bottom;
|
|
61
64
|
|
|
62
65
|
// Get the configuration for columns and size
|
|
63
66
|
const {
|
|
@@ -74,6 +77,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
74
77
|
const position = (0, _Config.getPosition)(positions.value[id], COL, SIZE);
|
|
75
78
|
const translateX = (0, _reactNativeReanimated.useSharedValue)(position.x);
|
|
76
79
|
const translateY = (0, _reactNativeReanimated.useSharedValue)(position.y);
|
|
80
|
+
const startX = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
81
|
+
const startY = (0, _reactNativeReanimated.useSharedValue)(0);
|
|
77
82
|
|
|
78
83
|
// Effect to reset isGestureActive when not in editing mode
|
|
79
84
|
(0, _react.useEffect)(() => {
|
|
@@ -92,80 +97,71 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
92
97
|
translateY.value = (0, _reactNativeReanimated.withTiming)(pos.y, _Config.animationConfig);
|
|
93
98
|
}
|
|
94
99
|
});
|
|
100
|
+
const pan = _reactNativeGestureHandler.Gesture.Pan().onStart(() => {
|
|
101
|
+
if (editing && draggable) {
|
|
102
|
+
// Store the starting position
|
|
103
|
+
startX.value = translateX.value;
|
|
104
|
+
startY.value = translateY.value;
|
|
105
|
+
isGestureActive.value = false;
|
|
106
|
+
}
|
|
107
|
+
}).onUpdate(e => {
|
|
108
|
+
if (editing && draggable) {
|
|
109
|
+
// Calculate new position
|
|
110
|
+
translateX.value = startX.value + e.translationX;
|
|
111
|
+
translateY.value = startY.value + e.translationY;
|
|
95
112
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
ctx.y = translateY.value;
|
|
103
|
-
isGestureActive.value = false;
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
onActive: ({
|
|
107
|
-
translationX,
|
|
108
|
-
translationY
|
|
109
|
-
}, ctx) => {
|
|
110
|
-
if (editing && draggable) {
|
|
111
|
-
// Calculate new position
|
|
112
|
-
translateX.value = ctx.x + translationX;
|
|
113
|
-
translateY.value = ctx.y + translationY;
|
|
114
|
-
|
|
115
|
-
// Calculate new order based on position
|
|
116
|
-
const newOrder = (0, _Config.getOrder)(translateX.value, translateY.value, Object.keys(positions.value).length - 1, COL, SIZE);
|
|
117
|
-
const oldOrder = positions.value[id];
|
|
118
|
-
if (newOrder !== oldOrder) {
|
|
119
|
-
// Find the item to swap positions with
|
|
120
|
-
const idToSwap = Object.keys(positions.value).find(key => positions.value[key] === newOrder);
|
|
113
|
+
// Calculate new order based on position
|
|
114
|
+
const newOrder = (0, _Config.getOrder)(translateX.value, translateY.value, Object.keys(positions.value).length - 1, COL, SIZE);
|
|
115
|
+
const oldOrder = positions.value[id];
|
|
116
|
+
if (newOrder !== oldOrder) {
|
|
117
|
+
// Find the item to swap positions with
|
|
118
|
+
const idToSwap = Object.keys(positions.value).find(key => positions.value[key] === newOrder);
|
|
121
119
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
120
|
+
// Only swap if the target item is reorderable
|
|
121
|
+
const targetItem = data.find(tile => tile.id === Number(idToSwap));
|
|
122
|
+
if (idToSwap && targetItem?.reorderable !== false) {
|
|
123
|
+
const newPositions = {
|
|
124
|
+
...positions.value
|
|
125
|
+
};
|
|
126
|
+
newPositions[id] = newOrder;
|
|
127
|
+
newPositions[idToSwap] = oldOrder;
|
|
128
|
+
positions.value = newPositions;
|
|
132
129
|
}
|
|
130
|
+
}
|
|
133
131
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
// Handle scrolling during drag
|
|
133
|
+
const lowerBound = scrollY.value;
|
|
134
|
+
const upperBound = lowerBound + containerHeight - SIZE;
|
|
135
|
+
const maxScroll = contentHeight - containerHeight;
|
|
136
|
+
const leftToScrollDown = maxScroll - scrollY.value;
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
// Scroll down
|
|
149
|
-
if (translateY.value > upperBound) {
|
|
150
|
-
const diff = Math.min(translateY.value - upperBound, leftToScrollDown);
|
|
151
|
-
scrollY.value += diff;
|
|
152
|
-
(0, _reactNativeReanimated.scrollTo)(scrollView, 0, scrollY.value, false);
|
|
153
|
-
ctx.y += diff;
|
|
154
|
-
translateY.value = ctx.y + translationY;
|
|
155
|
-
}
|
|
138
|
+
// Scroll up
|
|
139
|
+
if (translateY.value < lowerBound) {
|
|
140
|
+
const diff = Math.min(lowerBound - translateY.value, lowerBound);
|
|
141
|
+
scrollY.value -= diff;
|
|
142
|
+
(0, _reactNativeReanimated.scrollTo)(scrollView, 0, scrollY.value, false);
|
|
143
|
+
startY.value -= diff;
|
|
144
|
+
translateY.value = startY.value + e.translationY;
|
|
156
145
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
(0, _reactNativeReanimated.runOnJS)(onDragEnd)(positions.value); // Call onDragEnd on the JS thread
|
|
165
|
-
});
|
|
166
|
-
translateY.value = (0, _reactNativeReanimated.withTiming)(newPosition.y, _Config.animationConfig);
|
|
146
|
+
// Scroll down
|
|
147
|
+
if (translateY.value > upperBound) {
|
|
148
|
+
const diff = Math.min(translateY.value - upperBound, leftToScrollDown);
|
|
149
|
+
scrollY.value += diff;
|
|
150
|
+
(0, _reactNativeReanimated.scrollTo)(scrollView, 0, scrollY.value, false);
|
|
151
|
+
startY.value += diff;
|
|
152
|
+
translateY.value = startY.value + e.translationY;
|
|
167
153
|
}
|
|
168
154
|
}
|
|
155
|
+
}).onEnd(() => {
|
|
156
|
+
if (draggable) {
|
|
157
|
+
// Snap the item back into its place when the drag ends
|
|
158
|
+
const newPosition = (0, _Config.getPosition)(positions.value[id], COL, SIZE);
|
|
159
|
+
translateX.value = (0, _reactNativeReanimated.withTiming)(newPosition.x, _Config.animationConfig, () => {
|
|
160
|
+
isGestureActive.value = false; // Set gesture to inactive
|
|
161
|
+
(0, _reactNativeReanimated.runOnJS)(onDragEnd)(positions.value); // Call onDragEnd on the JS thread
|
|
162
|
+
});
|
|
163
|
+
translateY.value = (0, _reactNativeReanimated.withTiming)(newPosition.y, _Config.animationConfig);
|
|
164
|
+
}
|
|
169
165
|
});
|
|
170
166
|
|
|
171
167
|
// Animated style for the item
|
|
@@ -191,9 +187,8 @@ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e;
|
|
|
191
187
|
});
|
|
192
188
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
193
189
|
style: style,
|
|
194
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.
|
|
195
|
-
|
|
196
|
-
onGestureEvent: onGestureEvent,
|
|
190
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeGestureHandler.GestureDetector, {
|
|
191
|
+
gesture: pan,
|
|
197
192
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeReanimated.default.View, {
|
|
198
193
|
style: _reactNative.StyleSheet.absoluteFill,
|
|
199
194
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeReanimated","_reactNativeGestureHandler","_reactNativeSafeAreaContext","_Config","_jsxRuntime","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","SortableItemWrapper","children","positions","id","onDragEnd","scrollView","scrollY","editing","draggable","data","inset","useSafeAreaInsets","
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeReanimated","_reactNativeGestureHandler","_reactNativeSafeAreaContext","_Config","_jsxRuntime","_getRequireWildcardCache","e","WeakMap","r","t","__esModule","default","has","get","n","__proto__","a","Object","defineProperty","getOwnPropertyDescriptor","u","hasOwnProperty","call","i","set","SortableItemWrapper","children","positions","id","onDragEnd","scrollView","scrollY","editing","draggable","data","inset","useSafeAreaInsets","height","useWindowDimensions","containerHeight","top","bottom","COL","SIZE","MARGIN","useSortableConfig","contentHeight","keys","value","length","isGestureActive","useSharedValue","position","getPosition","translateX","x","translateY","y","startX","startY","useEffect","useAnimatedReaction","newOrder","pos","withTiming","animationConfig","pan","Gesture","Pan","onStart","onUpdate","translationX","translationY","getOrder","oldOrder","idToSwap","find","key","targetItem","tile","Number","reorderable","newPositions","lowerBound","upperBound","maxScroll","leftToScrollDown","diff","Math","min","scrollTo","onEnd","newPosition","runOnJS","style","useAnimatedStyle","zIndex","scale","withSpring","left","width","margin","transform","jsx","View","GestureDetector","gesture","StyleSheet","absoluteFill","_default","exports"],"sourceRoot":"../../src","sources":["SortableItemWrapper.js"],"mappings":"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","ignoreList":[]}
|
package/lib/module/Config.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useWindowDimensions } from 'react-native';
|
|
4
4
|
import { Easing } from 'react-native-reanimated';
|
|
5
5
|
import React, { createContext, useContext } from 'react';
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// Default configuration for the sortable grid/list (static fallback values)
|
|
8
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const {
|
|
10
|
-
width
|
|
11
|
-
} = Dimensions.get('window');
|
|
12
|
-
|
|
13
|
-
// Default configuration for the sortable grid/list
|
|
14
9
|
const defaultConfig = {
|
|
15
10
|
MARGIN: 10,
|
|
16
11
|
// Default margin between items
|
|
17
12
|
COL: 2,
|
|
18
13
|
// Default number of columns
|
|
19
|
-
SIZE:
|
|
14
|
+
SIZE: 100 // Temporary fallback size
|
|
20
15
|
};
|
|
21
16
|
|
|
22
17
|
// Create a Context for the sortable grid/list configuration
|
|
@@ -32,11 +27,9 @@ export const animationConfig = {
|
|
|
32
27
|
};
|
|
33
28
|
|
|
34
29
|
// Helper function to calculate the item's position based on its index
|
|
35
|
-
// Used to position items in a grid layout
|
|
36
30
|
export const getPosition = (position, COL, SIZE) => {
|
|
37
31
|
'worklet';
|
|
38
32
|
|
|
39
|
-
// Necessary for Reanimated 2 to run this function on the UI thread
|
|
40
33
|
return {
|
|
41
34
|
x: position % COL === 0 ? 0 : SIZE * (position % COL),
|
|
42
35
|
y: Math.floor(position / COL) * SIZE
|
|
@@ -47,7 +40,6 @@ export const getPosition = (position, COL, SIZE) => {
|
|
|
47
40
|
export const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
48
41
|
'worklet';
|
|
49
42
|
|
|
50
|
-
// Necessary for Reanimated 2 to run this function on the UI thread
|
|
51
43
|
const x = Math.round(tx / SIZE) * SIZE;
|
|
52
44
|
const y = Math.round(ty / SIZE) * SIZE;
|
|
53
45
|
const row = Math.max(y, 0) / SIZE;
|
|
@@ -58,31 +50,22 @@ export const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
|
58
50
|
/**
|
|
59
51
|
* SortableConfigProvider component
|
|
60
52
|
*
|
|
61
|
-
* Wrap your sortable grid/list components with this provider to set custom configuration.
|
|
62
|
-
* This provider allows for overriding default settings like margin and the number of columns.
|
|
63
|
-
*
|
|
64
53
|
* @param {Object} config - Custom configuration to override the default settings.
|
|
65
54
|
* @param {number} config.MARGIN - Margin between items.
|
|
66
55
|
* @param {number} config.COL - Number of columns in the grid.
|
|
67
56
|
* @param {React.ReactNode} children - Child components that will use this configuration.
|
|
68
|
-
*
|
|
69
|
-
* Usage:
|
|
70
|
-
*
|
|
71
|
-
* <SortableConfigProvider config={{ MARGIN: 15, COL: 3 }}>
|
|
72
|
-
* <YourSortableComponent />
|
|
73
|
-
* </SortableConfigProvider>
|
|
74
57
|
*/
|
|
75
58
|
const SortableConfigProvider = ({
|
|
76
59
|
children,
|
|
77
|
-
config
|
|
60
|
+
config = {}
|
|
78
61
|
}) => {
|
|
79
|
-
|
|
62
|
+
const {
|
|
63
|
+
width
|
|
64
|
+
} = useWindowDimensions();
|
|
80
65
|
const mergedConfig = {
|
|
81
66
|
...defaultConfig,
|
|
82
67
|
...config
|
|
83
68
|
};
|
|
84
|
-
|
|
85
|
-
// Recalculate SIZE based on COL and MARGIN
|
|
86
69
|
mergedConfig.SIZE = width / mergedConfig.COL - mergedConfig.MARGIN;
|
|
87
70
|
return /*#__PURE__*/_jsx(ConfigContext.Provider, {
|
|
88
71
|
value: mergedConfig,
|
package/lib/module/Config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["useWindowDimensions","Easing","React","createContext","useContext","jsx","_jsx","defaultConfig","MARGIN","COL","SIZE","ConfigContext","useSortableConfig","animationConfig","easing","inOut","ease","duration","getPosition","position","x","y","Math","floor","getOrder","tx","ty","max","round","row","col","min","SortableConfigProvider","children","config","width","mergedConfig","Provider","value"],"sourceRoot":"../../src","sources":["Config.js"],"mappings":";;AAAA,SAASA,mBAAmB,QAAQ,cAAc;AAClD,SAASC,MAAM,QAAQ,yBAAyB;AAChD,OAAOC,KAAK,IAAIC,aAAa,EAAEC,UAAU,QAAQ,OAAO;;AAExD;AAAA,SAAAC,GAAA,IAAAC,IAAA;AACA,MAAMC,aAAa,GAAG;EACpBC,MAAM,EAAE,EAAE;EAAE;EACZC,GAAG,EAAE,CAAC;EAAE;EACRC,IAAI,EAAE,GAAG,CAAE;AACb,CAAC;;AAED;AACA,MAAMC,aAAa,gBAAGR,aAAa,CAACI,aAAa,CAAC;;AAElD;AACA,OAAO,MAAMK,iBAAiB,GAAGA,CAAA,KAAMR,UAAU,CAACO,aAAa,CAAC;;AAEhE;AACA,OAAO,MAAME,eAAe,GAAG;EAC7BC,MAAM,EAAEb,MAAM,CAACc,KAAK,CAACd,MAAM,CAACe,IAAI,CAAC;EACjCC,QAAQ,EAAE;AACZ,CAAC;;AAED;AACA,OAAO,MAAMC,WAAW,GAAGA,CAACC,QAAQ,EAAEV,GAAG,EAAEC,IAAI,KAAK;EAClD,SAAS;;EACT,OAAO;IACLU,CAAC,EAAED,QAAQ,GAAGV,GAAG,KAAK,CAAC,GAAG,CAAC,GAAGC,IAAI,IAAIS,QAAQ,GAAGV,GAAG,CAAC;IACrDY,CAAC,EAAEC,IAAI,CAACC,KAAK,CAACJ,QAAQ,GAAGV,GAAG,CAAC,GAAGC;EAClC,CAAC;AACH,CAAC;;AAED;AACA,OAAO,MAAMc,QAAQ,GAAGA,CAACC,EAAE,EAAEC,EAAE,EAAEC,GAAG,EAAElB,GAAG,EAAEC,IAAI,KAAK;EAClD,SAAS;;EACT,MAAMU,CAAC,GAAGE,IAAI,CAACM,KAAK,CAACH,EAAE,GAAGf,IAAI,CAAC,GAAGA,IAAI;EACtC,MAAMW,CAAC,GAAGC,IAAI,CAACM,KAAK,CAACF,EAAE,GAAGhB,IAAI,CAAC,GAAGA,IAAI;EACtC,MAAMmB,GAAG,GAAGP,IAAI,CAACK,GAAG,CAACN,CAAC,EAAE,CAAC,CAAC,GAAGX,IAAI;EACjC,MAAMoB,GAAG,GAAGR,IAAI,CAACK,GAAG,CAACP,CAAC,EAAE,CAAC,CAAC,GAAGV,IAAI;EACjC,OAAOY,IAAI,CAACS,GAAG,CAACF,GAAG,GAAGpB,GAAG,GAAGqB,GAAG,EAAEH,GAAG,CAAC;AACvC,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMK,sBAAsB,GAAGA,CAAC;EAAEC,QAAQ;EAAEC,MAAM,GAAG,CAAC;AAAE,CAAC,KAAK;EAC5D,MAAM;IAAEC;EAAM,CAAC,GAAGnC,mBAAmB,CAAC,CAAC;EAEvC,MAAMoC,YAAY,GAAG;IACnB,GAAG7B,aAAa;IAChB,GAAG2B;EACL,CAAC;EAEDE,YAAY,CAAC1B,IAAI,GAAGyB,KAAK,GAAGC,YAAY,CAAC3B,GAAG,GAAG2B,YAAY,CAAC5B,MAAM;EAElE,oBACEF,IAAA,CAACK,aAAa,CAAC0B,QAAQ;IAACC,KAAK,EAAEF,YAAa;IAAAH,QAAA,EACzCA;EAAQ,CACa,CAAC;AAE7B,CAAC;AAED,eAAeD,sBAAsB","ignoreList":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React, { useEffect } from 'react';
|
|
4
|
-
import {
|
|
5
|
-
import Animated, {
|
|
6
|
-
import {
|
|
4
|
+
import { StyleSheet, useWindowDimensions } from 'react-native';
|
|
5
|
+
import Animated, { useAnimatedStyle, useAnimatedReaction, withSpring, scrollTo, withTiming, useSharedValue, runOnJS } from 'react-native-reanimated';
|
|
6
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
7
7
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
8
8
|
import { animationConfig, getOrder, getPosition } from "./Config.js";
|
|
9
9
|
import { useSortableConfig } from "./Config.js";
|
|
@@ -54,7 +54,10 @@ const SortableItemWrapper = ({
|
|
|
54
54
|
}) => {
|
|
55
55
|
// Get safe area insets for accurate height calculation
|
|
56
56
|
const inset = useSafeAreaInsets();
|
|
57
|
-
const
|
|
57
|
+
const {
|
|
58
|
+
height
|
|
59
|
+
} = useWindowDimensions();
|
|
60
|
+
const containerHeight = height - inset.top - inset.bottom;
|
|
58
61
|
|
|
59
62
|
// Get the configuration for columns and size
|
|
60
63
|
const {
|
|
@@ -71,6 +74,8 @@ const SortableItemWrapper = ({
|
|
|
71
74
|
const position = getPosition(positions.value[id], COL, SIZE);
|
|
72
75
|
const translateX = useSharedValue(position.x);
|
|
73
76
|
const translateY = useSharedValue(position.y);
|
|
77
|
+
const startX = useSharedValue(0);
|
|
78
|
+
const startY = useSharedValue(0);
|
|
74
79
|
|
|
75
80
|
// Effect to reset isGestureActive when not in editing mode
|
|
76
81
|
useEffect(() => {
|
|
@@ -89,80 +94,71 @@ const SortableItemWrapper = ({
|
|
|
89
94
|
translateY.value = withTiming(pos.y, animationConfig);
|
|
90
95
|
}
|
|
91
96
|
});
|
|
97
|
+
const pan = Gesture.Pan().onStart(() => {
|
|
98
|
+
if (editing && draggable) {
|
|
99
|
+
// Store the starting position
|
|
100
|
+
startX.value = translateX.value;
|
|
101
|
+
startY.value = translateY.value;
|
|
102
|
+
isGestureActive.value = false;
|
|
103
|
+
}
|
|
104
|
+
}).onUpdate(e => {
|
|
105
|
+
if (editing && draggable) {
|
|
106
|
+
// Calculate new position
|
|
107
|
+
translateX.value = startX.value + e.translationX;
|
|
108
|
+
translateY.value = startY.value + e.translationY;
|
|
92
109
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
ctx.y = translateY.value;
|
|
100
|
-
isGestureActive.value = false;
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
onActive: ({
|
|
104
|
-
translationX,
|
|
105
|
-
translationY
|
|
106
|
-
}, ctx) => {
|
|
107
|
-
if (editing && draggable) {
|
|
108
|
-
// Calculate new position
|
|
109
|
-
translateX.value = ctx.x + translationX;
|
|
110
|
-
translateY.value = ctx.y + translationY;
|
|
111
|
-
|
|
112
|
-
// Calculate new order based on position
|
|
113
|
-
const newOrder = getOrder(translateX.value, translateY.value, Object.keys(positions.value).length - 1, COL, SIZE);
|
|
114
|
-
const oldOrder = positions.value[id];
|
|
115
|
-
if (newOrder !== oldOrder) {
|
|
116
|
-
// Find the item to swap positions with
|
|
117
|
-
const idToSwap = Object.keys(positions.value).find(key => positions.value[key] === newOrder);
|
|
110
|
+
// Calculate new order based on position
|
|
111
|
+
const newOrder = getOrder(translateX.value, translateY.value, Object.keys(positions.value).length - 1, COL, SIZE);
|
|
112
|
+
const oldOrder = positions.value[id];
|
|
113
|
+
if (newOrder !== oldOrder) {
|
|
114
|
+
// Find the item to swap positions with
|
|
115
|
+
const idToSwap = Object.keys(positions.value).find(key => positions.value[key] === newOrder);
|
|
118
116
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
117
|
+
// Only swap if the target item is reorderable
|
|
118
|
+
const targetItem = data.find(tile => tile.id === Number(idToSwap));
|
|
119
|
+
if (idToSwap && targetItem?.reorderable !== false) {
|
|
120
|
+
const newPositions = {
|
|
121
|
+
...positions.value
|
|
122
|
+
};
|
|
123
|
+
newPositions[id] = newOrder;
|
|
124
|
+
newPositions[idToSwap] = oldOrder;
|
|
125
|
+
positions.value = newPositions;
|
|
129
126
|
}
|
|
127
|
+
}
|
|
130
128
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
129
|
+
// Handle scrolling during drag
|
|
130
|
+
const lowerBound = scrollY.value;
|
|
131
|
+
const upperBound = lowerBound + containerHeight - SIZE;
|
|
132
|
+
const maxScroll = contentHeight - containerHeight;
|
|
133
|
+
const leftToScrollDown = maxScroll - scrollY.value;
|
|
136
134
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
// Scroll down
|
|
146
|
-
if (translateY.value > upperBound) {
|
|
147
|
-
const diff = Math.min(translateY.value - upperBound, leftToScrollDown);
|
|
148
|
-
scrollY.value += diff;
|
|
149
|
-
scrollTo(scrollView, 0, scrollY.value, false);
|
|
150
|
-
ctx.y += diff;
|
|
151
|
-
translateY.value = ctx.y + translationY;
|
|
152
|
-
}
|
|
135
|
+
// Scroll up
|
|
136
|
+
if (translateY.value < lowerBound) {
|
|
137
|
+
const diff = Math.min(lowerBound - translateY.value, lowerBound);
|
|
138
|
+
scrollY.value -= diff;
|
|
139
|
+
scrollTo(scrollView, 0, scrollY.value, false);
|
|
140
|
+
startY.value -= diff;
|
|
141
|
+
translateY.value = startY.value + e.translationY;
|
|
153
142
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
runOnJS(onDragEnd)(positions.value); // Call onDragEnd on the JS thread
|
|
162
|
-
});
|
|
163
|
-
translateY.value = withTiming(newPosition.y, animationConfig);
|
|
143
|
+
// Scroll down
|
|
144
|
+
if (translateY.value > upperBound) {
|
|
145
|
+
const diff = Math.min(translateY.value - upperBound, leftToScrollDown);
|
|
146
|
+
scrollY.value += diff;
|
|
147
|
+
scrollTo(scrollView, 0, scrollY.value, false);
|
|
148
|
+
startY.value += diff;
|
|
149
|
+
translateY.value = startY.value + e.translationY;
|
|
164
150
|
}
|
|
165
151
|
}
|
|
152
|
+
}).onEnd(() => {
|
|
153
|
+
if (draggable) {
|
|
154
|
+
// Snap the item back into its place when the drag ends
|
|
155
|
+
const newPosition = getPosition(positions.value[id], COL, SIZE);
|
|
156
|
+
translateX.value = withTiming(newPosition.x, animationConfig, () => {
|
|
157
|
+
isGestureActive.value = false; // Set gesture to inactive
|
|
158
|
+
runOnJS(onDragEnd)(positions.value); // Call onDragEnd on the JS thread
|
|
159
|
+
});
|
|
160
|
+
translateY.value = withTiming(newPosition.y, animationConfig);
|
|
161
|
+
}
|
|
166
162
|
});
|
|
167
163
|
|
|
168
164
|
// Animated style for the item
|
|
@@ -188,9 +184,8 @@ const SortableItemWrapper = ({
|
|
|
188
184
|
});
|
|
189
185
|
return /*#__PURE__*/_jsx(Animated.View, {
|
|
190
186
|
style: style,
|
|
191
|
-
children: /*#__PURE__*/_jsx(
|
|
192
|
-
|
|
193
|
-
onGestureEvent: onGestureEvent,
|
|
187
|
+
children: /*#__PURE__*/_jsx(GestureDetector, {
|
|
188
|
+
gesture: pan,
|
|
194
189
|
children: /*#__PURE__*/_jsx(Animated.View, {
|
|
195
190
|
style: StyleSheet.absoluteFill,
|
|
196
191
|
children: children
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","useEffect","
|
|
1
|
+
{"version":3,"names":["React","useEffect","StyleSheet","useWindowDimensions","Animated","useAnimatedStyle","useAnimatedReaction","withSpring","scrollTo","withTiming","useSharedValue","runOnJS","Gesture","GestureDetector","useSafeAreaInsets","animationConfig","getOrder","getPosition","useSortableConfig","jsx","_jsx","SortableItemWrapper","children","positions","id","onDragEnd","scrollView","scrollY","editing","draggable","data","inset","height","containerHeight","top","bottom","COL","SIZE","MARGIN","contentHeight","Object","keys","value","length","isGestureActive","position","translateX","x","translateY","y","startX","startY","newOrder","pos","pan","Pan","onStart","onUpdate","e","translationX","translationY","oldOrder","idToSwap","find","key","targetItem","tile","Number","reorderable","newPositions","lowerBound","upperBound","maxScroll","leftToScrollDown","diff","Math","min","onEnd","newPosition","style","zIndex","scale","left","width","margin","transform","View","gesture","absoluteFill"],"sourceRoot":"../../src","sources":["SortableItemWrapper.js"],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-sortable-dynamic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "This package provides a highly customizable, animated, and performant sortable grid list component for React Native. It allows users to easily reorder grid items through drag-and-drop gestures, with smooth animations powered by react-native-reanimated and gesture handling by react-native-gesture-handler.",
|
|
5
5
|
"source": "./src/index.js",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
package/src/Config.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useWindowDimensions } from 'react-native';
|
|
2
2
|
import { Easing } from 'react-native-reanimated';
|
|
3
3
|
import React, { createContext, useContext } from 'react';
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
const { width } = Dimensions.get('window');
|
|
7
|
-
|
|
8
|
-
// Default configuration for the sortable grid/list
|
|
5
|
+
// Default configuration for the sortable grid/list (static fallback values)
|
|
9
6
|
const defaultConfig = {
|
|
10
7
|
MARGIN: 10, // Default margin between items
|
|
11
8
|
COL: 2, // Default number of columns
|
|
12
|
-
SIZE:
|
|
9
|
+
SIZE: 100, // Temporary fallback size
|
|
13
10
|
};
|
|
14
11
|
|
|
15
12
|
// Create a Context for the sortable grid/list configuration
|
|
@@ -25,9 +22,8 @@ export const animationConfig = {
|
|
|
25
22
|
};
|
|
26
23
|
|
|
27
24
|
// Helper function to calculate the item's position based on its index
|
|
28
|
-
// Used to position items in a grid layout
|
|
29
25
|
export const getPosition = (position, COL, SIZE) => {
|
|
30
|
-
'worklet';
|
|
26
|
+
'worklet';
|
|
31
27
|
return {
|
|
32
28
|
x: position % COL === 0 ? 0 : SIZE * (position % COL),
|
|
33
29
|
y: Math.floor(position / COL) * SIZE,
|
|
@@ -36,7 +32,7 @@ export const getPosition = (position, COL, SIZE) => {
|
|
|
36
32
|
|
|
37
33
|
// Helper function to determine the new order of items during drag-and-drop
|
|
38
34
|
export const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
39
|
-
'worklet';
|
|
35
|
+
'worklet';
|
|
40
36
|
const x = Math.round(tx / SIZE) * SIZE;
|
|
41
37
|
const y = Math.round(ty / SIZE) * SIZE;
|
|
42
38
|
const row = Math.max(y, 0) / SIZE;
|
|
@@ -47,28 +43,19 @@ export const getOrder = (tx, ty, max, COL, SIZE) => {
|
|
|
47
43
|
/**
|
|
48
44
|
* SortableConfigProvider component
|
|
49
45
|
*
|
|
50
|
-
* Wrap your sortable grid/list components with this provider to set custom configuration.
|
|
51
|
-
* This provider allows for overriding default settings like margin and the number of columns.
|
|
52
|
-
*
|
|
53
46
|
* @param {Object} config - Custom configuration to override the default settings.
|
|
54
47
|
* @param {number} config.MARGIN - Margin between items.
|
|
55
48
|
* @param {number} config.COL - Number of columns in the grid.
|
|
56
49
|
* @param {React.ReactNode} children - Child components that will use this configuration.
|
|
57
|
-
*
|
|
58
|
-
* Usage:
|
|
59
|
-
*
|
|
60
|
-
* <SortableConfigProvider config={{ MARGIN: 15, COL: 3 }}>
|
|
61
|
-
* <YourSortableComponent />
|
|
62
|
-
* </SortableConfigProvider>
|
|
63
50
|
*/
|
|
64
|
-
const SortableConfigProvider = ({ children, config }) => {
|
|
65
|
-
|
|
51
|
+
const SortableConfigProvider = ({ children, config = {} }) => {
|
|
52
|
+
const { width } = useWindowDimensions();
|
|
53
|
+
|
|
66
54
|
const mergedConfig = {
|
|
67
55
|
...defaultConfig,
|
|
68
56
|
...config,
|
|
69
57
|
};
|
|
70
58
|
|
|
71
|
-
// Recalculate SIZE based on COL and MARGIN
|
|
72
59
|
mergedConfig.SIZE = width / mergedConfig.COL - mergedConfig.MARGIN;
|
|
73
60
|
|
|
74
61
|
return (
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { StyleSheet, useWindowDimensions } from 'react-native';
|
|
3
3
|
import Animated, {
|
|
4
|
-
useAnimatedGestureHandler,
|
|
5
4
|
useAnimatedStyle,
|
|
6
5
|
useAnimatedReaction,
|
|
7
6
|
withSpring,
|
|
@@ -10,7 +9,7 @@ import Animated, {
|
|
|
10
9
|
useSharedValue,
|
|
11
10
|
runOnJS,
|
|
12
11
|
} from 'react-native-reanimated';
|
|
13
|
-
import {
|
|
12
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
14
13
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
15
14
|
import { animationConfig, getOrder, getPosition } from './Config';
|
|
16
15
|
import { useSortableConfig } from './Config';
|
|
@@ -60,8 +59,8 @@ const SortableItemWrapper = ({
|
|
|
60
59
|
}) => {
|
|
61
60
|
// Get safe area insets for accurate height calculation
|
|
62
61
|
const inset = useSafeAreaInsets();
|
|
63
|
-
const
|
|
64
|
-
|
|
62
|
+
const { height } = useWindowDimensions();
|
|
63
|
+
const containerHeight = height - inset.top - inset.bottom;
|
|
65
64
|
|
|
66
65
|
// Get the configuration for columns and size
|
|
67
66
|
const { COL, SIZE, MARGIN } = useSortableConfig();
|
|
@@ -75,6 +74,9 @@ const SortableItemWrapper = ({
|
|
|
75
74
|
const translateX = useSharedValue(position.x);
|
|
76
75
|
const translateY = useSharedValue(position.y);
|
|
77
76
|
|
|
77
|
+
const startX = useSharedValue(0);
|
|
78
|
+
const startY = useSharedValue(0);
|
|
79
|
+
|
|
78
80
|
// Effect to reset isGestureActive when not in editing mode
|
|
79
81
|
useEffect(() => {
|
|
80
82
|
if (!editing) {
|
|
@@ -94,21 +96,20 @@ const SortableItemWrapper = ({
|
|
|
94
96
|
}
|
|
95
97
|
);
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
onStart: (_, ctx) => {
|
|
99
|
+
const pan = Gesture.Pan()
|
|
100
|
+
.onStart(() => {
|
|
100
101
|
if (editing && draggable) {
|
|
101
102
|
// Store the starting position
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
startX.value = translateX.value;
|
|
104
|
+
startY.value = translateY.value;
|
|
104
105
|
isGestureActive.value = false;
|
|
105
106
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
107
|
+
})
|
|
108
|
+
.onUpdate((e) => {
|
|
108
109
|
if (editing && draggable) {
|
|
109
110
|
// Calculate new position
|
|
110
|
-
translateX.value =
|
|
111
|
-
translateY.value =
|
|
111
|
+
translateX.value = startX.value + e.translationX;
|
|
112
|
+
translateY.value = startY.value + e.translationY;
|
|
112
113
|
|
|
113
114
|
// Calculate new order based on position
|
|
114
115
|
const newOrder = getOrder(
|
|
@@ -147,8 +148,8 @@ const SortableItemWrapper = ({
|
|
|
147
148
|
const diff = Math.min(lowerBound - translateY.value, lowerBound);
|
|
148
149
|
scrollY.value -= diff;
|
|
149
150
|
scrollTo(scrollView, 0, scrollY.value, false);
|
|
150
|
-
|
|
151
|
-
translateY.value =
|
|
151
|
+
startY.value -= diff;
|
|
152
|
+
translateY.value = startY.value + e.translationY;
|
|
152
153
|
}
|
|
153
154
|
// Scroll down
|
|
154
155
|
if (translateY.value > upperBound) {
|
|
@@ -158,12 +159,12 @@ const SortableItemWrapper = ({
|
|
|
158
159
|
);
|
|
159
160
|
scrollY.value += diff;
|
|
160
161
|
scrollTo(scrollView, 0, scrollY.value, false);
|
|
161
|
-
|
|
162
|
-
translateY.value =
|
|
162
|
+
startY.value += diff;
|
|
163
|
+
translateY.value = startY.value + e.translationY;
|
|
163
164
|
}
|
|
164
165
|
}
|
|
165
|
-
}
|
|
166
|
-
onEnd
|
|
166
|
+
})
|
|
167
|
+
.onEnd(() => {
|
|
167
168
|
if (draggable) {
|
|
168
169
|
// Snap the item back into its place when the drag ends
|
|
169
170
|
const newPosition = getPosition(positions.value[id], COL, SIZE);
|
|
@@ -173,8 +174,7 @@ const SortableItemWrapper = ({
|
|
|
173
174
|
});
|
|
174
175
|
translateY.value = withTiming(newPosition.y, animationConfig);
|
|
175
176
|
}
|
|
176
|
-
}
|
|
177
|
-
});
|
|
177
|
+
});
|
|
178
178
|
|
|
179
179
|
// Animated style for the item
|
|
180
180
|
const style = useAnimatedStyle(() => {
|
|
@@ -199,11 +199,11 @@ const SortableItemWrapper = ({
|
|
|
199
199
|
|
|
200
200
|
return (
|
|
201
201
|
<Animated.View style={style}>
|
|
202
|
-
<
|
|
202
|
+
<GestureDetector gesture={pan}>
|
|
203
203
|
<Animated.View style={StyleSheet.absoluteFill}>
|
|
204
204
|
{children}
|
|
205
205
|
</Animated.View>
|
|
206
|
-
</
|
|
206
|
+
</GestureDetector>
|
|
207
207
|
</Animated.View>
|
|
208
208
|
);
|
|
209
209
|
};
|