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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-gesture-handler",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.5",
|
|
4
4
|
"description": "Declarative API exposing native platform touch and gesture system to React Native",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "jest",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@react-native/jest-preset": "0.85.0",
|
|
78
78
|
"@testing-library/react-native": "^12.5.1",
|
|
79
79
|
"@types/invariant": "^2.2.37",
|
|
80
|
-
"@types/jest": "^
|
|
80
|
+
"@types/jest": "^29.5.12",
|
|
81
81
|
"@types/react": "^19.2.0",
|
|
82
82
|
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
83
83
|
"@typescript-eslint/parser": "^6.9.0",
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"eslint-plugin-prettier": "^5.0.1",
|
|
91
91
|
"eslint-plugin-react": "^7.37.5",
|
|
92
92
|
"husky": "^8.0.1",
|
|
93
|
-
"jest": "^
|
|
93
|
+
"jest": "^29.7.0",
|
|
94
94
|
"lint-staged": "^12.3.2",
|
|
95
95
|
"madge": "^6.1.0",
|
|
96
96
|
"prettier": "3.3.3",
|
|
@@ -82,6 +82,9 @@ export default {
|
|
|
82
82
|
NodeManager.dropGestureHandler(handlerTag);
|
|
83
83
|
},
|
|
84
84
|
configureRelations(handlerTag: number, relations: GestureRelations) {
|
|
85
|
+
if (!NodeManager.hasHandler(handlerTag)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
85
88
|
InteractionManager.instance.configureInteractions(
|
|
86
89
|
NodeManager.getHandler(handlerTag),
|
|
87
90
|
relations
|
|
@@ -89,7 +92,8 @@ export default {
|
|
|
89
92
|
},
|
|
90
93
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
91
94
|
flushOperations() {},
|
|
92
|
-
|
|
95
|
+
installUIRuntimeBindings() {
|
|
93
96
|
// No-op on web
|
|
97
|
+
return true;
|
|
94
98
|
},
|
|
95
99
|
};
|
|
@@ -18,19 +18,30 @@ import type {
|
|
|
18
18
|
LegacyRectButtonProps,
|
|
19
19
|
RectButtonWithRefProps,
|
|
20
20
|
} from './GestureButtonsProps';
|
|
21
|
-
import GestureHandlerButton from './GestureHandlerButton';
|
|
21
|
+
import GestureHandlerButton, { type ButtonProps } from './GestureHandlerButton';
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
type LegacyRawButtonInnerProps = LegacyRawButtonProps & {
|
|
24
|
+
needsOffscreenAlphaCompositing?: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const LegacyRawButtonInner = createNativeWrapper<LegacyRawButtonInnerProps>(
|
|
28
|
+
GestureHandlerButton as unknown as HostComponent<LegacyRawButtonInnerProps>,
|
|
28
29
|
{
|
|
29
30
|
shouldCancelWhenOutside: false,
|
|
30
31
|
shouldActivateOnStart: Platform.OS === 'web',
|
|
31
32
|
}
|
|
32
33
|
);
|
|
33
34
|
|
|
35
|
+
/**
|
|
36
|
+
* @deprecated use `RawButton` instead
|
|
37
|
+
*/
|
|
38
|
+
export const LegacyRawButton = (
|
|
39
|
+
props: Omit<
|
|
40
|
+
React.ComponentProps<typeof LegacyRawButtonInner>,
|
|
41
|
+
'needsOffscreenAlphaCompositing'
|
|
42
|
+
>
|
|
43
|
+
) => <LegacyRawButtonInner {...props} needsOffscreenAlphaCompositing />;
|
|
44
|
+
|
|
34
45
|
class InnerBaseButton extends React.Component<BaseButtonWithRefProps> {
|
|
35
46
|
static defaultProps = {
|
|
36
47
|
delayLongPress: 600,
|
|
@@ -280,4 +291,9 @@ export const LegacyBorderlessButton = ({
|
|
|
280
291
|
ref?: React.Ref<React.ComponentType<any>> | undefined;
|
|
281
292
|
}) => <InnerBorderlessButton innerRef={ref} {...props} />;
|
|
282
293
|
|
|
283
|
-
|
|
294
|
+
/**
|
|
295
|
+
* @deprecated use `PureNativeButton` instead
|
|
296
|
+
*/
|
|
297
|
+
export const LegacyPureNativeButton = (
|
|
298
|
+
props: Omit<ButtonProps, 'needsOffscreenAlphaCompositing'>
|
|
299
|
+
) => <GestureHandlerButton {...props} needsOffscreenAlphaCompositing />;
|
|
@@ -60,18 +60,31 @@ export interface ButtonProps extends ViewProps, AccessibilityProps {
|
|
|
60
60
|
touchSoundDisabled?: boolean | undefined;
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* to any negative value).
|
|
63
|
+
* Minimum duration (in milliseconds) of the press-in animation on a
|
|
64
|
+
* quick tap. Defaults to 50ms.
|
|
66
65
|
*/
|
|
67
|
-
|
|
66
|
+
tapAnimationInDuration?: number | undefined;
|
|
68
67
|
|
|
69
68
|
/**
|
|
70
|
-
* Minimum duration (in milliseconds)
|
|
71
|
-
*
|
|
72
|
-
* state is visible on quick taps. Defaults to 100ms.
|
|
69
|
+
* Minimum duration (in milliseconds) of the press-out animation on a
|
|
70
|
+
* quick tap. Defaults to 100ms.
|
|
73
71
|
*/
|
|
74
|
-
|
|
72
|
+
tapAnimationOutDuration?: number | undefined;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Threshold (in milliseconds) at which the press-out animation
|
|
76
|
+
* switches from the tap-out timing to `longPressAnimationOutDuration`.
|
|
77
|
+
* Set to any negative value to disable the switch.
|
|
78
|
+
*/
|
|
79
|
+
longPressDuration?: number | undefined;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Duration of the press-out animation, in milliseconds, when the
|
|
83
|
+
* button is released after being held past `longPressDuration`.
|
|
84
|
+
* Defaults to `tapAnimationOutDuration` when not set (or set to any
|
|
85
|
+
* negative value).
|
|
86
|
+
*/
|
|
87
|
+
longPressAnimationOutDuration?: number | undefined;
|
|
75
88
|
|
|
76
89
|
/**
|
|
77
90
|
* Opacity applied to the button when it is pressed.
|
|
@@ -88,6 +101,44 @@ export interface ButtonProps extends ViewProps, AccessibilityProps {
|
|
|
88
101
|
*/
|
|
89
102
|
activeUnderlayOpacity?: number | undefined;
|
|
90
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Web only.
|
|
106
|
+
*
|
|
107
|
+
* Opacity applied to the button when it is hovered. Defaults to
|
|
108
|
+
* `defaultOpacity` when not set.
|
|
109
|
+
*/
|
|
110
|
+
hoverOpacity?: number | undefined;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Web only.
|
|
114
|
+
*
|
|
115
|
+
* Scale applied to the button when it is hovered. Defaults to
|
|
116
|
+
* `defaultScale` when not set.
|
|
117
|
+
*/
|
|
118
|
+
hoverScale?: number | undefined;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Web only.
|
|
122
|
+
*
|
|
123
|
+
* Opacity applied to the underlay when the button is hovered. Defaults
|
|
124
|
+
* to `defaultUnderlayOpacity` when not set.
|
|
125
|
+
*/
|
|
126
|
+
hoverUnderlayOpacity?: number | undefined;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Web only.
|
|
130
|
+
*
|
|
131
|
+
* Duration of the hover-in animation, in milliseconds. Defaults to 50ms.
|
|
132
|
+
*/
|
|
133
|
+
hoverAnimationInDuration?: number | undefined;
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Web only.
|
|
137
|
+
*
|
|
138
|
+
* Duration of the hover-out animation, in milliseconds. Defaults to 100ms.
|
|
139
|
+
*/
|
|
140
|
+
hoverAnimationOutDuration?: number | undefined;
|
|
141
|
+
|
|
91
142
|
/**
|
|
92
143
|
* Opacity applied to the button when it is not pressed.
|
|
93
144
|
*/
|
|
@@ -108,6 +159,17 @@ export interface ButtonProps extends ViewProps, AccessibilityProps {
|
|
|
108
159
|
*/
|
|
109
160
|
underlayColor?: ColorValue | undefined;
|
|
110
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Android only.
|
|
164
|
+
*
|
|
165
|
+
* Whether the view should render with an offscreen alpha-compositing buffer
|
|
166
|
+
* when its `opacity` is less than 1. Defaults to `false` — without the
|
|
167
|
+
* offscreen buffer, children that draw past the view's bounds (e.g. anti-
|
|
168
|
+
* aliased border edges) are not clipped by the layer when `opacity < 1`.
|
|
169
|
+
* Set to `true` to opt back into the standard Android behavior.
|
|
170
|
+
*/
|
|
171
|
+
needsOffscreenAlphaCompositing?: boolean | undefined;
|
|
172
|
+
|
|
111
173
|
/**
|
|
112
174
|
* Style object, use it to set additional styles.
|
|
113
175
|
*/
|
|
@@ -8,11 +8,18 @@ import { GestureLifecycleEvent } from '../web/tools/GestureLifecycleEvents';
|
|
|
8
8
|
type ButtonProps = ViewProps & {
|
|
9
9
|
ref?: React.Ref<React.ComponentRef<typeof View>>;
|
|
10
10
|
enabled?: boolean;
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
tapAnimationInDuration?: number;
|
|
12
|
+
tapAnimationOutDuration?: number;
|
|
13
|
+
longPressDuration?: number;
|
|
14
|
+
longPressAnimationOutDuration?: number;
|
|
15
|
+
hoverAnimationInDuration?: number;
|
|
16
|
+
hoverAnimationOutDuration?: number;
|
|
13
17
|
activeOpacity?: number;
|
|
14
18
|
activeScale?: number;
|
|
15
19
|
activeUnderlayOpacity?: number;
|
|
20
|
+
hoverOpacity?: number;
|
|
21
|
+
hoverScale?: number;
|
|
22
|
+
hoverUnderlayOpacity?: number;
|
|
16
23
|
defaultOpacity?: number;
|
|
17
24
|
defaultScale?: number;
|
|
18
25
|
defaultUnderlayOpacity?: number;
|
|
@@ -22,11 +29,18 @@ type ButtonProps = ViewProps & {
|
|
|
22
29
|
export const ButtonComponent = ({
|
|
23
30
|
ref: externalRef,
|
|
24
31
|
enabled = true,
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
tapAnimationInDuration = 50,
|
|
33
|
+
tapAnimationOutDuration = 100,
|
|
34
|
+
longPressDuration = -1,
|
|
35
|
+
longPressAnimationOutDuration = 100,
|
|
36
|
+
hoverAnimationInDuration = 50,
|
|
37
|
+
hoverAnimationOutDuration = 100,
|
|
27
38
|
activeOpacity = 1,
|
|
28
39
|
activeScale = 1,
|
|
29
40
|
activeUnderlayOpacity = 0,
|
|
41
|
+
hoverOpacity: hoverOpacityProp,
|
|
42
|
+
hoverScale: hoverScaleProp,
|
|
43
|
+
hoverUnderlayOpacity: hoverUnderlayOpacityProp,
|
|
30
44
|
defaultOpacity = 1,
|
|
31
45
|
defaultScale = 1,
|
|
32
46
|
defaultUnderlayOpacity = 0,
|
|
@@ -35,16 +49,15 @@ export const ButtonComponent = ({
|
|
|
35
49
|
children,
|
|
36
50
|
...rest
|
|
37
51
|
}: ButtonProps) => {
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
? tapAnimationDuration
|
|
43
|
-
: pressAndHoldAnimationDurationProp;
|
|
52
|
+
const hoverOpacity = hoverOpacityProp ?? defaultOpacity;
|
|
53
|
+
const hoverScale = hoverScaleProp ?? defaultScale;
|
|
54
|
+
const hoverUnderlayOpacity =
|
|
55
|
+
hoverUnderlayOpacityProp ?? defaultUnderlayOpacity;
|
|
44
56
|
|
|
45
57
|
const [pressed, setPressed] = React.useState(false);
|
|
58
|
+
const [hovered, setHovered] = React.useState(false);
|
|
46
59
|
const [currentDuration, setCurrentDuration] = React.useState(
|
|
47
|
-
|
|
60
|
+
tapAnimationInDuration
|
|
48
61
|
);
|
|
49
62
|
const pressInTimestamp = React.useRef(0);
|
|
50
63
|
const pressOutTimer = React.useRef<ReturnType<typeof setTimeout> | null>(
|
|
@@ -114,10 +127,10 @@ export const ButtonComponent = ({
|
|
|
114
127
|
pressOutTimer.current = null;
|
|
115
128
|
}
|
|
116
129
|
pressInTimestamp.current = performance.now();
|
|
117
|
-
setCurrentDuration(
|
|
130
|
+
setCurrentDuration(tapAnimationInDuration);
|
|
118
131
|
setPressed(true);
|
|
119
132
|
},
|
|
120
|
-
[enabled,
|
|
133
|
+
[enabled, tapAnimationInDuration]
|
|
121
134
|
);
|
|
122
135
|
|
|
123
136
|
const pressOut = React.useCallback(
|
|
@@ -137,34 +150,88 @@ export const ButtonComponent = ({
|
|
|
137
150
|
const elapsed = performance.now() - pressInTimestamp.current;
|
|
138
151
|
pressInTimestamp.current = 0;
|
|
139
152
|
|
|
140
|
-
if (elapsed >=
|
|
141
|
-
|
|
153
|
+
if (longPressDuration >= 0 && elapsed >= longPressDuration) {
|
|
154
|
+
// Long-press release — use the configured long-press out duration.
|
|
155
|
+
setCurrentDuration(longPressAnimationOutDuration);
|
|
142
156
|
setPressed(false);
|
|
143
|
-
|
|
144
|
-
|
|
157
|
+
} else if (elapsed >= tapAnimationInDuration) {
|
|
158
|
+
// Press-in animation fully finished - release with the configured out duration.
|
|
159
|
+
setCurrentDuration(tapAnimationOutDuration);
|
|
160
|
+
setPressed(false);
|
|
161
|
+
// elapsed * 2 to ensure there is at least half of the tapAnimationOutDuration left for the animation to play
|
|
162
|
+
} else if (elapsed * 2 >= tapAnimationOutDuration) {
|
|
145
163
|
setCurrentDuration(elapsed);
|
|
146
164
|
setPressed(false);
|
|
147
165
|
} else {
|
|
148
|
-
// Let the in-progress CSS press-in transition continue; schedule press-out after remaining time
|
|
149
|
-
const remaining =
|
|
166
|
+
// Let the in-progress CSS press-in transition continue; schedule press-out after remaining time.
|
|
167
|
+
const remaining = tapAnimationInDuration - elapsed;
|
|
150
168
|
pressOutTimer.current = setTimeout(() => {
|
|
151
169
|
pressOutTimer.current = null;
|
|
152
|
-
setCurrentDuration(
|
|
170
|
+
setCurrentDuration(tapAnimationOutDuration);
|
|
153
171
|
setPressed(false);
|
|
154
172
|
}, remaining);
|
|
155
173
|
}
|
|
156
174
|
},
|
|
157
|
-
[
|
|
175
|
+
[
|
|
176
|
+
longPressDuration,
|
|
177
|
+
longPressAnimationOutDuration,
|
|
178
|
+
tapAnimationInDuration,
|
|
179
|
+
tapAnimationOutDuration,
|
|
180
|
+
]
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const handlePointerEnter = React.useCallback(
|
|
184
|
+
(event: NativeSyntheticEvent<{ pointerType?: string }>) => {
|
|
185
|
+
if (!enabled || event.nativeEvent.pointerType === 'touch') {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
// Skip duration update while pressed so the press transition owns it.
|
|
189
|
+
if (!pressed) {
|
|
190
|
+
setCurrentDuration(hoverAnimationInDuration);
|
|
191
|
+
}
|
|
192
|
+
setHovered(true);
|
|
193
|
+
},
|
|
194
|
+
[enabled, pressed, hoverAnimationInDuration]
|
|
158
195
|
);
|
|
159
196
|
|
|
197
|
+
const handlePointerLeave = React.useCallback(
|
|
198
|
+
(event: NativeSyntheticEvent<{ pointerType?: string }>) => {
|
|
199
|
+
pressOut(event);
|
|
200
|
+
if (event.nativeEvent.pointerType === 'touch') {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!pressed) {
|
|
204
|
+
setCurrentDuration(hoverAnimationOutDuration);
|
|
205
|
+
}
|
|
206
|
+
setHovered(false);
|
|
207
|
+
},
|
|
208
|
+
[pressOut, pressed, hoverAnimationOutDuration]
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
// Mask hover at render rather than clearing the state. Avoids a state
|
|
212
|
+
// write inside an effect, and lets hover resume naturally when `enabled`
|
|
213
|
+
// flips back to true while the pointer is still inside.
|
|
214
|
+
const effectiveHovered = hovered && enabled;
|
|
215
|
+
|
|
160
216
|
const currentUnderlayOpacity = pressed
|
|
161
217
|
? activeUnderlayOpacity
|
|
162
|
-
:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
const
|
|
166
|
-
const
|
|
167
|
-
|
|
218
|
+
: effectiveHovered
|
|
219
|
+
? hoverUnderlayOpacity
|
|
220
|
+
: defaultUnderlayOpacity;
|
|
221
|
+
const hasUnderlay = underlayColor != null && underlayColor !== 'transparent';
|
|
222
|
+
const hasOpacity =
|
|
223
|
+
activeOpacity !== 1 || hoverOpacity !== 1 || defaultOpacity !== 1;
|
|
224
|
+
const currentOpacity = pressed
|
|
225
|
+
? activeOpacity
|
|
226
|
+
: effectiveHovered
|
|
227
|
+
? hoverOpacity
|
|
228
|
+
: defaultOpacity;
|
|
229
|
+
const hasScale = activeScale !== 1 || hoverScale !== 1 || defaultScale !== 1;
|
|
230
|
+
const currentScale = pressed
|
|
231
|
+
? activeScale
|
|
232
|
+
: effectiveHovered
|
|
233
|
+
? hoverScale
|
|
234
|
+
: defaultScale;
|
|
168
235
|
|
|
169
236
|
const easing = 'cubic-bezier(0.5, 1, 0.89, 1)';
|
|
170
237
|
const transitionProps: string[] = [];
|
|
@@ -178,6 +245,7 @@ export const ButtonComponent = ({
|
|
|
178
245
|
|
|
179
246
|
return (
|
|
180
247
|
<View
|
|
248
|
+
{...rest}
|
|
181
249
|
ref={setRef}
|
|
182
250
|
accessibilityRole="button"
|
|
183
251
|
style={[
|
|
@@ -191,11 +259,11 @@ export const ButtonComponent = ({
|
|
|
191
259
|
...(hasUnderlay && { overflow: 'hidden' }),
|
|
192
260
|
},
|
|
193
261
|
]}
|
|
262
|
+
onPointerEnter={handlePointerEnter}
|
|
194
263
|
onPointerDown={pressIn}
|
|
195
264
|
onPointerUp={pressOut}
|
|
196
265
|
onPointerCancel={pressOut}
|
|
197
|
-
onPointerLeave={
|
|
198
|
-
{...rest}>
|
|
266
|
+
onPointerLeave={handlePointerLeave}>
|
|
199
267
|
{hasUnderlay && (
|
|
200
268
|
<View
|
|
201
269
|
style={{
|
|
@@ -377,6 +377,7 @@ const LegacyPressable = (props: LegacyPressableProps) => {
|
|
|
377
377
|
<GestureDetector gesture={gesture}>
|
|
378
378
|
<NativeButton
|
|
379
379
|
{...remainingProps}
|
|
380
|
+
needsOffscreenAlphaCompositing
|
|
380
381
|
onLayout={setDimensions}
|
|
381
382
|
accessible={accessible !== false}
|
|
382
383
|
hitSlop={appliedHitSlop}
|
|
@@ -32,7 +32,8 @@ export type InnerPressableEvent = {
|
|
|
32
32
|
|
|
33
33
|
export type PressableEvent = { nativeEvent: InnerPressableEvent };
|
|
34
34
|
|
|
35
|
-
export interface LegacyPressableProps
|
|
35
|
+
export interface LegacyPressableProps
|
|
36
|
+
extends Omit<CommonPressableProps, 'needsOffscreenAlphaCompositing'> {
|
|
36
37
|
/**
|
|
37
38
|
* A gesture object or an array of gesture objects containing the configuration and callbacks to be
|
|
38
39
|
* used with the Pressable's gesture handlers.
|
|
@@ -44,6 +44,7 @@ import { MouseButton } from '../handlers/gestureHandlerCommon';
|
|
|
44
44
|
import { GestureDetector } from '../v3/detectors';
|
|
45
45
|
import type { PanGestureActiveEvent } from '../v3/hooks/gestures';
|
|
46
46
|
import { usePanGesture, useTapGesture } from '../v3/hooks/gestures';
|
|
47
|
+
import type { WithSharedValue } from '../v3/types';
|
|
47
48
|
|
|
48
49
|
const DRAG_TOSS = 0.05;
|
|
49
50
|
|
|
@@ -75,7 +76,7 @@ export enum DrawerKeyboardDismissMode {
|
|
|
75
76
|
ON_DRAG,
|
|
76
77
|
}
|
|
77
78
|
|
|
78
|
-
export
|
|
79
|
+
export type DrawerLayoutProps = {
|
|
79
80
|
/**
|
|
80
81
|
* This attribute is present in the native android implementation already and is one
|
|
81
82
|
* of the required params. The gesture handler version of DrawerLayout makes it
|
|
@@ -193,14 +194,6 @@ export interface DrawerLayoutProps {
|
|
|
193
194
|
*/
|
|
194
195
|
drawerContainerStyle?: StyleProp<ViewStyle>;
|
|
195
196
|
|
|
196
|
-
/**
|
|
197
|
-
* Enables two-finger gestures on supported devices, for example iPads with
|
|
198
|
-
* trackpads. If not enabled the gesture will require click + drag, with
|
|
199
|
-
* `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger
|
|
200
|
-
* the gesture.
|
|
201
|
-
*/
|
|
202
|
-
enableTrackpadTwoFingerGesture?: boolean;
|
|
203
|
-
|
|
204
197
|
onDrawerSlide?: (position: number) => void;
|
|
205
198
|
|
|
206
199
|
// Implicit `children` prop has been removed in @types/react^18.0.
|
|
@@ -216,25 +209,36 @@ export interface DrawerLayoutProps {
|
|
|
216
209
|
*/
|
|
217
210
|
userSelect?: UserSelect;
|
|
218
211
|
|
|
219
|
-
/**
|
|
220
|
-
* @default 'auto'
|
|
221
|
-
* Sets the displayed cursor pictogram when the drawer is being dragged.
|
|
222
|
-
* Values: see CSS cursor values
|
|
223
|
-
*/
|
|
224
|
-
activeCursor?: ActiveCursor;
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* @default 'MouseButton.LEFT'
|
|
228
|
-
* Allows to choose which mouse button should underlying pan handler react to.
|
|
229
|
-
*/
|
|
230
|
-
mouseButton?: MouseButton;
|
|
231
|
-
|
|
232
212
|
/**
|
|
233
213
|
* @default 'false if MouseButton.RIGHT is specified'
|
|
234
214
|
* Allows to enable/disable context menu.
|
|
235
215
|
*/
|
|
236
216
|
enableContextMenu?: boolean;
|
|
237
|
-
}
|
|
217
|
+
} & WithSharedValue<
|
|
218
|
+
{
|
|
219
|
+
/**
|
|
220
|
+
* Enables two-finger gestures on supported devices, for example iPads with
|
|
221
|
+
* trackpads. If not enabled the gesture will require click + drag, with
|
|
222
|
+
* `enableTrackpadTwoFingerGesture` swiping with two fingers will also trigger
|
|
223
|
+
* the gesture.
|
|
224
|
+
*/
|
|
225
|
+
enableTrackpadTwoFingerGesture?: boolean;
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* @default 'auto'
|
|
229
|
+
* Sets the displayed cursor pictogram when the drawer is being dragged.
|
|
230
|
+
* Values: see CSS cursor values
|
|
231
|
+
*/
|
|
232
|
+
activeCursor?: ActiveCursor;
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* @default 'MouseButton.LEFT'
|
|
236
|
+
* Allows to choose which mouse button should underlying pan handler react to.
|
|
237
|
+
*/
|
|
238
|
+
mouseButton?: MouseButton;
|
|
239
|
+
},
|
|
240
|
+
ActiveCursor | MouseButton
|
|
241
|
+
>;
|
|
238
242
|
|
|
239
243
|
export type DrawerMovementOption = {
|
|
240
244
|
initialVelocity?: number;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import type { ForwardedRef } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import React, {
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useImperativeHandle,
|
|
6
|
+
useMemo,
|
|
7
|
+
} from 'react';
|
|
3
8
|
import type { LayoutChangeEvent } from 'react-native';
|
|
4
9
|
import { I18nManager, StyleSheet, View } from 'react-native';
|
|
5
10
|
import Animated, {
|
|
@@ -14,9 +19,16 @@ import Animated, {
|
|
|
14
19
|
withSpring,
|
|
15
20
|
} from 'react-native-reanimated';
|
|
16
21
|
|
|
22
|
+
import { Reanimated } from '../../handlers/gestures/reanimatedWrapper';
|
|
23
|
+
import { tagMessage } from '../../utils';
|
|
17
24
|
import { GestureDetector } from '../../v3/detectors';
|
|
18
25
|
import type { PanGestureActiveEvent } from '../../v3/hooks/gestures';
|
|
19
26
|
import { usePanGesture, useTapGesture } from '../../v3/hooks/gestures';
|
|
27
|
+
import {
|
|
28
|
+
maybeUnpackValue,
|
|
29
|
+
SHARED_VALUE_OFFSET,
|
|
30
|
+
} from '../../v3/hooks/utils/reanimatedUtils';
|
|
31
|
+
import type { SharedValueOrT } from '../../v3/types';
|
|
20
32
|
import type {
|
|
21
33
|
SwipeableMethods,
|
|
22
34
|
SwipeableProps,
|
|
@@ -44,8 +56,8 @@ const Swipeable = (props: SwipeableProps) => {
|
|
|
44
56
|
testID,
|
|
45
57
|
children,
|
|
46
58
|
enableTrackpadTwoFingerGesture = DEFAULT_ENABLE_TRACKING_TWO_FINGER_GESTURE,
|
|
47
|
-
|
|
48
|
-
|
|
59
|
+
dragOffsetFromLeft = DEFAULT_DRAG_OFFSET,
|
|
60
|
+
dragOffsetFromRight = -DEFAULT_DRAG_OFFSET,
|
|
49
61
|
friction = DEFAULT_FRICTION,
|
|
50
62
|
overshootFriction = DEFAULT_OVERSHOOT_FRICTION,
|
|
51
63
|
onSwipeableOpenStartDrag,
|
|
@@ -63,6 +75,40 @@ const Swipeable = (props: SwipeableProps) => {
|
|
|
63
75
|
...remainingProps
|
|
64
76
|
} = props;
|
|
65
77
|
|
|
78
|
+
if (__DEV__) {
|
|
79
|
+
const checkValue = (value: SharedValueOrT<number>) => {
|
|
80
|
+
'worklet';
|
|
81
|
+
if (maybeUnpackValue<number>(value) > 0) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
tagMessage('dragOffsetFromRight should be non-positive.')
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
checkValue(dragOffsetFromRight);
|
|
89
|
+
|
|
90
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!Reanimated?.isSharedValue<number>(dragOffsetFromRight)) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const listenerId = Math.random() + SHARED_VALUE_OFFSET;
|
|
97
|
+
|
|
98
|
+
Reanimated?.runOnUI(() => {
|
|
99
|
+
'worklet';
|
|
100
|
+
dragOffsetFromRight.addListener(listenerId, checkValue);
|
|
101
|
+
})();
|
|
102
|
+
|
|
103
|
+
return () => {
|
|
104
|
+
Reanimated?.runOnUI(() => {
|
|
105
|
+
'worklet';
|
|
106
|
+
dragOffsetFromRight.removeListener(listenerId);
|
|
107
|
+
})();
|
|
108
|
+
};
|
|
109
|
+
}, [dragOffsetFromRight, checkValue]);
|
|
110
|
+
}
|
|
111
|
+
|
|
66
112
|
const shouldEnableTap = useSharedValue<boolean>(false);
|
|
67
113
|
const rowState = useSharedValue<number>(0);
|
|
68
114
|
|
|
@@ -468,9 +514,9 @@ const Swipeable = (props: SwipeableProps) => {
|
|
|
468
514
|
});
|
|
469
515
|
|
|
470
516
|
const panGesture = usePanGesture({
|
|
471
|
-
enabled: enabled
|
|
517
|
+
enabled: enabled ?? true,
|
|
472
518
|
enableTrackpadTwoFingerGesture: enableTrackpadTwoFingerGesture,
|
|
473
|
-
activeOffsetX: [
|
|
519
|
+
activeOffsetX: [dragOffsetFromRight, dragOffsetFromLeft],
|
|
474
520
|
simultaneousWith,
|
|
475
521
|
requireToFail,
|
|
476
522
|
block,
|