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:

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

[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
This commit is contained in:
shubhamguptadream11
2024-09-16 09:29:00 -07:00
committed by Facebook GitHub Bot
parent b4c41ec768
commit 4e1d7015c1
4 changed files with 41 additions and 1 deletions
+7
View File
@@ -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<any>) => 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 {
+9 -1
View File
@@ -157,6 +157,12 @@ export type Props = $ReadOnly<{|
* See https://reactnative.dev/docs/modal#onorientationchange
*/
onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
/**
* 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<Props, State> {
const containerStyles = {
backgroundColor:
this.props.transparent === true ? 'transparent' : 'white',
this.props.transparent === true
? 'transparent'
: this.props.overlayColor ?? 'white',
};
let animationType = this.props.animationType || 'none';
@@ -6377,6 +6377,7 @@ export type Props = $ReadOnly<{|
| \\"landscape-right\\",
>,
onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
overlayColor?: ?string,
|}>;
type State = {
isRendered: boolean,
@@ -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() {
/>
</View>
</View>
<View style={styles.block}>
<Text style={styles.title}>Overlay Color ⚫️</Text>
<View style={styles.row}>
{overlayColors.map(type => (
<RNTOption
key={type}
style={styles.option}
label={type === undefined ? 'default' : type}
multiSelect={true}
onPress={() =>
setProps(prev => ({
...prev,
overlayColor: type,
}))
}
selected={type === overlayColor}
/>
))}
</View>
</View>
</>
);