react-native-gesture-handler 3.0.0-beta.4 → 3.0.0-beta.5
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/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +12 -4
- package/android/src/main/java/com/swmansion/gesturehandler/core/NativeViewGestureHandler.kt +6 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/Extensions.kt +21 -0
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +113 -49
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerDetectorView.kt +75 -98
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +7 -10
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRegistry.kt +64 -2
- package/apple/RNGestureHandler.mm +50 -27
- package/apple/RNGestureHandlerButton.h +4 -2
- package/apple/RNGestureHandlerButton.mm +106 -27
- package/apple/RNGestureHandlerButtonComponentView.mm +17 -2
- package/apple/RNGestureHandlerDetector.mm +99 -75
- package/apple/RNGestureHandlerModule.mm +11 -14
- package/apple/RNGestureHandlerRegistry.h +14 -0
- package/apple/RNGestureHandlerRegistry.m +56 -0
- package/lib/module/RNGestureHandlerModule.web.js +5 -1
- package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
- package/lib/module/components/GestureButtons.js +16 -5
- package/lib/module/components/GestureButtons.js.map +1 -1
- package/lib/module/components/GestureHandlerButton.js.map +1 -1
- package/lib/module/components/GestureHandlerButton.web.js +63 -23
- package/lib/module/components/GestureHandlerButton.web.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +1 -0
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/ReanimatedDrawerLayout.js.map +1 -1
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js +38 -5
- package/lib/module/components/ReanimatedSwipeable/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js +1 -2
- package/lib/module/handlers/gestures/GestureDetector/useDetectorUpdater.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/utils.js +0 -47
- package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
- package/lib/module/handlers/gestures/reanimatedWrapper.js +14 -2
- package/lib/module/handlers/gestures/reanimatedWrapper.js.map +1 -1
- package/lib/module/mocks/module.js +3 -2
- package/lib/module/mocks/module.js.map +1 -1
- package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
- package/lib/module/specs/RNGestureHandlerButtonNativeComponent.ts +28 -13
- package/lib/module/v3/NativeProxy.js +5 -3
- package/lib/module/v3/NativeProxy.js.map +1 -1
- package/lib/module/v3/NativeProxy.web.js +2 -2
- package/lib/module/v3/NativeProxy.web.js.map +1 -1
- package/lib/module/v3/components/GestureButtons.js +8 -3
- package/lib/module/v3/components/GestureButtons.js.map +1 -1
- package/lib/module/v3/components/Touchable/Touchable.js +53 -4
- package/lib/module/v3/components/Touchable/Touchable.js.map +1 -1
- package/lib/module/v3/detectors/HostGestureDetector.web.js +178 -59
- package/lib/module/v3/detectors/HostGestureDetector.web.js.map +1 -1
- package/lib/module/v3/detectors/NativeDetector.js +3 -2
- package/lib/module/v3/detectors/NativeDetector.js.map +1 -1
- package/lib/module/v3/detectors/VirtualDetector/InterceptingGestureDetector.js +3 -4
- package/lib/module/v3/detectors/VirtualDetector/InterceptingGestureDetector.js.map +1 -1
- package/lib/module/v3/detectors/VirtualDetector/VirtualDetector.js +2 -2
- package/lib/module/v3/detectors/VirtualDetector/VirtualDetector.js.map +1 -1
- package/lib/module/v3/detectors/useGestureRelationsUpdater.js +23 -0
- package/lib/module/v3/detectors/useGestureRelationsUpdater.js.map +1 -0
- package/lib/module/v3/detectors/utils.js +10 -8
- package/lib/module/v3/detectors/utils.js.map +1 -1
- package/lib/module/v3/hooks/useGesture.js +3 -18
- package/lib/module/v3/hooks/useGesture.js.map +1 -1
- package/lib/module/v3/hooks/utils/configUtils.js +1 -3
- package/lib/module/v3/hooks/utils/configUtils.js.map +1 -1
- package/lib/module/v3/hooks/utils/eventHandlersUtils.js +31 -29
- package/lib/module/v3/hooks/utils/eventHandlersUtils.js.map +1 -1
- package/lib/module/v3/hooks/utils/reanimatedUtils.js +8 -2
- package/lib/module/v3/hooks/utils/reanimatedUtils.js.map +1 -1
- package/lib/module/web/tools/NodeManager.js +44 -0
- package/lib/module/web/tools/NodeManager.js.map +1 -1
- package/lib/typescript/RNGestureHandlerModule.web.d.ts +1 -1
- package/lib/typescript/RNGestureHandlerModule.web.d.ts.map +1 -1
- package/lib/typescript/components/GestureButtons.d.ts +14 -6
- package/lib/typescript/components/GestureButtons.d.ts.map +1 -1
- package/lib/typescript/components/GestureHandlerButton.d.ts +62 -8
- package/lib/typescript/components/GestureHandlerButton.d.ts.map +1 -1
- package/lib/typescript/components/GestureHandlerButton.web.d.ts +10 -3
- package/lib/typescript/components/GestureHandlerButton.web.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/Pressable.d.ts.map +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts +1 -1
- package/lib/typescript/components/Pressable/PressableProps.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts +16 -14
- package/lib/typescript/components/ReanimatedDrawerLayout.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts +2 -1
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeable.d.ts.map +1 -1
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts +30 -34
- package/lib/typescript/components/ReanimatedSwipeable/ReanimatedSwipeableProps.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/useDetectorUpdater.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/GestureDetector/utils.d.ts +0 -1
- package/lib/typescript/handlers/gestures/GestureDetector/utils.d.ts.map +1 -1
- package/lib/typescript/handlers/gestures/reanimatedWrapper.d.ts.map +1 -1
- package/lib/typescript/mocks/module.d.ts +1 -1
- package/lib/typescript/mocks/module.d.ts.map +1 -1
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +2 -2
- package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts.map +1 -1
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +19 -11
- package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts.map +1 -1
- package/lib/typescript/v3/NativeProxy.d.ts +1 -1
- package/lib/typescript/v3/NativeProxy.d.ts.map +1 -1
- package/lib/typescript/v3/NativeProxy.web.d.ts +1 -1
- package/lib/typescript/v3/NativeProxy.web.d.ts.map +1 -1
- package/lib/typescript/v3/components/GestureButtons.d.ts +1 -38
- package/lib/typescript/v3/components/GestureButtons.d.ts.map +1 -1
- package/lib/typescript/v3/components/GestureButtonsProps.d.ts +1 -1
- package/lib/typescript/v3/components/GestureButtonsProps.d.ts.map +1 -1
- package/lib/typescript/v3/components/Touchable/Touchable.d.ts.map +1 -1
- package/lib/typescript/v3/components/Touchable/TouchableProps.d.ts +39 -1
- package/lib/typescript/v3/components/Touchable/TouchableProps.d.ts.map +1 -1
- package/lib/typescript/v3/detectors/HostGestureDetector.web.d.ts.map +1 -1
- package/lib/typescript/v3/detectors/NativeDetector.d.ts.map +1 -1
- package/lib/typescript/v3/detectors/VirtualDetector/InterceptingGestureDetector.d.ts.map +1 -1
- package/lib/typescript/v3/detectors/useGestureRelationsUpdater.d.ts +3 -0
- package/lib/typescript/v3/detectors/useGestureRelationsUpdater.d.ts.map +1 -0
- package/lib/typescript/v3/detectors/utils.d.ts +3 -3
- package/lib/typescript/v3/detectors/utils.d.ts.map +1 -1
- package/lib/typescript/v3/hooks/useGesture.d.ts.map +1 -1
- package/lib/typescript/v3/hooks/utils/configUtils.d.ts.map +1 -1
- package/lib/typescript/v3/hooks/utils/eventHandlersUtils.d.ts.map +1 -1
- package/lib/typescript/v3/hooks/utils/reanimatedUtils.d.ts +1 -0
- package/lib/typescript/v3/hooks/utils/reanimatedUtils.d.ts.map +1 -1
- package/lib/typescript/web/tools/NodeManager.d.ts +7 -0
- package/lib/typescript/web/tools/NodeManager.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/RNGestureHandlerModule.web.ts +5 -1
- package/src/components/GestureButtons.tsx +23 -7
- package/src/components/GestureHandlerButton.tsx +70 -8
- package/src/components/GestureHandlerButton.web.tsx +97 -29
- package/src/components/Pressable/Pressable.tsx +1 -0
- package/src/components/Pressable/PressableProps.tsx +2 -1
- package/src/components/ReanimatedDrawerLayout.tsx +27 -23
- package/src/components/ReanimatedSwipeable/ReanimatedSwipeable.tsx +51 -5
- package/src/components/ReanimatedSwipeable/ReanimatedSwipeableProps.ts +31 -39
- package/src/handlers/gestures/GestureDetector/useDetectorUpdater.ts +1 -2
- package/src/handlers/gestures/GestureDetector/utils.ts +0 -52
- package/src/handlers/gestures/reanimatedWrapper.ts +20 -2
- package/src/mocks/module.tsx +4 -2
- package/src/specs/NativeRNGestureHandlerModule.ts +2 -4
- package/src/specs/RNGestureHandlerButtonNativeComponent.ts +28 -13
- package/src/v3/NativeProxy.ts +9 -7
- package/src/v3/NativeProxy.web.ts +2 -2
- package/src/v3/components/GestureButtons.tsx +13 -5
- package/src/v3/components/GestureButtonsProps.ts +1 -0
- package/src/v3/components/Touchable/Touchable.tsx +65 -4
- package/src/v3/components/Touchable/TouchableProps.ts +49 -1
- package/src/v3/detectors/HostGestureDetector.web.tsx +265 -108
- package/src/v3/detectors/NativeDetector.tsx +3 -2
- package/src/v3/detectors/VirtualDetector/InterceptingGestureDetector.tsx +3 -4
- package/src/v3/detectors/VirtualDetector/VirtualDetector.tsx +2 -2
- package/src/v3/detectors/useGestureRelationsUpdater.ts +30 -0
- package/src/v3/detectors/utils.ts +28 -12
- package/src/v3/hooks/useGesture.ts +4 -14
- package/src/v3/hooks/utils/configUtils.ts +2 -3
- package/src/v3/hooks/utils/eventHandlersUtils.ts +43 -32
- package/src/v3/hooks/utils/reanimatedUtils.ts +10 -10
- package/src/web/tools/NodeManager.ts +57 -0
- package/lib/module/RNRenderer.js +0 -6
- package/lib/module/RNRenderer.js.map +0 -1
- package/lib/module/RNRenderer.web.js +0 -6
- package/lib/module/RNRenderer.web.js.map +0 -1
- package/lib/typescript/RNRenderer.d.ts +0 -2
- package/lib/typescript/RNRenderer.d.ts.map +0 -1
- package/lib/typescript/RNRenderer.web.d.ts +0 -4
- package/lib/typescript/RNRenderer.web.d.ts.map +0 -1
- package/src/RNRenderer.ts +0 -3
- package/src/RNRenderer.web.ts +0 -3
|
@@ -3,17 +3,14 @@ import type { StyleProp, ViewStyle } from 'react-native';
|
|
|
3
3
|
import type { SharedValue } from 'react-native-reanimated';
|
|
4
4
|
|
|
5
5
|
import type { HitSlop } from '../../handlers/gestureHandlerCommon';
|
|
6
|
-
import type { AnyGesture } from '../../v3/types';
|
|
6
|
+
import type { AnyGesture, WithSharedValue } from '../../v3/types';
|
|
7
7
|
|
|
8
8
|
export enum SwipeDirection {
|
|
9
9
|
LEFT = 'left',
|
|
10
10
|
RIGHT = 'right',
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
16
|
-
*/
|
|
13
|
+
export type SwipeableProps = {
|
|
17
14
|
ref?: React.Ref<SwipeableMethods>;
|
|
18
15
|
|
|
19
16
|
/**
|
|
@@ -23,27 +20,6 @@ export interface SwipeableProps {
|
|
|
23
20
|
|
|
24
21
|
children?: React.ReactNode;
|
|
25
22
|
|
|
26
|
-
/**
|
|
27
|
-
* Indicates whether `ReanimatedSwipeable` should be analyzing stream of touch events or not.
|
|
28
|
-
* @see https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/pan-gesture#enabledvalue-boolean
|
|
29
|
-
*/
|
|
30
|
-
enabled?: boolean;
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* This parameter enables control over what part of the connected view area can be used to begin recognizing the gesture.
|
|
34
|
-
* When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly.
|
|
35
|
-
* @see https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/pan-gesture#hitslopsettings
|
|
36
|
-
*/
|
|
37
|
-
hitSlop?: HitSlop;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Enables two-finger gestures on supported devices, for example iPads with
|
|
41
|
-
* trackpads. If not enabled the gesture will require click + drag, with
|
|
42
|
-
* `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger
|
|
43
|
-
* the gesture.
|
|
44
|
-
*/
|
|
45
|
-
enableTrackpadTwoFingerGesture?: boolean;
|
|
46
|
-
|
|
47
23
|
/**
|
|
48
24
|
* Specifies how much the visual interaction will be delayed compared to the
|
|
49
25
|
* gesture distance. e.g. value of 1 will indicate that the swipeable panel
|
|
@@ -66,18 +42,6 @@ export interface SwipeableProps {
|
|
|
66
42
|
*/
|
|
67
43
|
rightThreshold?: number;
|
|
68
44
|
|
|
69
|
-
/**
|
|
70
|
-
* Distance that the panel must be dragged from the left edge to be considered
|
|
71
|
-
* a swipe. The default value is 10.
|
|
72
|
-
*/
|
|
73
|
-
dragOffsetFromLeftEdge?: number;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Distance that the panel must be dragged from the right edge to be considered
|
|
77
|
-
* a swipe. The default value is 10.
|
|
78
|
-
*/
|
|
79
|
-
dragOffsetFromRightEdge?: number;
|
|
80
|
-
|
|
81
45
|
/**
|
|
82
46
|
* Value indicating if the swipeable panel can be pulled further than the left
|
|
83
47
|
* actions panel's width. It is set to true by default as long as the left
|
|
@@ -204,7 +168,35 @@ export interface SwipeableProps {
|
|
|
204
168
|
* used with the swipeable's gesture handler.
|
|
205
169
|
*/
|
|
206
170
|
block?: AnyGesture | AnyGesture[];
|
|
207
|
-
}
|
|
171
|
+
} & WithSharedValue<{
|
|
172
|
+
/**
|
|
173
|
+
* Indicates whether `ReanimatedSwipeable` should be analyzing stream of touch events or not.
|
|
174
|
+
* @see https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/pan-gesture#enabledvalue-boolean
|
|
175
|
+
*/
|
|
176
|
+
enabled?: boolean | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* This parameter enables control over what part of the connected view area can be used to begin recognizing the gesture.
|
|
179
|
+
* When a negative number is provided the bounds of the view will reduce the area by the given number of points in each of the sides evenly.
|
|
180
|
+
* @see https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/pan-gesture#hitslopsettings
|
|
181
|
+
*/
|
|
182
|
+
hitSlop?: HitSlop | undefined;
|
|
183
|
+
/**
|
|
184
|
+
* Enables two-finger gestures on supported devices, for example iPads with
|
|
185
|
+
* trackpads. If not enabled the gesture will require click + drag, with
|
|
186
|
+
* `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger
|
|
187
|
+
* the gesture.
|
|
188
|
+
*/
|
|
189
|
+
enableTrackpadTwoFingerGesture?: boolean | undefined;
|
|
190
|
+
/**
|
|
191
|
+
* The horizontal offset from the starting point required to trigger a right-swipe gesture. Defaults to 10.
|
|
192
|
+
*/
|
|
193
|
+
dragOffsetFromLeft?: number;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The horizontal offset from the starting point required to trigger a left-swipe gesture. Defaults to -10.
|
|
197
|
+
*/
|
|
198
|
+
dragOffsetFromRight?: number;
|
|
199
|
+
}>;
|
|
208
200
|
|
|
209
201
|
export interface SwipeableMethods {
|
|
210
202
|
close: () => void;
|
|
@@ -10,7 +10,7 @@ import { dropHandlers } from './dropHandlers';
|
|
|
10
10
|
import { needsToReattach } from './needsToReattach';
|
|
11
11
|
import type { AttachedGestureState, GestureDetectorState } from './types';
|
|
12
12
|
import { updateHandlers } from './updateHandlers';
|
|
13
|
-
import { useForceRender
|
|
13
|
+
import { useForceRender } from './utils';
|
|
14
14
|
|
|
15
15
|
// Returns a function that's responsible for updating the attached gestures
|
|
16
16
|
// If the view has changed, it will reattach the handlers to the new view
|
|
@@ -34,7 +34,6 @@ export function useDetectorUpdater(
|
|
|
34
34
|
didUnderlyingViewChange ||
|
|
35
35
|
needsToReattach(preparedGesture, gesturesToAttach)
|
|
36
36
|
) {
|
|
37
|
-
validateDetectorChildren(state.viewRef);
|
|
38
37
|
dropHandlers(preparedGesture);
|
|
39
38
|
attachHandlers({
|
|
40
39
|
preparedGesture,
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { useCallback, useRef, useState } from 'react';
|
|
2
|
-
import { Platform } from 'react-native';
|
|
3
2
|
|
|
4
|
-
import { RNRenderer } from '../../../RNRenderer';
|
|
5
3
|
import { isTestEnv, tagMessage } from '../../../utils';
|
|
6
4
|
import type {
|
|
7
5
|
GestureHandlerNativeEvent,
|
|
@@ -124,56 +122,6 @@ export function checkGestureCallbacksForWorklets(gesture: GestureType) {
|
|
|
124
122
|
}
|
|
125
123
|
}
|
|
126
124
|
|
|
127
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
128
|
-
export function validateDetectorChildren(ref: any) {
|
|
129
|
-
// Finds the first native view under the Wrap component and traverses the fiber tree upwards
|
|
130
|
-
// to check whether there is more than one native view as a pseudo-direct child of GestureDetector
|
|
131
|
-
// i.e. this is not ok:
|
|
132
|
-
// Wrap
|
|
133
|
-
// |
|
|
134
|
-
// / \
|
|
135
|
-
// / \
|
|
136
|
-
// / \
|
|
137
|
-
// / \
|
|
138
|
-
// NativeView NativeView
|
|
139
|
-
//
|
|
140
|
-
// but this is fine:
|
|
141
|
-
// Wrap
|
|
142
|
-
// |
|
|
143
|
-
// NativeView
|
|
144
|
-
// |
|
|
145
|
-
// / \
|
|
146
|
-
// / \
|
|
147
|
-
// / \
|
|
148
|
-
// / \
|
|
149
|
-
// NativeView NativeView
|
|
150
|
-
if (__DEV__ && Platform.OS !== 'web') {
|
|
151
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
152
|
-
const wrapType =
|
|
153
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
154
|
-
ref._reactInternals.elementType;
|
|
155
|
-
|
|
156
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
157
|
-
let instance =
|
|
158
|
-
RNRenderer.findHostInstance_DEPRECATED(
|
|
159
|
-
ref
|
|
160
|
-
)._internalFiberInstanceHandleDEV;
|
|
161
|
-
|
|
162
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
163
|
-
while (instance && instance.elementType !== wrapType) {
|
|
164
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
165
|
-
if (instance.sibling) {
|
|
166
|
-
throw new Error(
|
|
167
|
-
'GestureDetector has more than one native view as its children. This can happen if you are using a custom component that renders multiple views, like React.Fragment. You should wrap content of GestureDetector with a <View> or <Animated.View>.'
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
172
|
-
instance = instance.return;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
125
|
export function useForceRender() {
|
|
178
126
|
const [renderState, setRenderState] = useState(false);
|
|
179
127
|
const forceRender = useCallback(() => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ComponentClass } from 'react';
|
|
2
2
|
|
|
3
|
+
import { ghQueueMicrotask } from '../../ghQueueMicrotask';
|
|
3
4
|
import { tagMessage } from '../../utils';
|
|
4
5
|
import { NativeProxy } from '../../v3/NativeProxy';
|
|
5
6
|
import type {
|
|
@@ -82,7 +83,25 @@ let Reanimated:
|
|
|
82
83
|
|
|
83
84
|
try {
|
|
84
85
|
Reanimated = require('react-native-reanimated');
|
|
85
|
-
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
|
87
|
+
const Worklets = require('react-native-worklets');
|
|
88
|
+
|
|
89
|
+
// Make sure worklets are initialized before attempting to install UI runtime bindings
|
|
90
|
+
Worklets?.scheduleOnUI(() => {
|
|
91
|
+
'worklet';
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
ghQueueMicrotask(() => {
|
|
95
|
+
const decorated = NativeProxy.installUIRuntimeBindings();
|
|
96
|
+
|
|
97
|
+
if (!decorated) {
|
|
98
|
+
console.warn(
|
|
99
|
+
tagMessage(
|
|
100
|
+
'Failed to install UI runtime bindings. Please report this at https://github.com/software-mansion/react-native-gesture-handler/issues.'
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
});
|
|
86
105
|
} catch (e) {
|
|
87
106
|
// When 'react-native-reanimated' is not available we want to quietly continue
|
|
88
107
|
// @ts-ignore TS demands the variable to be initialized
|
|
@@ -93,7 +112,6 @@ if (!Reanimated?.useSharedValue) {
|
|
|
93
112
|
// @ts-ignore Make sure the loaded module is actually Reanimated, if it's not
|
|
94
113
|
// reset the module to undefined so we can fallback to the default implementation
|
|
95
114
|
Reanimated = undefined;
|
|
96
|
-
NativeProxy.setReanimatedAvailable(false);
|
|
97
115
|
}
|
|
98
116
|
|
|
99
117
|
if (Reanimated !== undefined && !Reanimated.setGestureState) {
|
package/src/mocks/module.tsx
CHANGED
|
@@ -2,6 +2,8 @@ const NOOP = () => {
|
|
|
2
2
|
// Do nothing
|
|
3
3
|
};
|
|
4
4
|
|
|
5
|
+
const NOOPTrue = () => true;
|
|
6
|
+
|
|
5
7
|
const attachGestureHandler = NOOP;
|
|
6
8
|
const createGestureHandler = NOOP;
|
|
7
9
|
const dropGestureHandler = NOOP;
|
|
@@ -9,7 +11,7 @@ const setGestureHandlerConfig = NOOP;
|
|
|
9
11
|
const updateGestureHandlerConfig = NOOP;
|
|
10
12
|
const flushOperations = NOOP;
|
|
11
13
|
const configureRelations = NOOP;
|
|
12
|
-
const
|
|
14
|
+
const installUIRuntimeBindings = NOOPTrue;
|
|
13
15
|
const install = NOOP;
|
|
14
16
|
|
|
15
17
|
export default {
|
|
@@ -19,7 +21,7 @@ export default {
|
|
|
19
21
|
setGestureHandlerConfig,
|
|
20
22
|
updateGestureHandlerConfig,
|
|
21
23
|
configureRelations,
|
|
22
|
-
|
|
24
|
+
installUIRuntimeBindings,
|
|
23
25
|
flushOperations,
|
|
24
26
|
install,
|
|
25
27
|
} as const;
|
|
@@ -3,15 +3,13 @@ import { TurboModuleRegistry } from 'react-native';
|
|
|
3
3
|
import type { Double } from 'react-native/Libraries/Types/CodegenTypes';
|
|
4
4
|
|
|
5
5
|
export interface Spec extends TurboModule {
|
|
6
|
-
// This method returns a boolean only to force the codegen to generate
|
|
7
|
-
// a synchronous method. The returned value doesn't have any meaning.
|
|
8
6
|
createGestureHandler: (
|
|
9
7
|
handlerName: string,
|
|
10
8
|
handlerTag: Double,
|
|
11
9
|
// Record<> is not supported by codegen
|
|
12
10
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
13
11
|
config: Object
|
|
14
|
-
) =>
|
|
12
|
+
) => void;
|
|
15
13
|
attachGestureHandler: (
|
|
16
14
|
handlerTag: Double,
|
|
17
15
|
newView: Double,
|
|
@@ -25,7 +23,7 @@ export interface Spec extends TurboModule {
|
|
|
25
23
|
configureRelations: (handlerTag: Double, relations: Object) => void;
|
|
26
24
|
dropGestureHandler: (handlerTag: Double) => void;
|
|
27
25
|
flushOperations: () => void;
|
|
28
|
-
|
|
26
|
+
installUIRuntimeBindings: () => boolean;
|
|
29
27
|
}
|
|
30
28
|
|
|
31
29
|
export default TurboModuleRegistry.getEnforcing<Spec>('RNGestureHandlerModule');
|
|
@@ -2,6 +2,7 @@ import type { ColorValue, ViewProps } from 'react-native';
|
|
|
2
2
|
import type {
|
|
3
3
|
Float,
|
|
4
4
|
Int32,
|
|
5
|
+
UnsafeMixed,
|
|
5
6
|
WithDefault,
|
|
6
7
|
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
7
8
|
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
@@ -19,8 +20,11 @@ interface NativeProps extends ViewProps {
|
|
|
19
20
|
'box-none' | 'none' | 'box-only' | 'auto',
|
|
20
21
|
'auto'
|
|
21
22
|
>;
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
tapAnimationInDuration?: WithDefault<Int32, 50>;
|
|
24
|
+
tapAnimationOutDuration?: WithDefault<Int32, 100>;
|
|
25
|
+
longPressDuration?: WithDefault<Int32, -1>;
|
|
26
|
+
longPressAnimationOutDuration?: WithDefault<Int32, -1>;
|
|
27
|
+
needsOffscreenAlphaCompositing?: WithDefault<boolean, false>;
|
|
24
28
|
activeOpacity?: WithDefault<Float, 1>;
|
|
25
29
|
activeScale?: WithDefault<Float, 1>;
|
|
26
30
|
activeUnderlayOpacity?: WithDefault<Float, 0>;
|
|
@@ -54,17 +58,28 @@ interface NativeProps extends ViewProps {
|
|
|
54
58
|
borderBlockEndColor?: ColorValue;
|
|
55
59
|
borderBlockStartColor?: ColorValue;
|
|
56
60
|
|
|
57
|
-
// Border radius —
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
// Border radius — declared as UnsafeMixed (folly::dynamic on iOS,
|
|
62
|
+
// DynamicFromObject on Android) so codegen forwards the raw value
|
|
63
|
+
// without coercing to Float. This lets the Android view manager parse
|
|
64
|
+
// both numeric points and percentage strings via
|
|
65
|
+
// LengthPercentage.setFromDynamic, matching RN's standard View. The
|
|
66
|
+
// non-logical variants are declared explicitly so they're dispatched
|
|
67
|
+
// through our delegate instead of falling through to
|
|
68
|
+
// BaseViewManagerDelegate, which casts to Double and would crash on a
|
|
69
|
+
// string value.
|
|
70
|
+
borderRadius?: UnsafeMixed;
|
|
71
|
+
borderTopLeftRadius?: UnsafeMixed;
|
|
72
|
+
borderTopRightRadius?: UnsafeMixed;
|
|
73
|
+
borderBottomLeftRadius?: UnsafeMixed;
|
|
74
|
+
borderBottomRightRadius?: UnsafeMixed;
|
|
75
|
+
borderTopStartRadius?: UnsafeMixed;
|
|
76
|
+
borderTopEndRadius?: UnsafeMixed;
|
|
77
|
+
borderBottomStartRadius?: UnsafeMixed;
|
|
78
|
+
borderBottomEndRadius?: UnsafeMixed;
|
|
79
|
+
borderEndEndRadius?: UnsafeMixed;
|
|
80
|
+
borderEndStartRadius?: UnsafeMixed;
|
|
81
|
+
borderStartEndRadius?: UnsafeMixed;
|
|
82
|
+
borderStartStartRadius?: UnsafeMixed;
|
|
68
83
|
}
|
|
69
84
|
|
|
70
85
|
export default codegenNativeComponent<NativeProps>('RNGestureHandlerButton');
|
package/src/v3/NativeProxy.ts
CHANGED
|
@@ -16,11 +16,13 @@ export const NativeProxy = {
|
|
|
16
16
|
handlerTag: number,
|
|
17
17
|
config?: T
|
|
18
18
|
) => {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
scheduleOperationToBeFlushed(() => {
|
|
20
|
+
RNGestureHandlerModule.createGestureHandler(
|
|
21
|
+
handlerName,
|
|
22
|
+
handlerTag,
|
|
23
|
+
config || {}
|
|
24
|
+
);
|
|
25
|
+
});
|
|
24
26
|
},
|
|
25
27
|
setGestureHandlerConfig: <
|
|
26
28
|
TConfig,
|
|
@@ -59,7 +61,7 @@ export const NativeProxy = {
|
|
|
59
61
|
RNGestureHandlerModule.configureRelations(handlerTag, relations);
|
|
60
62
|
});
|
|
61
63
|
},
|
|
62
|
-
|
|
63
|
-
RNGestureHandlerModule.
|
|
64
|
+
installUIRuntimeBindings: () => {
|
|
65
|
+
return RNGestureHandlerModule.installUIRuntimeBindings();
|
|
64
66
|
},
|
|
65
67
|
} as const;
|
|
@@ -43,7 +43,7 @@ export const NativeProxy = {
|
|
|
43
43
|
configureRelations: (handlerTag: number, relations: GestureRelations) => {
|
|
44
44
|
RNGestureHandlerModule.configureRelations(handlerTag, relations);
|
|
45
45
|
},
|
|
46
|
-
|
|
47
|
-
RNGestureHandlerModule.
|
|
46
|
+
installUIRuntimeBindings: () => {
|
|
47
|
+
return RNGestureHandlerModule.installUIRuntimeBindings();
|
|
48
48
|
},
|
|
49
49
|
} as const;
|
|
@@ -15,17 +15,25 @@ import type {
|
|
|
15
15
|
type CallbackEventType = GestureEvent<NativeHandlerData>;
|
|
16
16
|
type EndCallbackEventType = GestureEndEvent<NativeHandlerData>;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
type RawButtonInnerProps = RawButtonProps & {
|
|
19
|
+
needsOffscreenAlphaCompositing?: boolean | undefined;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const RawButtonInner = createNativeWrapper<
|
|
22
23
|
React.ComponentRef<typeof GestureHandlerButton>,
|
|
23
|
-
|
|
24
|
+
RawButtonInnerProps
|
|
24
25
|
>(GestureHandlerButton, {
|
|
25
26
|
shouldCancelWhenOutside: false,
|
|
26
27
|
shouldActivateOnStart: false,
|
|
27
28
|
});
|
|
28
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @deprecated `RawButton` is deprecated, use `Clickable` instead
|
|
32
|
+
*/
|
|
33
|
+
export const RawButton = (props: RawButtonProps) => (
|
|
34
|
+
<RawButtonInner {...props} needsOffscreenAlphaCompositing />
|
|
35
|
+
);
|
|
36
|
+
|
|
29
37
|
/**
|
|
30
38
|
* @deprecated `BaseButton` is deprecated, use `Touchable` instead
|
|
31
39
|
*/
|
|
@@ -5,6 +5,7 @@ import GestureHandlerButton from '../../../components/GestureHandlerButton';
|
|
|
5
5
|
import { NativeDetector } from '../../detectors/NativeDetector';
|
|
6
6
|
import { useNativeGesture } from '../../hooks';
|
|
7
7
|
import type {
|
|
8
|
+
AnimationDuration,
|
|
8
9
|
CallbackEventType,
|
|
9
10
|
EndCallbackEventType,
|
|
10
11
|
TouchableProps,
|
|
@@ -12,6 +13,8 @@ import type {
|
|
|
12
13
|
|
|
13
14
|
const isAndroid = Platform.OS === 'android';
|
|
14
15
|
const TRANSPARENT_RIPPLE = { rippleColor: 'transparent' as const };
|
|
16
|
+
const DEFAULT_IN_DURATION_MS = 50;
|
|
17
|
+
const DEFAULT_OUT_DURATION_MS = 100;
|
|
15
18
|
|
|
16
19
|
enum PointerState {
|
|
17
20
|
UNKNOWN,
|
|
@@ -19,11 +22,60 @@ enum PointerState {
|
|
|
19
22
|
OUTSIDE,
|
|
20
23
|
}
|
|
21
24
|
|
|
25
|
+
// Clamp user-supplied durations to finite, non-negative milliseconds.
|
|
26
|
+
// Negative, NaN, or Infinity values would produce invalid CSS transitions
|
|
27
|
+
// on web and negative setTimeout delays in branch 3 of the press-out path.
|
|
28
|
+
function sanitizeDuration(value: number): number {
|
|
29
|
+
return Number.isFinite(value) && value >= 0 ? value : 0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function resolveAnimationDuration(value: AnimationDuration | undefined) {
|
|
33
|
+
if (value === undefined) {
|
|
34
|
+
return {
|
|
35
|
+
tapAnimationInDuration: DEFAULT_IN_DURATION_MS,
|
|
36
|
+
tapAnimationOutDuration: DEFAULT_OUT_DURATION_MS,
|
|
37
|
+
longPressAnimationOutDuration: DEFAULT_OUT_DURATION_MS,
|
|
38
|
+
hoverAnimationInDuration: DEFAULT_IN_DURATION_MS,
|
|
39
|
+
hoverAnimationOutDuration: DEFAULT_OUT_DURATION_MS,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (typeof value === 'number') {
|
|
44
|
+
const sanitized = sanitizeDuration(value);
|
|
45
|
+
return {
|
|
46
|
+
tapAnimationInDuration: sanitized,
|
|
47
|
+
tapAnimationOutDuration: sanitized,
|
|
48
|
+
longPressAnimationOutDuration: sanitized,
|
|
49
|
+
hoverAnimationInDuration: sanitized,
|
|
50
|
+
hoverAnimationOutDuration: sanitized,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The union guarantees variant 2 supplies top-level `in`/`out`, variant 3
|
|
55
|
+
// supplies both category objects — so per-category fallback to base is
|
|
56
|
+
// always defined for well-typed input; the 0 fallbacks here are unreachable.
|
|
57
|
+
const baseIn = 'in' in value ? value.in : 0;
|
|
58
|
+
const baseOut = 'out' in value ? value.out : 0;
|
|
59
|
+
const tapOut = value.tap?.out ?? baseOut;
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
tapAnimationInDuration: sanitizeDuration(value.tap?.in ?? baseIn),
|
|
63
|
+
tapAnimationOutDuration: sanitizeDuration(tapOut),
|
|
64
|
+
longPressAnimationOutDuration: sanitizeDuration(
|
|
65
|
+
value.longPress?.out ?? tapOut
|
|
66
|
+
),
|
|
67
|
+
hoverAnimationInDuration: sanitizeDuration(value.hover?.in ?? baseIn),
|
|
68
|
+
hoverAnimationOutDuration: sanitizeDuration(value.hover?.out ?? baseOut),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
22
72
|
export const Touchable = (props: TouchableProps) => {
|
|
23
73
|
const {
|
|
24
|
-
underlayColor = '
|
|
74
|
+
underlayColor = 'transparent',
|
|
25
75
|
defaultUnderlayOpacity = 0,
|
|
76
|
+
activeUnderlayOpacity = 0.105,
|
|
26
77
|
defaultOpacity = 1,
|
|
78
|
+
animationDuration,
|
|
27
79
|
androidRipple,
|
|
28
80
|
delayLongPress = 600,
|
|
29
81
|
onLongPress,
|
|
@@ -37,6 +89,9 @@ export const Touchable = (props: TouchableProps) => {
|
|
|
37
89
|
...rest
|
|
38
90
|
} = props;
|
|
39
91
|
|
|
92
|
+
const resolvedDurations = resolveAnimationDuration(animationDuration);
|
|
93
|
+
const resolvedDelayLongPress = sanitizeDuration(delayLongPress);
|
|
94
|
+
|
|
40
95
|
const shouldUseNativeRipple = isAndroid && androidRipple !== undefined;
|
|
41
96
|
|
|
42
97
|
const pointerState = useRef<PointerState>(PointerState.UNKNOWN);
|
|
@@ -54,9 +109,12 @@ export const Touchable = (props: TouchableProps) => {
|
|
|
54
109
|
longPressDetected.current = false;
|
|
55
110
|
|
|
56
111
|
if (onLongPress && !longPressTimeout.current) {
|
|
57
|
-
longPressTimeout.current = setTimeout(
|
|
112
|
+
longPressTimeout.current = setTimeout(
|
|
113
|
+
wrappedLongPress,
|
|
114
|
+
resolvedDelayLongPress
|
|
115
|
+
);
|
|
58
116
|
}
|
|
59
|
-
}, [onLongPress,
|
|
117
|
+
}, [onLongPress, resolvedDelayLongPress, wrappedLongPress]);
|
|
60
118
|
|
|
61
119
|
const onBegin = useCallback(
|
|
62
120
|
(e: CallbackEventType) => {
|
|
@@ -155,11 +213,14 @@ export const Touchable = (props: TouchableProps) => {
|
|
|
155
213
|
<GestureHandlerButton
|
|
156
214
|
{...rest}
|
|
157
215
|
{...rippleProps}
|
|
216
|
+
{...resolvedDurations}
|
|
158
217
|
ref={ref ?? null}
|
|
159
218
|
enabled={!disabled}
|
|
160
219
|
defaultOpacity={defaultOpacity}
|
|
161
220
|
defaultUnderlayOpacity={defaultUnderlayOpacity}
|
|
162
|
-
|
|
221
|
+
activeUnderlayOpacity={activeUnderlayOpacity}
|
|
222
|
+
underlayColor={underlayColor}
|
|
223
|
+
longPressDuration={resolvedDelayLongPress}>
|
|
163
224
|
{children}
|
|
164
225
|
</GestureHandlerButton>
|
|
165
226
|
</NativeDetector>
|
|
@@ -17,11 +17,59 @@ type PressableAndroidRippleConfig = {
|
|
|
17
17
|
|
|
18
18
|
type RippleProps = 'rippleColor' | 'rippleRadius' | 'borderless' | 'foreground';
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
type DurationProps =
|
|
21
|
+
| 'tapAnimationInDuration'
|
|
22
|
+
| 'tapAnimationOutDuration'
|
|
23
|
+
| 'longPressDuration'
|
|
24
|
+
| 'longPressAnimationOutDuration'
|
|
25
|
+
| 'hoverAnimationInDuration'
|
|
26
|
+
| 'hoverAnimationOutDuration';
|
|
27
|
+
|
|
28
|
+
type InOutDuration = { in: number; out: number };
|
|
29
|
+
type LongPressDuration = { out: number };
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Configuration for press / hover animation timing.
|
|
33
|
+
*
|
|
34
|
+
* - A single number applies to every phase of every category.
|
|
35
|
+
* - An object with top-level `in` / `out` sets the baseline; `tap` and
|
|
36
|
+
* `hover` may override either side or both — any field left out
|
|
37
|
+
* inherits the top-level value.
|
|
38
|
+
* - Alternatively, both categories may be specified in full without a
|
|
39
|
+
* top-level baseline.
|
|
40
|
+
*
|
|
41
|
+
* `longPress` optionally customizes the press-out duration once the
|
|
42
|
+
* press has been held past `delayLongPress`. If omitted, the long-press
|
|
43
|
+
* release falls back to the resolved tap-out timing.
|
|
44
|
+
*/
|
|
45
|
+
export type AnimationDuration =
|
|
46
|
+
| number
|
|
47
|
+
| (InOutDuration & {
|
|
48
|
+
tap?: Partial<InOutDuration>;
|
|
49
|
+
hover?: Partial<InOutDuration>;
|
|
50
|
+
longPress?: LongPressDuration;
|
|
51
|
+
})
|
|
52
|
+
| {
|
|
53
|
+
tap: InOutDuration;
|
|
54
|
+
hover: InOutDuration;
|
|
55
|
+
longPress?: LongPressDuration;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type TouchableProps = Omit<
|
|
59
|
+
ButtonProps,
|
|
60
|
+
RippleProps | 'enabled' | DurationProps
|
|
61
|
+
> &
|
|
21
62
|
Omit<
|
|
22
63
|
BaseButtonProps,
|
|
23
64
|
keyof RawButtonProps | 'onActiveStateChange' | 'onPress'
|
|
24
65
|
> & {
|
|
66
|
+
/**
|
|
67
|
+
* Press and hover animation durations, in milliseconds. Pass a single
|
|
68
|
+
* number to apply it to every phase, or an object to customize per phase
|
|
69
|
+
* and per category. Defaults to 50ms for the in phase and 100ms for the
|
|
70
|
+
* out phase.
|
|
71
|
+
*/
|
|
72
|
+
animationDuration?: AnimationDuration | undefined;
|
|
25
73
|
/**
|
|
26
74
|
* Configuration for the ripple effect on Android.
|
|
27
75
|
*/
|