Home

Awesome

react-native-dialog

npm version

A flexible pure JavaScript React-Native dialog that follows closely the native UI guidelines.

Features

Demo

<p align="center"> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-dialog/master/.github/docs-images/react-native-dialog-ios-alert.png" height="500" /> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-dialog/master/.github/docs-images/react-native-dialog-android-alert.png" height="500" /> </p> <p align="center"> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-dialog/master/.github/docs-images/react-native-dialog-ios-input.png" height="500" /> <img src="https://raw.githubusercontent.com/mmazzarolo/react-native-dialog/master/.github/docs-images/react-native-dialog-android-input.png" height="500" /> </p>

Setup

Install the library using npm or yarn:

# Using npm:
$ npm install react-native-dialog
# Using yarn:
$ yarn add react-native-dialog

Usage

React-native-dialog exposes a set of components that can be used to build the UI of the dialog:

  1. Import react-native-dialog:
import Dialog from "react-native-dialog";
  1. Create a dialog and nest its content inside of it:
return (
  <View>
    <Dialog.Container>
      <Dialog.Title>Account delete</Dialog.Title>
      <Dialog.Description>
        Do you want to delete this account? You cannot undo this action.
      </Dialog.Description>
      <Dialog.Button label="Cancel" />
      <Dialog.Button label="Delete" />
    </Dialog.Container>
  </View>
);
  1. Then simply show it by setting the visible prop to true:
return (
  <View>
    <Dialog.Container visible={true}>
      <Dialog.Title>Account delete</Dialog.Title>
      <Dialog.Description>
        Do you want to delete this account? You cannot undo this action.
      </Dialog.Description>
      <Dialog.Button label="Cancel" />
      <Dialog.Button label="Delete" />
    </Dialog.Container>
  </View>
);

The visible prop is the only prop you'll really need to make the dialog work: you should control this prop value by saving it in your state and setting it to true or false when needed.

A complete example

The following example consists in a component (DialogTester) with a button and a dialog. The dialog is controlled by the dialogVisible state variable and it is initially hidden since its value is false. Pressing the button sets dialogVisible to true, making the dialog visible. Inside the dialog there are two buttons that, when pressed, set dialogVisible to false, hiding the dialog.

import React, { useState } from "react";
import { Button, StyleSheet, View } from "react-native";
import Dialog from "react-native-dialog";

export default function App() {
  const [visible, setVisible] = useState(false);

  const showDialog = () => {
    setVisible(true);
  };

  const handleCancel = () => {
    setVisible(false);
  };

  const handleDelete = () => {
    // The user has pressed the "Delete" button, so here you can do your own logic.
    // ...Your logic
    setVisible(false);
  };

  return (
    <View style={styles.container}>
      <Button title="Show dialog" onPress={showDialog} />
      <Dialog.Container visible={visible}>
        <Dialog.Title>Account delete</Dialog.Title>
        <Dialog.Description>
          Do you want to delete this account? You cannot undo this action.
        </Dialog.Description>
        <Dialog.Button label="Cancel" onPress={handleCancel} />
        <Dialog.Button label="Delete" onPress={handleDelete} />
      </Dialog.Container>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

Available props

Dialog.Button props

NameTypeDefaultDescription
labelstringREQUIREDThe label text
colorstring#007ff9 on iOS, #169689 on AndroidThe label color
boldboolfalseShow the label with a bold font weight?
disabledboolfalseDisable the button?
onPressfuncREQUIREDCalled when the button is pressed

Dialog.Description props

NameTypeDefaultDescription
childrenstringREQUIREDThe description text

Dialog.Container props

NameTypeDefaultDescription
blurComponentIOSnodeA low-opacityThe blur component used in iOS
visibleboolREQUIREDShow the dialog?
childrennodeREQUIREDThe dialog content
contentStyleanyundefinedExtra style applied to the dialog content
headerStyleanyundefinedExtra style applied to the dialog header
footerStyleanyundefinedExtra style applied to the dialog footer
buttonSeparatorStyleanyundefinedExtra style applied to the dialog button separator
onBackdropPressfuncundefinedCallback invoked when the backdrop is pressed
onRequestClosefuncundefinedCallback invoked when the hardware back button on Android or the menu button on Apple TV is pressed
keyboardVerticalOffsetnumberundefinedkeyboardVerticalOffset for iOS
verticalButtonsboolfalseRenders button vertically
useNativeDriverboolfalseDefines if animations should use native driver

Dialog.Input props

NameTypeDefaultDescription
labelstringundefinedThe input floating label
wrapperStyleanyundefinedThe style applied to the input wrapper View
textInputRefrefundefinedRef to the input
unstableLabelStyleanyundefinedLikely to be removed in a future version. See issue #141 for discussion

Dialog.Input also accepts all the React-Native's TextInput component props.

Dialog.CodeInput props

NameTypeDefaultDescription
wrapperStyleanyundefinedThe style applied to the input wrapper View
digitContainerStyleanyundefinedThe style applied to the digit container View
digitContainerFocusedStyleanyundefinedThe style applied to the digit container View when in focus
digitStyleanyundefinedThe style applied to the digit text
codeLengthnumber4The total number of digits
onCodeChangefuncundefinedCalled when the input changed

Dialog.CodeInput also accepts all the React-Native's TextInput component props.

Dialog.Title props

NameTypeDefaultDescription
childrenstringREQUIREDThe title text

Dialog.Title also accepts all the React-Native's Text component props.

Dialog.Switch props

NameTypeDefaultDescription
labelstringundefinedThe switch description text
unstableLabelStyleanyundefinedLikely to be removed in a future version. See issue #141 for discussion

Dialog.Switch also accepts all the React-Native's Switch component props.

Frequently Asked Questions

How can I use a custom blur component as the dialog background on iOS?

To achieve a look even closer to the native iOS dialog you can provide your own component in the blurComponentIOS prop of a Dialog.Container and it will be injected in the dialog to be used as a background. The blurComponentIOS can be useful for example if you want to apply a native blur effect to the dialog. Here is an example using react-native-blur:

const blurComponentIOS = (
  <BlurView style={StyleSheet.absoluteFill} blurType="xlight" blurAmount={50} />
);
return (
  <View style={styles.container}>
    <Dialog.Container visible={visible} blurComponentIOS={blurComponentIOS}>
      <Dialog.Title>Account delete</Dialog.Title>
      <Dialog.Description>
        Do you want to delete this account? You cannot undo this action.
      </Dialog.Description>
      <Dialog.Button label="Cancel" onPress={handleCancel} />
      <Dialog.Button label="Delete" onPress={handleConfirm} />
    </Dialog.Container>
  </View>
);

How can I add a 'tap outside dialog' callback?

react-native-dialog uses a thin abstraction on top of the React-Native's modal component. Any properties you add to Dialog.Container are mapped through to the modal. The modal has an onBackdropPress property that can be used to register clicks on the backdrop.

Below is an example of how you can close the dialog by tapping outside.

const [visible, setVisible] = useState(true);

const handleCancel = () => {
  setVisible(false);
};

return (
  <Dialog.Container visible={visible} onBackdropPress={handleCancel}>
    <Dialog.Title>Title</Dialog.Title>
    <Dialog.Button label="Cancel" onPress={handleCancel} />
  </Dialog.Container>
);

Acknowledgments

Thanks to the user @honaf who has kindly offered the react-native-dialog namespace. Also thanks to the user @leecade who offered the namespace react-native-alert (which has not been used since "Dialog" seems to suit better this component) and to @tyxou for the entire codebase refactoring to hooks.