diff --git a/src/CONST.js b/src/CONST.js index 906d90effbc9..8da883e8a9f3 100644 --- a/src/CONST.js +++ b/src/CONST.js @@ -29,6 +29,7 @@ const CONST = { }, MODAL: { MODAL_TYPE: { + CONFIRM: 'confirm', CENTERED: 'centered', BOTTOM_DOCKED: 'bottom_docked', POPOVER: 'popover', diff --git a/src/components/ConfirmModal.js b/src/components/ConfirmModal.js new file mode 100644 index 000000000000..2e10bb1fddf0 --- /dev/null +++ b/src/components/ConfirmModal.js @@ -0,0 +1,90 @@ +import React from 'react'; +import { + TouchableOpacity, Text, View, +} from 'react-native'; +import PropTypes from 'prop-types'; +import Header from './Header'; +import Modal from './Modal'; +import styles from '../styles/styles'; +import CONST from '../CONST'; +import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; + +const propTypes = { + /** Title of the modal */ + title: PropTypes.string.isRequired, + + /** A callback to call when the form has been submitted */ + onConfirm: PropTypes.func.isRequired, + + /** A callback to call when the form has been closed */ + onCancel: PropTypes.func.isRequired, + + /** Modal visibility */ + isVisible: PropTypes.bool.isRequired, + + /** Confirm button text */ + confirmText: PropTypes.string, + + /** Cancel button text */ + cancelText: PropTypes.string, + + /** Modal content text */ + prompt: PropTypes.string, + + ...windowDimensionsPropTypes, +}; + +const defaultProps = { + confirmText: 'Yes', + cancelText: 'No', + prompt: '', +}; + +const ConfirmModal = props => ( + + + +
+ + + + {props.prompt} + + + + + {props.confirmText} + + + + + + {props.cancelText} + + + + +); + +ConfirmModal.propTypes = propTypes; +ConfirmModal.defaultProps = defaultProps; +ConfirmModal.displayName = 'ConfirmModal'; +export default withWindowDimensions(ConfirmModal); diff --git a/src/components/Modal/ModalPropTypes.js b/src/components/Modal/ModalPropTypes.js index 565b9dbaf47b..54d509921552 100644 --- a/src/components/Modal/ModalPropTypes.js +++ b/src/components/Modal/ModalPropTypes.js @@ -20,6 +20,7 @@ const propTypes = { // Style of modal to display type: PropTypes.oneOf([ + CONST.MODAL.MODAL_TYPE.CONFIRM, CONST.MODAL.MODAL_TYPE.CENTERED, CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED, CONST.MODAL.MODAL_TYPE.POPOVER, diff --git a/src/components/UpdateAppModal/BaseUpdateAppModal.js b/src/components/UpdateAppModal/BaseUpdateAppModal.js index 3741996d3159..e547c460e95f 100644 --- a/src/components/UpdateAppModal/BaseUpdateAppModal.js +++ b/src/components/UpdateAppModal/BaseUpdateAppModal.js @@ -1,11 +1,6 @@ import React, {PureComponent} from 'react'; -import { - TouchableOpacity, Text, -} from 'react-native'; -import HeaderWithCloseButton from '../HeaderWithCloseButton'; -import Modal from '../Modal'; -import styles from '../../styles/styles'; import {propTypes, defaultProps} from './UpdateAppModalPropTypes'; +import ConfirmModal from '../ConfirmModal'; class BaseUpdateAppModal extends PureComponent { constructor(props) { @@ -29,36 +24,16 @@ class BaseUpdateAppModal extends PureComponent { render() { return ( <> - this.setState({isModalOpen: false})} + - this.setState({isModalOpen: false})} - /> - - A new version of Expensify.cash is available. - Update now or restart the app at a later time to download the latest changes. - - {this.props.onSubmit && ( - - - Update App - - - )} - + onConfirm={this.submitAndClose} + onCancel={() => this.setState({isModalOpen: false})} + prompt="A new version of Expensify.cash is available. + Update now or restart the app at a later time to download the latest changes." + confirmText="Update App" + cancelText="Cancel" + /> ); } diff --git a/src/styles/getModalStyles.js b/src/styles/getModalStyles.js index dc5319b441a1..f3ab417db1a4 100644 --- a/src/styles/getModalStyles.js +++ b/src/styles/getModalStyles.js @@ -19,6 +19,36 @@ export default (type, windowDimensions, popoverAnchorPosition = {}) => { let shouldAddTopSafeAreaPadding = false; switch (type) { + case CONST.MODAL.MODAL_TYPE.CONFIRM: + // A confirm modal is one that has a visible backdrop + // and can be dismissed by clicking outside of the modal. + modalStyle = { + ...modalStyle, + ...{ + alignItems: 'center', + }, + }; + modalContainerStyle = { + // Shadow Styles + shadowColor: colors.black, + shadowOffset: { + width: 0, + height: 0, + }, + shadowOpacity: 0.1, + shadowRadius: 5, + + borderRadius: 12, + overflow: 'hidden', + width: variables.sideBarWidth, + }; + + // setting this to undefined we effectively disable the + // ability to swipe our modal + swipeDirection = undefined; + animationIn = 'fadeIn'; + animationOut = 'fadeOut'; + break; case CONST.MODAL.MODAL_TYPE.CENTERED: // A centered modal is one that has a visible backdrop // and can be dismissed by clicking outside of the modal. diff --git a/src/styles/utilities/spacing.js b/src/styles/utilities/spacing.js index ba8b03f522f3..2fe247fecdcb 100644 --- a/src/styles/utilities/spacing.js +++ b/src/styles/utilities/spacing.js @@ -13,6 +13,14 @@ export default { margin: 8, }, + m4: { + margin: 16, + }, + + m5: { + margin: 20, + }, + mh1: { marginHorizontal: 4, },