Skip to content

Commit 2cf7c53

Browse files
authored
Merge pull request Expensify#69444 from software-mansion-labs/reduce-motion-reanimated-patch
2 parents faa6258 + c2f4c7e commit 2cf7c53

4 files changed

Lines changed: 57 additions & 4 deletions

File tree

patches/react-native-reanimated/details.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,9 @@
2222
- E/App issue: https://github.com/Expensify/App/pull/63623
2323
- PR Introducing Patch: 🛑
2424

25+
### [react-native-reanimated+3.19.1+004+reduce-motion-animation-callbacks.patch](react-native-reanimated+3.19.1+004+reduce-motion-animation-callbacks.patch)
26+
27+
- Reason: The layout animation callbacks were not called when Reduce Motion accessibility setting was enabled on mobile devices (on native apps). This caused the app to be unresponsive after opening a modal.
28+
- Upstream PR/issue: https://github.com/software-mansion/react-native-reanimated/pull/8142
29+
- E/App issue: https://github.com/Expensify/App/issues/69190
30+
- PR Introducing Patch: https://github.com/Expensify/App/pull/69444
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
diff --git a/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx b/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx
2+
index a2f6cf1..93a37f5 100644
3+
--- a/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx
4+
+++ b/node_modules/react-native-reanimated/src/createAnimatedComponent/createAnimatedComponent.tsx
5+
@@ -503,13 +503,6 @@ export function createAnimatedComponent(
6+
return;
7+
}
8+
9+
- if (this._isReducedMotion(currentConfig)) {
10+
- if (!previousConfig) {
11+
- return;
12+
- }
13+
- currentConfig = undefined;
14+
- }
15+
-
16+
updateLayoutAnimations(
17+
isFabric() && type === LayoutAnimationType.ENTERING
18+
? this.reanimatedID
19+
@@ -608,14 +601,6 @@ export function createAnimatedComponent(
20+
},
21+
});
22+
23+
- _isReducedMotion(config?: LayoutAnimationOrBuilder): boolean {
24+
- return config &&
25+
- 'getReduceMotion' in config &&
26+
- typeof config.getReduceMotion === 'function'
27+
- ? getReduceMotionFromConfig(config.getReduceMotion())
28+
- : getReduceMotionFromConfig();
29+
- }
30+
-
31+
// This is a component lifecycle method from React, therefore we are not calling it directly.
32+
// It is called before the component gets rerendered. This way we can access components' position before it changed
33+
// and later on, in componentDidUpdate, calculate translation for layout transition.

src/components/Modal/ReanimatedModal/Backdrop/index.web.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useMemo} from 'react';
22
import {View} from 'react-native';
3-
import Animated, {Keyframe} from 'react-native-reanimated';
3+
import Animated, {Keyframe, ReduceMotion} from 'react-native-reanimated';
44
import type {BackdropProps} from '@components/Modal/ReanimatedModal/types';
55
import {getModalInAnimation, getModalOutAnimation} from '@components/Modal/ReanimatedModal/utils';
66
import {PressableWithoutFeedback} from '@components/Pressable';
@@ -26,15 +26,15 @@ function Backdrop({
2626
return;
2727
}
2828
const FadeIn = new Keyframe(getModalInAnimation('fadeIn'));
29-
return FadeIn.duration(animationInTiming);
29+
return FadeIn.duration(animationInTiming).reduceMotion(ReduceMotion.Never);
3030
}, [animationInTiming, backdropOpacity]);
3131

3232
const Exiting = useMemo(() => {
3333
if (!backdropOpacity) {
3434
return;
3535
}
3636
const FadeOut = new Keyframe(getModalOutAnimation('fadeOut'));
37-
return FadeOut.duration(animationOutTiming);
37+
return FadeOut.duration(animationOutTiming).reduceMotion(ReduceMotion.Never);
3838
}, [animationOutTiming, backdropOpacity]);
3939

4040
const backdropStyle = useMemo(

src/components/Modal/ReanimatedModal/Container/index.web.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,19 @@ function Container({
3131
return;
3232
}
3333
isInitiated.set(true);
34-
initProgress.set(withTiming(1, {duration: animationInTiming, easing, reduceMotion: ReduceMotion.Never}, onOpenCallBack));
34+
initProgress.set(
35+
withTiming(
36+
1,
37+
{
38+
duration: animationInTiming,
39+
easing,
40+
// on web the callbacks are not called when animations are disabled with the reduced motion setting on
41+
// we enable the animations to make sure they are called
42+
reduceMotion: ReduceMotion.Never,
43+
},
44+
onOpenCallBack,
45+
),
46+
);
3547
}, [animationInTiming, onOpenCallBack, initProgress, isInitiated]);
3648

3749
// instead of an entering transition since keyframe animations break keyboard on mWeb Chrome (#62799)
@@ -43,6 +55,8 @@ function Container({
4355
.duration(animationOutTiming)
4456
// eslint-disable-next-line react-compiler/react-compiler
4557
.withCallback(() => onCloseCallbackRef.current())
58+
// on web the callbacks are not called when animations are disabled with the reduced motion setting on
59+
// we enable the animations to make sure they are called
4660
.reduceMotion(ReduceMotion.Never),
4761
[animationOutTiming, animationOut],
4862
);

0 commit comments

Comments
 (0)