Asbar Ali
Asbar Ali

Reputation: 995

How to dim a background in react native modal?

Following is my created react native Modal and still couldn't find how to dim the background and transparent around pop-up modal.I am not using any external libraries and trying to find solution without libraries.Is it possible to do with on this way?

enter image description here

My Modal Component

render() {
let modal = this.state.modalType=='skill'? <SkillModal /> : <TrialModal />;
return (
  <View style={styles.container}>
    <Modal
      animationType='slide'
      onRequestClose={() => console.log('no warning')}
      presentationStyle="FormSheet"
      transparent
      visible={this.state.showModal}
    >
      <View>
        <View style={styles.modalView} >
          <TouchableOpacity
            onPress={this.closeModalFunc}
          >
            <Text style={styles.closeText}>X</Text>
          </TouchableOpacity>
          <View>
            {modal}
          </View>
        </View>
      </View>
    </Modal>
  </View>
  );
}

Modal Component Style

import {StyleSheet} from 'react-native';
import colors from '../../../theme/colors';
import metrics from '../../../theme/metrics';
import {container} from '../../../theme/base';

const styles = StyleSheet.create({
container: {
 backgroundColor: colors.background.gray,
},
modalView: {
 backgroundColor: colors.background.white,
 margin: 40,
},
closeText: {
  backgroundColor: colors.background.purpleishBlue,
  color: colors.background.white,
  borderRadius: metrics.avatar.small,
  width: 32,
  padding: 6,
  alignSelf: 'flex-end',
  textAlign: 'center',
  borderWidth: 1,
  borderColor: colors.background.white,
 },
});

export default styles;

Upvotes: 39

Views: 139410

Answers (11)

Quốc Bảo
Quốc Bảo

Reputation: 241

write a component like that:

 <>
  {visible && <View style={styles.dimModal} />}
  <Modal
    visible={visible}
    transparent={true}
    statusBarTranslucent={true}
    animationType="slide">
    <TouchableWithoutFeedback onPress={onClose}>
      <View style={styles.container}>
        <TouchableWithoutFeedback>
          <View style={styles.content}>
           {your content}
          </View>
        </TouchableWithoutFeedback>
      </View>
    </TouchableWithoutFeedback>
   </Modal>
  </>

const styles = StyleSheet.create({ container: { flex: 1, }, dimModal: { position: 'absolute', top: 0, right: 0, left: 0, bottom: 0, backgroundColor: 'rgba(0, 0, 0, 0.5)', }, }};

Upvotes: 0

hanuruh
hanuruh

Reputation: 260

This worked for me:

<View style={{opacity: modalVisible? 0.5 : undefined}}>
    <Modal
        animationType="slide"
        transparent={true}
        visible={modalVisible}
        onRequestClose={() => {
           setModalVisible(!modalVisible);
        }}>
        ...
    </Modal>
</View>

Upvotes: 2

prog
prog

Reputation: 193

React native provides a prop you can apply to the component

activeOpacity={0.9}

Which you can set to whatever you'd like

Upvotes: -1

Trevor
Trevor

Reputation: 1604

I created a container style then I applied the rgba values for backgroundColor e.g:

modalContainer:{
    flex: 1,
    //backgroundColor: 'transparent',
    backgroundColor: 'rgba(0,0,0,0.7)',
    alignItems: 'center',
    justifyContent: 'center',
},

Then inside the modal I created my actual modal dialog with rounded corners (I achieved this by adding another element inside the modal content and gave it a white background with rounded corners).

Upvotes: 11

Shadab Ali
Shadab Ali

Reputation: 439

I just Wrap the whole modalView in another View and simply apply background to it

<View style={styles.modalbackdrop}>   
   <View style={styles.modalView}></View>
</View>

and apply following

backgroundColor: 'rgba(0, 0, 0, 0.8)',
height: '100%',

Upvotes: 6

Anil Rai
Anil Rai

Reputation: 134

You must add statusBarTranslucent props to Modal component and set it to true. Then you will get your desired output. No need to set transparent props to true or any other tedious styles.

