react-native-gesture-handler 2.18.0 → 2.19.0
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +1 -0
- package/android/build.gradle +4 -17
- package/android/src/main/AndroidManifest.xml +1 -3
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +21 -21
- package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +2 -2
- package/android/src/main/java/com/swmansion/gesturehandler/core/HoverGestureHandler.kt +5 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +80 -4
- package/android/src/main/java/com/swmansion/gesturehandler/core/PinchGestureHandler.kt +2 -1
- package/android/src/main/java/com/swmansion/gesturehandler/core/ScaleGestureDetector.java +10 -0
- package/android/src/main/java/com/swmansion/gesturehandler/core/Vector.kt +2 -2
- package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +3 -0
- package/android/src/main/jni/cpp-adapter.cpp +2 -4
- package/apple/Handlers/RNFlingHandler.h +1 -0
- package/apple/Handlers/RNFlingHandler.m +153 -19
- package/apple/Handlers/RNHoverHandler.m +44 -2
- package/apple/Handlers/RNLongPressHandler.m +109 -20
- package/apple/Handlers/RNManualHandler.m +53 -29
- package/apple/Handlers/RNNativeViewHandler.mm +22 -15
- package/apple/RNGHUIKit.h +2 -0
- package/apple/RNGHVector.h +31 -0
- package/apple/RNGHVector.m +67 -0
- package/apple/RNGestureHandler.h +7 -0
- package/apple/{RNGestureHandler.m → RNGestureHandler.mm} +63 -1
- package/apple/RNGestureHandlerButtonComponentView.mm +6 -0
- package/apple/RNGestureHandlerDirection.h +25 -0
- package/apple/RNGestureHandlerModule.mm +2 -4
- package/lib/commonjs/PointerType.js +2 -1
- package/lib/commonjs/PointerType.js.map +1 -1
- package/lib/commonjs/components/Pressable/Pressable.js +67 -70
- package/lib/commonjs/components/Pressable/Pressable.js.map +1 -1
- package/lib/commonjs/components/Pressable/index.js +0 -8
- package/lib/commonjs/components/Pressable/index.js.map +1 -1
- package/lib/commonjs/components/ReanimatedSwipeable.js +60 -41
- package/lib/commonjs/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/commonjs/components/Swipeable.js +5 -0
- package/lib/commonjs/components/Swipeable.js.map +1 -1
- package/lib/commonjs/handlers/LongPressGestureHandler.js +1 -1
- package/lib/commonjs/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/utils.js +1 -1
- package/lib/commonjs/handlers/gestures/GestureDetector/utils.js.map +1 -1
- package/lib/commonjs/handlers/gestures/longPressGesture.js +10 -0
- package/lib/commonjs/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/commonjs/mocks.js +16 -3
- package/lib/commonjs/mocks.js.map +1 -1
- package/lib/commonjs/utils.js +4 -0
- package/lib/commonjs/utils.js.map +1 -1
- package/lib/commonjs/web/constants.js +3 -3
- package/lib/commonjs/web/constants.js.map +1 -1
- package/lib/commonjs/web/handlers/GestureHandler.js +1 -0
- package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js +43 -9
- package/lib/commonjs/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +14 -3
- package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/commonjs/web/handlers/PanGestureHandler.js +4 -0
- package/lib/commonjs/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/commonjs/web/interfaces.js.map +1 -1
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +55 -8
- package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/commonjs/web/tools/KeyboardEventManager.js +110 -0
- package/lib/commonjs/web/tools/KeyboardEventManager.js.map +1 -0
- package/lib/commonjs/web/tools/Vector.js +4 -2
- package/lib/commonjs/web/tools/Vector.js.map +1 -1
- package/lib/commonjs/web/utils.js +14 -13
- package/lib/commonjs/web/utils.js.map +1 -1
- package/lib/module/PointerType.js +2 -1
- package/lib/module/PointerType.js.map +1 -1
- package/lib/module/components/Pressable/Pressable.js +66 -70
- package/lib/module/components/Pressable/Pressable.js.map +1 -1
- package/lib/module/components/Pressable/index.js +0 -1
- package/lib/module/components/Pressable/index.js.map +1 -1
- package/lib/module/components/ReanimatedSwipeable.js +58 -37
- package/lib/module/components/ReanimatedSwipeable.js.map +1 -1
- package/lib/module/components/Swipeable.js +6 -0
- package/lib/module/components/Swipeable.js.map +1 -1
- package/lib/module/handlers/LongPressGestureHandler.js +1 -1
- package/lib/module/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/handlers/gestures/GestureDetector/utils.js +2 -2
- package/lib/module/handlers/gestures/GestureDetector/utils.js.map +1 -1
- package/lib/module/handlers/gestures/longPressGesture.js +10 -0
- package/lib/module/handlers/gestures/longPressGesture.js.map +1 -1
- package/lib/module/mocks.js +13 -3
- package/lib/module/mocks.js.map +1 -1
- package/lib/module/utils.js +1 -0
- package/lib/module/utils.js.map +1 -1
- package/lib/module/web/constants.js +1 -1
- package/lib/module/web/constants.js.map +1 -1
- package/lib/module/web/handlers/GestureHandler.js +1 -0
- package/lib/module/web/handlers/GestureHandler.js.map +1 -1
- package/lib/module/web/handlers/LongPressGestureHandler.js +43 -9
- package/lib/module/web/handlers/LongPressGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/NativeViewGestureHandler.js +14 -3
- package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
- package/lib/module/web/handlers/PanGestureHandler.js +4 -0
- package/lib/module/web/handlers/PanGestureHandler.js.map +1 -1
- package/lib/module/web/interfaces.js.map +1 -1
- package/lib/module/web/tools/GestureHandlerWebDelegate.js +54 -8
- package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
- package/lib/module/web/tools/KeyboardEventManager.js +96 -0
- package/lib/module/web/tools/KeyboardEventManager.js.map +1 -0
- package/lib/module/web/tools/Vector.js +5 -3
- package/lib/module/web/tools/Vector.js.map +1 -1
- package/lib/module/web/utils.js +14 -13
- package/lib/module/web/utils.js.map +1 -1
- package/lib/typescript/PointerType.d.ts +2 -1
- package/lib/typescript/components/Pressable/index.d.ts +1 -1
- package/lib/typescript/components/Swipeable.d.ts +5 -0
- package/lib/typescript/handlers/LongPressGestureHandler.d.ts +5 -1
- package/lib/typescript/handlers/gestures/longPressGesture.d.ts +5 -0
- package/lib/typescript/mocks.d.ts +4 -3
- package/lib/typescript/utils.d.ts +1 -0
- package/lib/typescript/web/constants.d.ts +1 -1
- package/lib/typescript/web/handlers/GestureHandler.d.ts +1 -1
- package/lib/typescript/web/handlers/LongPressGestureHandler.d.ts +3 -0
- package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
- package/lib/typescript/web/interfaces.d.ts +1 -1
- package/lib/typescript/web/tools/GestureHandlerDelegate.d.ts +1 -0
- package/lib/typescript/web/tools/GestureHandlerWebDelegate.d.ts +6 -0
- package/lib/typescript/web/tools/KeyboardEventManager.d.ts +13 -0
- package/package.json +3 -3
- package/src/PointerType.ts +1 -0
- package/src/components/Pressable/Pressable.tsx +70 -50
- package/src/components/Pressable/index.ts +1 -1
- package/src/components/ReanimatedSwipeable.tsx +70 -47
- package/src/components/Swipeable.tsx +6 -0
- package/src/handlers/LongPressGestureHandler.ts +6 -0
- package/src/handlers/gestures/GestureDetector/utils.ts +2 -2
- package/src/handlers/gestures/longPressGesture.ts +9 -0
- package/src/{mocks.ts → mocks.tsx} +8 -3
- package/src/utils.ts +2 -0
- package/src/web/constants.ts +1 -1
- package/src/web/handlers/GestureHandler.ts +3 -1
- package/src/web/handlers/LongPressGestureHandler.ts +49 -10
- package/src/web/handlers/NativeViewGestureHandler.ts +14 -4
- package/src/web/handlers/PanGestureHandler.ts +4 -0
- package/src/web/interfaces.ts +1 -1
- package/src/web/tools/GestureHandlerDelegate.ts +1 -0
- package/src/web/tools/GestureHandlerWebDelegate.ts +67 -8
- package/src/web/tools/KeyboardEventManager.ts +91 -0
- package/src/web/tools/Vector.ts +4 -3
- package/src/web/utils.ts +15 -13
@@ -1,2 +1,2 @@
|
|
1
1
|
export declare const DEFAULT_TOUCH_SLOP = 15;
|
2
|
-
export declare const
|
2
|
+
export declare const MINIMAL_RECOGNIZABLE_MAGNITUDE = 0.1;
|
@@ -3,10 +3,10 @@ import { State } from '../../State';
|
|
3
3
|
import { Config, AdaptedEvent } from '../interfaces';
|
4
4
|
import EventManager from '../tools/EventManager';
|
5
5
|
import PointerTracker from '../tools/PointerTracker';
|
6
|
-
import { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
|
7
6
|
import IGestureHandler from './IGestureHandler';
|
8
7
|
import { MouseButton } from '../../handlers/gestureHandlerCommon';
|
9
8
|
import { PointerType } from '../../PointerType';
|
9
|
+
import { GestureHandlerDelegate } from '../tools/GestureHandlerDelegate';
|
10
10
|
export default abstract class GestureHandler implements IGestureHandler {
|
11
11
|
private lastSentState;
|
12
12
|
protected currentState: State;
|
@@ -6,6 +6,7 @@ export default class LongPressGestureHandler extends GestureHandler {
|
|
6
6
|
private minDurationMs;
|
7
7
|
private defaultMaxDistSq;
|
8
8
|
private maxDistSq;
|
9
|
+
private numberOfPointers;
|
9
10
|
private startX;
|
10
11
|
private startY;
|
11
12
|
private startTime;
|
@@ -19,8 +20,10 @@ export default class LongPressGestureHandler extends GestureHandler {
|
|
19
20
|
protected resetConfig(): void;
|
20
21
|
protected onStateChange(_newState: State, _oldState: State): void;
|
21
22
|
protected onPointerDown(event: AdaptedEvent): void;
|
23
|
+
protected onPointerAdd(event: AdaptedEvent): void;
|
22
24
|
protected onPointerMove(event: AdaptedEvent): void;
|
23
25
|
protected onPointerUp(event: AdaptedEvent): void;
|
26
|
+
protected onPointerRemove(event: AdaptedEvent): void;
|
24
27
|
private tryBegin;
|
25
28
|
private tryActivate;
|
26
29
|
private checkDistanceFail;
|
@@ -10,6 +10,7 @@ export default class NativeViewGestureHandler extends GestureHandler {
|
|
10
10
|
private minDistSq;
|
11
11
|
init(ref: number, propsRef: React.RefObject<unknown>): void;
|
12
12
|
updateGestureConfig({ enabled, ...props }: Config): void;
|
13
|
+
private restoreViewStyles;
|
13
14
|
protected resetConfig(): void;
|
14
15
|
protected onPointerDown(event: AdaptedEvent): void;
|
15
16
|
protected onPointerAdd(event: AdaptedEvent): void;
|
@@ -17,7 +17,7 @@ export interface Handler {
|
|
17
17
|
}
|
18
18
|
type ConfigArgs = number | boolean | HitSlop | UserSelect | TouchAction | ActiveCursor | Directions | Handler[] | null | undefined;
|
19
19
|
export interface Config extends Record<string, ConfigArgs> {
|
20
|
-
enabled
|
20
|
+
enabled: boolean;
|
21
21
|
simultaneousHandlers?: Handler[] | null;
|
22
22
|
waitFor?: Handler[] | null;
|
23
23
|
blocksHandlers?: Handler[] | null;
|
@@ -2,9 +2,11 @@ import type IGestureHandler from '../handlers/IGestureHandler';
|
|
2
2
|
import { GestureHandlerDelegate, MeasureResult } from './GestureHandlerDelegate';
|
3
3
|
import { Config } from '../interfaces';
|
4
4
|
export declare class GestureHandlerWebDelegate implements GestureHandlerDelegate<HTMLElement, IGestureHandler> {
|
5
|
+
private isInitialized;
|
5
6
|
private view;
|
6
7
|
private gestureHandler;
|
7
8
|
private eventManagers;
|
9
|
+
private defaultViewStyles;
|
8
10
|
getView(): HTMLElement;
|
9
11
|
init(viewRef: number, handler: IGestureHandler): void;
|
10
12
|
isPointerInBounds({ x, y }: {
|
@@ -19,6 +21,10 @@ export declare class GestureHandlerWebDelegate implements GestureHandlerDelegate
|
|
19
21
|
private removeContextMenuListeners;
|
20
22
|
private disableContextMenu;
|
21
23
|
private enableContextMenu;
|
24
|
+
private setUserSelect;
|
25
|
+
private setTouchAction;
|
26
|
+
private setContextMenu;
|
27
|
+
onEnabledChange(enabled: boolean): void;
|
22
28
|
onBegin(): void;
|
23
29
|
onActivate(): void;
|
24
30
|
onEnd(): void;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { AdaptedEvent, EventTypes } from '../interfaces';
|
2
|
+
import EventManager from './EventManager';
|
3
|
+
export default class KeyboardEventManager extends EventManager<HTMLElement> {
|
4
|
+
private activationKeys;
|
5
|
+
private cancelationKeys;
|
6
|
+
private isPressed;
|
7
|
+
private keyDownCallback;
|
8
|
+
private keyUpCallback;
|
9
|
+
private dispatchEvent;
|
10
|
+
registerListeners(): void;
|
11
|
+
unregisterListeners(): void;
|
12
|
+
protected mapEvent(event: KeyboardEvent, eventType: EventTypes): AdaptedEvent;
|
13
|
+
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "react-native-gesture-handler",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.19.0",
|
4
4
|
"description": "Experimental implementation of a new declarative API for gesture handling in react-native",
|
5
5
|
"scripts": {
|
6
6
|
"prepare": "bob build && husky install",
|
@@ -11,7 +11,7 @@
|
|
11
11
|
"ts-check": "yarn tsc --noEmit",
|
12
12
|
"format:js": "prettier --write --list-different './{src,example,FabricExample,MacOSExample}/**/*.{js,jsx,ts,tsx}'",
|
13
13
|
"format:android": "node ./scripts/format-android.js",
|
14
|
-
"format:
|
14
|
+
"format:apple": "find apple/ -iname *.h -o -iname *.m -o -iname *.cpp -o -iname *.mm | xargs clang-format -i",
|
15
15
|
"lint:js": "eslint --ext '.js,.ts,.tsx' src/ example/src FabricExample/src MacOSExample/src && yarn prettier --check './{src,example,FabricExample,MacOSExample}/**/*.{js,jsx,ts,tsx}'",
|
16
16
|
"lint:js-root": "eslint --ext '.js,.ts,.tsx' src/ && yarn prettier --check './src/**/*.{js,jsx,ts,tsx}'",
|
17
17
|
"lint:android": "./android/gradlew -p android spotlessCheck -q",
|
@@ -114,7 +114,7 @@
|
|
114
114
|
"lint-staged": {
|
115
115
|
"./{src,example,FabricExample,MacOSExample}/**/*.{ts,tsx}": "yarn format:js",
|
116
116
|
"android/**/*.kt": "yarn format:android",
|
117
|
-
"apple/**/*.{h,m,mm,cpp}": "yarn format:
|
117
|
+
"apple/**/*.{h,m,mm,cpp}": "yarn format:apple",
|
118
118
|
"src/specs/*.ts": "yarn sync-architectures"
|
119
119
|
},
|
120
120
|
"release-it": {
|
package/src/PointerType.ts
CHANGED
@@ -22,13 +22,34 @@ import {
|
|
22
22
|
} from './utils';
|
23
23
|
import { PressabilityDebugView } from '../../handlers/PressabilityDebugView';
|
24
24
|
import { GestureTouchEvent } from '../../handlers/gestureHandlerCommon';
|
25
|
+
import { INT32_MAX } from '../../utils';
|
25
26
|
|
26
27
|
const DEFAULT_LONG_PRESS_DURATION = 500;
|
27
28
|
|
28
29
|
export default function Pressable(props: PressableProps) {
|
29
|
-
const
|
30
|
-
|
31
|
-
|
30
|
+
const {
|
31
|
+
testOnly_pressed,
|
32
|
+
hitSlop,
|
33
|
+
pressRetentionOffset,
|
34
|
+
delayHoverIn,
|
35
|
+
onHoverIn,
|
36
|
+
delayHoverOut,
|
37
|
+
onHoverOut,
|
38
|
+
delayLongPress,
|
39
|
+
unstable_pressDelay,
|
40
|
+
onPress,
|
41
|
+
onPressIn,
|
42
|
+
onPressOut,
|
43
|
+
onLongPress,
|
44
|
+
style,
|
45
|
+
children,
|
46
|
+
android_disableSound,
|
47
|
+
android_ripple,
|
48
|
+
disabled,
|
49
|
+
...remainingProps
|
50
|
+
} = props;
|
51
|
+
|
52
|
+
const [pressedState, setPressedState] = useState(testOnly_pressed ?? false);
|
32
53
|
|
33
54
|
const pressableRef = useRef<View>(null);
|
34
55
|
|
@@ -39,18 +60,16 @@ export default function Pressable(props: PressableProps) {
|
|
39
60
|
|
40
61
|
const normalizedHitSlop: Insets = useMemo(
|
41
62
|
() =>
|
42
|
-
typeof
|
43
|
-
|
44
|
-
: props.hitSlop ?? {},
|
45
|
-
[props.hitSlop]
|
63
|
+
typeof hitSlop === 'number' ? numberAsInset(hitSlop) : hitSlop ?? {},
|
64
|
+
[hitSlop]
|
46
65
|
);
|
47
66
|
|
48
67
|
const normalizedPressRetentionOffset: Insets = useMemo(
|
49
68
|
() =>
|
50
|
-
typeof
|
51
|
-
? numberAsInset(
|
52
|
-
:
|
53
|
-
[
|
69
|
+
typeof pressRetentionOffset === 'number'
|
70
|
+
? numberAsInset(pressRetentionOffset)
|
71
|
+
: pressRetentionOffset ?? {},
|
72
|
+
[pressRetentionOffset]
|
54
73
|
);
|
55
74
|
|
56
75
|
const hoverInTimeout = useRef<number | null>(null);
|
@@ -65,29 +84,29 @@ export default function Pressable(props: PressableProps) {
|
|
65
84
|
if (hoverOutTimeout.current) {
|
66
85
|
clearTimeout(hoverOutTimeout.current);
|
67
86
|
}
|
68
|
-
if (
|
87
|
+
if (delayHoverIn) {
|
69
88
|
hoverInTimeout.current = setTimeout(
|
70
|
-
() =>
|
71
|
-
|
89
|
+
() => onHoverIn?.(gestureToPressableEvent(event)),
|
90
|
+
delayHoverIn
|
72
91
|
);
|
73
92
|
return;
|
74
93
|
}
|
75
|
-
|
94
|
+
onHoverIn?.(gestureToPressableEvent(event));
|
76
95
|
})
|
77
96
|
.onFinalize((event) => {
|
78
97
|
if (hoverInTimeout.current) {
|
79
98
|
clearTimeout(hoverInTimeout.current);
|
80
99
|
}
|
81
|
-
if (
|
100
|
+
if (delayHoverOut) {
|
82
101
|
hoverOutTimeout.current = setTimeout(
|
83
|
-
() =>
|
84
|
-
|
102
|
+
() => onHoverOut?.(gestureToPressableEvent(event)),
|
103
|
+
delayHoverOut
|
85
104
|
);
|
86
105
|
return;
|
87
106
|
}
|
88
|
-
|
107
|
+
onHoverOut?.(gestureToPressableEvent(event));
|
89
108
|
}),
|
90
|
-
[
|
109
|
+
[delayHoverIn, delayHoverOut, onHoverIn, onHoverOut]
|
91
110
|
);
|
92
111
|
|
93
112
|
const pressDelayTimeoutRef = useRef<number | null>(null);
|
@@ -108,12 +127,12 @@ export default function Pressable(props: PressableProps) {
|
|
108
127
|
|
109
128
|
deferredEventPayload.current = null;
|
110
129
|
|
111
|
-
|
130
|
+
onPressIn?.(event);
|
112
131
|
isPressCallbackEnabled.current = true;
|
113
132
|
pressDelayTimeoutRef.current = null;
|
114
133
|
setPressedState(true);
|
115
134
|
},
|
116
|
-
[
|
135
|
+
[onPressIn]
|
117
136
|
);
|
118
137
|
|
119
138
|
const pressOutHandler = useCallback(
|
@@ -126,7 +145,7 @@ export default function Pressable(props: PressableProps) {
|
|
126
145
|
return;
|
127
146
|
}
|
128
147
|
|
129
|
-
if (
|
148
|
+
if (unstable_pressDelay && pressDelayTimeoutRef.current !== null) {
|
130
149
|
// When delay is preemptively finished by lifting touches,
|
131
150
|
// we want to immediately activate it's effects - pressInHandler,
|
132
151
|
// even though we are located at the pressOutHandler
|
@@ -135,14 +154,14 @@ export default function Pressable(props: PressableProps) {
|
|
135
154
|
}
|
136
155
|
|
137
156
|
if (deferredEventPayload.current) {
|
138
|
-
|
157
|
+
onPressIn?.(deferredEventPayload.current);
|
139
158
|
deferredEventPayload.current = null;
|
140
159
|
}
|
141
160
|
|
142
|
-
|
161
|
+
onPressOut?.(event);
|
143
162
|
|
144
163
|
if (isPressCallbackEnabled.current) {
|
145
|
-
|
164
|
+
onPress?.(event);
|
146
165
|
}
|
147
166
|
|
148
167
|
if (longPressTimeoutRef.current) {
|
@@ -155,7 +174,7 @@ export default function Pressable(props: PressableProps) {
|
|
155
174
|
isPressCallbackEnabled.current = true;
|
156
175
|
setPressedState(false);
|
157
176
|
},
|
158
|
-
[pressInHandler,
|
177
|
+
[onPress, onPressIn, onPressOut, pressInHandler, unstable_pressDelay]
|
159
178
|
);
|
160
179
|
|
161
180
|
const handlingOnTouchesDown = useRef<boolean>(false);
|
@@ -169,7 +188,7 @@ export default function Pressable(props: PressableProps) {
|
|
169
188
|
}
|
170
189
|
|
171
190
|
if (hasPassedBoundsChecks.current) {
|
172
|
-
|
191
|
+
onLongPress?.(gestureTouchToPressableEvent(event));
|
173
192
|
isPressCallbackEnabled.current = false;
|
174
193
|
}
|
175
194
|
|
@@ -178,19 +197,19 @@ export default function Pressable(props: PressableProps) {
|
|
178
197
|
longPressTimeoutRef.current = null;
|
179
198
|
}
|
180
199
|
},
|
181
|
-
[
|
200
|
+
[onLongPress]
|
182
201
|
);
|
183
202
|
|
184
203
|
const longPressTimeoutRef = useRef<number | null>(null);
|
185
204
|
const longPressMinDuration =
|
186
|
-
(
|
187
|
-
(
|
205
|
+
(delayLongPress ?? DEFAULT_LONG_PRESS_DURATION) +
|
206
|
+
(unstable_pressDelay ?? 0);
|
188
207
|
|
189
208
|
const pressAndTouchGesture = useMemo(
|
190
209
|
() =>
|
191
210
|
Gesture.LongPress()
|
192
|
-
.minDuration(
|
193
|
-
.maxDistance(
|
211
|
+
.minDuration(INT32_MAX) // Stops long press from blocking native gesture
|
212
|
+
.maxDistance(INT32_MAX) // Stops long press from cancelling after set distance
|
194
213
|
.cancelsTouchesInView(false)
|
195
214
|
.onTouchesDown((event) => {
|
196
215
|
handlingOnTouchesDown.current = true;
|
@@ -224,10 +243,10 @@ export default function Pressable(props: PressableProps) {
|
|
224
243
|
);
|
225
244
|
}
|
226
245
|
|
227
|
-
if (
|
246
|
+
if (unstable_pressDelay) {
|
228
247
|
pressDelayTimeoutRef.current = setTimeout(() => {
|
229
248
|
pressInHandler(gestureTouchToPressableEvent(event));
|
230
|
-
},
|
249
|
+
}, unstable_pressDelay);
|
231
250
|
} else {
|
232
251
|
pressInHandler(gestureTouchToPressableEvent(event));
|
233
252
|
}
|
@@ -275,7 +294,7 @@ export default function Pressable(props: PressableProps) {
|
|
275
294
|
normalizedHitSlop,
|
276
295
|
pressInHandler,
|
277
296
|
pressOutHandler,
|
278
|
-
|
297
|
+
unstable_pressDelay,
|
279
298
|
]
|
280
299
|
);
|
281
300
|
|
@@ -333,7 +352,7 @@ export default function Pressable(props: PressableProps) {
|
|
333
352
|
normalizedPressRetentionOffset
|
334
353
|
);
|
335
354
|
|
336
|
-
const isPressableEnabled =
|
355
|
+
const isPressableEnabled = disabled !== true;
|
337
356
|
|
338
357
|
const gestures = [pressAndTouchGesture, hoverGesture, buttonGesture];
|
339
358
|
|
@@ -353,40 +372,41 @@ export default function Pressable(props: PressableProps) {
|
|
353
372
|
|
354
373
|
const gesture = Gesture.Simultaneous(...gestures);
|
355
374
|
|
356
|
-
const defaultRippleColor =
|
375
|
+
const defaultRippleColor = android_ripple ? undefined : 'transparent';
|
357
376
|
|
358
377
|
// `cursor: 'pointer'` on `RNButton` crashes iOS
|
359
378
|
const pointerStyle: StyleProp<ViewStyle> =
|
360
379
|
Platform.OS === 'web' ? { cursor: 'pointer' } : {};
|
361
380
|
|
362
381
|
const styleProp =
|
363
|
-
typeof
|
364
|
-
? props.style({ pressed: pressedState })
|
365
|
-
: props.style;
|
382
|
+
typeof style === 'function' ? style({ pressed: pressedState }) : style;
|
366
383
|
|
367
384
|
const childrenProp =
|
368
|
-
typeof
|
369
|
-
?
|
370
|
-
:
|
385
|
+
typeof children === 'function'
|
386
|
+
? children({ pressed: pressedState })
|
387
|
+
: children;
|
371
388
|
|
372
389
|
const flattenedStyles = StyleSheet.flatten(styleProp ?? {});
|
373
390
|
|
374
391
|
const [innerStyles, outerStyles] = splitStyles(flattenedStyles);
|
375
392
|
|
376
393
|
return (
|
377
|
-
<View style={outerStyles}>
|
394
|
+
<View {...remainingProps} style={outerStyles}>
|
378
395
|
<GestureDetector gesture={gesture}>
|
379
396
|
<NativeButton
|
380
397
|
ref={pressableRef}
|
381
|
-
testID={props.testID}
|
382
398
|
hitSlop={appliedHitSlop}
|
383
399
|
enabled={isPressableEnabled}
|
384
|
-
touchSoundDisabled={
|
400
|
+
touchSoundDisabled={android_disableSound ?? undefined}
|
385
401
|
rippleColor={processColor(
|
386
|
-
|
402
|
+
android_ripple?.color ?? defaultRippleColor
|
387
403
|
)}
|
388
|
-
rippleRadius={
|
389
|
-
style={[
|
404
|
+
rippleRadius={android_ripple?.radius ?? undefined}
|
405
|
+
style={[
|
406
|
+
{ width: '100%', height: '100%' },
|
407
|
+
pointerStyle,
|
408
|
+
innerStyles,
|
409
|
+
]}>
|
390
410
|
{childrenProp}
|
391
411
|
{__DEV__ ? (
|
392
412
|
<PressabilityDebugView color="red" hitSlop={normalizedHitSlop} />
|
@@ -1,2 +1,2 @@
|
|
1
|
-
export { PressableProps } from './PressableProps';
|
1
|
+
export type { PressableProps } from './PressableProps';
|
2
2
|
export { default } from './Pressable';
|
@@ -199,6 +199,26 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
199
199
|
props: SwipeableProps,
|
200
200
|
ref: ForwardedRef<SwipeableMethods>
|
201
201
|
) {
|
202
|
+
const {
|
203
|
+
leftThreshold,
|
204
|
+
rightThreshold,
|
205
|
+
onSwipeableOpenStartDrag,
|
206
|
+
onSwipeableCloseStartDrag,
|
207
|
+
enableTrackpadTwoFingerGesture,
|
208
|
+
enabled,
|
209
|
+
containerStyle,
|
210
|
+
childrenContainerStyle,
|
211
|
+
animationOptions,
|
212
|
+
overshootLeft,
|
213
|
+
overshootRight,
|
214
|
+
onSwipeableWillOpen,
|
215
|
+
onSwipeableWillClose,
|
216
|
+
onSwipeableOpen,
|
217
|
+
onSwipeableClose,
|
218
|
+
testID,
|
219
|
+
...remainingProps
|
220
|
+
} = props;
|
221
|
+
|
202
222
|
const rowState = useSharedValue<number>(0);
|
203
223
|
|
204
224
|
const userDrag = useSharedValue<number>(0);
|
@@ -240,8 +260,8 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
240
260
|
overshootFriction = defaultProps.overshootFriction,
|
241
261
|
} = props;
|
242
262
|
|
243
|
-
const overshootLeftProp =
|
244
|
-
const overshootRightProp =
|
263
|
+
const overshootLeftProp = overshootLeft;
|
264
|
+
const overshootRightProp = overshootRight;
|
245
265
|
|
246
266
|
const calculateCurrentOffset = useCallback(() => {
|
247
267
|
'worklet';
|
@@ -317,45 +337,40 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
317
337
|
|
318
338
|
const dispatchImmediateEvents = useCallback(
|
319
339
|
(fromValue: number, toValue: number) => {
|
320
|
-
if (toValue > 0 &&
|
321
|
-
|
322
|
-
} else if (toValue < 0 &&
|
323
|
-
|
324
|
-
} else if (
|
340
|
+
if (toValue > 0 && onSwipeableWillOpen) {
|
341
|
+
onSwipeableWillOpen('left');
|
342
|
+
} else if (toValue < 0 && onSwipeableWillOpen) {
|
343
|
+
onSwipeableWillOpen('right');
|
344
|
+
} else if (onSwipeableWillClose) {
|
325
345
|
const closingDirection = fromValue > 0 ? 'left' : 'right';
|
326
|
-
|
346
|
+
onSwipeableWillClose(closingDirection);
|
327
347
|
}
|
328
348
|
},
|
329
|
-
[
|
330
|
-
props,
|
331
|
-
props.onSwipeableWillClose,
|
332
|
-
props.onSwipeableWillOpen,
|
333
|
-
swipeableMethods,
|
334
|
-
]
|
349
|
+
[onSwipeableWillClose, onSwipeableWillOpen]
|
335
350
|
);
|
336
351
|
|
337
352
|
const dispatchEndEvents = useCallback(
|
338
353
|
(fromValue: number, toValue: number) => {
|
339
|
-
if (toValue > 0 &&
|
340
|
-
|
341
|
-
} else if (toValue < 0 &&
|
342
|
-
|
343
|
-
} else if (
|
354
|
+
if (toValue > 0 && onSwipeableOpen) {
|
355
|
+
onSwipeableOpen('left', swipeableMethods.current);
|
356
|
+
} else if (toValue < 0 && onSwipeableOpen) {
|
357
|
+
onSwipeableOpen('right', swipeableMethods.current);
|
358
|
+
} else if (onSwipeableClose) {
|
344
359
|
const closingDirection = fromValue > 0 ? 'left' : 'right';
|
345
|
-
|
360
|
+
onSwipeableClose(closingDirection, swipeableMethods.current);
|
346
361
|
}
|
347
362
|
},
|
348
|
-
[
|
363
|
+
[onSwipeableClose, onSwipeableOpen]
|
349
364
|
);
|
350
365
|
|
351
|
-
const animationOptionsProp =
|
366
|
+
const animationOptionsProp = animationOptions;
|
352
367
|
|
353
368
|
const animateRow = useCallback(
|
354
369
|
(fromValue: number, toValue: number, velocityX?: number) => {
|
355
370
|
'worklet';
|
356
371
|
rowState.value = Math.sign(toValue);
|
357
372
|
|
358
|
-
const
|
373
|
+
const translationSpringConfig = {
|
359
374
|
duration: 1000,
|
360
375
|
dampingRatio: 0.9,
|
361
376
|
stiffness: 500,
|
@@ -364,9 +379,14 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
364
379
|
...animationOptionsProp,
|
365
380
|
};
|
366
381
|
|
382
|
+
const progressSpringConfig = {
|
383
|
+
...translationSpringConfig,
|
384
|
+
velocity: 0,
|
385
|
+
};
|
386
|
+
|
367
387
|
appliedTranslation.value = withSpring(
|
368
388
|
toValue,
|
369
|
-
|
389
|
+
translationSpringConfig,
|
370
390
|
(isFinished) => {
|
371
391
|
if (isFinished) {
|
372
392
|
runOnJS(dispatchEndEvents)(fromValue, toValue);
|
@@ -376,23 +396,27 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
376
396
|
|
377
397
|
const progressTarget = toValue === 0 ? 0 : 1;
|
378
398
|
|
379
|
-
// Velocity is in px, while progress is in %
|
380
|
-
springConfig.velocity = 0;
|
381
|
-
|
382
399
|
showLeftProgress.value =
|
383
|
-
leftWidth.value > 0
|
400
|
+
leftWidth.value > 0
|
401
|
+
? withSpring(progressTarget, progressSpringConfig)
|
402
|
+
: 0;
|
384
403
|
showRightProgress.value =
|
385
|
-
rightWidth.value > 0
|
404
|
+
rightWidth.value > 0
|
405
|
+
? withSpring(progressTarget, progressSpringConfig)
|
406
|
+
: 0;
|
386
407
|
|
387
408
|
runOnJS(dispatchImmediateEvents)(fromValue, toValue);
|
388
409
|
},
|
389
410
|
[
|
390
|
-
|
411
|
+
rowState,
|
412
|
+
animationOptionsProp,
|
391
413
|
appliedTranslation,
|
392
|
-
|
414
|
+
showLeftProgress,
|
415
|
+
leftWidth.value,
|
416
|
+
showRightProgress,
|
417
|
+
rightWidth.value,
|
393
418
|
dispatchImmediateEvents,
|
394
|
-
|
395
|
-
rowState,
|
419
|
+
dispatchEndEvents,
|
396
420
|
]
|
397
421
|
);
|
398
422
|
|
@@ -483,8 +507,8 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
483
507
|
</Animated.View>
|
484
508
|
);
|
485
509
|
|
486
|
-
const leftThresholdProp =
|
487
|
-
const rightThresholdProp =
|
510
|
+
const leftThresholdProp = leftThreshold;
|
511
|
+
const rightThresholdProp = rightThreshold;
|
488
512
|
|
489
513
|
const handleRelease = (
|
490
514
|
event: GestureStateChangeEvent<PanGestureHandlerEventPayload>
|
@@ -535,9 +559,6 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
535
559
|
}
|
536
560
|
});
|
537
561
|
|
538
|
-
const onSwipeableOpenStartDrag = props.onSwipeableOpenStartDrag;
|
539
|
-
const onSwipeableCloseStartDrag = props.onSwipeableCloseStartDrag;
|
540
|
-
|
541
562
|
const panGesture = Gesture.Pan()
|
542
563
|
.onUpdate((event: GestureUpdateEvent<PanGestureHandlerEventPayload>) => {
|
543
564
|
userDrag.value = event.translationX;
|
@@ -564,10 +585,8 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
564
585
|
}
|
565
586
|
);
|
566
587
|
|
567
|
-
if (
|
568
|
-
panGesture.enableTrackpadTwoFingerGesture(
|
569
|
-
props.enableTrackpadTwoFingerGesture
|
570
|
-
);
|
588
|
+
if (enableTrackpadTwoFingerGesture) {
|
589
|
+
panGesture.enableTrackpadTwoFingerGesture(enableTrackpadTwoFingerGesture);
|
571
590
|
}
|
572
591
|
|
573
592
|
panGesture.activeOffsetX([
|
@@ -580,7 +599,7 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
580
599
|
swipeableMethods,
|
581
600
|
]);
|
582
601
|
|
583
|
-
panGesture.enabled(
|
602
|
+
panGesture.enabled(enabled !== false);
|
584
603
|
|
585
604
|
const animatedStyle = useAnimatedStyle(
|
586
605
|
() => ({
|
@@ -590,12 +609,10 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
590
609
|
[appliedTranslation, rowState]
|
591
610
|
);
|
592
611
|
|
593
|
-
const
|
594
|
-
const childrenContainerStyle = props.childrenContainerStyle;
|
595
|
-
|
596
|
-
return (
|
612
|
+
const swipeableComponent = (
|
597
613
|
<GestureDetector gesture={panGesture} touchAction="pan-y">
|
598
614
|
<Animated.View
|
615
|
+
{...remainingProps}
|
599
616
|
onLayout={onRowLayout}
|
600
617
|
style={[styles.container, containerStyle]}>
|
601
618
|
{leftElement}
|
@@ -608,6 +625,12 @@ const Swipeable = forwardRef<SwipeableMethods, SwipeableProps>(
|
|
608
625
|
</Animated.View>
|
609
626
|
</GestureDetector>
|
610
627
|
);
|
628
|
+
|
629
|
+
return testID ? (
|
630
|
+
<View testID={testID}>{swipeableComponent}</View>
|
631
|
+
) : (
|
632
|
+
swipeableComponent
|
633
|
+
);
|
611
634
|
}
|
612
635
|
);
|
613
636
|
|
@@ -222,6 +222,12 @@ type SwipeableState = {
|
|
222
222
|
rowWidth?: number;
|
223
223
|
};
|
224
224
|
|
225
|
+
/**
|
226
|
+
* @deprecated use Reanimated version of Swipeable instead
|
227
|
+
*
|
228
|
+
* This component allows for implementing swipeable rows or similar interaction.
|
229
|
+
*/
|
230
|
+
|
225
231
|
export default class Swipeable extends Component<
|
226
232
|
SwipeableProps,
|
227
233
|
SwipeableState
|
@@ -8,6 +8,7 @@ import {
|
|
8
8
|
export const longPressGestureHandlerProps = [
|
9
9
|
'minDurationMs',
|
10
10
|
'maxDist',
|
11
|
+
'numberOfPointers',
|
11
12
|
] as const;
|
12
13
|
|
13
14
|
export interface LongPressGestureConfig {
|
@@ -24,6 +25,11 @@ export interface LongPressGestureConfig {
|
|
24
25
|
* will fail to recognize the gesture. The default value is 10.
|
25
26
|
*/
|
26
27
|
maxDist?: number;
|
28
|
+
|
29
|
+
/**
|
30
|
+
* Determine exact number of points required to handle the long press gesture.
|
31
|
+
*/
|
32
|
+
numberOfPointers?: number;
|
27
33
|
}
|
28
34
|
|
29
35
|
export interface LongPressGestureHandlerProps
|