Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 67 additions & 77 deletions packages/react-native/Libraries/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {RootTag} from '../ReactNative/RootTag';
import type {DirectEventHandler} from '../Types/CodegenTypes';

import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
import {type ColorValue} from '../StyleSheet/StyleSheet';
import {type EventSubscription} from '../vendor/emitter/EventEmitter';
import ModalInjection from './ModalInjection';
import NativeModalManager from './NativeModalManager';
Expand Down Expand Up @@ -60,99 +61,62 @@ type OrientationChangeEvent = $ReadOnly<{
orientation: 'portrait' | 'landscape',
}>;

export type Props = $ReadOnly<{
...ViewProps,

export type ModalBaseProps = {
/**
* The `animationType` prop controls how the modal animates.
*
* See https://reactnative.dev/docs/modal#animationtype
* @deprecated Use animationType instead
*/
animationType?: ?('none' | 'slide' | 'fade'),

animated?: boolean,
/**
* The `presentationStyle` prop controls how the modal appears.
* The `animationType` prop controls how the modal animates.
*
* See https://reactnative.dev/docs/modal#presentationstyle
* - `slide` slides in from the bottom
* - `fade` fades into view
* - `none` appears without an animation
*/
presentationStyle?: ?(
| 'fullScreen'
| 'pageSheet'
| 'formSheet'
| 'overFullScreen'
),

animationType?: ?('none' | 'slide' | 'fade'),
/**
* The `transparent` prop determines whether your modal will fill the
* entire view.
*
* See https://reactnative.dev/docs/modal#transparent
* The `transparent` prop determines whether your modal will fill the entire view.
* Setting this to `true` will render the modal over a transparent background.
*/
transparent?: ?boolean,

/**
* The `statusBarTranslucent` prop determines whether your modal should go under
* the system statusbar.
*
* See https://reactnative.dev/docs/modal.html#statusbartranslucent-android
*/
statusBarTranslucent?: ?boolean,

/**
* The `navigationBarTranslucent` prop determines whether your modal should go under
* the system navigationbar.
*
* See https://reactnative.dev/docs/modal.html#navigationbartranslucent-android
*/
navigationBarTranslucent?: ?boolean,

/**
* The `hardwareAccelerated` prop controls whether to force hardware
* acceleration for the underlying window.
*
* This prop works only on Android.
*
* See https://reactnative.dev/docs/modal#hardwareaccelerated
*/
hardwareAccelerated?: ?boolean,

/**
* The `visible` prop determines whether your modal is visible.
*
* See https://reactnative.dev/docs/modal#visible
*/
visible?: ?boolean,

/**
* The `onRequestClose` callback is called when the user taps the hardware
* back button on Android or the menu button on Apple TV.
* The `onRequestClose` callback is called when the user taps the hardware back button on Android or the menu button on Apple TV.
*
* This is required on Apple TV and Android.
*
* See https://reactnative.dev/docs/modal#onrequestclose
*/
// onRequestClose?: (event: NativeSyntheticEvent<any>) => void;
onRequestClose?: ?DirectEventHandler<null>,

/**
* The `onShow` prop allows passing a function that will be called once the
* modal has been shown.
*
* See https://reactnative.dev/docs/modal#onshow
* The `onShow` prop allows passing a function that will be called once the modal has been shown.
*/
// onShow?: (event: NativeSyntheticEvent<any>) => void;
onShow?: ?DirectEventHandler<null>,

/**
* The `onDismiss` prop allows passing a function that will be called once
* the modal has been dismissed.
*
* See https://reactnative.dev/docs/modal#ondismiss
* The `backdropColor` props sets the background color of the modal's container.
* Defaults to `white` if not provided and transparent is `false`. Ignored if `transparent` is `true`.
*/
onDismiss?: ?() => mixed,
backdropColor?: ColorValue,
};

export type ModalPropsIOS = {
/**
* The `presentationStyle` determines the style of modal to show
*/
presentationStyle?: ?(
| 'fullScreen'
| 'pageSheet'
| 'formSheet'
| 'overFullScreen'
),

/**
* The `supportedOrientations` prop allows the modal to be rotated to any of the specified orientations.
*
* See https://reactnative.dev/docs/modal#supportedorientations
* On iOS, the modal is still restricted by what's specified in your app's Info.plist's UISupportedInterfaceOrientations field.
*/
supportedOrientations?: ?$ReadOnlyArray<
| 'portrait'
Expand All @@ -162,21 +126,47 @@ export type Props = $ReadOnly<{
| 'landscape-right',
>,

/**
* The `onDismiss` prop allows passing a function that will be called once the modal has been dismissed.
*/
// onDismiss?: (() => void) | undefined;
onDismiss?: ?() => void,

/**
* The `onOrientationChange` callback is called when the orientation changes while the modal is being displayed.
*
* See https://reactnative.dev/docs/modal#onorientationchange
* The orientation provided is only 'portrait' or 'landscape'. This callback is also called on initial render, regardless of the current orientation.
*/
// onOrientationChange?:
// | ((event: NativeSyntheticEvent<any>) => void)
// | undefined;
onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
};

export type ModalPropsAndroid = {
/**
* The `backdropColor` props sets the background color of the modal's container.
* Defaults to `white` if not provided and transparent is `false`. Ignored if `transparent` is `true`.
* Controls whether to force hardware acceleration for the underlying window.
*/
backdropColor?: ?string,
}>;
hardwareAccelerated?: ?boolean,

/**
* Determines whether your modal should go under the system statusbar.
*/
statusBarTranslucent?: ?boolean,

/**
* Determines whether your modal should go under the system navigationbar.
*/
navigationBarTranslucent?: ?boolean,
};

export type ModalProps = {
...ModalBaseProps,
...ModalPropsIOS,
...ModalPropsAndroid,
...ViewProps,
};

function confirmProps(props: Props) {
function confirmProps(props: ModalProps) {
if (__DEV__) {
if (
props.presentationStyle &&
Expand Down Expand Up @@ -204,7 +194,7 @@ type State = {
isRendered: boolean,
};

class Modal extends React.Component<Props, State> {
class Modal extends React.Component<ModalProps, State> {
static defaultProps: {hardwareAccelerated: boolean, visible: boolean} = {
visible: true,
hardwareAccelerated: false,
Expand All @@ -215,7 +205,7 @@ class Modal extends React.Component<Props, State> {
_identifier: number;
_eventSubscription: ?EventSubscription;

constructor(props: Props) {
constructor(props: ModalProps) {
super(props);
if (__DEV__) {
confirmProps(props);
Expand Down Expand Up @@ -251,7 +241,7 @@ class Modal extends React.Component<Props, State> {
}
}

componentDidUpdate(prevProps: Props) {
componentDidUpdate(prevProps: ModalProps) {
if (prevProps.visible === false && this.props.visible === true) {
this.setState({isRendered: true});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5759,43 +5759,53 @@ exports[`public API should not change unintentionally Libraries/Modal/Modal.js 1
"type OrientationChangeEvent = $ReadOnly<{
orientation: \\"portrait\\" | \\"landscape\\",
}>;
export type Props = $ReadOnly<{
...ViewProps,
export type ModalBaseProps = {
animated?: boolean,
animationType?: ?(\\"none\\" | \\"slide\\" | \\"fade\\"),
transparent?: ?boolean,
visible?: ?boolean,
onRequestClose?: ?DirectEventHandler<null>,
onShow?: ?DirectEventHandler<null>,
backdropColor?: ColorValue,
};
export type ModalPropsIOS = {
presentationStyle?: ?(
| \\"fullScreen\\"
| \\"pageSheet\\"
| \\"formSheet\\"
| \\"overFullScreen\\"
),
transparent?: ?boolean,
statusBarTranslucent?: ?boolean,
navigationBarTranslucent?: ?boolean,
hardwareAccelerated?: ?boolean,
visible?: ?boolean,
onRequestClose?: ?DirectEventHandler<null>,
onShow?: ?DirectEventHandler<null>,
onDismiss?: ?() => mixed,
supportedOrientations?: ?$ReadOnlyArray<
| \\"portrait\\"
| \\"portrait-upside-down\\"
| \\"landscape\\"
| \\"landscape-left\\"
| \\"landscape-right\\",
>,
onDismiss?: ?() => void,
onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
backdropColor?: ?string,
}>;
};
export type ModalPropsAndroid = {
hardwareAccelerated?: ?boolean,
statusBarTranslucent?: ?boolean,
navigationBarTranslucent?: ?boolean,
};
export type ModalProps = {
...ModalBaseProps,
...ModalPropsIOS,
...ModalPropsAndroid,
...ViewProps,
};
type State = {
isRendered: boolean,
};
declare class Modal extends React.Component<Props, State> {
declare class Modal extends React.Component<ModalProps, State> {
static defaultProps: { hardwareAccelerated: boolean, visible: boolean };
static contextType: React.Context<RootTag>;
constructor(props: Props): void;
constructor(props: ModalProps): void;
componentDidMount(): void;
componentWillUnmount(): void;
componentDidUpdate(prevProps: Props): void;
componentDidUpdate(prevProps: ModalProps): void;
render(): React.Node;
}
declare const ExportedModal: React.ComponentType<
Expand Down
2 changes: 1 addition & 1 deletion packages/rn-tester/js/examples/Modal/ModalPresentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/* eslint-disable no-alert */

import type {RNTesterModuleExample} from '../../types/RNTesterTypes';
import type {Props as ModalProps} from 'react-native/Libraries/Modal/Modal';
import type {ModalProps} from 'react-native/Libraries/Modal/Modal';

import RNTesterButton from '../../components/RNTesterButton';
import RNTesterText from '../../components/RNTesterText';
Expand Down
1 change: 1 addition & 0 deletions scripts/build/build-types/buildTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const ENTRY_POINTS = [
'packages/react-native/Libraries/Vibration/Vibration.js',
'packages/react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js',
'packages/react-native/Libraries/PushNotificationIOS/PushNotificationIOS.js',
'packages/react-native/Libraries/Modal/Modal.js',
];

/**
Expand Down