From 4e1d7015c1d4e2703133b1347ed97a0cc93b1318 Mon Sep 17 00:00:00 2001 From: shubhamguptadream11 Date: Mon, 16 Sep 2024 09:29:00 -0700 Subject: [PATCH] feat: add overlayColor prop to modal component for customisable background overlay (#46322) Summary: Solves these issues: - https://github.com/facebook/react-native/issues/18398 - https://github.com/facebook/react-native/issues/12478 Solves this proposal: https://github.com/react-native-community/discussions-and-proposals/discussions/774 ## Changelog: [GENERAL] [ADDED] - added overlayColor prop to modal component for customisable background overlay **Motivation:** Currently, the React Native Modal component only allows the background to be set to either `transparent` or `white`. This limits the ability to dim the background or apply custom colors, which is essential for creating a more polished and user-friendly interface. **Change Log:** Modal Component Enhancements: - Introduced a new optional prop `overlayColor` to the Modal component. - Updated the background color logic to prioritize `overlayColor` when transparent is `false`. - Ensured backward compatibility by defaulting to `white` when `overlayColor` is not provided. Pull Request resolved: https://github.com/facebook/react-native/pull/46322 Test Plan: - Test the changes on both iOS and Android devices/emulators to ensure consistent behavior. - Added example in **rn-tester** app **Sample screenshot with custom overlayColor passed as 'red'.** ![simulator_screenshot_4F112217-7AD5-4030-8A18-6260AD32988A](https://github.com/user-attachments/assets/52f16ef2-874b-487c-908b-1aa2a1b8fafb) Reviewed By: cipolleschi Differential Revision: D62201559 Pulled By: alanleedev fbshipit-source-id: e990d7f18f5edf61f0107026ea899c5f22d47bfd --- .../react-native/Libraries/Modal/Modal.d.ts | 7 ++++++ .../react-native/Libraries/Modal/Modal.js | 10 +++++++- .../__snapshots__/public-api-test.js.snap | 1 + .../js/examples/Modal/ModalPresentation.js | 24 +++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Modal/Modal.d.ts b/packages/react-native/Libraries/Modal/Modal.d.ts index 4cc2df22367..6305af3d521 100644 --- a/packages/react-native/Libraries/Modal/Modal.d.ts +++ b/packages/react-native/Libraries/Modal/Modal.d.ts @@ -10,6 +10,7 @@ import type * as React from 'react'; import {ViewProps} from '../Components/View/ViewPropTypes'; import {NativeSyntheticEvent} from '../Types/CoreEventTypes'; +import {ColorValue} from '../StyleSheet/StyleSheet'; export interface ModalBaseProps { /** @@ -43,6 +44,12 @@ export interface ModalBaseProps { * The `onShow` prop allows passing a function that will be called once the modal has been shown. */ onShow?: ((event: NativeSyntheticEvent) => void) | undefined; + + /** + * The `overlayColor` props sets the color of the modal's background overlay. + * Defaults to `white` if not provided and transparent is `false`. Ignored if `transparent` is `true`. + */ + overlayColor?: ColorValue | undefined; } export interface ModalPropsIOS { diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index f0cb2144532..9771ae95c2b 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -157,6 +157,12 @@ export type Props = $ReadOnly<{| * See https://reactnative.dev/docs/modal#onorientationchange */ onOrientationChange?: ?DirectEventHandler, + + /** + * The `overlayColor` props sets the color of the modal's background overlay. + * Defaults to `white` if not provided and transparent is `false`. Ignored if `transparent` is `true`. + */ + overlayColor?: ?string, |}>; function confirmProps(props: Props) { @@ -249,7 +255,9 @@ class Modal extends React.Component { const containerStyles = { backgroundColor: - this.props.transparent === true ? 'transparent' : 'white', + this.props.transparent === true + ? 'transparent' + : this.props.overlayColor ?? 'white', }; let animationType = this.props.animationType || 'none'; 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 416f975e52d..21a9e670c8a 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 @@ -6377,6 +6377,7 @@ export type Props = $ReadOnly<{| | \\"landscape-right\\", >, onOrientationChange?: ?DirectEventHandler, + overlayColor?: ?string, |}>; type State = { isRendered: boolean, diff --git a/packages/rn-tester/js/examples/Modal/ModalPresentation.js b/packages/rn-tester/js/examples/Modal/ModalPresentation.js index e5f2cad774e..a371d67b8e7 100644 --- a/packages/rn-tester/js/examples/Modal/ModalPresentation.js +++ b/packages/rn-tester/js/examples/Modal/ModalPresentation.js @@ -34,6 +34,8 @@ const supportedOrientations = [ 'landscape-right', ]; +const overlayColors = ['red', 'blue', undefined]; + function ModalPresentation() { const onDismiss = React.useCallback(() => { alert('onDismiss'); @@ -63,10 +65,12 @@ function ModalPresentation() { onDismiss: undefined, onShow: undefined, visible: false, + overlayColor: undefined, }); const presentationStyle = props.presentationStyle; const hardwareAccelerated = props.hardwareAccelerated; const statusBarTranslucent = props.statusBarTranslucent; + const overlayColor = props.overlayColor; const [currentOrientation, setCurrentOrientation] = React.useState('unknown'); @@ -211,6 +215,26 @@ function ModalPresentation() { /> + + Overlay Color ⚫️ + + {overlayColors.map(type => ( + + setProps(prev => ({ + ...prev, + overlayColor: type, + })) + } + selected={type === overlayColor} + /> + ))} + + );