diff --git a/src/components/Modal/BaseModal.js b/src/components/Modal/BaseModal.js
index faf5a4ecb65e..a00b9d142dce 100644
--- a/src/components/Modal/BaseModal.js
+++ b/src/components/Modal/BaseModal.js
@@ -1,15 +1,28 @@
import React, {PureComponent} from 'react';
import {View} from 'react-native';
+import PropTypes from 'prop-types';
import ReactNativeModal from 'react-native-modal';
import {SafeAreaInsetsContext} from 'react-native-safe-area-context';
import KeyboardShortcut from '../../libs/KeyboardShortcut';
import styles, {getModalPaddingStyles, getSafeAreaPadding} from '../../styles/styles';
import themeColors from '../../styles/themes/default';
-import {propTypes, defaultProps} from './ModalPropTypes';
+import {propTypes as modalPropTypes, defaultProps as modalDefaultProps} from './ModalPropTypes';
import getModalStyles from '../../styles/getModalStyles';
import {setModalVisibility} from '../../libs/actions/Modal';
+const propTypes = {
+ ...modalPropTypes,
+
+ /** The ref to the modal container */
+ forwardedRef: PropTypes.func,
+};
+
+const defaultProps = {
+ ...modalDefaultProps,
+ forwardedRef: () => {},
+};
+
class BaseModal extends PureComponent {
constructor(props) {
super(props);
@@ -94,6 +107,8 @@ class BaseModal extends PureComponent {
backdropColor={themeColors.modalBackdrop}
backdropOpacity={hideBackdrop ? 0 : 0.5}
backdropTransitionOutTiming={0}
+ hasBackdrop={this.props.fullscreen}
+ coverScreen={this.props.fullscreen}
style={modalStyle}
deviceHeight={this.props.windowHeight}
deviceWidth={this.props.windowWidth}
@@ -128,6 +143,7 @@ class BaseModal extends PureComponent {
...modalContainerStyle,
...modalPaddingStyles,
}}
+ ref={this.props.forwardedRef}
>
{this.props.children}
@@ -142,4 +158,7 @@ class BaseModal extends PureComponent {
BaseModal.propTypes = propTypes;
BaseModal.defaultProps = defaultProps;
BaseModal.displayName = 'BaseModal';
-export default BaseModal;
+export default React.forwardRef((props, ref) => (
+ // eslint-disable-next-line react/jsx-props-no-spreading
+
+));
diff --git a/src/components/Modal/ModalPropTypes.js b/src/components/Modal/ModalPropTypes.js
index 8da6403308a3..b0b554ff4c21 100644
--- a/src/components/Modal/ModalPropTypes.js
+++ b/src/components/Modal/ModalPropTypes.js
@@ -4,6 +4,12 @@ import CONST from '../../CONST';
import {windowDimensionsPropTypes} from '../withWindowDimensions';
const propTypes = {
+ /** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */
+ fullscreen: PropTypes.bool,
+
+ /** Should we close modal on outside click */
+ shouldCloseOnOutsideClick: PropTypes.bool,
+
/** Should we announce the Modal visibility changes? */
shouldSetModalVisibility: PropTypes.bool,
@@ -52,6 +58,8 @@ const propTypes = {
};
const defaultProps = {
+ fullscreen: true,
+ shouldCloseOnOutsideClick: false,
shouldSetModalVisibility: true,
onSubmit: null,
type: '',
diff --git a/src/components/Modal/index.js b/src/components/Modal/index.js
index 169b63d794e6..f74fdd6137dc 100644
--- a/src/components/Modal/index.js
+++ b/src/components/Modal/index.js
@@ -1,14 +1,47 @@
-import React from 'react';
+import React, {Component} from 'react';
import withWindowDimensions from '../withWindowDimensions';
import BaseModal from './BaseModal';
import {propTypes, defaultProps} from './ModalPropTypes';
-const Modal = props => (
- // eslint-disable-next-line react/jsx-props-no-spreading
-
- {props.children}
-
-);
+class Modal extends Component {
+ constructor(props) {
+ super(props);
+ this.closeOnOutsideClick = this.closeOnOutsideClick.bind(this);
+ }
+
+ componentDidMount() {
+ if (this.props.shouldCloseOnOutsideClick) {
+ document.addEventListener('mousedown', this.closeOnOutsideClick);
+ }
+ }
+
+ componentWillUnmount() {
+ if (this.props.shouldCloseOnOutsideClick) {
+ document.removeEventListener('mousedown', this.closeOnOutsideClick);
+ }
+ }
+
+ closeOnOutsideClick(event) {
+ if (this.props.isVisible
+ && this.baseModalRef
+ && !this.baseModalRef.contains(event.target)
+ && this.props.shouldCloseOnOutsideClick) {
+ this.props.onClose();
+ }
+ }
+
+ render() {
+ return (
+ this.baseModalRef = el}
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ {...this.props}
+ >
+ {this.props.children}
+
+ );
+ }
+}
Modal.propTypes = propTypes;
Modal.defaultProps = defaultProps;
diff --git a/src/components/Popover/PopoverPropTypes.js b/src/components/Popover/PopoverPropTypes.js
index ae11632acc0e..acc030ad80c0 100644
--- a/src/components/Popover/PopoverPropTypes.js
+++ b/src/components/Popover/PopoverPropTypes.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import {propTypes as modalPropTypes, defaultProps as defaultModalProps} from '../Modal/ModalPropTypes';
const propTypes = {
- ...(_.omit(modalPropTypes, 'type', 'popoverAnchorPosition')),
+ ...(_.omit(modalPropTypes, ['type', 'popoverAnchorPosition'])),
/** The anchor position of the popover */
anchorPosition: PropTypes.shape({
@@ -15,7 +15,7 @@ const propTypes = {
};
const defaultProps = {
- ...(_.omit(defaultModalProps, 'type', 'popoverAnchorPosition')),
+ ...(_.omit(defaultModalProps, ['type', 'popoverAnchorPosition'])),
// Anchor position is optional only because it is not relevant on mobile
anchorPosition: {},
diff --git a/src/components/Popover/index.js b/src/components/Popover/index.js
index bfb412f53a2d..e2ea99d50b2b 100644
--- a/src/components/Popover/index.js
+++ b/src/components/Popover/index.js
@@ -1,4 +1,5 @@
import React from 'react';
+import {createPortal} from 'react-dom';
import {propTypes, defaultProps} from './PopoverPropTypes';
import CONST from '../../CONST';
import Modal from '../Modal';
@@ -8,16 +9,32 @@ import withWindowDimensions from '../withWindowDimensions';
* This is a convenience wrapper around the Modal component for a responsive Popover.
* On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths.
*/
-const Popover = props => (
-
-);
+const Popover = (props) => {
+ if (!props.fullscreen && !props.isSmallScreenWidth) {
+ return createPortal(
+ ,
+ document.body,
+ );
+ }
+ return (
+
+ );
+};
Popover.propTypes = propTypes;
Popover.defaultProps = defaultProps;
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 9b8b7d6d0947..305d1b442c24 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -279,6 +279,7 @@ class ReportActionItem extends Component {
animationOutTiming={1}
measureContent={this.measureContent}
shouldSetModalVisibility={false}
+ fullscreen={false}
>