Skip to content

Commit 3caba34

Browse files
authored
Merge pull request Expensify#64805 from software-mansion-labs/feat/use-react-native-reanimated-in-fullscreen-modals
Use ReanimatedModal for FULLSCREEN modals
2 parents 139bd29 + 9a7101f commit 3caba34

11 files changed

Lines changed: 42 additions & 27 deletions

File tree

src/components/Modal/BaseModal.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,27 @@ import Navigation from '@libs/Navigation/Navigation';
2323
import variables from '@styles/variables';
2424
import {areAllModalsHidden, closeTop, onModalDidClose, setCloseModal, setModalVisibility, willAlertModalBecomeVisible} from '@userActions/Modal';
2525
import CONST from '@src/CONST';
26-
import BottomDockedModal from './BottomDockedModal';
27-
import type ModalProps from './BottomDockedModal/types';
2826
import ModalContent from './ModalContent';
2927
import ModalContext from './ModalContext';
28+
import ReanimatedModal from './ReanimatedModal';
29+
import type ReanimatedModalProps from './ReanimatedModal/types';
3030
import type BaseModalProps from './types';
3131

32-
type ModalComponentProps = (ReactNativeModalProps | ModalProps) & {
32+
const REANIMATED_MODAL_TYPES: Array<ValueOf<typeof CONST.MODAL.MODAL_TYPE>> = [CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED, CONST.MODAL.MODAL_TYPE.FULLSCREEN];
33+
34+
type ModalComponentProps = (ReactNativeModalProps | ReanimatedModalProps) & {
3335
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;
3436
};
3537

3638
function ModalComponent({type, ...props}: ModalComponentProps) {
37-
if (type === CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED) {
38-
// eslint-disable-next-line react/jsx-props-no-spreading
39-
return <BottomDockedModal {...(props as ModalProps)} />;
39+
if (type && REANIMATED_MODAL_TYPES.includes(type)) {
40+
return (
41+
<ReanimatedModal
42+
// eslint-disable-next-line react/jsx-props-no-spreading
43+
{...(props as ReanimatedModalProps)}
44+
type={type}
45+
/>
46+
);
4047
}
4148
// eslint-disable-next-line react/jsx-props-no-spreading
4249
return <ReactNativeModal {...(props as ReactNativeModalProps)} />;

src/components/Modal/BottomDockedModal/Backdrop/index.tsx renamed to src/components/Modal/ReanimatedModal/Backdrop/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, {useMemo} from 'react';
22
import Animated, {Easing, Keyframe} from 'react-native-reanimated';
3-
import type {BackdropProps} from '@components/Modal/BottomDockedModal/types';
3+
import type {BackdropProps} from '@components/Modal/ReanimatedModal/types';
44
import {PressableWithoutFeedback} from '@components/Pressable';
55
import useLocalize from '@hooks/useLocalize';
66
import useThemeStyles from '@hooks/useThemeStyles';

src/components/Modal/BottomDockedModal/Backdrop/index.web.tsx renamed to src/components/Modal/ReanimatedModal/Backdrop/index.web.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, {useMemo} from 'react';
22
import {View} from 'react-native';
33
import Animated, {Easing, Keyframe} from 'react-native-reanimated';
4-
import type {BackdropProps} from '@components/Modal/BottomDockedModal/types';
4+
import type {BackdropProps} from '@components/Modal/ReanimatedModal/types';
55
import {PressableWithoutFeedback} from '@components/Pressable';
66
import useLocalize from '@hooks/useLocalize';
77
import useThemeStyles from '@hooks/useThemeStyles';

src/components/Modal/BottomDockedModal/Container/index.tsx renamed to src/components/Modal/ReanimatedModal/Container/index.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import React, {useMemo} from 'react';
22
import {View} from 'react-native';
33
import Animated, {Easing, Keyframe, runOnJS} from 'react-native-reanimated';
4-
import type ModalProps from '@components/Modal/BottomDockedModal/types';
5-
import type {ContainerProps} from '@components/Modal/BottomDockedModal/types';
4+
import type ReanimatedModalProps from '@components/Modal/ReanimatedModal/types';
5+
import type {ContainerProps} from '@components/Modal/ReanimatedModal/types';
66
import useThemeStyles from '@hooks/useThemeStyles';
7+
import CONST from '@src/CONST';
78

89
const easing = Easing.bezier(0.76, 0.0, 0.24, 1.0).factory();
910

10-
function Container({style, animationInTiming = 300, animationOutTiming = 300, onCloseCallBack, onOpenCallBack, ...props}: Partial<ModalProps> & ContainerProps) {
11+
function Container({style, animationInTiming = 300, animationOutTiming = 300, onCloseCallBack, onOpenCallBack, type, ...props}: Partial<ReanimatedModalProps> & ContainerProps) {
1112
const styles = useThemeStyles();
1213

1314
const Entering = useMemo(() => {
@@ -49,7 +50,7 @@ function Container({style, animationInTiming = 300, animationOutTiming = 300, on
4950
{...props}
5051
>
5152
<Animated.View
52-
style={styles.modalAnimatedContainer}
53+
style={[styles.modalAnimatedContainer, type !== CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED && styles.flex1]}
5354
entering={Entering}
5455
exiting={Exiting}
5556
>

src/components/Modal/BottomDockedModal/Container/index.web.tsx renamed to src/components/Modal/ReanimatedModal/Container/index.web.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import React, {useEffect, useMemo, useRef} from 'react';
22
import Animated, {Easing, Keyframe, useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
3-
import type ModalProps from '@components/Modal/BottomDockedModal/types';
4-
import type {ContainerProps} from '@components/Modal/BottomDockedModal/types';
3+
import type ReanimatedModalProps from '@components/Modal/ReanimatedModal/types';
4+
import type {ContainerProps} from '@components/Modal/ReanimatedModal/types';
55
import useThemeStyles from '@hooks/useThemeStyles';
66

77
const easing = Easing.bezier(0.76, 0.0, 0.24, 1.0).factory();
88

9-
function Container({style, animationInTiming = 300, animationOutTiming = 300, onOpenCallBack, onCloseCallBack, ...props}: ModalProps & ContainerProps) {
9+
function Container({style, animationInTiming = 300, animationOutTiming = 300, onOpenCallBack, onCloseCallBack, ...props}: ReanimatedModalProps & ContainerProps) {
1010
const styles = useThemeStyles();
1111
const onCloseCallbackRef = useRef(onCloseCallBack);
1212
const opacity = useSharedValue(0);

src/components/Modal/BottomDockedModal/index.tsx renamed to src/components/Modal/ReanimatedModal/index.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import getPlatform from '@libs/getPlatform';
99
import CONST from '@src/CONST';
1010
import Backdrop from './Backdrop';
1111
import Container from './Container';
12-
import type ModalProps from './types';
12+
import type ReanimatedModalProps from './types';
1313

14-
function BottomDockedModal({
14+
function ReanimatedModal({
1515
testID,
1616
animationInDelay,
1717
animationInTiming = 300,
@@ -32,9 +32,10 @@ function BottomDockedModal({
3232
onBackdropPress = noop,
3333
onBackButtonPress = noop,
3434
style,
35+
type,
3536
statusBarTranslucent = false,
3637
...props
37-
}: ModalProps) {
38+
}: ReanimatedModalProps) {
3839
const [isVisibleState, setIsVisibleState] = useState(isVisible);
3940
const [isContainerOpen, setIsContainerOpen] = useState(false);
4041
const [isTransitioning, setIsTransitioning] = useState(false);
@@ -141,6 +142,7 @@ function BottomDockedModal({
141142
onOpenCallBack={onOpenCallBack}
142143
onCloseCallBack={onCloseCallBack}
143144
style={style}
145+
type={type}
144146
>
145147
{children}
146148
</Container>
@@ -207,6 +209,6 @@ function BottomDockedModal({
207209
);
208210
}
209211

210-
BottomDockedModal.displayName = 'BottomDockedModal';
212+
ReanimatedModal.displayName = 'ReanimatedModal';
211213

212-
export default BottomDockedModal;
214+
export default ReanimatedModal;

src/components/Modal/BottomDockedModal/types.ts renamed to src/components/Modal/ReanimatedModal/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {NativeSyntheticEvent, StyleProp, ViewProps, ViewStyle} from 'react-
33
import type {ModalProps as ReactNativeModalProps} from 'react-native-modal';
44
import type {SharedValue} from 'react-native-reanimated';
55
import type {ValueOf} from 'type-fest';
6+
import type CONST from '@src/CONST';
67

78
type GestureProps = {
89
/** Height of the device (used for positioning) */
@@ -14,7 +15,7 @@ type GestureProps = {
1415

1516
type AnimationOut = ValueOf<Pick<ReactNativeModalProps, 'animationOut'>>;
1617

17-
type ModalProps = ViewProps &
18+
type ReanimatedModalProps = ViewProps &
1819
GestureProps & {
1920
/** Content inside the modal */
2021
children: ReactNode;
@@ -115,6 +116,9 @@ type ModalProps = ViewProps &
115116
supportedOrientations?: Array<'portrait' | 'portrait-upside-down' | 'landscape' | 'landscape-left' | 'landscape-right'>;
116117

117118
navigationBarTranslucent?: boolean;
119+
120+
/** Modal type */
121+
type?: ValueOf<typeof CONST.MODAL.MODAL_TYPE>;
118122
};
119123

120124
type BackdropProps = {
@@ -154,5 +158,5 @@ type ContainerProps = {
154158
panPosition?: {translateX: SharedValue<number>; translateY: SharedValue<number>};
155159
};
156160

157-
export default ModalProps;
161+
export default ReanimatedModalProps;
158162
export type {BackdropProps, ContainerProps, AnimationOut};

src/components/Modal/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type {GestureResponderEvent, PanResponderGestureState, ViewStyle} from 'r
33
import type {Direction, ModalProps as ReactNativeModalProps} from 'react-native-modal';
44
import type {ValueOf} from 'type-fest';
55
import type CONST from '@src/CONST';
6-
import type BottomDockedModalProps from './BottomDockedModal/types';
6+
import type ReanimatedModalProps from './ReanimatedModal/types';
77

88
type FocusTrapOptions = Exclude<FocusTrapProps['focusTrapOptions'], undefined>;
99

@@ -19,7 +19,7 @@ type WindowState = {
1919
};
2020

2121
type BaseModalProps = Partial<ReactNativeModalProps> &
22-
Partial<BottomDockedModalProps> & {
22+
Partial<ReanimatedModalProps> & {
2323
/** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */
2424
fullscreen?: boolean;
2525

src/components/PopoverMenu.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import FocusTrapForModal from './FocusTrap/FocusTrapForModal';
2525
import * as Expensicons from './Icon/Expensicons';
2626
import type {MenuItemProps} from './MenuItem';
2727
import MenuItem from './MenuItem';
28-
import type BottomDockedModalProps from './Modal/BottomDockedModal/types';
28+
import type ReanimatedModalProps from './Modal/ReanimatedModal/types';
2929
import type BaseModalProps from './Modal/types';
3030
import OfflineWithFeedback from './OfflineWithFeedback';
3131
import PopoverWithMeasuredContent from './PopoverWithMeasuredContent';
@@ -69,7 +69,7 @@ type PopoverMenuItem = MenuItemProps & {
6969
testID?: string;
7070
};
7171

72-
type PopoverModalProps = Pick<ModalProps, 'animationIn' | 'animationOut' | 'animationInTiming' | 'animationOutTiming'> & Pick<BottomDockedModalProps, 'animationInDelay'>;
72+
type PopoverModalProps = Pick<ModalProps, 'animationIn' | 'animationOut' | 'animationInTiming' | 'animationOutTiming'> & Pick<ReanimatedModalProps, 'animationInDelay'>;
7373

7474
type PopoverMenuProps = Partial<PopoverModalProps> & {
7575
/** Callback method fired when the user requests to close the modal */

src/pages/settings/Subscription/SubscriptionPlan/ComparePlansModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react';
22
import {View} from 'react-native';
33
import HeaderWithBackButton from '@components/HeaderWithBackButton';
44
import Modal from '@components/Modal';
5-
import type {AnimationOut} from '@components/Modal/BottomDockedModal/types';
5+
import type {AnimationOut} from '@components/Modal/ReanimatedModal/types';
66
import ScrollView from '@components/ScrollView';
77
import Text from '@components/Text';
88
import TextLink from '@components/TextLink';

0 commit comments

Comments
 (0)