import React, { PureComponent } from 'react'; import { createPortal } from 'react-dom'; import { TransitionGroup, CSSTransition } from 'react-transition-group'; import ModalBody from './ModalBody'; import './index.scss'; export interface IButton { text: string | React.ReactElement; type?: 'default' | 'primary' | 'success' | 'info' | 'warning' | 'danger' | 'link'; disabled?: boolean; onClick?(): void; } interface Props { isOpen?: boolean; title?: React.ReactNode; disableButtons?: boolean; hideButtons?: boolean; children: React.ReactNode; buttons?: IButton[]; maxWidth?: number; handleClose(): void; } interface ModalStyle { width?: string; maxWidth?: string; } const Fade = ({ ...props }: any) => ( ); export default class Modal extends PureComponent { public modalParent: HTMLElement; public modalBody: ModalBody; public componentDidUpdate(prevProps: Props) { if (prevProps.isOpen !== this.props.isOpen) { document.body.classList.toggle('no-scroll', !!this.props.isOpen); } } public componentDidMount() { const modalEl = document.getElementById('ModalContainer'); if (modalEl) { this.modalParent = document.createElement('div'); modalEl.appendChild(this.modalParent); } } public componentWillUnmount() { document.body.classList.remove('no-scroll'); const modalEl = document.getElementById('ModalContainer'); if (modalEl) { modalEl.removeChild(this.modalParent); } } public render() { const { isOpen, title, children, buttons, disableButtons, hideButtons, handleClose, maxWidth } = this.props; const hasButtons = buttons && buttons.length; const modalStyle: ModalStyle = {}; if (maxWidth) { modalStyle.width = '100%'; modalStyle.maxWidth = `${maxWidth}px`; } const modalBodyProps = { title, children, modalStyle, hasButtons, buttons, disableButtons, hideButtons, handleClose }; const modal = ( {isOpen && ( // Trap focus in modal by focusing the first element after the animation is complete this.modalBody.firstTabStop.focus()}>
(this.modalBody = div as ModalBody)} />
)} ); if (this.modalParent) { return createPortal(modal, this.modalParent); } else { return modal; } } }