Get rid of the directional gesture options (#32788)
Stacked on #32786. `startGestureTransition` doesn't have a concept of two directions. It's just a start and end range now.
Sebastian Markbåge committed
Apr 1, 2025 at 12:07 UTC
8b2046d0ce379e083b4f5678598c2af9d507f507
4 files changed
+29
-50
fixtures/view-transition/src/components/SwipeRecognizer.js
+9
-3
@@ -38,9 +38,15 @@ export default function SwipeRecognizer({
38
() => {
39
gesture(direction);
40
},
41
- {
42
- range: [0, direction === 'left' || direction === 'up' ? 100 : 0, 100],
43
- }
41
+ direction === 'left' || direction === 'up'
42
+ ? {
43
+ rangeStart: 100,
44
+ rangeEnd: 0,
45
+ }
46
+ : {
47
+ rangeStart: 0,
48
+ rangeEnd: 100,
49
+ }
50
);
51
}
52
function onScrollEnd() {
packages/react-reconciler/src/ReactFiberGestureScheduler.js
+16
-41
@@ -23,10 +23,8 @@ import {getCurrentGestureOffset, stopViewTransition} from './ReactFiberConfig';
23
export type ScheduledGesture = {
24
provider: GestureTimeline,
25
count: number, // The number of times this same provider has been started.
26
- direction: boolean, // false = previous, true = next
27
- rangePrevious: number, // The end along the timeline where the previous state is reached.
28
- rangeCurrent: number, // The starting offset along the timeline.
29
- rangeNext: number, // The end along the timeline where the next state is reached.
26
+ rangeStart: number, // The percentage along the timeline where the "current" state starts.
27
+ rangeEnd: number, // The percentage along the timeline where the "destination" state is reached.
28
running: null | RunningViewTransition, // Used to cancel the running transition after we're done.
29
prev: null | ScheduledGesture, // The previous scheduled gesture in the queue for this root.
30
next: null | ScheduledGesture, // The next scheduled gesture in the queue for this root.
@@ -51,10 +49,8 @@ export function scheduleGesture(
49
const gesture: ScheduledGesture = {
50
provider: provider,
51
count: 0,
54
- direction: false,
55
- rangePrevious: -1,
56
- rangeCurrent: -1,
57
- rangeNext: -1,
52
+ rangeStart: 0, // Uninitialized
53
+ rangeEnd: 100, // Uninitialized
54
running: null,
55
prev: prev,
56
next: null,
@@ -73,45 +69,24 @@ export function startScheduledGesture(
69
gestureTimeline: GestureTimeline,
70
gestureOptions: ?GestureOptions,
71
): null | ScheduledGesture {
76
- const currentOffset = getCurrentGestureOffset(gestureTimeline);
77
- const range = gestureOptions && gestureOptions.range;
78
- const rangePrevious: number = range ? range[0] : 0; // If no range is provider we assume it's the starting point of the range.
79
- const rangeCurrent: number = range ? range[1] : currentOffset;
80
- const rangeNext: number = range ? range[2] : 100; // If no range is provider we assume it's the starting point of the range.
81
- if (__DEV__) {
82
- if (
83
- (rangePrevious > rangeCurrent && rangeNext > rangeCurrent) ||
84
- (rangePrevious < rangeCurrent && rangeNext < rangeCurrent)
85
- ) {
86
- console.error(
87
- 'The range of a gesture needs "previous" and "next" to be on either side of ' +
88
- 'the "current" offset. Both cannot be above current and both cannot be below current.',
89
- );
90
- }
91
- }
92
- const isFlippedDirection = rangePrevious > rangeNext;
93
- const initialDirection =
94
- // If a range is specified we can imply initial direction if it's not the current
95
- // value such as if the gesture starts after it has already moved.
96
- currentOffset < rangeCurrent
97
- ? isFlippedDirection
98
- : currentOffset > rangeCurrent
99
- ? !isFlippedDirection
100
- : // Otherwise, look for an explicit option.
101
- gestureOptions
102
- ? gestureOptions.direction === 'next'
103
- : false;
104
-
72
+ const rangeStart =
73
+ gestureOptions && gestureOptions.rangeStart != null
74
+ ? gestureOptions.rangeStart
75
+ : getCurrentGestureOffset(gestureTimeline);
76
+ const rangeEnd =
77
+ gestureOptions && gestureOptions.rangeEnd != null
78
+ ? gestureOptions.rangeEnd
79
+ : rangeStart < 50
80
+ ? 100
81
+ : 0;
82
let prev = root.pendingGestures;
83
while (prev !== null) {
84
if (prev.provider === gestureTimeline) {
85
// Existing instance found.
86
prev.count++;
87
// Update the options.
111
- prev.direction = initialDirection;
112
- prev.rangePrevious = rangePrevious;
113
- prev.rangeCurrent = rangeCurrent;
114
- prev.rangeNext = rangeNext;
88
+ prev.rangeStart = rangeStart;
89
+ prev.rangeEnd = rangeEnd;
90
return prev;
91
}
92
const next = prev.next;
packages/react-reconciler/src/ReactFiberWorkLoop.js
+2
-4
@@ -3932,10 +3932,8 @@ function commitGestureOnRoot(
3932
pendingViewTransition = finishedGesture.running = startGestureTransition(
3933
root.containerInfo,
3934
finishedGesture.provider,
3935
- finishedGesture.rangeCurrent,
3936
- finishedGesture.direction
3937
- ? finishedGesture.rangeNext
3938
- : finishedGesture.rangePrevious,
3935
+ finishedGesture.rangeStart,
3936
+ finishedGesture.rangeEnd,
3937
pendingTransitionTypes,
3938
flushGestureMutations,
3939
flushGestureAnimations,
packages/shared/ReactTypes.js
+2
-2
@@ -172,8 +172,8 @@ export type ReactFormState<S, ReferenceId> = [
172
export type GestureProvider = any;
173
174
export type GestureOptions = {
175
- direction?: 'previous' | 'next',
176
- range?: [/*previous*/ number, /*current*/ number, /*next*/ number],
175
+ rangeStart?: number,
176
+ rangeEnd?: number,
177
};
178
179
export type Awaited<T> = T extends null | void