@react-navigation/stack 8.0.0-alpha.36 → 8.0.0-alpha.38
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/lib/module/index.js +2 -2
- package/lib/module/index.js.map +1 -1
- package/lib/module/utils/GestureHandlerContext.js +5 -0
- package/lib/module/utils/GestureHandlerContext.js.map +1 -0
- package/lib/module/utils/gestureActivationCriteria.js +10 -8
- package/lib/module/utils/gestureActivationCriteria.js.map +1 -1
- package/lib/module/utils/useGestureHandler.js +9 -0
- package/lib/module/utils/useGestureHandler.js.map +1 -0
- package/lib/module/views/GestureHandler.js +15 -14
- package/lib/module/views/GestureHandler.js.map +1 -1
- package/lib/module/views/GestureHandlerNative.js +16 -10
- package/lib/module/views/GestureHandlerNative.js.map +1 -1
- package/lib/module/views/Stack/Card.js +74 -76
- package/lib/module/views/Stack/Card.js.map +1 -1
- package/lib/module/views/Stack/CardStack.js +33 -11
- package/lib/module/views/Stack/CardStack.js.map +1 -1
- package/lib/module/views/Stack/StackView.js +24 -7
- package/lib/module/views/Stack/StackView.js.map +1 -1
- package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts +1 -1
- package/lib/typescript/src/TransitionConfigs/CardStyleInterpolators.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts +1 -1
- package/lib/typescript/src/TransitionConfigs/HeaderStyleInterpolators.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionPresets.d.ts.map +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts +1 -1
- package/lib/typescript/src/TransitionConfigs/TransitionSpecs.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +12 -12
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createStackNavigator.d.ts +3 -2
- package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
- package/lib/typescript/src/utils/CardAnimationContext.d.ts +1 -1
- package/lib/typescript/src/utils/CardAnimationContext.d.ts.map +1 -1
- package/lib/typescript/src/utils/GestureHandlerContext.d.ts +3 -0
- package/lib/typescript/src/utils/GestureHandlerContext.d.ts.map +1 -0
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts +3 -50
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts.map +1 -1
- package/lib/typescript/src/utils/getDistanceForDirection.d.ts +1 -1
- package/lib/typescript/src/utils/getDistanceForDirection.d.ts.map +1 -1
- package/lib/typescript/src/utils/getInvertedMultiplier.d.ts +1 -1
- package/lib/typescript/src/utils/getInvertedMultiplier.d.ts.map +1 -1
- package/lib/typescript/src/utils/getModalRoutesKeys.d.ts +1 -1
- package/lib/typescript/src/utils/getModalRoutesKeys.d.ts.map +1 -1
- package/lib/typescript/src/utils/useCardAnimation.d.ts +1 -1
- package/lib/typescript/src/utils/useCardAnimation.d.ts.map +1 -1
- package/lib/typescript/src/utils/useGestureHandler.d.ts +2 -0
- package/lib/typescript/src/utils/useGestureHandler.d.ts.map +1 -0
- package/lib/typescript/src/views/GestureHandler.android.d.ts +1 -1
- package/lib/typescript/src/views/GestureHandler.android.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandler.d.ts +7 -11
- package/lib/typescript/src/views/GestureHandler.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandler.ios.d.ts +1 -1
- package/lib/typescript/src/views/GestureHandler.ios.d.ts.map +1 -1
- package/lib/typescript/src/views/GestureHandlerNative.d.ts +9 -4
- package/lib/typescript/src/views/GestureHandlerNative.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/Header.d.ts +2 -2
- package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderContainer.d.ts +3 -2
- package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts +3 -2
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/Card.d.ts +2 -2
- package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts +3 -3
- package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContent.d.ts +1 -1
- package/lib/typescript/src/views/Stack/CardContent.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts +3 -3
- package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/StackView.d.ts +4 -4
- package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
- package/package.json +16 -16
- package/src/index.tsx +2 -2
- package/src/utils/GestureHandlerContext.tsx +5 -0
- package/src/utils/gestureActivationCriteria.tsx +13 -9
- package/src/utils/useGestureHandler.tsx +9 -0
- package/src/views/GestureHandler.tsx +27 -16
- package/src/views/GestureHandlerNative.tsx +26 -12
- package/src/views/Stack/Card.tsx +111 -101
- package/src/views/Stack/CardStack.tsx +62 -28
- package/src/views/Stack/StackView.tsx +41 -11
- package/lib/module/utils/GestureHandlerRefContext.js +0 -5
- package/lib/module/utils/GestureHandlerRefContext.js.map +0 -1
- package/lib/module/utils/findLastIndex.js +0 -11
- package/lib/module/utils/findLastIndex.js.map +0 -1
- package/lib/module/utils/useGestureHandlerRef.js +0 -12
- package/lib/module/utils/useGestureHandlerRef.js.map +0 -1
- package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts +0 -3
- package/lib/typescript/src/utils/GestureHandlerRefContext.d.ts.map +0 -1
- package/lib/typescript/src/utils/findLastIndex.d.ts +0 -2
- package/lib/typescript/src/utils/findLastIndex.d.ts.map +0 -1
- package/lib/typescript/src/utils/useGestureHandlerRef.d.ts +0 -3
- package/lib/typescript/src/utils/useGestureHandlerRef.d.ts.map +0 -1
- package/src/utils/GestureHandlerRefContext.tsx +0 -5
- package/src/utils/findLastIndex.tsx +0 -9
- package/src/utils/useGestureHandlerRef.tsx +0 -15
package/src/views/Stack/Card.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
View,
|
|
10
10
|
type ViewStyle,
|
|
11
11
|
} from 'react-native';
|
|
12
|
+
import type { PanGestureConfig } from 'react-native-gesture-handler';
|
|
12
13
|
import type { EdgeInsets } from 'react-native-safe-area-context';
|
|
13
14
|
import useLatestCallback from 'use-latest-callback';
|
|
14
15
|
|
|
@@ -23,11 +24,7 @@ import { gestureActivationCriteria } from '../../utils/gestureActivationCriteria
|
|
|
23
24
|
import { getDistanceForDirection } from '../../utils/getDistanceForDirection';
|
|
24
25
|
import { getInvertedMultiplier } from '../../utils/getInvertedMultiplier';
|
|
25
26
|
import { getShadowStyle } from '../../utils/getShadowStyle';
|
|
26
|
-
import {
|
|
27
|
-
GestureState,
|
|
28
|
-
PanGestureHandler,
|
|
29
|
-
type PanGestureHandlerGestureEvent,
|
|
30
|
-
} from '../GestureHandler';
|
|
27
|
+
import { GestureDetector, usePanGesture } from '../GestureHandler';
|
|
31
28
|
import { CardContent } from './CardContent';
|
|
32
29
|
|
|
33
30
|
type Props = {
|
|
@@ -243,84 +240,6 @@ function Card({
|
|
|
243
240
|
}
|
|
244
241
|
);
|
|
245
242
|
|
|
246
|
-
const onGestureStateChange = useLatestCallback(
|
|
247
|
-
({ nativeEvent }: PanGestureHandlerGestureEvent) => {
|
|
248
|
-
switch (nativeEvent.state) {
|
|
249
|
-
case GestureState.ACTIVE:
|
|
250
|
-
clearTimeout(pendingGestureCallbackRef.current);
|
|
251
|
-
clearTimeout(pendingOnCloseCallbackRef.current);
|
|
252
|
-
isSwiping.setValue(TRUE);
|
|
253
|
-
onGestureBegin?.();
|
|
254
|
-
break;
|
|
255
|
-
case GestureState.CANCELLED:
|
|
256
|
-
case GestureState.FAILED: {
|
|
257
|
-
isSwiping.setValue(FALSE);
|
|
258
|
-
|
|
259
|
-
const velocity =
|
|
260
|
-
gestureDirection === 'vertical' ||
|
|
261
|
-
gestureDirection === 'vertical-inverted'
|
|
262
|
-
? nativeEvent.velocityY
|
|
263
|
-
: nativeEvent.velocityX;
|
|
264
|
-
|
|
265
|
-
animate({
|
|
266
|
-
closing,
|
|
267
|
-
velocity,
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
onGestureCanceled?.();
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
|
-
case GestureState.END: {
|
|
274
|
-
isSwiping.setValue(FALSE);
|
|
275
|
-
|
|
276
|
-
let distance;
|
|
277
|
-
let translation;
|
|
278
|
-
let velocity;
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
gestureDirection === 'vertical' ||
|
|
282
|
-
gestureDirection === 'vertical-inverted'
|
|
283
|
-
) {
|
|
284
|
-
distance = layout.height;
|
|
285
|
-
translation = nativeEvent.translationY;
|
|
286
|
-
velocity = nativeEvent.velocityY;
|
|
287
|
-
} else {
|
|
288
|
-
distance = layout.width;
|
|
289
|
-
translation = nativeEvent.translationX;
|
|
290
|
-
velocity = nativeEvent.velocityX;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const shouldClose =
|
|
294
|
-
(translation + velocity * gestureVelocityImpact) *
|
|
295
|
-
getInvertedMultiplier(gestureDirection, direction === 'rtl') >
|
|
296
|
-
distance / 2
|
|
297
|
-
? velocity !== 0 || translation !== 0
|
|
298
|
-
: closing;
|
|
299
|
-
|
|
300
|
-
animate({ closing: shouldClose, velocity });
|
|
301
|
-
|
|
302
|
-
if (shouldClose) {
|
|
303
|
-
// We call onClose with a delay to make sure that the animation has already started
|
|
304
|
-
// This will make sure that the state update caused by this doesn't affect start of animation
|
|
305
|
-
pendingGestureCallbackRef.current = setTimeout(() => {
|
|
306
|
-
onClose();
|
|
307
|
-
|
|
308
|
-
// Check if the screen is still closing with a delay
|
|
309
|
-
// So state update from onClose has a chance to go through
|
|
310
|
-
// If route wasn't removed after onClose, re-open it
|
|
311
|
-
pendingOnCloseCallbackRef.current = setTimeout(() => {
|
|
312
|
-
maybeAnimate();
|
|
313
|
-
}, 32);
|
|
314
|
-
}, 16);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
onGestureEnd?.();
|
|
318
|
-
break;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
);
|
|
323
|
-
|
|
324
243
|
React.useLayoutEffect(() => {
|
|
325
244
|
layoutAnim.width.setValue(layout.width);
|
|
326
245
|
layoutAnim.height.setValue(layout.height);
|
|
@@ -478,17 +397,89 @@ function Card({
|
|
|
478
397
|
[styleInterpolator, interpolationProps]
|
|
479
398
|
);
|
|
480
399
|
|
|
481
|
-
const
|
|
400
|
+
const onGestureActivate: PanGestureConfig['onActivate'] = useLatestCallback(
|
|
401
|
+
() => {
|
|
402
|
+
clearTimeout(pendingGestureCallbackRef.current);
|
|
403
|
+
clearTimeout(pendingOnCloseCallbackRef.current);
|
|
404
|
+
isSwiping.setValue(TRUE);
|
|
405
|
+
onGestureBegin?.();
|
|
406
|
+
}
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
const onGestureDeactivate: PanGestureConfig['onDeactivate'] =
|
|
410
|
+
useLatestCallback((event) => {
|
|
411
|
+
isSwiping.setValue(FALSE);
|
|
412
|
+
|
|
413
|
+
let distance;
|
|
414
|
+
let translation;
|
|
415
|
+
let velocity;
|
|
416
|
+
|
|
417
|
+
if (
|
|
418
|
+
gestureDirection === 'vertical' ||
|
|
419
|
+
gestureDirection === 'vertical-inverted'
|
|
420
|
+
) {
|
|
421
|
+
distance = layout.height;
|
|
422
|
+
translation = event.translationY;
|
|
423
|
+
velocity = event.velocityY;
|
|
424
|
+
} else {
|
|
425
|
+
distance = layout.width;
|
|
426
|
+
translation = event.translationX;
|
|
427
|
+
velocity = event.velocityX;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
gesture.setValue(translation);
|
|
431
|
+
|
|
432
|
+
if (event.canceled) {
|
|
433
|
+
animate({
|
|
434
|
+
closing,
|
|
435
|
+
velocity,
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
onGestureCanceled?.();
|
|
439
|
+
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const shouldClose =
|
|
444
|
+
(translation + velocity * gestureVelocityImpact) *
|
|
445
|
+
getInvertedMultiplier(gestureDirection, direction === 'rtl') >
|
|
446
|
+
distance / 2
|
|
447
|
+
? velocity !== 0 || translation !== 0
|
|
448
|
+
: closing;
|
|
449
|
+
|
|
450
|
+
animate({ closing: shouldClose, velocity });
|
|
451
|
+
|
|
452
|
+
if (shouldClose) {
|
|
453
|
+
// We call onClose with a delay to make sure that the animation has already started
|
|
454
|
+
// This will make sure that the state update caused by this doesn't affect start of animation
|
|
455
|
+
pendingGestureCallbackRef.current = setTimeout(() => {
|
|
456
|
+
onClose();
|
|
457
|
+
|
|
458
|
+
// Check if the screen is still closing with a delay
|
|
459
|
+
// So state update from onClose has a chance to go through
|
|
460
|
+
// If route wasn't removed after onClose, re-open it
|
|
461
|
+
pendingOnCloseCallbackRef.current = setTimeout(() => {
|
|
462
|
+
maybeAnimate();
|
|
463
|
+
}, 32);
|
|
464
|
+
}, 16);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
onGestureEnd?.();
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
const onGestureEvent: PanGestureConfig['onUpdate'] = React.useMemo(
|
|
482
471
|
() =>
|
|
483
472
|
gestureEnabled
|
|
484
473
|
? Animated.event(
|
|
485
474
|
[
|
|
486
475
|
{
|
|
487
|
-
nativeEvent:
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
476
|
+
nativeEvent: {
|
|
477
|
+
handlerData:
|
|
478
|
+
gestureDirection === 'vertical' ||
|
|
479
|
+
gestureDirection === 'vertical-inverted'
|
|
480
|
+
? { translationY: gesture }
|
|
481
|
+
: { translationX: gesture },
|
|
482
|
+
},
|
|
492
483
|
},
|
|
493
484
|
],
|
|
494
485
|
{ useNativeDriver }
|
|
@@ -497,6 +488,35 @@ function Card({
|
|
|
497
488
|
[gesture, gestureDirection, gestureEnabled]
|
|
498
489
|
);
|
|
499
490
|
|
|
491
|
+
const panGestureConfig = React.useMemo(
|
|
492
|
+
(): PanGestureConfig => ({
|
|
493
|
+
enabled: layout.width !== 0 && gestureEnabled,
|
|
494
|
+
onActivate: onGestureActivate,
|
|
495
|
+
onDeactivate: onGestureDeactivate,
|
|
496
|
+
onUpdate: onGestureEvent,
|
|
497
|
+
disableReanimated: true,
|
|
498
|
+
useAnimated: true,
|
|
499
|
+
...gestureActivationCriteria({
|
|
500
|
+
layout,
|
|
501
|
+
direction,
|
|
502
|
+
gestureDirection,
|
|
503
|
+
gestureResponseDistance,
|
|
504
|
+
}),
|
|
505
|
+
}),
|
|
506
|
+
[
|
|
507
|
+
direction,
|
|
508
|
+
gestureDirection,
|
|
509
|
+
gestureEnabled,
|
|
510
|
+
gestureResponseDistance,
|
|
511
|
+
layout,
|
|
512
|
+
onGestureActivate,
|
|
513
|
+
onGestureDeactivate,
|
|
514
|
+
onGestureEvent,
|
|
515
|
+
]
|
|
516
|
+
);
|
|
517
|
+
|
|
518
|
+
const panGesture = usePanGesture(panGestureConfig);
|
|
519
|
+
|
|
500
520
|
const { backgroundColor } = StyleSheet.flatten(contentStyle || {});
|
|
501
521
|
|
|
502
522
|
const isTransparent =
|
|
@@ -528,17 +548,7 @@ function Card({
|
|
|
528
548
|
<Animated.View
|
|
529
549
|
style={[styles.container, containerStyle, customContainerStyle]}
|
|
530
550
|
>
|
|
531
|
-
<
|
|
532
|
-
enabled={layout.width !== 0 && gestureEnabled}
|
|
533
|
-
onGestureEvent={onGestureEvent}
|
|
534
|
-
onHandlerStateChange={onGestureStateChange}
|
|
535
|
-
{...gestureActivationCriteria({
|
|
536
|
-
layout,
|
|
537
|
-
direction,
|
|
538
|
-
gestureDirection,
|
|
539
|
-
gestureResponseDistance,
|
|
540
|
-
})}
|
|
541
|
-
>
|
|
551
|
+
<GestureDetector gesture={panGesture}>
|
|
542
552
|
<Animated.View
|
|
543
553
|
needsOffscreenAlphaCompositing={hasOpacityStyle(cardStyle)}
|
|
544
554
|
style={[styles.container, cardStyle]}
|
|
@@ -567,7 +577,7 @@ function Card({
|
|
|
567
577
|
{children}
|
|
568
578
|
</CardContent>
|
|
569
579
|
</Animated.View>
|
|
570
|
-
</
|
|
580
|
+
</GestureDetector>
|
|
571
581
|
</Animated.View>
|
|
572
582
|
</CardAnimationContext.Provider>
|
|
573
583
|
);
|
|
@@ -113,12 +113,16 @@ const NAMED_TRANSITIONS_PRESETS = {
|
|
|
113
113
|
}),
|
|
114
114
|
} as const satisfies Record<StackAnimationName, TransitionPreset>;
|
|
115
115
|
|
|
116
|
-
const FALLBACK_DESCRIPTOR = Object.freeze({ options: {} });
|
|
117
|
-
|
|
118
116
|
const HIDDEN_HEADER_HEIGHT = { measured: false, value: 0 };
|
|
119
117
|
|
|
120
118
|
const getInterpolationIndex = (scenes: Scene[], index: number) => {
|
|
121
|
-
const
|
|
119
|
+
const scene = scenes[index];
|
|
120
|
+
|
|
121
|
+
if (scene == null) {
|
|
122
|
+
throw new Error(`Couldn't find a scene at index ${index}.`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const { cardStyleInterpolator } = scene.descriptor.options;
|
|
122
126
|
|
|
123
127
|
// Start from current card and count backwards the number of cards with same interpolation
|
|
124
128
|
let interpolationIndex = 0;
|
|
@@ -347,27 +351,36 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
347
351
|
const oldScene = state.scenes[index];
|
|
348
352
|
|
|
349
353
|
const currentGesture = gestures[route.key];
|
|
354
|
+
|
|
355
|
+
if (currentGesture == null) {
|
|
356
|
+
throw new Error(`Couldn't find a gesture for route '${route.key}'.`);
|
|
357
|
+
}
|
|
358
|
+
|
|
350
359
|
const previousGesture = previousRoute
|
|
351
360
|
? gestures[previousRoute.key]
|
|
352
361
|
: undefined;
|
|
353
362
|
const nextGesture = nextRoute ? gestures[nextRoute.key] : undefined;
|
|
354
363
|
|
|
355
364
|
const descriptor =
|
|
356
|
-
props.descriptors[route.key]
|
|
357
|
-
state.descriptors[route.key]
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
365
|
+
props.descriptors[route.key] ??
|
|
366
|
+
state.descriptors[route.key] ??
|
|
367
|
+
oldScene?.descriptor;
|
|
368
|
+
|
|
369
|
+
if (descriptor == null) {
|
|
370
|
+
throw new Error(`Couldn't find a descriptor for route '${route.key}'.`);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const nextOptions = nextRoute
|
|
374
|
+
? (props.descriptors[nextRoute.key] ?? state.descriptors[nextRoute.key])
|
|
375
|
+
?.options
|
|
376
|
+
: undefined;
|
|
377
|
+
|
|
378
|
+
const previousOptions = previousRoute
|
|
379
|
+
? (
|
|
380
|
+
props.descriptors[previousRoute.key] ??
|
|
381
|
+
state.descriptors[previousRoute.key]
|
|
382
|
+
)?.options
|
|
383
|
+
: undefined;
|
|
371
384
|
|
|
372
385
|
// When a screen is not the last, it should use next screen's transition config
|
|
373
386
|
// Many transitions also animate the previous screen, so using 2 different transitions doesn't look right
|
|
@@ -582,7 +595,13 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
582
595
|
private getFocusedRoute = () => {
|
|
583
596
|
const { state } = this.props;
|
|
584
597
|
|
|
585
|
-
|
|
598
|
+
const route = state.routes[state.index];
|
|
599
|
+
|
|
600
|
+
if (route == null) {
|
|
601
|
+
throw new Error(`Couldn't find a route at index ${state.index}.`);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
return route;
|
|
586
605
|
};
|
|
587
606
|
|
|
588
607
|
private getPreviousScene = ({ route }: { route: Route<string> }) => {
|
|
@@ -628,6 +647,10 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
628
647
|
|
|
629
648
|
const focusedRoute = state.routes[state.index];
|
|
630
649
|
|
|
650
|
+
if (focusedRoute == null) {
|
|
651
|
+
throw new Error(`Couldn't find a route at index ${state.index}.`);
|
|
652
|
+
}
|
|
653
|
+
|
|
631
654
|
// Render only two top-most active headers as a workaround for
|
|
632
655
|
// https://github.com/react-navigation/react-navigation/issues/12456.
|
|
633
656
|
// If the header is persisted, it might be placed incorrectly when navigating back
|
|
@@ -682,6 +705,19 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
682
705
|
const gesture = gestures[route.key];
|
|
683
706
|
const scene = scenes[index];
|
|
684
707
|
|
|
708
|
+
if (gesture == null) {
|
|
709
|
+
throw new Error(
|
|
710
|
+
`Couldn't find a gesture for route '${route.key}'.`
|
|
711
|
+
);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (scene == null) {
|
|
715
|
+
throw new Error(`Couldn't find a scene at index ${index}.`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
const nextScene = scenes[index + 1];
|
|
719
|
+
const nextRoute = self[index + 1];
|
|
720
|
+
|
|
685
721
|
const {
|
|
686
722
|
inactiveBehavior = 'pause',
|
|
687
723
|
animation,
|
|
@@ -712,15 +748,12 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
712
748
|
getAnimationEnabled(animation) ||
|
|
713
749
|
// Also check next screen's animation,
|
|
714
750
|
// As it will result in both screens being visible
|
|
715
|
-
(
|
|
716
|
-
? getAnimationEnabled(
|
|
717
|
-
scenes[index + 1].descriptor.options.animation
|
|
718
|
-
)
|
|
751
|
+
(nextScene
|
|
752
|
+
? getAnimationEnabled(nextScene.descriptor.options.animation)
|
|
719
753
|
: false);
|
|
720
754
|
|
|
721
755
|
const isNextScreenTransparent =
|
|
722
|
-
|
|
723
|
-
'transparentModal';
|
|
756
|
+
nextScene?.descriptor.options.presentation === 'transparentModal';
|
|
724
757
|
|
|
725
758
|
const isRemoving =
|
|
726
759
|
replacingRouteKeys.includes(route.key) ||
|
|
@@ -728,9 +761,10 @@ export class CardStack extends React.Component<Props, State> {
|
|
|
728
761
|
|
|
729
762
|
const isFocusing =
|
|
730
763
|
openingRouteKeys.includes(route.key) ||
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
764
|
+
(nextRoute != null &&
|
|
765
|
+
[...closingRouteKeys, ...replacingRouteKeys].includes(
|
|
766
|
+
nextRoute.key
|
|
767
|
+
));
|
|
734
768
|
|
|
735
769
|
const isInactive = isInactiveRoute(route, this.props.routes);
|
|
736
770
|
const isRetained = state.retainedRouteKeys?.includes(route.key);
|
|
@@ -64,10 +64,20 @@ export class StackView extends React.Component<Props, State> {
|
|
|
64
64
|
) {
|
|
65
65
|
const allRoutes = props.state.routes;
|
|
66
66
|
const previousRoutes = state.previousState?.routes ?? [];
|
|
67
|
-
const previousFocusedRoute =
|
|
68
|
-
|
|
69
|
-
: undefined;
|
|
67
|
+
const previousFocusedRoute =
|
|
68
|
+
state.previousState?.routes[state.previousState.index];
|
|
70
69
|
const nextFocusedRouteFromState = props.state.routes[props.state.index];
|
|
70
|
+
|
|
71
|
+
if (state.previousState && previousFocusedRoute == null) {
|
|
72
|
+
throw new Error(
|
|
73
|
+
`Couldn't find a route at index ${state.previousState.index}.`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (nextFocusedRouteFromState == null) {
|
|
78
|
+
throw new Error(`Couldn't find a route at index ${props.state.index}.`);
|
|
79
|
+
}
|
|
80
|
+
|
|
71
81
|
const activeRoutes = props.state.routes.slice(0, props.state.index + 1);
|
|
72
82
|
|
|
73
83
|
// If there was no change in routes, we don't need to compute anything
|
|
@@ -118,7 +128,7 @@ export class StackView extends React.Component<Props, State> {
|
|
|
118
128
|
{}
|
|
119
129
|
);
|
|
120
130
|
|
|
121
|
-
routes = routes.map((route) => map[route.key]
|
|
131
|
+
routes = routes.map((route) => map[route.key] ?? route);
|
|
122
132
|
}
|
|
123
133
|
|
|
124
134
|
const routeKeys = new Set(routes.map((route) => route.key));
|
|
@@ -126,8 +136,16 @@ export class StackView extends React.Component<Props, State> {
|
|
|
126
136
|
...routes,
|
|
127
137
|
...props.state.routes.filter((route) => !routeKeys.has(route.key)),
|
|
128
138
|
].reduce<StackDescriptorMap>((acc, route) => {
|
|
129
|
-
|
|
130
|
-
props.descriptors[route.key]
|
|
139
|
+
const descriptor =
|
|
140
|
+
props.descriptors[route.key] ?? state.descriptors[route.key];
|
|
141
|
+
|
|
142
|
+
if (descriptor == null) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Couldn't find a descriptor for route '${route.key}'.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
acc[route.key] = descriptor;
|
|
131
149
|
|
|
132
150
|
return acc;
|
|
133
151
|
}, {});
|
|
@@ -157,16 +175,22 @@ export class StackView extends React.Component<Props, State> {
|
|
|
157
175
|
// Get previous focused route from previous active routes
|
|
158
176
|
const nextFocusedRoute = activeRoutes[activeRoutes.length - 1];
|
|
159
177
|
|
|
178
|
+
if (nextFocusedRoute == null) {
|
|
179
|
+
throw new Error(
|
|
180
|
+
`Couldn't find a route at index ${activeRoutes.length - 1}.`
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
160
184
|
const isAnimationEnabled = (key: string) => {
|
|
161
|
-
const descriptor = props.descriptors[key]
|
|
185
|
+
const descriptor = props.descriptors[key] ?? state.descriptors[key];
|
|
162
186
|
|
|
163
187
|
return getAnimationEnabled(descriptor?.options.animation);
|
|
164
188
|
};
|
|
165
189
|
|
|
166
190
|
const getAnimationTypeForReplace = (key: string) => {
|
|
167
|
-
const descriptor = props.descriptors[key]
|
|
191
|
+
const descriptor = props.descriptors[key] ?? state.descriptors[key];
|
|
168
192
|
|
|
169
|
-
return descriptor
|
|
193
|
+
return descriptor?.options.animationTypeForReplace ?? 'push';
|
|
170
194
|
};
|
|
171
195
|
|
|
172
196
|
let routes = activeRoutes;
|
|
@@ -301,8 +325,14 @@ export class StackView extends React.Component<Props, State> {
|
|
|
301
325
|
...routes,
|
|
302
326
|
...props.state.routes.filter((route) => !routeKeys.has(route.key)),
|
|
303
327
|
].reduce<StackDescriptorMap>((acc, route) => {
|
|
304
|
-
|
|
305
|
-
props.descriptors[route.key]
|
|
328
|
+
const descriptor =
|
|
329
|
+
props.descriptors[route.key] ?? state.descriptors[route.key];
|
|
330
|
+
|
|
331
|
+
if (descriptor == null) {
|
|
332
|
+
throw new Error(`Couldn't find a descriptor for route '${route.key}'.`);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
acc[route.key] = descriptor;
|
|
306
336
|
|
|
307
337
|
return acc;
|
|
308
338
|
}, {});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","GestureHandlerRefContext","createContext"],"sourceRoot":"../../../src","sources":["utils/GestureHandlerRefContext.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,OAAO,MAAMC,wBAAwB,gBAAGD,KAAK,CAACE,aAAa,CAEjD,IAAI,CAAC","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["findLastIndex","array","callback","i","length"],"sourceRoot":"../../../src","sources":["utils/findLastIndex.tsx"],"mappings":";;AAAA,OAAO,SAASA,aAAaA,CAAIC,KAAU,EAAEC,QAA+B,EAAE;EAC5E,KAAK,IAAIC,CAAC,GAAGF,KAAK,CAACG,MAAM,GAAG,CAAC,EAAED,CAAC,IAAI,CAAC,EAAEA,CAAC,EAAE,EAAE;IAC1C,IAAID,QAAQ,CAACD,KAAK,CAACE,CAAC,CAAC,CAAC,EAAE;MACtB,OAAOA,CAAC;IACV;EACF;EAEA,OAAO,CAAC,CAAC;AACX","ignoreList":[]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import * as React from 'react';
|
|
4
|
-
import { GestureHandlerRefContext } from "./GestureHandlerRefContext.js";
|
|
5
|
-
export function useGestureHandlerRef() {
|
|
6
|
-
const ref = React.use(GestureHandlerRefContext);
|
|
7
|
-
if (ref === undefined) {
|
|
8
|
-
throw new Error("Couldn't find a ref for gesture handler. Are you inside a screen in Stack?");
|
|
9
|
-
}
|
|
10
|
-
return ref;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=useGestureHandlerRef.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["React","GestureHandlerRefContext","useGestureHandlerRef","ref","use","undefined","Error"],"sourceRoot":"../../../src","sources":["utils/useGestureHandlerRef.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAE9B,SAASC,wBAAwB,QAAQ,+BAA4B;AAErE,OAAO,SAASC,oBAAoBA,CAAA,EAAG;EACrC,MAAMC,GAAG,GAAGH,KAAK,CAACI,GAAG,CAACH,wBAAwB,CAAC;EAE/C,IAAIE,GAAG,KAAKE,SAAS,EAAE;IACrB,MAAM,IAAIC,KAAK,CACb,4EACF,CAAC;EACH;EAEA,OAAOH,GAAG;AACZ","ignoreList":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"GestureHandlerRefContext.d.ts","sourceRoot":"","sources":["../../../../src/utils/GestureHandlerRefContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,eAAO,MAAM,wBAAwB,yIAEtB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"findLastIndex.d.ts","sourceRoot":"","sources":["../../../../src/utils/findLastIndex.tsx"],"names":[],"mappings":"AAAA,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,UAQ3E"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useGestureHandlerRef.d.ts","sourceRoot":"","sources":["../../../../src/utils/useGestureHandlerRef.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,wBAAgB,oBAAoB,6HAUnC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
|
|
3
|
-
import { GestureHandlerRefContext } from './GestureHandlerRefContext';
|
|
4
|
-
|
|
5
|
-
export function useGestureHandlerRef() {
|
|
6
|
-
const ref = React.use(GestureHandlerRefContext);
|
|
7
|
-
|
|
8
|
-
if (ref === undefined) {
|
|
9
|
-
throw new Error(
|
|
10
|
-
"Couldn't find a ref for gesture handler. Are you inside a screen in Stack?"
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return ref;
|
|
15
|
-
}
|