Wrapper component that extends the react native Modal component

react-native-modal-wrapper

Wrapper component that extends the react native Modal component, adding overlay clickable behavior and allowing swipe in and out in all directions.

Install

npm install react-native-modal-wrapper --save

Central modal box example

<ModalWrapper
    onRequestClose={this.onCancel}
    style={{ width: 280, height: 180, paddingLeft: 24, paddingRight: 24 }}
    visible={isOpen}>
  <Text>New project</Text>
  <TextField
      autoFocus={true}
      placeholder="Project name"
      onNameChange={this.onNameChangeHandler}
      onSubmitEditing={this.onSubmit} />
  <View>
    <MDButton text="CANCEL" type="regular" flat={true} onPress={this.onCancel} />
    <MDButton text="CREATE" type="primary" flat={true} onPress={this.onSubmit} />
  </View>
</ModalWrapper>

Bottom contextual menu example

<ModalWrapper
    containerStyle={{ flexDirection: 'row', alignItems: 'flex-end' }}
    onRequestClose={onClosed}
    style={{ flex: 1 }}
    visible={isOpen}>
  {this.contextMenuActions.map(([id, text, onPress]) =>
	<MDButtonIcon
	    key={id}
	    name={id}
	    iconStyle={styles.optionText}
	    style={styles.option}
	    onPress={() => {
		  onClosed();
	      onPress();
	    }}>
	  <Text>{text}</Text>
	</MDButtonIcon>
  )}
</ModalWrapper>

Right contextual menu example

<ModalWrapper
    containerStyle={{ flexDirection: 'row', justifyContent: 'flex-end' }}
    onRequestClose={() => this.setState({ isFilterByTagPanelOpen: false })}
    position="right"
    style={styles.sidebar}
    visible={isFilterByTagPanelOpen}>
  <FilterByTag
      onClose={() => this.setState({ isFilterByTagPanelOpen: false })}
      onSelection={tags => updateProjectFilter({ tags })}>
  </FilterByTag>
</ModalWrapper>

Modal without overlay example

<View style={styles.container} onLayout={() => this.forceUpdate()}>
  {/* Page Content */}
  <ModalWrapper
      isNative={false}
      onRequestClose={this.onRequestClose}
      position='left'
      shouldAnimateOnRequestClose={true}
      showOverlay={false}
      style={[styles.modalStyle, (() => {
        const { height, width } = Dimensions.get('window');
        const modalHeight = 100;
        const modalWidth = 280;
        return {
          top: (height - modalHeight) / 2,
          left: (width - modalWidth) / 2
        };
      })()]}
      visible={this.state.visible}>
    <View style={styles.container}>
      <Text style={styles.modalText}>Modal without overlay</Text>
    </View>
  </ModalWrapper>
</View>

Properties

This component supports all the properties of the original react native modal component https://facebook.github.io/react-native/docs/modal.html, plus the following:

Prop Default Type Description
animateOnMount false bool Determine whether or not animate the modal if it's visible when it mounts.
animationDuration 300 number Duration of the animation.
position bottom string Position where the sliding animation of the modal should start. Accepted values: "top", "bottom", "left", "right".
containerStyle - any Container styles used for positioning the modal with flexbox (default: alignItems: 'center', flex: 1, justifyContent: 'center'). See the examples.
isNative true bool Determine the usage of the react native modal component or a simple view wrapper instead. It can be set to false to overcome some react native modal limitations (for example to have more than one modal open at the same time).
onAnimateClose () => null func Callback executed after the modal is closed.
onAnimateOpen () => null func Callback executed after the modal is open.
overlayStyle - any Styles used to define the overlay backgroundColor (default: "#000") and opacity (default: 0.5).
overlayTestID - string testID prop for the overlay element.
screenHeight computed screen height number Allow the user to manually set the right screen height to adjust the keyboardSpacer due to an issue on iPad in react native https://github.com/facebook/react-native/issues/7340.
shouldAnimateOnOverlayPress true bool Determine whether or not animate the modal closing down when the overlay is pressed.
shouldAnimateOnRequestClose false bool Determine whether or not animate the modal closing down when the onRequestClose callback is executed.
shouldCloseOnOverlayPress true bool Determine whether or not allow the modal closing down if the overlay is pressed.
showOverlay true bool Determine whether or not showing the overlay. In combination with isNative={false} it is possible to interact with the background of the application when the modal is still open.
style - any Styles of the modal (default: backgroundColor: '#fff', justifyContent: 'center').

Note: this component sets some properties of the underlying native modal component to allow sliding flexibility in each direction and the clickable overlay behavior, therefore we suggest not to change those. However, you can set to 0 the animationDuration prop to avoid the component sliding logic from top, bottom, left or right and therefore turning on the react native modal animationType prop, disabled by default. Here the list of the react native modal properties set by default:

Prop Default Type Description
animationType "none" string The react native modal has limited animation customization, therefore the animation logic is done externally using position and animationDuration.
transparent true bool We want to have the overlay by default.

GitHub