Upvotes: -1

v.nivuahc
v.nivuahc

Reputation: 862

I managed to get a transparent dark background wich close the modal when you click on it.
I use a first external container in the modal element, which has full screen dimensions. In it, the inner container has a box size and is centered in the screen.

Here the code (react: v16.13, react-native: v0.63.2)

import React from 'react';
import {Modal, Text, TouchableWithoutFeedback, View} from 'react-native';
import {style} from './style';

const MyModal = ({visible, onDismiss}) => {
  return (
    <Modal visible={visible} transparent>
      <TouchableWithoutFeedback onPress={() => onDismiss()}>
        <View style={style.modal}>
          <TouchableWithoutFeedback>
            <View style={style.modalInner}>
              <Text>Something in the modal</Text>
            </View>
          </TouchableWithoutFeedback>
        </View>
      </TouchableWithoutFeedback>
    </Modal>
  );
};

export default MyModal;

The onDismiss is a callback toggling the value of the visible variable given to this component from his parent.

TouchableWithoutFeedback adds the onPress event handling on the containers. The external one respond on click, to close/dismiss the modal. The inner one do nothing (default behavior when onPress is not given).

With the style :

import {StyleSheet} from 'react-native';

export const style = StyleSheet.create({
  modal: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'rgba(0,0,0,0.5)',
  },

  modalInner: {
    height: 200,
    padding: 35,
    justifyContent: 'space-around',
    alignItems: 'center',
    backgroundColor: '#FFF',
    shadowColor: '#000',
    shadowOffset: {
      width: 0,
      height: 2,
    },
    shadowOpacity: 0.25,
    shadowRadius: 3.84,
    elevation: 5,
  },
});

Note that the parent element of my <MyModal> is the root <View> of my app, with the style {flex: 1}.

Upvotes: 13

MaybeNextTime
MaybeNextTime

Reputation: 611

With react-native-modal, you can use backdropOpacity property to dim background when modal is visible

import React, {useState} from 'react';
import {Button, Text, View} from 'react-native';
import Modal from 'react-native-modal';

function ModalTester() {
  const [isModalVisible, setModalVisible] = useState(false);

  const toggleModal = () => {
    setModalVisible(!isModalVisible);
  };

  render() {
return (
  <View style={{flex: 1}}>
    <Button title="Show modal" onPress={toggleModal} />

    <Modal isVisible={isModalVisible} backdropOpacity={0.3}>
      <View style={{flex: 1}}>
        <Text>Hello!</Text>

        <Button title="Hide modal" onPress={toggleModal} />
      </View>
    </Modal>
  </View>
);
  }
}

export default ModalTester;

Upvotes: 9

Yassine Letaief
Yassine Letaief

Reputation: 526

I had the same problem as you and I solved it by setting transparent={true} in the Props of the modal and by setting a 50% transparency in the style of the Modal's main View: backgroundColor: 'rgba(0, 0, 0, 0.5)'

Upvotes: 50

mai danh
mai danh

Reputation: 943

I solve this one by create my own component MyPopup like below

class MyPopup extends React.PureComponent {

render() {
    return (
        <Modal 
            animationType="fade"
            transparent={true}
            visible={this.props.visible}
            >
                <View style={{flex: 1, alignItems: 'center', justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)'}}>
                    {this.props.children}
                </View>
        </Modal>
    )
}}

Then I use it like

<MyPopup visible={this.state.modalVisible}>
<View style={{
    width: '90%',
    height: 50,
    borderColor: '#ccc',
    borderWidth: 1,
    borderStyle: 'solid',
    backgroundColor: 'white',
    elevation: 20,
    padding: 10,
    borderRadius: 4,
}}>
    <Text>Hello, This is my model with dim background color</Text>
</View>

Upvotes: 66

Ahsan Ali
Ahsan Ali

Reputation: 5135

You can programmatically set the opacity of your main View when Modal is visible.

<View style={[styles.container, this.state.showModal ? {backgroundColor: 'rgba(0,0,0,0.5)'} : '']}>

Upvotes: 33

Related Questions