react-native-gesture-handler 2.20.2 → 2.21.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/RNGestureHandler.podspec +9 -0
- package/ReanimatedDrawerLayout/package.json +6 -0
- package/android/build.gradle +19 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +6 -2
- package/android/src/main/java/com/swmansion/gesturehandler/core/RotationGestureDetector.kt +53 -21
- package/apple/RNGestureHandlerPointerTracker.m +4 -2
- package/lib/commonjs/RNGestureHandlerModule.web.js +15 -2
- package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +2 -6
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/ReanimatedDrawerLayout.js +389 -0
- package/lib/commonjs/components/ReanimatedDrawerLayout.js.map +1 -0
- package/lib/commonjs/components/ReanimatedSwipeable.js +117 -148
- package/lib/commonjs/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/findNodeHandle.js +12 -0
- package/lib/commonjs/findNodeHandle.js.map +1 -0
- package/lib/commonjs/findNodeHandle.web.js +40 -0
- package/lib/commonjs/findNodeHandle.web.js.map +1 -0
- package/lib/commonjs/handlers/createHandler.js +4 -2
- package/lib/commonjs/handlers/createHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.web.js +51 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/Wrap.web.js.map +1 -0
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js +3 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js +5 -3
- package/lib/commonjs/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js +4 -2
- package/lib/commonjs/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +4 -0
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +59 -0
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js +10 -1
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/EventManager.js +6 -0
- package/lib/commonjs/web/tools/EventManager.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +1 -3
- package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +5 -2
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/KeyboardEventManager.js +2 -2
- package/lib/commonjs/web/tools/KeyboardEventManager.js.map +1 -1
- package/lib/commonjs/web/tools/PointerTracker.js +6 -30
- package/lib/commonjs/web/tools/PointerTracker.js.map +1 -1
- package/lib/commonjs/web/tools/WheelEventManager.js +74 -0
- package/lib/commonjs/web/tools/WheelEventManager.js.map +1 -0
- package/lib/commonjs/web/utils.js +16 -0
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/RNGestureHandlerModule.web.js +16 -3
- package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +2 -6
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/ReanimatedDrawerLayout.js +365 -0
- package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -0
- package/lib/module/components/ReanimatedSwipeable.js +119 -145
- package/lib/module/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/findNodeHandle.js +3 -0
- package/lib/module/findNodeHandle.js.map +1 -0
- package/lib/module/findNodeHandle.web.js +32 -0
- package/lib/module/findNodeHandle.web.js.map +1 -0
- package/lib/module/handlers/createHandler.js +2 -1
- package/lib/module/handlers/createHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/Wrap.web.js +34 -0
- package/lib/module/handlers/gestures/GestureDetector/Wrap.web.js.map +1 -0
- package/lib/module/handlers/gestures/GestureDetector/index.js +2 -1
- package/lib/module/handlers/gestures/GestureDetector/index.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +2 -2
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useViewRefHandler.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +4 -0
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +58 -0
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js +8 -0
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/EventManager.js +6 -0
- package/lib/module/web/tools/EventManager.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerOrchestrator.js +1 -3
- package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js +3 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/KeyboardEventManager.js +2 -2
- package/lib/module/web/tools/KeyboardEventManager.js.map +1 -1
- package/lib/module/web/tools/PointerTracker.js +6 -30
- package/lib/module/web/tools/PointerTracker.js.map +1 -1
- package/lib/module/web/tools/WheelEventManager.js +60 -0
- package/lib/module/web/tools/WheelEventManager.js.map +1 -0
- package/lib/module/web/utils.js +15 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts +162 -0
- package/lib/typescript/components/ReanimatedSwipeable.d.ts +22 -16
- package/lib/typescript/findNodeHandle.d.ts +2 -0
- package/lib/typescript/findNodeHandle.web.d.ts +2 -0
- package/lib/typescript/handlers/gestures/GestureDetector/Wrap.web.d.ts +7 -0
- package/lib/typescript/web/handlers/GestureHandler.d.ts +2 -1
- package/lib/typescript/web/handlers/PanGestureHandler.d.ts +5 -0
- package/lib/typescript/web/interfaces.d.ts +16 -0
- package/lib/typescript/web/tools/EventManager.d.ts +2 -0
- package/lib/typescript/web/tools/PointerTracker.d.ts +2 -8
- package/lib/typescript/web/tools/WheelEventManager.d.ts +11 -0
- package/lib/typescript/web/utils.d.ts +2 -1
- package/package.json +3 -2
- package/src/RNGestureHandlerModule.web.ts +23 -4
- package/src/components/Pressable/Pressable.tsx +2 -6
- package/src/components/ReanimatedDrawerLayout.tsx +741 -0
- package/src/components/ReanimatedSwipeable.tsx +361 -305
- package/src/findNodeHandle.ts +3 -0
- package/src/findNodeHandle.web.ts +35 -0
- package/src/handlers/createHandler.tsx +2 -1
- package/src/handlers/gestures/GestureDetector/Wrap.web.tsx +44 -0
- package/src/handlers/gestures/GestureDetector/index.tsx +2 -1
- package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +1 -1
- package/src/handlers/gestures/GestureDetector/useViewRefHandler.ts +1 -1
- package/src/web/handlers/GestureHandler.ts +5 -1
- package/src/web/handlers/PanGestureHandler.ts +69 -1
- package/src/web/interfaces.ts +17 -0
- package/src/web/tools/EventManager.ts +4 -0
- package/src/web/tools/GestureHandlerOrchestrator.ts +1 -7
- package/src/web/tools/GestureHandlerWebDelegate.ts +3 -1
- package/src/web/tools/KeyboardEventManager.ts +2 -2
- package/src/web/tools/PointerTracker.ts +6 -28
- package/src/web/tools/WheelEventManager.ts +48 -0
- package/src/web/utils.ts +47 -1
|
@@ -7,7 +7,7 @@ import React, {
|
|
|
7
7
|
forwardRef,
|
|
8
8
|
useCallback,
|
|
9
9
|
useImperativeHandle,
|
|
10
|
-
|
|
10
|
+
useMemo,
|
|
11
11
|
} from 'react';
|
|
12
12
|
import { GestureObjects as Gesture } from '../handlers/gestures/gestureObjects';
|
|
13
13
|
import { GestureDetector } from '../handlers/gestures/GestureDetector';
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
import type { PanGestureHandlerProps } from '../handlers/PanGestureHandler';
|
|
19
19
|
import type { PanGestureHandlerEventPayload } from '../handlers/GestureHandlerEventPayload';
|
|
20
20
|
import Animated, {
|
|
21
|
-
Extrapolation,
|
|
22
21
|
SharedValue,
|
|
23
22
|
interpolate,
|
|
24
23
|
runOnJS,
|
|
@@ -42,6 +41,11 @@ type SwipeableExcludes = Exclude<
|
|
|
42
41
|
'onGestureEvent' | 'onHandlerStateChange'
|
|
43
42
|
>;
|
|
44
43
|
|
|
44
|
+
enum SwipeDirection {
|
|
45
|
+
LEFT = 'left',
|
|
46
|
+
RIGHT = 'right',
|
|
47
|
+
}
|
|
48
|
+
|
|
45
49
|
export interface SwipeableProps
|
|
46
50
|
extends Pick<PanGestureHandlerProps, SwipeableExcludes> {
|
|
47
51
|
/**
|
|
@@ -111,65 +115,74 @@ export interface SwipeableProps
|
|
|
111
115
|
* Called when action panel gets open (either right or left).
|
|
112
116
|
*/
|
|
113
117
|
onSwipeableOpen?: (
|
|
114
|
-
direction:
|
|
115
|
-
swipeable: SwipeableMethods
|
|
118
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
116
119
|
) => void;
|
|
117
120
|
|
|
118
121
|
/**
|
|
119
122
|
* Called when action panel is closed.
|
|
120
123
|
*/
|
|
121
124
|
onSwipeableClose?: (
|
|
122
|
-
direction:
|
|
123
|
-
swipeable: SwipeableMethods
|
|
125
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
124
126
|
) => void;
|
|
125
127
|
|
|
126
128
|
/**
|
|
127
129
|
* Called when action panel starts animating on open (either right or left).
|
|
128
130
|
*/
|
|
129
|
-
onSwipeableWillOpen?: (
|
|
131
|
+
onSwipeableWillOpen?: (
|
|
132
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
133
|
+
) => void;
|
|
130
134
|
|
|
131
135
|
/**
|
|
132
136
|
* Called when action panel starts animating on close.
|
|
133
137
|
*/
|
|
134
|
-
onSwipeableWillClose?: (
|
|
138
|
+
onSwipeableWillClose?: (
|
|
139
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
140
|
+
) => void;
|
|
135
141
|
|
|
136
142
|
/**
|
|
137
143
|
* Called when action panel starts being shown on dragging to open.
|
|
138
144
|
*/
|
|
139
|
-
onSwipeableOpenStartDrag?: (
|
|
145
|
+
onSwipeableOpenStartDrag?: (
|
|
146
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
147
|
+
) => void;
|
|
140
148
|
|
|
141
149
|
/**
|
|
142
150
|
* Called when action panel starts being shown on dragging to close.
|
|
143
151
|
*/
|
|
144
|
-
onSwipeableCloseStartDrag?: (
|
|
152
|
+
onSwipeableCloseStartDrag?: (
|
|
153
|
+
direction: SwipeDirection.LEFT | SwipeDirection.RIGHT
|
|
154
|
+
) => void;
|
|
145
155
|
|
|
146
156
|
/**
|
|
157
|
+
* `progress`: Equals `0` when `swipeable` is closed, `1` when `swipeable` is opened.
|
|
158
|
+
* - When the element overshoots it's opened position the value tends towards `Infinity`.
|
|
159
|
+
* - Goes back to `1` when `swipeable` is released.
|
|
147
160
|
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
* progressAnimatedValue: [0, 1] dragAnimatedValue: [0, +]
|
|
161
|
+
* `translation`: a horizontal offset of the `swipeable` relative to its closed position.\
|
|
162
|
+
* `swipeableMethods`: provides an object exposing methods for controlling the `swipeable`.
|
|
152
163
|
*
|
|
153
164
|
* To support `rtl` flexbox layouts use `flexDirection` styling.
|
|
154
165
|
* */
|
|
155
166
|
renderLeftActions?: (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
167
|
+
progress: SharedValue<number>,
|
|
168
|
+
translation: SharedValue<number>,
|
|
169
|
+
swipeableMethods: SwipeableMethods
|
|
159
170
|
) => React.ReactNode;
|
|
171
|
+
|
|
160
172
|
/**
|
|
173
|
+
* `progress`: Equals `0` when `swipeable` is closed, `1` when `swipeable` is opened.
|
|
174
|
+
* - When the element overshoots it's opened position the value tends towards `Infinity`.
|
|
175
|
+
* - Goes back to `1` when `swipeable` is released.
|
|
161
176
|
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* progressAnimatedValue: [0, 1] dragAnimatedValue: [0, -]
|
|
177
|
+
* `translation`: a horizontal offset of the `swipeable` relative to its closed position.\
|
|
178
|
+
* `swipeableMethods`: provides an object exposing methods for controlling the `swipeable`.
|
|
166
179
|
*
|
|
167
180
|
* To support `rtl` flexbox layouts use `flexDirection` styling.
|
|
168
181
|
* */
|
|
169
182
|
renderRightActions?: (
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
183
|
+
progress: SharedValue<number>,
|
|
184
|
+
translation: SharedValue<number>,
|
|
185
|
+
swipeableMethods: SwipeableMethods
|
|
173
186
|
) => React.ReactNode;
|
|
174
187
|
|
|
175
188
|
animationOptions?: Record<string, unknown>;
|
|
@@ -199,86 +212,69 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
199
212
|
props: SwipeableProps,
|
|
200
213
|
ref: ForwardedRef<SwipeableMethods>
|
|
201
214
|
) {
|
|
215
|
+
const defaultProps = {
|
|
216
|
+
friction: 1,
|
|
217
|
+
overshootFriction: 1,
|
|
218
|
+
dragOffset: 10,
|
|
219
|
+
enableTrackpadTwoFingerGesture: false,
|
|
220
|
+
};
|
|
221
|
+
|
|
202
222
|
const {
|
|
203
223
|
leftThreshold,
|
|
204
224
|
rightThreshold,
|
|
205
|
-
onSwipeableOpenStartDrag,
|
|
206
|
-
onSwipeableCloseStartDrag,
|
|
207
|
-
enableTrackpadTwoFingerGesture,
|
|
208
225
|
enabled,
|
|
209
226
|
containerStyle,
|
|
210
227
|
childrenContainerStyle,
|
|
211
228
|
animationOptions,
|
|
212
229
|
overshootLeft,
|
|
213
230
|
overshootRight,
|
|
231
|
+
testID,
|
|
232
|
+
children,
|
|
233
|
+
enableTrackpadTwoFingerGesture = defaultProps.enableTrackpadTwoFingerGesture,
|
|
234
|
+
dragOffsetFromLeftEdge = defaultProps.dragOffset,
|
|
235
|
+
dragOffsetFromRightEdge = defaultProps.dragOffset,
|
|
236
|
+
friction = defaultProps.friction,
|
|
237
|
+
overshootFriction = defaultProps.overshootFriction,
|
|
238
|
+
onSwipeableOpenStartDrag,
|
|
239
|
+
onSwipeableCloseStartDrag,
|
|
214
240
|
onSwipeableWillOpen,
|
|
215
241
|
onSwipeableWillClose,
|
|
216
242
|
onSwipeableOpen,
|
|
217
243
|
onSwipeableClose,
|
|
218
|
-
|
|
244
|
+
renderLeftActions,
|
|
245
|
+
renderRightActions,
|
|
219
246
|
...remainingProps
|
|
220
247
|
} = props;
|
|
221
248
|
|
|
222
249
|
const rowState = useSharedValue<number>(0);
|
|
223
250
|
|
|
224
251
|
const userDrag = useSharedValue<number>(0);
|
|
252
|
+
|
|
225
253
|
const appliedTranslation = useSharedValue<number>(0);
|
|
226
254
|
|
|
227
255
|
const rowWidth = useSharedValue<number>(0);
|
|
228
256
|
const leftWidth = useSharedValue<number>(0);
|
|
229
257
|
const rightWidth = useSharedValue<number>(0);
|
|
230
|
-
const rightOffset = useSharedValue<number>(0);
|
|
231
258
|
|
|
232
|
-
|
|
233
|
-
const
|
|
259
|
+
// used for synchronizing layout measurements between JS and UI
|
|
260
|
+
const rightOffset = useSharedValue<number | null>(null);
|
|
234
261
|
|
|
235
262
|
const showLeftProgress = useSharedValue<number>(0);
|
|
236
263
|
const showRightProgress = useSharedValue<number>(0);
|
|
237
264
|
|
|
238
|
-
const
|
|
239
|
-
close: () => {
|
|
240
|
-
'worklet';
|
|
241
|
-
},
|
|
242
|
-
openLeft: () => {
|
|
243
|
-
'worklet';
|
|
244
|
-
},
|
|
245
|
-
openRight: () => {
|
|
246
|
-
'worklet';
|
|
247
|
-
},
|
|
248
|
-
reset: () => {
|
|
249
|
-
'worklet';
|
|
250
|
-
},
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
const defaultProps = {
|
|
254
|
-
friction: 1,
|
|
255
|
-
overshootFriction: 1,
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
const {
|
|
259
|
-
friction = defaultProps.friction,
|
|
260
|
-
overshootFriction = defaultProps.overshootFriction,
|
|
261
|
-
} = props;
|
|
262
|
-
|
|
263
|
-
const overshootLeftProp = overshootLeft;
|
|
264
|
-
const overshootRightProp = overshootRight;
|
|
265
|
-
|
|
266
|
-
const calculateCurrentOffset = useCallback(() => {
|
|
265
|
+
const updateRightElementWidth = useCallback(() => {
|
|
267
266
|
'worklet';
|
|
268
|
-
if (
|
|
269
|
-
|
|
270
|
-
} else if (rowState.value === -1) {
|
|
271
|
-
return -rowWidth.value - rightOffset.value;
|
|
267
|
+
if (rightOffset.value === null) {
|
|
268
|
+
rightOffset.value = rowWidth.value;
|
|
272
269
|
}
|
|
273
|
-
|
|
274
|
-
}, [
|
|
270
|
+
rightWidth.value = Math.max(0, rowWidth.value - rightOffset.value);
|
|
271
|
+
}, [rightOffset, rightWidth, rowWidth]);
|
|
275
272
|
|
|
276
|
-
const updateAnimatedEvent = () => {
|
|
273
|
+
const updateAnimatedEvent = useCallback(() => {
|
|
277
274
|
'worklet';
|
|
278
|
-
rightWidth.value = Math.max(0, rowWidth.value - rightOffset.value);
|
|
279
275
|
|
|
280
|
-
const
|
|
281
|
-
const
|
|
276
|
+
const shouldOvershootLeft = overshootLeft ?? leftWidth.value > 0;
|
|
277
|
+
const shouldOvershootRight = overshootRight ?? rightWidth.value > 0;
|
|
282
278
|
|
|
283
279
|
const startOffset =
|
|
284
280
|
rowState.value === 1
|
|
@@ -298,10 +294,11 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
298
294
|
leftWidth.value + 1,
|
|
299
295
|
],
|
|
300
296
|
[
|
|
301
|
-
-rightWidth.value -
|
|
297
|
+
-rightWidth.value -
|
|
298
|
+
(shouldOvershootRight ? 1 / overshootFriction : 0),
|
|
302
299
|
-rightWidth.value,
|
|
303
300
|
leftWidth.value,
|
|
304
|
-
leftWidth.value + (
|
|
301
|
+
leftWidth.value + (shouldOvershootLeft ? 1 / overshootFriction : 0),
|
|
305
302
|
]
|
|
306
303
|
);
|
|
307
304
|
|
|
@@ -313,12 +310,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
313
310
|
[0, 0, 1]
|
|
314
311
|
)
|
|
315
312
|
: 0;
|
|
316
|
-
|
|
317
|
-
showLeftProgress.value,
|
|
318
|
-
[0, Number.MIN_VALUE],
|
|
319
|
-
[-10000, 0],
|
|
320
|
-
Extrapolation.CLAMP
|
|
321
|
-
);
|
|
313
|
+
|
|
322
314
|
showRightProgress.value =
|
|
323
315
|
rightWidth.value > 0
|
|
324
316
|
? interpolate(
|
|
@@ -327,23 +319,31 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
327
319
|
[1, 0, 0]
|
|
328
320
|
)
|
|
329
321
|
: 0;
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
322
|
+
}, [
|
|
323
|
+
appliedTranslation,
|
|
324
|
+
friction,
|
|
325
|
+
leftWidth,
|
|
326
|
+
overshootFriction,
|
|
327
|
+
rightWidth,
|
|
328
|
+
rowState,
|
|
329
|
+
showLeftProgress,
|
|
330
|
+
showRightProgress,
|
|
331
|
+
userDrag,
|
|
332
|
+
overshootLeft,
|
|
333
|
+
overshootRight,
|
|
334
|
+
]);
|
|
337
335
|
|
|
338
336
|
const dispatchImmediateEvents = useCallback(
|
|
339
337
|
(fromValue: number, toValue: number) => {
|
|
338
|
+
'worklet';
|
|
340
339
|
if (toValue > 0 && onSwipeableWillOpen) {
|
|
341
|
-
onSwipeableWillOpen(
|
|
340
|
+
runOnJS(onSwipeableWillOpen)(SwipeDirection.RIGHT);
|
|
342
341
|
} else if (toValue < 0 && onSwipeableWillOpen) {
|
|
343
|
-
onSwipeableWillOpen(
|
|
342
|
+
runOnJS(onSwipeableWillOpen)(SwipeDirection.LEFT);
|
|
344
343
|
} else if (onSwipeableWillClose) {
|
|
345
|
-
|
|
346
|
-
|
|
344
|
+
runOnJS(onSwipeableWillClose)(
|
|
345
|
+
fromValue > 0 ? SwipeDirection.LEFT : SwipeDirection.RIGHT
|
|
346
|
+
);
|
|
347
347
|
}
|
|
348
348
|
},
|
|
349
349
|
[onSwipeableWillClose, onSwipeableWillOpen]
|
|
@@ -351,255 +351,311 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
351
351
|
|
|
352
352
|
const dispatchEndEvents = useCallback(
|
|
353
353
|
(fromValue: number, toValue: number) => {
|
|
354
|
+
'worklet';
|
|
354
355
|
if (toValue > 0 && onSwipeableOpen) {
|
|
355
|
-
onSwipeableOpen(
|
|
356
|
+
runOnJS(onSwipeableOpen)(SwipeDirection.RIGHT);
|
|
356
357
|
} else if (toValue < 0 && onSwipeableOpen) {
|
|
357
|
-
onSwipeableOpen(
|
|
358
|
+
runOnJS(onSwipeableOpen)(SwipeDirection.LEFT);
|
|
358
359
|
} else if (onSwipeableClose) {
|
|
359
|
-
|
|
360
|
-
|
|
360
|
+
runOnJS(onSwipeableClose)(
|
|
361
|
+
fromValue > 0 ? SwipeDirection.LEFT : SwipeDirection.RIGHT
|
|
362
|
+
);
|
|
361
363
|
}
|
|
362
364
|
},
|
|
363
365
|
[onSwipeableClose, onSwipeableOpen]
|
|
364
366
|
);
|
|
365
367
|
|
|
366
|
-
const
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
368
|
+
const animateRow: (toValue: number, velocityX?: number) => void =
|
|
369
|
+
useCallback(
|
|
370
|
+
(toValue: number, velocityX?: number) => {
|
|
371
|
+
'worklet';
|
|
372
|
+
|
|
373
|
+
const translationSpringConfig = {
|
|
374
|
+
duration: 1000,
|
|
375
|
+
dampingRatio: 0.9,
|
|
376
|
+
stiffness: 500,
|
|
377
|
+
velocity: velocityX,
|
|
378
|
+
overshootClamping: true,
|
|
379
|
+
...animationOptions,
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const isClosing = toValue === 0;
|
|
383
|
+
const moveToRight = isClosing ? rowState.value < 0 : toValue > 0;
|
|
384
|
+
|
|
385
|
+
const usedWidth = isClosing
|
|
386
|
+
? moveToRight
|
|
387
|
+
? rightWidth.value
|
|
388
|
+
: leftWidth.value
|
|
389
|
+
: moveToRight
|
|
390
|
+
? leftWidth.value
|
|
391
|
+
: rightWidth.value;
|
|
392
|
+
|
|
393
|
+
const progressSpringConfig = {
|
|
394
|
+
...translationSpringConfig,
|
|
395
|
+
restDisplacementThreshold: 0.01,
|
|
396
|
+
restSpeedThreshold: 0.01,
|
|
397
|
+
velocity:
|
|
398
|
+
velocityX &&
|
|
399
|
+
interpolate(velocityX, [-usedWidth, usedWidth], [-1, 1]),
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const frozenRowState = rowState.value;
|
|
403
|
+
|
|
404
|
+
appliedTranslation.value = withSpring(
|
|
405
|
+
toValue,
|
|
406
|
+
translationSpringConfig,
|
|
407
|
+
(isFinished) => {
|
|
408
|
+
if (isFinished) {
|
|
409
|
+
dispatchEndEvents(frozenRowState, toValue);
|
|
410
|
+
}
|
|
393
411
|
}
|
|
394
|
-
|
|
395
|
-
);
|
|
412
|
+
);
|
|
396
413
|
|
|
397
|
-
|
|
414
|
+
const progressTarget = toValue === 0 ? 0 : 1;
|
|
398
415
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
416
|
+
showLeftProgress.value =
|
|
417
|
+
leftWidth.value > 0
|
|
418
|
+
? withSpring(progressTarget, progressSpringConfig)
|
|
419
|
+
: 0;
|
|
420
|
+
showRightProgress.value =
|
|
421
|
+
rightWidth.value > 0
|
|
422
|
+
? withSpring(progressTarget, progressSpringConfig)
|
|
423
|
+
: 0;
|
|
407
424
|
|
|
408
|
-
|
|
409
|
-
},
|
|
410
|
-
[
|
|
411
|
-
rowState,
|
|
412
|
-
animationOptionsProp,
|
|
413
|
-
appliedTranslation,
|
|
414
|
-
showLeftProgress,
|
|
415
|
-
leftWidth.value,
|
|
416
|
-
showRightProgress,
|
|
417
|
-
rightWidth.value,
|
|
418
|
-
dispatchImmediateEvents,
|
|
419
|
-
dispatchEndEvents,
|
|
420
|
-
]
|
|
421
|
-
);
|
|
425
|
+
dispatchImmediateEvents(frozenRowState, toValue);
|
|
422
426
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
'worklet';
|
|
438
|
-
animateRow(calculateCurrentOffset(), 0);
|
|
439
|
-
},
|
|
440
|
-
openLeft() {
|
|
441
|
-
'worklet';
|
|
442
|
-
animateRow(calculateCurrentOffset(), leftWidth.value);
|
|
443
|
-
},
|
|
444
|
-
openRight() {
|
|
445
|
-
'worklet';
|
|
446
|
-
rightWidth.value = rowWidth.value - rightOffset.value;
|
|
447
|
-
animateRow(calculateCurrentOffset(), -rightWidth.value);
|
|
448
|
-
},
|
|
449
|
-
reset() {
|
|
450
|
-
'worklet';
|
|
451
|
-
userDrag.value = 0;
|
|
452
|
-
showLeftProgress.value = 0;
|
|
453
|
-
appliedTranslation.value = 0;
|
|
454
|
-
rowState.value = 0;
|
|
455
|
-
},
|
|
456
|
-
};
|
|
427
|
+
rowState.value = Math.sign(toValue);
|
|
428
|
+
},
|
|
429
|
+
[
|
|
430
|
+
rowState,
|
|
431
|
+
animationOptions,
|
|
432
|
+
appliedTranslation,
|
|
433
|
+
showLeftProgress,
|
|
434
|
+
leftWidth,
|
|
435
|
+
showRightProgress,
|
|
436
|
+
rightWidth,
|
|
437
|
+
dispatchImmediateEvents,
|
|
438
|
+
dispatchEndEvents,
|
|
439
|
+
]
|
|
440
|
+
);
|
|
457
441
|
|
|
458
|
-
const
|
|
442
|
+
const swipeableMethods = useMemo<SwipeableMethods>(
|
|
459
443
|
() => ({
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
444
|
+
close() {
|
|
445
|
+
'worklet';
|
|
446
|
+
animateRow(0);
|
|
447
|
+
},
|
|
448
|
+
openLeft() {
|
|
449
|
+
'worklet';
|
|
450
|
+
animateRow(leftWidth.value);
|
|
451
|
+
},
|
|
452
|
+
openRight() {
|
|
453
|
+
'worklet';
|
|
454
|
+
// rightOffset and rowWidth are already much sooner than rightWidth
|
|
455
|
+
animateRow((rightOffset.value ?? 0) - rowWidth.value);
|
|
456
|
+
},
|
|
457
|
+
reset() {
|
|
458
|
+
'worklet';
|
|
459
|
+
userDrag.value = 0;
|
|
460
|
+
showLeftProgress.value = 0;
|
|
461
|
+
appliedTranslation.value = 0;
|
|
462
|
+
rowState.value = 0;
|
|
463
|
+
},
|
|
465
464
|
}),
|
|
466
|
-
[
|
|
465
|
+
[
|
|
466
|
+
leftWidth,
|
|
467
|
+
rightOffset,
|
|
468
|
+
rowWidth,
|
|
469
|
+
userDrag,
|
|
470
|
+
showLeftProgress,
|
|
471
|
+
appliedTranslation,
|
|
472
|
+
rowState,
|
|
473
|
+
animateRow,
|
|
474
|
+
]
|
|
467
475
|
);
|
|
468
476
|
|
|
469
|
-
const
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
swipeableMethods.current
|
|
475
|
-
)}
|
|
476
|
-
<View
|
|
477
|
-
onLayout={({ nativeEvent }) =>
|
|
478
|
-
(leftWidth.value = nativeEvent.layout.x)
|
|
479
|
-
}
|
|
480
|
-
/>
|
|
481
|
-
</Animated.View>
|
|
477
|
+
const onRowLayout = useCallback(
|
|
478
|
+
({ nativeEvent }: LayoutChangeEvent) => {
|
|
479
|
+
rowWidth.value = nativeEvent.layout.width;
|
|
480
|
+
},
|
|
481
|
+
[rowWidth]
|
|
482
482
|
);
|
|
483
483
|
|
|
484
|
-
const
|
|
485
|
-
() => (
|
|
486
|
-
|
|
487
|
-
{
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
484
|
+
const leftElement = useCallback(
|
|
485
|
+
() => (
|
|
486
|
+
<Animated.View style={[styles.leftActions]}>
|
|
487
|
+
{renderLeftActions?.(
|
|
488
|
+
showLeftProgress,
|
|
489
|
+
appliedTranslation,
|
|
490
|
+
swipeableMethods
|
|
491
|
+
)}
|
|
492
|
+
<View
|
|
493
|
+
onLayout={({ nativeEvent }) =>
|
|
494
|
+
(leftWidth.value = nativeEvent.layout.x)
|
|
495
|
+
}
|
|
496
|
+
/>
|
|
497
|
+
</Animated.View>
|
|
498
|
+
),
|
|
499
|
+
[
|
|
500
|
+
appliedTranslation,
|
|
501
|
+
leftWidth,
|
|
502
|
+
renderLeftActions,
|
|
503
|
+
showLeftProgress,
|
|
504
|
+
swipeableMethods,
|
|
505
|
+
]
|
|
493
506
|
);
|
|
494
507
|
|
|
495
|
-
const rightElement =
|
|
496
|
-
|
|
497
|
-
{
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
+
const rightElement = useCallback(
|
|
509
|
+
() => (
|
|
510
|
+
<Animated.View style={[styles.rightActions]}>
|
|
511
|
+
{renderRightActions?.(
|
|
512
|
+
showRightProgress,
|
|
513
|
+
appliedTranslation,
|
|
514
|
+
swipeableMethods
|
|
515
|
+
)}
|
|
516
|
+
<View
|
|
517
|
+
onLayout={({ nativeEvent }) => {
|
|
518
|
+
rightOffset.value = nativeEvent.layout.x;
|
|
519
|
+
}}
|
|
520
|
+
/>
|
|
521
|
+
</Animated.View>
|
|
522
|
+
),
|
|
523
|
+
[
|
|
524
|
+
appliedTranslation,
|
|
525
|
+
renderRightActions,
|
|
526
|
+
rightOffset,
|
|
527
|
+
showRightProgress,
|
|
528
|
+
swipeableMethods,
|
|
529
|
+
]
|
|
508
530
|
);
|
|
509
531
|
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
) => {
|
|
516
|
-
'worklet';
|
|
517
|
-
const { velocityX } = event;
|
|
518
|
-
userDrag.value = event.translationX;
|
|
532
|
+
const handleRelease = useCallback(
|
|
533
|
+
(event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
534
|
+
'worklet';
|
|
535
|
+
const { velocityX } = event;
|
|
536
|
+
userDrag.value = event.translationX;
|
|
519
537
|
|
|
520
|
-
|
|
538
|
+
updateRightElementWidth();
|
|
521
539
|
|
|
522
|
-
|
|
523
|
-
|
|
540
|
+
const leftThresholdProp = leftThreshold ?? leftWidth.value / 2;
|
|
541
|
+
const rightThresholdProp = rightThreshold ?? rightWidth.value / 2;
|
|
524
542
|
|
|
525
|
-
|
|
526
|
-
|
|
543
|
+
const translationX =
|
|
544
|
+
(userDrag.value + DRAG_TOSS * velocityX) / friction;
|
|
527
545
|
|
|
528
|
-
|
|
546
|
+
let toValue = 0;
|
|
529
547
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
548
|
+
if (rowState.value === 0) {
|
|
549
|
+
if (translationX > leftThresholdProp) {
|
|
550
|
+
toValue = leftWidth.value;
|
|
551
|
+
} else if (translationX < -rightThresholdProp) {
|
|
552
|
+
toValue = -rightWidth.value;
|
|
553
|
+
}
|
|
554
|
+
} else if (rowState.value === 1) {
|
|
555
|
+
// Swiped to left
|
|
556
|
+
if (translationX > -leftThresholdProp) {
|
|
557
|
+
toValue = leftWidth.value;
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
// Swiped to right
|
|
561
|
+
if (translationX < rightThresholdProp) {
|
|
562
|
+
toValue = -rightWidth.value;
|
|
563
|
+
}
|
|
545
564
|
}
|
|
546
|
-
}
|
|
547
565
|
|
|
548
|
-
|
|
549
|
-
|
|
566
|
+
animateRow(toValue, velocityX / friction);
|
|
567
|
+
},
|
|
568
|
+
[
|
|
569
|
+
animateRow,
|
|
570
|
+
friction,
|
|
571
|
+
leftThreshold,
|
|
572
|
+
leftWidth,
|
|
573
|
+
rightThreshold,
|
|
574
|
+
rightWidth,
|
|
575
|
+
rowState,
|
|
576
|
+
userDrag,
|
|
577
|
+
updateRightElementWidth,
|
|
578
|
+
]
|
|
579
|
+
);
|
|
550
580
|
|
|
551
|
-
const close = () => {
|
|
581
|
+
const close = useCallback(() => {
|
|
552
582
|
'worklet';
|
|
553
|
-
animateRow(
|
|
554
|
-
};
|
|
555
|
-
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
: rowState.value === 1
|
|
570
|
-
? 'left'
|
|
571
|
-
: event.translationX > 0
|
|
572
|
-
? 'left'
|
|
573
|
-
: 'right';
|
|
574
|
-
|
|
575
|
-
if (rowState.value === 0 && onSwipeableOpenStartDrag) {
|
|
576
|
-
runOnJS(onSwipeableOpenStartDrag)(direction);
|
|
577
|
-
} else if (rowState.value !== 0 && onSwipeableCloseStartDrag) {
|
|
578
|
-
runOnJS(onSwipeableCloseStartDrag)(direction);
|
|
579
|
-
}
|
|
580
|
-
updateAnimatedEvent();
|
|
581
|
-
})
|
|
582
|
-
.onEnd(
|
|
583
|
-
(event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
584
|
-
handleRelease(event);
|
|
585
|
-
}
|
|
586
|
-
);
|
|
587
|
-
|
|
588
|
-
if (enableTrackpadTwoFingerGesture) {
|
|
589
|
-
panGesture.enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture);
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
panGesture.activeOffsetX([
|
|
593
|
-
-dragOffsetFromRightEdge,
|
|
594
|
-
dragOffsetFromLeftEdge,
|
|
595
|
-
]);
|
|
596
|
-
tapGesture.shouldCancelWhenOutside(true);
|
|
583
|
+
animateRow(0);
|
|
584
|
+
}, [animateRow]);
|
|
585
|
+
|
|
586
|
+
const dragStarted = useSharedValue<boolean>(false);
|
|
587
|
+
|
|
588
|
+
const tapGesture = useMemo(
|
|
589
|
+
() =>
|
|
590
|
+
Gesture.Tap()
|
|
591
|
+
.shouldCancelWhenOutside(true)
|
|
592
|
+
.onStart(() => {
|
|
593
|
+
if (rowState.value !== 0) {
|
|
594
|
+
close();
|
|
595
|
+
}
|
|
596
|
+
}),
|
|
597
|
+
[close, rowState]
|
|
598
|
+
);
|
|
597
599
|
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
600
|
+
const panGesture = useMemo(
|
|
601
|
+
() =>
|
|
602
|
+
Gesture.Pan()
|
|
603
|
+
.enabled(enabled !== false)
|
|
604
|
+
.enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture)
|
|
605
|
+
.activeOffsetX([-dragOffsetFromRightEdge, dragOffsetFromLeftEdge])
|
|
606
|
+
.onStart(() => {
|
|
607
|
+
updateRightElementWidth();
|
|
608
|
+
})
|
|
609
|
+
.onUpdate(
|
|
610
|
+
(event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
|
|
611
|
+
userDrag.value = event.translationX;
|
|
612
|
+
|
|
613
|
+
const direction =
|
|
614
|
+
rowState.value === -1
|
|
615
|
+
? SwipeDirection.RIGHT
|
|
616
|
+
: rowState.value === 1
|
|
617
|
+
? SwipeDirection.LEFT
|
|
618
|
+
: event.translationX > 0
|
|
619
|
+
? SwipeDirection.RIGHT
|
|
620
|
+
: SwipeDirection.LEFT;
|
|
621
|
+
|
|
622
|
+
if (!dragStarted.value) {
|
|
623
|
+
dragStarted.value = true;
|
|
624
|
+
if (rowState.value === 0 && onSwipeableOpenStartDrag) {
|
|
625
|
+
runOnJS(onSwipeableOpenStartDrag)(direction);
|
|
626
|
+
} else if (onSwipeableCloseStartDrag) {
|
|
627
|
+
runOnJS(onSwipeableCloseStartDrag)(direction);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
updateAnimatedEvent();
|
|
632
|
+
}
|
|
633
|
+
)
|
|
634
|
+
.onEnd(
|
|
635
|
+
(event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
636
|
+
handleRelease(event);
|
|
637
|
+
}
|
|
638
|
+
)
|
|
639
|
+
.onFinalize(() => {
|
|
640
|
+
dragStarted.value = false;
|
|
641
|
+
}),
|
|
642
|
+
[
|
|
643
|
+
dragOffsetFromLeftEdge,
|
|
644
|
+
dragOffsetFromRightEdge,
|
|
645
|
+
dragStarted,
|
|
646
|
+
enableTrackpadTwoFingerGesture,
|
|
647
|
+
enabled,
|
|
648
|
+
handleRelease,
|
|
649
|
+
onSwipeableCloseStartDrag,
|
|
650
|
+
onSwipeableOpenStartDrag,
|
|
651
|
+
rowState,
|
|
652
|
+
updateAnimatedEvent,
|
|
653
|
+
updateRightElementWidth,
|
|
654
|
+
userDrag,
|
|
655
|
+
]
|
|
656
|
+
);
|
|
601
657
|
|
|
602
|
-
|
|
658
|
+
useImperativeHandle(ref, () => swipeableMethods, [swipeableMethods]);
|
|
603
659
|
|
|
604
660
|
const animatedStyle = useAnimatedStyle(
|
|
605
661
|
() => ({
|
|
@@ -615,8 +671,8 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
|
615
671
|
{...remainingProps}
|
|
616
672
|
onLayout={onRowLayout}
|
|
617
673
|
style={[styles.container, containerStyle]}>
|
|
618
|
-
{leftElement}
|
|
619
|
-
{rightElement}
|
|
674
|
+
{leftElement()}
|
|
675
|
+
{rightElement()}
|
|
620
676
|
<GestureDetector gesture={tapGesture} touchAction="pan-y">
|
|
621
677
|
<Animated.View style={[animatedStyle, childrenContainerStyle]}>
|
|
622
678
|
{children}
|