Skip to content

Commit

Permalink
feat: add overlayColor prop to modal component for customisable backg…
Browse files Browse the repository at this point in the history
…round overlay (#46322)

Summary:
Solves these issues:
- #18398
- #12478

Solves this proposal: react-native-community/discussions-and-proposals#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: #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
  • Loading branch information
shubhamguptadream11 authored and facebook-github-bot committed Sep 16, 2024
1 parent b4c41ec commit 4e1d701
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/react-native/Libraries/Modal/Modal.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/**
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 9 additions & 1 deletion packages/react-native/Libraries/Modal/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6377,6 +6377,7 @@ export type Props = $ReadOnly<{|
| \\"landscape-right\\",
>,
onOrientationChange?: ?DirectEventHandler<OrientationChangeEvent>,
overlayColor?: ?string,
|}>;
type State = {
isRendered: boolean,
Expand Down
24 changes: 24 additions & 0 deletions packages/rn-tester/js/examples/Modal/ModalPresentation.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const supportedOrientations = [
'landscape-right',
];

const overlayColors = ['red', 'blue', undefined];

function ModalPresentation() {
const onDismiss = React.useCallback(() => {
alert('onDismiss');
Expand Down Expand Up @@ -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');

Expand Down Expand Up @@ -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>
</>
);

Expand Down

0 comments on commit 4e1d701

Please sign in to comment.