react-native-screen-transitions 2.3.1 → 2.3.3
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/README.md +50 -12
- package/lib/commonjs/__configs__/index.js.map +1 -0
- package/lib/commonjs/{configs → __configs__}/presets.js +7 -3
- package/lib/commonjs/__configs__/presets.js.map +1 -0
- package/lib/commonjs/{configs → __configs__}/specs.js +1 -0
- package/lib/commonjs/__configs__/specs.js.map +1 -0
- package/lib/commonjs/components/controllers/screen-lifecycle.js +5 -5
- package/lib/commonjs/components/controllers/screen-lifecycle.js.map +1 -1
- package/lib/commonjs/components/create-transition-aware-component.js +13 -32
- package/lib/commonjs/components/create-transition-aware-component.js.map +1 -1
- package/lib/commonjs/components/integrations/masked-view.js +3 -4
- package/lib/commonjs/components/integrations/masked-view.js.map +1 -1
- package/lib/commonjs/components/root-transition-aware.js +3 -3
- package/lib/commonjs/components/root-transition-aware.js.map +1 -1
- package/lib/commonjs/constants.js +103 -0
- package/lib/commonjs/constants.js.map +1 -0
- package/lib/commonjs/hooks/animation/use-associated-style.js +3 -4
- package/lib/commonjs/hooks/animation/use-associated-style.js.map +1 -1
- package/lib/commonjs/hooks/animation/use-screen-animation.js +6 -28
- package/lib/commonjs/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/commonjs/hooks/bounds/use-bound-registry.js +92 -31
- package/lib/commonjs/hooks/bounds/use-bound-registry.js.map +1 -1
- package/lib/commonjs/hooks/gestures/use-build-gestures.js +27 -41
- package/lib/commonjs/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/commonjs/index.js +3 -3
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/utils/debounce.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/utils/useDismissedRouteError.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/views/FontProcessor.js +1 -1
- package/lib/commonjs/integrations/native-stack/views/FontProcessor.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/views/FontProcessor.native.js +1 -1
- package/lib/commonjs/integrations/native-stack/views/FontProcessor.native.js.map +1 -1
- package/lib/commonjs/integrations/native-stack/views/NativeStackView.native.js +2 -2
- package/lib/commonjs/integrations/native-stack/views/NativeStackView.native.js.map +1 -1
- package/lib/commonjs/providers/gestures.js +1 -9
- package/lib/commonjs/providers/gestures.js.map +1 -1
- package/lib/commonjs/{components/screen-transition-tree.js → providers/screen-transition-provider.js} +5 -5
- package/lib/commonjs/providers/screen-transition-provider.js.map +1 -0
- package/lib/commonjs/providers/transition-styles.js +4 -4
- package/lib/commonjs/providers/transition-styles.js.map +1 -1
- package/lib/commonjs/utils/animation/start-screen-transition.js +54 -0
- package/lib/commonjs/utils/animation/start-screen-transition.js.map +1 -0
- package/lib/commonjs/utils/bounds/index.js +6 -18
- package/lib/commonjs/utils/bounds/index.js.map +1 -1
- package/lib/commonjs/utils/gesture/apply-offset-rules.js +12 -21
- package/lib/commonjs/utils/gesture/apply-offset-rules.js.map +1 -1
- package/lib/commonjs/utils/gesture/determine-dismissal.js +7 -55
- package/lib/commonjs/utils/gesture/determine-dismissal.js.map +1 -1
- package/lib/commonjs/utils/gesture/reset-gesture-values.js +46 -0
- package/lib/commonjs/utils/gesture/reset-gesture-values.js.map +1 -0
- package/lib/commonjs/utils/gesture/velocity.js +89 -0
- package/lib/commonjs/utils/gesture/velocity.js.map +1 -0
- package/lib/commonjs/utils/reanimated/version.js +12 -0
- package/lib/commonjs/utils/reanimated/version.js.map +1 -0
- package/lib/module/__configs__/index.js.map +1 -0
- package/lib/module/{configs → __configs__}/presets.js +7 -3
- package/lib/module/__configs__/presets.js.map +1 -0
- package/lib/module/{configs → __configs__}/specs.js +1 -0
- package/lib/module/__configs__/specs.js.map +1 -0
- package/lib/module/components/controllers/screen-lifecycle.js +5 -5
- package/lib/module/components/controllers/screen-lifecycle.js.map +1 -1
- package/lib/module/components/create-transition-aware-component.js +13 -32
- package/lib/module/components/create-transition-aware-component.js.map +1 -1
- package/lib/module/components/integrations/masked-view.js +1 -2
- package/lib/module/components/integrations/masked-view.js.map +1 -1
- package/lib/module/components/root-transition-aware.js +3 -3
- package/lib/module/components/root-transition-aware.js.map +1 -1
- package/lib/module/constants.js +98 -0
- package/lib/module/constants.js.map +1 -0
- package/lib/module/hooks/animation/use-associated-style.js +3 -4
- package/lib/module/hooks/animation/use-associated-style.js.map +1 -1
- package/lib/module/hooks/animation/use-screen-animation.js +6 -28
- package/lib/module/hooks/animation/use-screen-animation.js.map +1 -1
- package/lib/module/hooks/bounds/use-bound-registry.js +93 -33
- package/lib/module/hooks/bounds/use-bound-registry.js.map +1 -1
- package/lib/module/hooks/gestures/use-build-gestures.js +22 -36
- package/lib/module/hooks/gestures/use-build-gestures.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/integrations/native-stack/utils/debounce.js.map +1 -1
- package/lib/module/integrations/native-stack/utils/useAnimatedHeaderHeight.js +1 -1
- package/lib/module/integrations/native-stack/utils/useAnimatedHeaderHeight.js.map +1 -1
- package/lib/module/integrations/native-stack/utils/useDismissedRouteError.js +1 -1
- package/lib/module/integrations/native-stack/utils/useDismissedRouteError.js.map +1 -1
- package/lib/module/integrations/native-stack/views/FontProcessor.js +1 -1
- package/lib/module/integrations/native-stack/views/FontProcessor.js.map +1 -1
- package/lib/module/integrations/native-stack/views/FontProcessor.native.js +2 -2
- package/lib/module/integrations/native-stack/views/FontProcessor.native.js.map +1 -1
- package/lib/module/integrations/native-stack/views/NativeStackView.native.js +2 -2
- package/lib/module/integrations/native-stack/views/NativeStackView.native.js.map +1 -1
- package/lib/module/providers/gestures.js +0 -8
- package/lib/module/providers/gestures.js.map +1 -1
- package/lib/module/{components/screen-transition-tree.js → providers/screen-transition-provider.js} +4 -4
- package/lib/module/providers/screen-transition-provider.js.map +1 -0
- package/lib/module/providers/transition-styles.js +4 -4
- package/lib/module/providers/transition-styles.js.map +1 -1
- package/lib/module/utils/animation/{run-transition.js → start-screen-transition.js} +15 -13
- package/lib/module/utils/animation/start-screen-transition.js.map +1 -0
- package/lib/module/utils/bounds/index.js +5 -17
- package/lib/module/utils/bounds/index.js.map +1 -1
- package/lib/module/utils/gesture/apply-offset-rules.js +1 -10
- package/lib/module/utils/gesture/apply-offset-rules.js.map +1 -1
- package/lib/module/utils/gesture/determine-dismissal.js +7 -55
- package/lib/module/utils/gesture/determine-dismissal.js.map +1 -1
- package/lib/module/utils/gesture/reset-gesture-values.js +41 -0
- package/lib/module/utils/gesture/reset-gesture-values.js.map +1 -0
- package/lib/module/utils/gesture/velocity.js +85 -0
- package/lib/module/utils/gesture/velocity.js.map +1 -0
- package/lib/module/utils/reanimated/version.js +7 -0
- package/lib/module/utils/reanimated/version.js.map +1 -0
- package/lib/typescript/{configs → __configs__}/index.d.ts +1 -1
- package/lib/typescript/__configs__/index.d.ts.map +1 -0
- package/lib/typescript/__configs__/presets.d.ts.map +1 -0
- package/lib/typescript/__configs__/specs.d.ts.map +1 -0
- package/lib/typescript/components/create-transition-aware-component.d.ts +14 -2
- package/lib/typescript/components/create-transition-aware-component.d.ts.map +1 -1
- package/lib/typescript/components/integrations/masked-view.d.ts.map +1 -1
- package/lib/typescript/components/root-transition-aware.d.ts.map +1 -1
- package/lib/typescript/constants.d.ts +57 -0
- package/lib/typescript/constants.d.ts.map +1 -0
- package/lib/typescript/hooks/animation/use-associated-style.d.ts.map +1 -1
- package/lib/typescript/hooks/animation/use-screen-animation.d.ts +1 -1
- package/lib/typescript/hooks/animation/use-screen-animation.d.ts.map +1 -1
- package/lib/typescript/hooks/bounds/use-bound-registry.d.ts +8 -9
- package/lib/typescript/hooks/bounds/use-bound-registry.d.ts.map +1 -1
- package/lib/typescript/hooks/gestures/use-build-gestures.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +100 -68
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/integrations/native-stack/utils/debounce.d.ts.map +1 -1
- package/lib/typescript/integrations/native-stack/utils/useAnimatedHeaderHeight.d.ts +2 -2
- package/lib/typescript/integrations/native-stack/utils/useDismissedRouteError.d.ts +2 -2
- package/lib/typescript/integrations/native-stack/utils/useDismissedRouteError.d.ts.map +1 -1
- package/lib/typescript/integrations/native-stack/views/FontProcessor.d.ts.map +1 -1
- package/lib/typescript/integrations/native-stack/views/FontProcessor.native.d.ts.map +1 -1
- package/lib/typescript/providers/gestures.d.ts +0 -1
- package/lib/typescript/providers/gestures.d.ts.map +1 -1
- package/lib/typescript/{components/screen-transition-tree.d.ts → providers/screen-transition-provider.d.ts} +2 -2
- package/lib/typescript/providers/screen-transition-provider.d.ts.map +1 -0
- package/lib/typescript/providers/transition-styles.d.ts.map +1 -1
- package/lib/typescript/types/core.d.ts +0 -8
- package/lib/typescript/types/core.d.ts.map +1 -1
- package/lib/typescript/utils/animation/start-screen-transition.d.ts +13 -0
- package/lib/typescript/utils/animation/start-screen-transition.d.ts.map +1 -0
- package/lib/typescript/utils/bounds/_types/get-bounds.d.ts +2 -2
- package/lib/typescript/utils/bounds/_types/get-bounds.d.ts.map +1 -1
- package/lib/typescript/utils/bounds/index.d.ts.map +1 -1
- package/lib/typescript/utils/gesture/apply-offset-rules.d.ts.map +1 -1
- package/lib/typescript/utils/gesture/determine-dismissal.d.ts +0 -1
- package/lib/typescript/utils/gesture/determine-dismissal.d.ts.map +1 -1
- package/lib/typescript/utils/gesture/reset-gesture-values.d.ts +16 -0
- package/lib/typescript/utils/gesture/reset-gesture-values.d.ts.map +1 -0
- package/lib/typescript/utils/gesture/velocity.d.ts +25 -0
- package/lib/typescript/utils/gesture/velocity.d.ts.map +1 -0
- package/lib/typescript/utils/reanimated/version.d.ts +2 -0
- package/lib/typescript/utils/reanimated/version.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/{configs → __configs__}/presets.ts +7 -1
- package/src/{configs → __configs__}/specs.ts +1 -0
- package/src/components/controllers/screen-lifecycle.tsx +5 -5
- package/src/components/create-transition-aware-component.tsx +23 -38
- package/src/components/integrations/masked-view.tsx +1 -3
- package/src/components/root-transition-aware.tsx +4 -8
- package/src/constants.ts +106 -0
- package/src/hooks/animation/use-associated-style.tsx +3 -4
- package/src/hooks/animation/use-screen-animation.tsx +15 -32
- package/src/hooks/bounds/use-bound-registry.tsx +112 -25
- package/src/hooks/gestures/use-build-gestures.tsx +31 -25
- package/src/index.ts +1 -1
- package/src/integrations/native-stack/utils/debounce.tsx +9 -9
- package/src/integrations/native-stack/utils/useAnimatedHeaderHeight.tsx +10 -10
- package/src/integrations/native-stack/utils/useDismissedRouteError.tsx +21 -21
- package/src/integrations/native-stack/views/FontProcessor.native.tsx +7 -7
- package/src/integrations/native-stack/views/FontProcessor.tsx +2 -2
- package/src/integrations/native-stack/views/NativeStackView.native.tsx +4 -4
- package/src/providers/gestures.tsx +0 -9
- package/src/{components/screen-transition-tree.tsx → providers/screen-transition-provider.tsx} +3 -3
- package/src/providers/transition-styles.tsx +6 -5
- package/src/types/core.ts +0 -9
- package/src/utils/animation/start-screen-transition.ts +61 -0
- package/src/utils/bounds/_types/get-bounds.ts +7 -7
- package/src/utils/bounds/index.ts +12 -19
- package/src/utils/gesture/apply-offset-rules.ts +9 -11
- package/src/utils/gesture/determine-dismissal.ts +18 -69
- package/src/utils/gesture/reset-gesture-values.ts +48 -0
- package/src/utils/gesture/velocity.ts +144 -0
- package/src/utils/reanimated/version.ts +5 -0
- package/lib/commonjs/components/bound-capture.js +0 -38
- package/lib/commonjs/components/bound-capture.js.map +0 -1
- package/lib/commonjs/components/screen-transition-tree.js.map +0 -1
- package/lib/commonjs/configs/index.js.map +0 -1
- package/lib/commonjs/configs/presets.js.map +0 -1
- package/lib/commonjs/configs/specs.js.map +0 -1
- package/lib/commonjs/utils/animation/run-transition.js +0 -52
- package/lib/commonjs/utils/animation/run-transition.js.map +0 -1
- package/lib/module/components/bound-capture.js +0 -33
- package/lib/module/components/bound-capture.js.map +0 -1
- package/lib/module/components/screen-transition-tree.js.map +0 -1
- package/lib/module/configs/index.js.map +0 -1
- package/lib/module/configs/presets.js.map +0 -1
- package/lib/module/configs/specs.js.map +0 -1
- package/lib/module/utils/animation/run-transition.js.map +0 -1
- package/lib/typescript/components/bound-capture.d.ts +0 -8
- package/lib/typescript/components/bound-capture.d.ts.map +0 -1
- package/lib/typescript/components/screen-transition-tree.d.ts.map +0 -1
- package/lib/typescript/configs/index.d.ts.map +0 -1
- package/lib/typescript/configs/presets.d.ts.map +0 -1
- package/lib/typescript/configs/specs.d.ts.map +0 -1
- package/lib/typescript/utils/animation/run-transition.d.ts +0 -12
- package/lib/typescript/utils/animation/run-transition.d.ts.map +0 -1
- package/src/components/bound-capture.tsx +0 -32
- package/src/utils/animation/run-transition.ts +0 -52
- /package/lib/commonjs/{configs → __configs__}/index.js +0 -0
- /package/lib/module/{configs → __configs__}/index.js +0 -0
- /package/lib/typescript/{configs → __configs__}/presets.d.ts +0 -0
- /package/lib/typescript/{configs → __configs__}/specs.d.ts +0 -0
- /package/src/{configs → __configs__}/index.ts +0 -0
|
@@ -1,72 +1,159 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
Fragment,
|
|
4
|
+
useCallback,
|
|
5
|
+
useContext,
|
|
6
|
+
useMemo,
|
|
7
|
+
} from "react";
|
|
2
8
|
import type { View } from "react-native";
|
|
3
9
|
import {
|
|
4
10
|
type AnimatedRef,
|
|
5
11
|
measure,
|
|
12
|
+
runOnJS,
|
|
13
|
+
runOnUI,
|
|
6
14
|
type StyleProps,
|
|
15
|
+
useAnimatedReaction,
|
|
7
16
|
useSharedValue,
|
|
8
17
|
} from "react-native-reanimated";
|
|
18
|
+
import type { SharedValue } from "react-native-reanimated/lib/typescript/commonTypes";
|
|
9
19
|
import { useKeys } from "../../providers/keys";
|
|
10
20
|
import { Bounds } from "../../stores/bounds";
|
|
11
21
|
import { flattenStyle } from "../../utils/bounds/_utils/flatten-styles";
|
|
12
22
|
import { isBoundsEqual } from "../../utils/bounds/_utils/is-bounds-equal";
|
|
23
|
+
import useStableCallback from "../use-stable-callback";
|
|
13
24
|
|
|
14
25
|
interface BoundMeasurerHookProps {
|
|
15
|
-
sharedBoundTag
|
|
26
|
+
sharedBoundTag?: string;
|
|
16
27
|
animatedRef: AnimatedRef<View>;
|
|
17
|
-
|
|
28
|
+
|
|
18
29
|
style: StyleProps;
|
|
30
|
+
onPress?: ((...args: unknown[]) => void) | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface MeasurementUpdateContextType {
|
|
34
|
+
updateSignal: SharedValue<number>;
|
|
19
35
|
}
|
|
20
36
|
|
|
37
|
+
const MeasurementUpdateContext =
|
|
38
|
+
createContext<MeasurementUpdateContextType | null>(null);
|
|
39
|
+
|
|
21
40
|
export const useBoundsRegistry = ({
|
|
22
41
|
sharedBoundTag,
|
|
23
42
|
animatedRef,
|
|
24
|
-
current,
|
|
25
43
|
style,
|
|
44
|
+
onPress,
|
|
26
45
|
}: BoundMeasurerHookProps) => {
|
|
27
|
-
const { previous } = useKeys();
|
|
46
|
+
const { previous, current } = useKeys();
|
|
28
47
|
|
|
29
|
-
const
|
|
48
|
+
const ROOT_MEASUREMENT_SIGNAL = useContext(MeasurementUpdateContext);
|
|
49
|
+
const ROOT_SIGNAL = useSharedValue(0);
|
|
50
|
+
const IS_ROOT = !ROOT_MEASUREMENT_SIGNAL;
|
|
51
|
+
const hasMeasured = useSharedValue(false);
|
|
30
52
|
|
|
31
|
-
const
|
|
53
|
+
const emitUpdate = useCallback(() => {
|
|
32
54
|
"worklet";
|
|
33
|
-
if (
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
if (IS_ROOT) ROOT_SIGNAL.value = ROOT_SIGNAL.value + 1;
|
|
56
|
+
}, [IS_ROOT, ROOT_SIGNAL]);
|
|
57
|
+
|
|
58
|
+
const maybeMeasureAndStore = useCallback(
|
|
59
|
+
({
|
|
60
|
+
onPress,
|
|
61
|
+
skipMarkingActive,
|
|
62
|
+
}: {
|
|
63
|
+
onPress?: () => void;
|
|
64
|
+
skipMarkingActive?: boolean;
|
|
65
|
+
}) => {
|
|
66
|
+
"worklet";
|
|
67
|
+
if (!sharedBoundTag) return;
|
|
68
|
+
|
|
69
|
+
const measured = measure(animatedRef);
|
|
70
|
+
|
|
71
|
+
if (!measured) {
|
|
72
|
+
console.warn(
|
|
73
|
+
`[react-native-screen-transitions] measure() returned null for sharedBoundTag="${sharedBoundTag}"`,
|
|
74
|
+
);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
36
78
|
const key = current.route.key;
|
|
79
|
+
|
|
37
80
|
if (isBoundsEqual({ measured, key, sharedBoundTag })) {
|
|
38
|
-
|
|
81
|
+
emitUpdate();
|
|
82
|
+
if (!skipMarkingActive) {
|
|
39
83
|
Bounds.setRouteActive(key, sharedBoundTag);
|
|
40
84
|
}
|
|
85
|
+
if (onPress) runOnJS(onPress)();
|
|
41
86
|
return;
|
|
42
87
|
}
|
|
43
88
|
|
|
89
|
+
emitUpdate();
|
|
90
|
+
|
|
44
91
|
Bounds.setBounds(key, sharedBoundTag, measured, flattenStyle(style));
|
|
45
|
-
if (
|
|
92
|
+
if (!skipMarkingActive) {
|
|
46
93
|
Bounds.setRouteActive(key, sharedBoundTag);
|
|
47
94
|
}
|
|
48
|
-
}
|
|
49
|
-
}, [sharedBoundTag, animatedRef, current.route.key, style]);
|
|
50
95
|
|
|
51
|
-
|
|
96
|
+
if (onPress) runOnJS(onPress)();
|
|
97
|
+
},
|
|
98
|
+
[sharedBoundTag, animatedRef, current.route.key, style, emitUpdate],
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const handleTransitionLayout = useCallback(() => {
|
|
52
102
|
"worklet";
|
|
53
|
-
const previousRouteKey = previous?.route.key;
|
|
54
103
|
|
|
55
|
-
|
|
104
|
+
const prevKey = previous?.route.key;
|
|
105
|
+
if (!sharedBoundTag || hasMeasured.value || !prevKey) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const prevBounds = Bounds.getBounds(prevKey)?.[sharedBoundTag];
|
|
110
|
+
|
|
111
|
+
if (prevBounds) {
|
|
112
|
+
// Should skip mark active if we are in a transition
|
|
113
|
+
maybeMeasureAndStore({ skipMarkingActive: true });
|
|
114
|
+
// Should not measure again while in transition
|
|
115
|
+
hasMeasured.value = true;
|
|
116
|
+
}
|
|
117
|
+
}, [maybeMeasureAndStore, sharedBoundTag, previous?.route.key, hasMeasured]);
|
|
118
|
+
|
|
119
|
+
const captureActiveOnPress = useStableCallback(() => {
|
|
120
|
+
if (!sharedBoundTag) {
|
|
121
|
+
if (onPress) onPress();
|
|
56
122
|
return;
|
|
57
123
|
}
|
|
58
124
|
|
|
59
|
-
|
|
60
|
-
|
|
125
|
+
// In this case, we DO want to mark active
|
|
126
|
+
runOnUI(maybeMeasureAndStore)({ onPress });
|
|
127
|
+
});
|
|
61
128
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
129
|
+
const MeasurementSyncProvider = useMemo(() => {
|
|
130
|
+
if (!IS_ROOT || !sharedBoundTag) {
|
|
131
|
+
return Fragment;
|
|
65
132
|
}
|
|
66
|
-
|
|
133
|
+
|
|
134
|
+
return ({ children }: { children: React.ReactNode }) => (
|
|
135
|
+
<MeasurementUpdateContext.Provider value={{ updateSignal: ROOT_SIGNAL }}>
|
|
136
|
+
{children}
|
|
137
|
+
</MeasurementUpdateContext.Provider>
|
|
138
|
+
);
|
|
139
|
+
}, [IS_ROOT, sharedBoundTag, ROOT_SIGNAL]);
|
|
140
|
+
|
|
141
|
+
useAnimatedReaction(
|
|
142
|
+
() => ROOT_MEASUREMENT_SIGNAL?.updateSignal.value,
|
|
143
|
+
(current) => {
|
|
144
|
+
"worklet";
|
|
145
|
+
|
|
146
|
+
// We don't want to run on the initial amount)
|
|
147
|
+
if (current === 0 || current === undefined) return;
|
|
148
|
+
|
|
149
|
+
// Children should not have the ability to mark active
|
|
150
|
+
maybeMeasureAndStore({ skipMarkingActive: true });
|
|
151
|
+
},
|
|
152
|
+
);
|
|
67
153
|
|
|
68
154
|
return {
|
|
69
|
-
|
|
70
|
-
|
|
155
|
+
handleTransitionLayout,
|
|
156
|
+
captureActiveOnPress,
|
|
157
|
+
MeasurementSyncProvider,
|
|
71
158
|
};
|
|
72
159
|
};
|
|
@@ -14,25 +14,27 @@ import {
|
|
|
14
14
|
type SharedValue,
|
|
15
15
|
useSharedValue,
|
|
16
16
|
} from "react-native-reanimated";
|
|
17
|
+
import {
|
|
18
|
+
DEFAULT_GESTURE_ACTIVATION_AREA,
|
|
19
|
+
DEFAULT_GESTURE_DIRECTION,
|
|
20
|
+
DEFAULT_GESTURE_DRIVES_PROGRESS,
|
|
21
|
+
DEFAULT_GESTURE_ENABLED,
|
|
22
|
+
GESTURE_VELOCITY_IMPACT,
|
|
23
|
+
} from "../../constants";
|
|
17
24
|
import type { ScrollConfig } from "../../providers/gestures";
|
|
18
25
|
import { useKeys } from "../../providers/keys";
|
|
19
26
|
import { Animations } from "../../stores/animations";
|
|
20
27
|
import { Gestures } from "../../stores/gestures";
|
|
21
28
|
import { NavigatorDismissState } from "../../stores/navigator-dismiss-state";
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import { runTransition } from "../../utils/animation/run-transition";
|
|
29
|
+
import { GestureOffsetState } from "../../types/gesture";
|
|
30
|
+
import { startScreenTransition } from "../../utils/animation/start-screen-transition";
|
|
25
31
|
import { applyOffsetRules } from "../../utils/gesture/check-gesture-activation";
|
|
26
32
|
import { determineDismissal } from "../../utils/gesture/determine-dismissal";
|
|
27
33
|
import { mapGestureToProgress } from "../../utils/gesture/map-gesture-to-progress";
|
|
34
|
+
import { resetGestureValues } from "../../utils/gesture/reset-gesture-values";
|
|
35
|
+
import { velocity } from "../../utils/gesture/velocity";
|
|
28
36
|
import useStableCallback from "../use-stable-callback";
|
|
29
37
|
|
|
30
|
-
const GESTURE_VELOCITY_IMPACT = 0.3;
|
|
31
|
-
const DEFAULT_GESTURE_DIRECTION = "horizontal";
|
|
32
|
-
const DEFAULT_GESTURE_ENABLED = false;
|
|
33
|
-
const DEFAULT_GESTURE_DRIVES_PROGRESS = true;
|
|
34
|
-
const DEFAULT_GESTURE_ACTIVATION_AREA: ActivationArea = "screen";
|
|
35
|
-
|
|
36
38
|
interface BuildGesturesHookProps {
|
|
37
39
|
scrollConfig: SharedValue<ScrollConfig | null>;
|
|
38
40
|
}
|
|
@@ -50,6 +52,7 @@ export const useBuildGestures = ({
|
|
|
50
52
|
x: 0,
|
|
51
53
|
y: 0,
|
|
52
54
|
});
|
|
55
|
+
|
|
53
56
|
const gestureOffsetState = useSharedValue<GestureOffsetState>(
|
|
54
57
|
GestureOffsetState.PENDING,
|
|
55
58
|
);
|
|
@@ -267,7 +270,7 @@ export const useBuildGestures = ({
|
|
|
267
270
|
(event: GestureStateChangeEvent<PanGestureHandlerEventPayload>) => {
|
|
268
271
|
"worklet";
|
|
269
272
|
|
|
270
|
-
const { shouldDismiss
|
|
273
|
+
const { shouldDismiss } = determineDismissal({
|
|
271
274
|
event,
|
|
272
275
|
directions,
|
|
273
276
|
dimensions,
|
|
@@ -276,29 +279,32 @@ export const useBuildGestures = ({
|
|
|
276
279
|
|
|
277
280
|
const spec = shouldDismiss ? transitionSpec?.close : transitionSpec?.open;
|
|
278
281
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
gestures.x.value = animate(0, { ...spec, velocity: vxPx });
|
|
287
|
-
gestures.y.value = animate(0, { ...spec, velocity: vyPx });
|
|
288
|
-
gestures.normalizedX.value = animate(0, { ...spec, velocity: vxNorm });
|
|
289
|
-
gestures.normalizedY.value = animate(0, { ...spec, velocity: vyNorm });
|
|
290
|
-
gestures.isDragging.value = 0;
|
|
282
|
+
resetGestureValues({
|
|
283
|
+
spec,
|
|
284
|
+
gestures,
|
|
285
|
+
shouldDismiss,
|
|
286
|
+
event,
|
|
287
|
+
dimensions,
|
|
288
|
+
});
|
|
291
289
|
|
|
292
290
|
if (shouldDismiss) {
|
|
293
291
|
runOnJS(setNavigatorDismissal)();
|
|
294
292
|
}
|
|
295
293
|
|
|
296
|
-
|
|
294
|
+
const initialVelocity = velocity.calculateProgressVelocity({
|
|
295
|
+
animations,
|
|
296
|
+
shouldDismiss,
|
|
297
|
+
event,
|
|
298
|
+
dimensions,
|
|
299
|
+
directions,
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
startScreenTransition({
|
|
297
303
|
target: shouldDismiss ? "close" : "open",
|
|
298
|
-
|
|
304
|
+
onAnimationFinish: shouldDismiss ? handleDismiss : undefined,
|
|
299
305
|
spec: transitionSpec,
|
|
300
|
-
velocity,
|
|
301
306
|
animations,
|
|
307
|
+
initialVelocity,
|
|
302
308
|
});
|
|
303
309
|
},
|
|
304
310
|
[
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlatList, Pressable, ScrollView, View } from "react-native";
|
|
2
|
+
import { presets, specs } from "./__configs__";
|
|
2
3
|
import { createTransitionAwareComponent } from "./components/create-transition-aware-component";
|
|
3
4
|
import MaskedView from "./components/integrations/masked-view";
|
|
4
|
-
import { presets, specs } from "./configs";
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
View: createTransitionAwareComponent(View),
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export function debounce<T extends (...args: any[]) => void>(
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
func: T,
|
|
3
|
+
duration: number,
|
|
4
4
|
): T {
|
|
5
|
-
|
|
5
|
+
let timeout: ReturnType<typeof setTimeout>;
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
return function (this: unknown, ...args) {
|
|
8
|
+
clearTimeout(timeout);
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
timeout = setTimeout(() => {
|
|
11
|
+
func.apply(this, args);
|
|
12
|
+
}, duration);
|
|
13
|
+
} as T;
|
|
14
14
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import type { Animated } from
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import type { Animated } from "react-native";
|
|
3
3
|
|
|
4
4
|
export const AnimatedHeaderHeightContext = React.createContext<
|
|
5
|
-
|
|
5
|
+
Animated.AnimatedInterpolation<number> | undefined
|
|
6
6
|
>(undefined);
|
|
7
7
|
|
|
8
8
|
export function useAnimatedHeaderHeight() {
|
|
9
|
-
|
|
9
|
+
const animatedValue = React.useContext(AnimatedHeaderHeightContext);
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
if (animatedValue === undefined) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"Couldn't find the header height. Are you inside a screen in a native stack navigator?",
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
return animatedValue;
|
|
18
18
|
}
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from
|
|
5
|
-
import * as React from
|
|
2
|
+
ParamListBase,
|
|
3
|
+
StackNavigationState,
|
|
4
|
+
} from "@react-navigation/native";
|
|
5
|
+
import * as React from "react";
|
|
6
6
|
|
|
7
7
|
export function useDismissedRouteError(
|
|
8
|
-
|
|
8
|
+
state: StackNavigationState<ParamListBase>,
|
|
9
9
|
) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const [nextDismissedKey, setNextDismissedKey] = React.useState<string | null>(
|
|
11
|
+
null,
|
|
12
|
+
);
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const dismissedRouteName = nextDismissedKey
|
|
15
|
+
? state.routes.find((route) => route.key === nextDismissedKey)?.name
|
|
16
|
+
: null;
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
React.useEffect(() => {
|
|
19
|
+
if (dismissedRouteName) {
|
|
20
|
+
const message =
|
|
21
|
+
`The screen '${dismissedRouteName}' was removed natively but didn't get removed from JS state. ` +
|
|
22
|
+
`This can happen if the action was prevented in a 'beforeRemove' listener, which is not fully supported in native-stack.\n\n` +
|
|
23
|
+
`Consider using a 'usePreventRemove' hook with 'headerBackButtonMenuEnabled: false' to prevent users from natively going back multiple screens.`;
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
console.error(message);
|
|
26
|
+
}
|
|
27
|
+
}, [dismissedRouteName]);
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
return { setNextDismissedKey };
|
|
30
30
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// @ts-expect-error importing private module
|
|
2
|
-
import ReactNativeStyleAttributes from
|
|
2
|
+
import ReactNativeStyleAttributes from "react-native/Libraries/Components/View/ReactNativeStyleAttributes";
|
|
3
3
|
|
|
4
4
|
export function processFonts(
|
|
5
|
-
|
|
5
|
+
fontFamilies: (string | undefined)[],
|
|
6
6
|
): (string | undefined)[] {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const fontFamilyProcessor = ReactNativeStyleAttributes.fontFamily?.process;
|
|
8
|
+
if (typeof fontFamilyProcessor === "function") {
|
|
9
|
+
return fontFamilies.map(fontFamilyProcessor);
|
|
10
|
+
}
|
|
11
|
+
return fontFamilies;
|
|
12
12
|
}
|
|
@@ -32,7 +32,7 @@ import {
|
|
|
32
32
|
ScreenStack,
|
|
33
33
|
ScreenStackItem,
|
|
34
34
|
} from "react-native-screens";
|
|
35
|
-
import {
|
|
35
|
+
import { ScreenTransitionProvider } from "../../../providers/screen-transition-provider";
|
|
36
36
|
import type {
|
|
37
37
|
NativeStackDescriptor,
|
|
38
38
|
NativeStackDescriptorMap,
|
|
@@ -267,12 +267,12 @@ const SceneView = ({
|
|
|
267
267
|
}, [canGoBack, backTitle]);
|
|
268
268
|
|
|
269
269
|
const isRemovePrevented = preventedRoutes[route.key]?.preventRemove;
|
|
270
|
+
|
|
270
271
|
const modifiedPresentation = enableTransitions
|
|
271
272
|
? "containedTransparentModal"
|
|
272
273
|
: presentation === "card"
|
|
273
274
|
? "push"
|
|
274
275
|
: presentation;
|
|
275
|
-
|
|
276
276
|
const modifiedAnimation = enableTransitions ? "none" : animation;
|
|
277
277
|
const modifiedHeaderShown =
|
|
278
278
|
enableTransitions || header !== undefined ? false : headerShown;
|
|
@@ -465,13 +465,13 @@ const SceneView = ({
|
|
|
465
465
|
value={isParentHeaderShown || headerShown !== false}
|
|
466
466
|
>
|
|
467
467
|
<HeaderBackContext.Provider value={headerBack}>
|
|
468
|
-
<
|
|
468
|
+
<ScreenTransitionProvider
|
|
469
469
|
previous={previousDescriptor}
|
|
470
470
|
current={descriptor}
|
|
471
471
|
next={nextDescriptor}
|
|
472
472
|
>
|
|
473
473
|
{render()}
|
|
474
|
-
</
|
|
474
|
+
</ScreenTransitionProvider>
|
|
475
475
|
</HeaderBackContext.Provider>
|
|
476
476
|
</HeaderShownContext.Provider>
|
|
477
477
|
</HeaderHeightContext.Provider>
|
|
@@ -26,15 +26,6 @@ type ScreenGestureProviderProps = {
|
|
|
26
26
|
children: React.ReactNode;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export const DEFAULT_SCROLL_CONFIG: ScrollConfig = {
|
|
30
|
-
x: 0,
|
|
31
|
-
y: 0,
|
|
32
|
-
contentHeight: 0,
|
|
33
|
-
contentWidth: 0,
|
|
34
|
-
layoutHeight: 0,
|
|
35
|
-
layoutWidth: 0,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
29
|
const GestureContext = createContext<GestureContextType | undefined>(undefined);
|
|
39
30
|
|
|
40
31
|
export const ScreenGestureProvider = ({
|
package/src/{components/screen-transition-tree.tsx → providers/screen-transition-provider.tsx}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
|
+
import { ScreenLifecycleController } from "../components/controllers/screen-lifecycle";
|
|
3
|
+
import { RootTransitionAware } from "../components/root-transition-aware";
|
|
2
4
|
import { ScreenGestureProvider } from "../providers/gestures";
|
|
3
5
|
import { KeysProvider } from "../providers/keys";
|
|
4
6
|
import { TransitionStylesProvider } from "../providers/transition-styles";
|
|
5
7
|
import type { NativeStackDescriptor } from "../types/navigator";
|
|
6
|
-
import { ScreenLifecycleController } from "./controllers/screen-lifecycle";
|
|
7
|
-
import { RootTransitionAware } from "./root-transition-aware";
|
|
8
8
|
|
|
9
9
|
type Props = {
|
|
10
10
|
previous?: NativeStackDescriptor;
|
|
@@ -13,7 +13,7 @@ type Props = {
|
|
|
13
13
|
children: React.ReactNode;
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export function
|
|
16
|
+
export function ScreenTransitionProvider({
|
|
17
17
|
previous,
|
|
18
18
|
current,
|
|
19
19
|
next,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, useContext, useMemo } from "react";
|
|
2
2
|
import { isWorkletFunction, useDerivedValue } from "react-native-reanimated";
|
|
3
|
+
import { NO_STYLES } from "../constants";
|
|
3
4
|
import { _useScreenAnimation } from "../hooks/animation/use-screen-animation";
|
|
4
5
|
import type { TransitionInterpolatedStyle } from "../types/animation";
|
|
5
6
|
|
|
@@ -7,8 +8,6 @@ type Props = {
|
|
|
7
8
|
children: React.ReactNode;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
|
-
const EMPTY_MAP = Object.freeze({});
|
|
11
|
-
|
|
12
11
|
const TransitionStylesContext = createContext<ReturnType<
|
|
13
12
|
typeof useMemo<{
|
|
14
13
|
stylesMap: ReturnType<typeof useDerivedValue<TransitionInterpolatedStyle>>;
|
|
@@ -25,13 +24,15 @@ export function TransitionStylesProvider({ children }: Props) {
|
|
|
25
24
|
"worklet";
|
|
26
25
|
|
|
27
26
|
if (screenStyleInterpolator && !isFunctionWorklet && __DEV__) {
|
|
28
|
-
console.warn(
|
|
29
|
-
|
|
27
|
+
console.warn(
|
|
28
|
+
`[react-native-screen-transitions] screenStyleInterpolator is not a worklet function`,
|
|
29
|
+
);
|
|
30
|
+
return NO_STYLES;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
return screenStyleInterpolator
|
|
33
34
|
? screenStyleInterpolator(screenInterpolatorProps.value)
|
|
34
|
-
:
|
|
35
|
+
: NO_STYLES;
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
const value = useMemo(() => {
|
package/src/types/core.ts
CHANGED
|
@@ -42,15 +42,6 @@ export type TransitionAwareProps<T extends object> = AnimatedProps<T> & {
|
|
|
42
42
|
* </Transition.View>
|
|
43
43
|
*/
|
|
44
44
|
sharedBoundTag?: string;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Eagerly measure this component on layout and store the result in the
|
|
48
|
-
* Bounds registry. Useful for nested shared elements that may not receive
|
|
49
|
-
* the press event but still need up-to-date measurements at navigation time.
|
|
50
|
-
*
|
|
51
|
-
* Only has an effect when used together with `sharedBoundTag`.
|
|
52
|
-
*/
|
|
53
|
-
measureOnLayout?: boolean;
|
|
54
45
|
};
|
|
55
46
|
|
|
56
47
|
export type TransitionConfig = {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { runOnJS } from "react-native-reanimated";
|
|
2
|
+
import type { AnimationMap } from "../../stores/animations";
|
|
3
|
+
import type { TransitionSpec } from "../../types/animation";
|
|
4
|
+
import { animate } from "./animate";
|
|
5
|
+
|
|
6
|
+
interface StartScreenTransitionProps {
|
|
7
|
+
target: "open" | "close";
|
|
8
|
+
spec?: TransitionSpec;
|
|
9
|
+
onAnimationFinish?: (finished: boolean) => void;
|
|
10
|
+
animations: AnimationMap;
|
|
11
|
+
/** Optional initial velocity for spring-based progress (units: progress/sec). */
|
|
12
|
+
initialVelocity?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const startScreenTransition = ({
|
|
16
|
+
target,
|
|
17
|
+
spec,
|
|
18
|
+
onAnimationFinish,
|
|
19
|
+
animations,
|
|
20
|
+
initialVelocity,
|
|
21
|
+
}: StartScreenTransitionProps) => {
|
|
22
|
+
"worklet";
|
|
23
|
+
const value = target === "open" ? 1 : 0;
|
|
24
|
+
const config = target === "open" ? spec?.open : spec?.close;
|
|
25
|
+
|
|
26
|
+
const isSpringConfig =
|
|
27
|
+
!!config && !("duration" in config) && !("easing" in config);
|
|
28
|
+
|
|
29
|
+
const effectiveConfig =
|
|
30
|
+
isSpringConfig && typeof initialVelocity === "number"
|
|
31
|
+
? { ...config, velocity: initialVelocity }
|
|
32
|
+
: config;
|
|
33
|
+
|
|
34
|
+
const { progress, animating, closing } = animations;
|
|
35
|
+
|
|
36
|
+
if (target === "close") {
|
|
37
|
+
closing.value = 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!config) {
|
|
41
|
+
animating.value = 0;
|
|
42
|
+
progress.value = value;
|
|
43
|
+
|
|
44
|
+
if (onAnimationFinish) {
|
|
45
|
+
runOnJS(onAnimationFinish)(true);
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
animating.value = 1;
|
|
51
|
+
|
|
52
|
+
progress.value = animate(value, effectiveConfig, (finished) => {
|
|
53
|
+
"worklet";
|
|
54
|
+
if (finished) {
|
|
55
|
+
if (onAnimationFinish) {
|
|
56
|
+
runOnJS(onAnimationFinish)(finished);
|
|
57
|
+
}
|
|
58
|
+
animating.value = 0;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ScreenTransitionState } from "../../../types/animation";
|
|
2
|
+
import type { ScreenPhase } from "../../../types/core";
|
|
3
3
|
|
|
4
4
|
export type GetBoundsParams = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
id: string | null;
|
|
6
|
+
phase?: ScreenPhase;
|
|
7
|
+
previous?: ScreenTransitionState;
|
|
8
|
+
current: ScreenTransitionState;
|
|
9
|
+
next?: ScreenTransitionState;
|
|
10
10
|
};
|