diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index f5f865853164..986b3723f734 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -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'; @@ -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) => void; onRequestClose?: ?DirectEventHandler, - /** - * 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) => void; onShow?: ?DirectEventHandler, /** - * 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' @@ -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) => void) + // | undefined; onOrientationChange?: ?DirectEventHandler, +}; +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 && @@ -204,7 +194,7 @@ type State = { isRendered: boolean, }; -class Modal extends React.Component { +class Modal extends React.Component { static defaultProps: {hardwareAccelerated: boolean, visible: boolean} = { visible: true, hardwareAccelerated: false, @@ -215,7 +205,7 @@ class Modal extends React.Component { _identifier: number; _eventSubscription: ?EventSubscription; - constructor(props: Props) { + constructor(props: ModalProps) { super(props); if (__DEV__) { confirmProps(props); @@ -251,7 +241,7 @@ class Modal extends React.Component { } } - componentDidUpdate(prevProps: Props) { + componentDidUpdate(prevProps: ModalProps) { if (prevProps.visible === false && this.props.visible === true) { this.setState({isRendered: true}); } diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 4b26c7513d64..25f89f1aeb7a 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -5759,23 +5759,22 @@ 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, + onShow?: ?DirectEventHandler, + backdropColor?: ColorValue, +}; +export type ModalPropsIOS = { presentationStyle?: ?( | \\"fullScreen\\" | \\"pageSheet\\" | \\"formSheet\\" | \\"overFullScreen\\" ), - transparent?: ?boolean, - statusBarTranslucent?: ?boolean, - navigationBarTranslucent?: ?boolean, - hardwareAccelerated?: ?boolean, - visible?: ?boolean, - onRequestClose?: ?DirectEventHandler, - onShow?: ?DirectEventHandler, - onDismiss?: ?() => mixed, supportedOrientations?: ?$ReadOnlyArray< | \\"portrait\\" | \\"portrait-upside-down\\" @@ -5783,19 +5782,30 @@ export type Props = $ReadOnly<{ | \\"landscape-left\\" | \\"landscape-right\\", >, + onDismiss?: ?() => void, onOrientationChange?: ?DirectEventHandler, - 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 { +declare class Modal extends React.Component { static defaultProps: { hardwareAccelerated: boolean, visible: boolean }; static contextType: React.Context; - 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< diff --git a/packages/rn-tester/js/examples/Modal/ModalPresentation.js b/packages/rn-tester/js/examples/Modal/ModalPresentation.js index 028232b0b860..e90c85f4dd4b 100644 --- a/packages/rn-tester/js/examples/Modal/ModalPresentation.js +++ b/packages/rn-tester/js/examples/Modal/ModalPresentation.js @@ -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'; diff --git a/scripts/build/build-types/buildTypes.js b/scripts/build/build-types/buildTypes.js index d4e3c252ed85..d217f0ffae77 100644 --- a/scripts/build/build-types/buildTypes.js +++ b/scripts/build/build-types/buildTypes.js @@ -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', ]; /**