import { Component } from 'react'; import { CSSTransition } from 'react-transition-group'; import Portal from '../portal'; import isBrowser from '../utils/isBrowser'; import { DialogElWrapper, DialogInnerEl, IMousePosition } from './DialogEl'; import { openDialog, closeDialog } from './open'; import { addEventListener } from '../utils/component/event-handler'; import { DialogPosition, IDialogPositionType } from './position'; const TIMEOUT = 300; // ms let mousePosition: IMousePosition | null = null; if (isBrowser) { addEventListener( document.documentElement, 'click', (e: MouseEvent) => { if (e.clientX === 0 || e.clientY === 0) { return; } mousePosition = { x: e.clientX, y: e.clientY, }; }, { capture: true } ); } export interface IDialogProps { title?: React.ReactNode; children?: React.ReactNode; footer?: React.ReactNode; visible: boolean; closeBtn?: boolean; onClose?: (e: KeyboardEvent | MouseEvent | TouchEvent) => void; mask?: boolean; maskClosable?: boolean; className?: string; style?: React.CSSProperties; position?: IDialogPositionType; onOpened?: () => void; onClosed?: () => void; } export interface IDialogState { prevOpen: boolean; exiting: boolean; } export class Dialog extends Component { static defaultProps = { onClose() {}, visible: false, className: '', style: {}, position: DialogPosition.auto, title: '', closeBtn: true, mask: true, maskClosable: true, footer: null, }; static openDialog = openDialog; static closeDialog = closeDialog; lastMousePosition: IMousePosition | null = null; constructor(props: IDialogProps) { super(props); this.state = { prevOpen: props.visible, exiting: false, }; } onClose = (e: KeyboardEvent | MouseEvent | TouchEvent) => { const { onClose } = this.props; onClose && onClose(e); }; onExited = () => { const { onClosed } = this.props; this.setState({ exiting: false, }); onClosed && onClosed(); }; static getDerivedStateFromProps( props: IDialogProps, { prevOpen }: IDialogState ): Partial | null { if (props.visible === prevOpen) { return null; } if (props.visible) { return { prevOpen: props.visible, exiting: false, }; } return { prevOpen: props.visible, exiting: true, }; } render() { const { visible, closeBtn, style, position, onOpened, onClosed, mask, maskClosable, children, ...props } = this.props; const { exiting } = this.state; if (visible) { this.lastMousePosition = this.lastMousePosition || mousePosition; } else { this.lastMousePosition = null; } return ( {children} ); } } export default Dialog;