import React from 'react' import PropTypes from 'prop-types' import { connect } from 'react-redux' import { injectIntl, defineMessages } from 'react-intl' import { openModal } from '../../actions/modal' import { cancelReplyCompose } from '../../actions/compose' import { CX, BREAKPOINT_EXTRA_SMALL, } from '../../constants' class ModalBase extends React.PureComponent { state = { revealed: !!this.props.children, } activeElement = this.state.revealed ? document.activeElement : null handleKeyUp = (e) => { if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27) && !!this.props.children) { this.handleOnClose() } } handleOnClose = (e, force) => { const { onOpenModal, composeText, composeId, onClose, intl, type, onCancelReplyCompose } = this.props if ((!!e && this.dialog !== e.target) && !force) return if (!composeId && composeText && type === 'COMPOSE') { onOpenModal('CONFIRM', { message: intl.formatMessage(messages.delete), confirm: intl.formatMessage(messages.confirm), onConfirm: () => onCancelReplyCompose(), onCancel: () => onOpenModal('COMPOSE'), }) } else { onClose() } } componentDidMount() { window.addEventListener('keyup', this.handleKeyUp, false) window.addEventListener('popstate', (e) => this.handleOnClose(e, true), false); } componentWillReceiveProps(nextProps) { if (!!nextProps.children && !this.props.children) { this.activeElement = document.activeElement this.getSiblings().forEach(sibling => sibling.setAttribute('inert', true)) } else if (!nextProps.children) { this.setState({ revealed: false }) } if (!nextProps.children && !!this.props.children) { this.activeElement.focus() this.activeElement = null } } componentDidUpdate(prevProps) { if (!this.props.children && !!prevProps.children) { this.getSiblings().forEach(sibling => sibling.removeAttribute('inert')) } if (this.props.children) { requestAnimationFrame(() => { this.setState({ revealed: true }) }) } } componentWillUnmount() { window.removeEventListener('keyup', this.handleKeyUp) window.removeEventListener('popstate', this.handleOnClose, false); } getSiblings = () => { return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node) } setRef = (n) => { this.node = n } setDialog = (n) => { this.dialog = n } render() { const { children, isCenteredXS, width } = this.props const isXS = width <= BREAKPOINT_EXTRA_SMALL const visible = !!children const containerClasses = CX({ d: 1, z4: 1, h100PC: visible, w100PC: visible, displayNone: !visible, }) const dialogClasses = CX({ d: 1, posFixed: 1, aiCenter: 1, jcCenter: !isXS || isCenteredXS, jcEnd: isXS && !isCenteredXS, z4: 1, w100PC: 1, h100PC: 1, top0: 1, rightAuto: 1, bottomAuto: 1, left0: 1, }) return (