import _extends from "@babel/runtime/helpers/esm/extends"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import classNames from 'classnames'; import contains from "rc-util/es/Dom/contains"; import useId from "rc-util/es/hooks/useId"; import KeyCode from "rc-util/es/KeyCode"; import pickAttrs from "rc-util/es/pickAttrs"; import * as React from 'react'; import { useEffect, useRef } from 'react'; import { getMotionName } from "../util"; import Content from "./Content"; import Mask from "./Mask"; import { warning } from "rc-util/es/warning"; var Dialog = function Dialog(props) { var _props$prefixCls = props.prefixCls, prefixCls = _props$prefixCls === void 0 ? 'rc-dialog' : _props$prefixCls, zIndex = props.zIndex, _props$visible = props.visible, visible = _props$visible === void 0 ? false : _props$visible, _props$keyboard = props.keyboard, keyboard = _props$keyboard === void 0 ? true : _props$keyboard, _props$focusTriggerAf = props.focusTriggerAfterClose, focusTriggerAfterClose = _props$focusTriggerAf === void 0 ? true : _props$focusTriggerAf, wrapStyle = props.wrapStyle, wrapClassName = props.wrapClassName, wrapProps = props.wrapProps, onClose = props.onClose, afterOpenChange = props.afterOpenChange, afterClose = props.afterClose, transitionName = props.transitionName, animation = props.animation, _props$closable = props.closable, closable = _props$closable === void 0 ? true : _props$closable, _props$mask = props.mask, mask = _props$mask === void 0 ? true : _props$mask, maskTransitionName = props.maskTransitionName, maskAnimation = props.maskAnimation, _props$maskClosable = props.maskClosable, maskClosable = _props$maskClosable === void 0 ? true : _props$maskClosable, maskStyle = props.maskStyle, maskProps = props.maskProps, rootClassName = props.rootClassName, modalClassNames = props.classNames, modalStyles = props.styles; if (process.env.NODE_ENV !== 'production') { ['wrapStyle', 'bodyStyle', 'maskStyle'].forEach(function (prop) { // (prop in props) && console.error(`Warning: ${prop} is deprecated, please use styles instead.`) warning(!(prop in props), "".concat(prop, " is deprecated, please use styles instead.")); }); if ('wrapClassName' in props) { warning(false, "wrapClassName is deprecated, please use classNames instead."); } } var lastOutSideActiveElementRef = useRef(); var wrapperRef = useRef(); var contentRef = useRef(); var _React$useState = React.useState(visible), _React$useState2 = _slicedToArray(_React$useState, 2), animatedVisible = _React$useState2[0], setAnimatedVisible = _React$useState2[1]; // ========================== Init ========================== var ariaId = useId(); function saveLastOutSideActiveElementRef() { if (!contains(wrapperRef.current, document.activeElement)) { lastOutSideActiveElementRef.current = document.activeElement; } } function focusDialogContent() { if (!contains(wrapperRef.current, document.activeElement)) { var _contentRef$current; (_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 || _contentRef$current.focus(); } } // ========================= Events ========================= function onDialogVisibleChanged(newVisible) { // Try to focus if (newVisible) { focusDialogContent(); } else { // Clean up scroll bar & focus back setAnimatedVisible(false); if (mask && lastOutSideActiveElementRef.current && focusTriggerAfterClose) { try { lastOutSideActiveElementRef.current.focus({ preventScroll: true }); } catch (e) { // Do nothing } lastOutSideActiveElementRef.current = null; } // Trigger afterClose only when change visible from true to false if (animatedVisible) { afterClose === null || afterClose === void 0 || afterClose(); } } afterOpenChange === null || afterOpenChange === void 0 || afterOpenChange(newVisible); } function onInternalClose(e) { onClose === null || onClose === void 0 || onClose(e); } // >>> Content var contentClickRef = useRef(false); var contentTimeoutRef = useRef(); // We need record content click incase content popup out of dialog var onContentMouseDown = function onContentMouseDown() { clearTimeout(contentTimeoutRef.current); contentClickRef.current = true; }; var onContentMouseUp = function onContentMouseUp() { contentTimeoutRef.current = setTimeout(function () { contentClickRef.current = false; }); }; // >>> Wrapper // Close only when element not on dialog var onWrapperClick = null; if (maskClosable) { onWrapperClick = function onWrapperClick(e) { if (contentClickRef.current) { contentClickRef.current = false; } else if (wrapperRef.current === e.target) { onInternalClose(e); } }; } function onWrapperKeyDown(e) { if (keyboard && e.keyCode === KeyCode.ESC) { e.stopPropagation(); onInternalClose(e); return; } // keep focus inside dialog if (visible && e.keyCode === KeyCode.TAB) { contentRef.current.changeActive(!e.shiftKey); } } // ========================= Effect ========================= useEffect(function () { if (visible) { setAnimatedVisible(true); saveLastOutSideActiveElementRef(); } }, [visible]); // Remove direct should also check the scroll bar update useEffect(function () { return function () { clearTimeout(contentTimeoutRef.current); }; }, []); var mergedStyle = _objectSpread(_objectSpread(_objectSpread({ zIndex: zIndex }, wrapStyle), modalStyles === null || modalStyles === void 0 ? void 0 : modalStyles.wrapper), {}, { display: !animatedVisible ? 'none' : null }); // ========================= Render ========================= return /*#__PURE__*/React.createElement("div", _extends({ className: classNames("".concat(prefixCls, "-root"), rootClassName) }, pickAttrs(props, { data: true })), /*#__PURE__*/React.createElement(Mask, { prefixCls: prefixCls, visible: mask && visible, motionName: getMotionName(prefixCls, maskTransitionName, maskAnimation), style: _objectSpread(_objectSpread({ zIndex: zIndex }, maskStyle), modalStyles === null || modalStyles === void 0 ? void 0 : modalStyles.mask), maskProps: maskProps, className: modalClassNames === null || modalClassNames === void 0 ? void 0 : modalClassNames.mask }), /*#__PURE__*/React.createElement("div", _extends({ tabIndex: -1, onKeyDown: onWrapperKeyDown, className: classNames("".concat(prefixCls, "-wrap"), wrapClassName, modalClassNames === null || modalClassNames === void 0 ? void 0 : modalClassNames.wrapper), ref: wrapperRef, onClick: onWrapperClick, style: mergedStyle }, wrapProps), /*#__PURE__*/React.createElement(Content, _extends({}, props, { onMouseDown: onContentMouseDown, onMouseUp: onContentMouseUp, ref: contentRef, closable: closable, ariaId: ariaId, prefixCls: prefixCls, visible: visible && animatedVisible, onClose: onInternalClose, onVisibleChanged: onDialogVisibleChanged, motionName: getMotionName(prefixCls, transitionName, animation) })))); }; export default Dialog;