@samitouri / QOS-React-2 / commits / 8b2046d0ce

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