UNPKG

rsuite

Version:

A suite of react components

276 lines (242 loc) 9.96 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose"; import _pick from "lodash/pick"; import * as React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { setStatic } from 'recompose'; import bindElementResize, { unbind as unbindElementResize } from 'element-resize-event'; import BaseModal from './BaseModal'; import Bounce from '../Animation/Bounce'; import { on, getHeight } from 'dom-lib'; import { prefix, defaultProps, createChainedFunction } from '../utils'; import ModalDialog, { modalDialogPropTypes } from './ModalDialog'; import ModalBody from './ModalBody'; import ModalHeader from './ModalHeader'; import ModalTitle from './ModalTitle'; import ModalFooter from './ModalFooter'; import { SIZE } from '../constants'; import ModalContext from './ModalContext'; import mergeRefs from '../utils/mergeRefs'; var BACKDROP_TRANSITION_DURATION = 150; var Modal = /*#__PURE__*/ function (_React$Component) { _inheritsLoose(Modal, _React$Component); // for test function Modal(props) { var _this; _this = _React$Component.call(this, props) || this; _this.dialogElement = void 0; _this.modalRef = void 0; _this.windowResizeListener = null; _this.contentElement = null; _this.getBodyStyles = function () { return _this.state.bodyStyles; }; _this.bindDialogRef = function (ref) { _this.dialogElement = ref; }; _this.handleShow = function () { var dialogElement = _this.dialogElement; _this.updateModalStyles(dialogElement); _this.contentElement = dialogElement.querySelector("." + _this.addPrefix('content')); _this.windowResizeListener = on(window, 'resize', _this.handleResize); bindElementResize(_this.contentElement, _this.handleResize); }; _this.handleShowing = function () { _this.updateModalStyles(_this.dialogElement, true); }; _this.handleHide = function () { _this.destroyEvent(); }; _this.handleDialogClick = function (event) { var _this$props, _this$props$onHide; if (event.target !== event.currentTarget) { return; } (_this$props = _this.props) === null || _this$props === void 0 ? void 0 : (_this$props$onHide = _this$props.onHide) === null || _this$props$onHide === void 0 ? void 0 : _this$props$onHide.call(_this$props, event); }; _this.handleResize = function () { _this.updateModalStyles(_this.dialogElement); }; _this.addPrefix = function (name) { return prefix(_this.props.classPrefix)(name); }; _this.state = { bodyStyles: {} }; _this.modalRef = React.createRef(); return _this; } var _proto = Modal.prototype; _proto.componentWillUnmount = function componentWillUnmount() { this.destroyEvent(); }; _proto.getBodyStylesByDialog = function getBodyStylesByDialog(dialogElement, entering) { var _this$props2 = this.props, overflow = _this$props2.overflow, drawer = _this$props2.drawer; var node = dialogElement || this.dialogElement; var scrollHeight = node ? node.scrollHeight : 0; if (!overflow) { return {}; } var bodyStyles = { overflow: 'auto' }; if (node) { // default margin var headerHeight = 46; var footerHeight = 46; var contentHeight = 30; var headerDOM = node.querySelector("." + this.addPrefix('header')); var footerDOM = node.querySelector("." + this.addPrefix('footer')); var contentDOM = node.querySelector("." + this.addPrefix('content')); headerHeight = headerDOM ? getHeight(headerDOM) + headerHeight : headerHeight; footerHeight = footerDOM ? getHeight(footerDOM) + headerHeight : headerHeight; contentHeight = contentDOM ? getHeight(contentDOM) + contentHeight : contentHeight; if (drawer) { bodyStyles.height = contentHeight - (headerHeight + footerHeight); } else { /** * Header height + Footer height + Dialog margin */ var excludeHeight = headerHeight + footerHeight + (entering ? 76 : 60); var bodyHeight = getHeight(window) - excludeHeight; var maxHeight = scrollHeight >= bodyHeight ? bodyHeight : scrollHeight; bodyStyles.maxHeight = maxHeight; } } return bodyStyles; }; _proto.destroyEvent = function destroyEvent() { var _this$windowResizeLis, _this$windowResizeLis2; (_this$windowResizeLis = this.windowResizeListener) === null || _this$windowResizeLis === void 0 ? void 0 : (_this$windowResizeLis2 = _this$windowResizeLis.off) === null || _this$windowResizeLis2 === void 0 ? void 0 : _this$windowResizeLis2.call(_this$windowResizeLis); if (this.contentElement) { unbindElementResize(this.contentElement); } }; _proto.updateModalStyles = function updateModalStyles(dialogElement, entering) { this.setState({ bodyStyles: this.getBodyStylesByDialog(dialogElement, entering) }); }; _proto.render = function render() { var _classNames, _classNames2, _this2 = this; var _this$props3 = this.props, className = _this$props3.className, children = _this$props3.children, dialogClassName = _this$props3.dialogClassName, backdropClassName = _this$props3.backdropClassName, dialogStyle = _this$props3.dialogStyle, animation = _this$props3.animation, classPrefix = _this$props3.classPrefix, show = _this$props3.show, size = _this$props3.size, full = _this$props3.full, dialogComponentClass = _this$props3.dialogComponentClass, animationProps = _this$props3.animationProps, animationTimeout = _this$props3.animationTimeout, onHide = _this$props3.onHide, rest = _objectWithoutPropertiesLoose(_this$props3, ["className", "children", "dialogClassName", "backdropClassName", "dialogStyle", "animation", "classPrefix", "show", "size", "full", "dialogComponentClass", "animationProps", "animationTimeout", "onHide"]); var inClass = { in: show && !animation }; var Dialog = dialogComponentClass; var classes = classNames(this.addPrefix(size), className, (_classNames = {}, _classNames[this.addPrefix('full')] = full, _classNames)); return React.createElement(ModalContext.Provider, { value: { onModalHide: onHide, getBodyStyles: this.getBodyStyles } }, React.createElement(BaseModal, _extends({}, rest, { ref: this.modalRef, show: show, onHide: onHide, className: this.addPrefix('wrapper'), onEntered: createChainedFunction(this.handleShow, this.props.onEntered), onEntering: createChainedFunction(this.handleShowing, this.props.onEntering), onExited: createChainedFunction(this.handleHide, this.props.onExited), backdropClassName: classNames(this.addPrefix('backdrop'), backdropClassName, inClass), containerClassName: classNames(this.addPrefix('open'), (_classNames2 = {}, _classNames2[this.addPrefix('has-backdrop')] = rest.backdrop, _classNames2)), transition: animation ? animation : undefined, animationProps: animationProps, dialogTransitionTimeout: animationTimeout, backdropTransitionTimeout: BACKDROP_TRANSITION_DURATION }), function (transitionProps, ref) { var transitionClassName = transitionProps.className, transitionRest = _objectWithoutPropertiesLoose(transitionProps, ["className"]); return React.createElement(Dialog, _extends({}, transitionRest, _pick(rest, Object.keys(modalDialogPropTypes)), { classPrefix: classPrefix, className: classNames(classes, transitionClassName), dialogClassName: dialogClassName, dialogStyle: dialogStyle, onClick: rest.backdrop === true ? _this2.handleDialogClick : null, dialogRef: mergeRefs(_this2.bindDialogRef, ref) }), children); })); }; return Modal; }(React.Component); Modal.propTypes = { classPrefix: PropTypes.string, size: PropTypes.oneOf(SIZE), container: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), onRendered: PropTypes.func, className: PropTypes.string, children: PropTypes.node, dialogClassName: PropTypes.string, backdropClassName: PropTypes.string, style: PropTypes.object, dialogStyle: PropTypes.object, backdropStyle: PropTypes.object, show: PropTypes.bool, full: PropTypes.bool, backdrop: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]), keyboard: PropTypes.bool, transition: PropTypes.elementType, dialogTransitionTimeout: PropTypes.number, backdropTransitionTimeout: PropTypes.number, autoFocus: PropTypes.bool, enforceFocus: PropTypes.bool, overflow: PropTypes.bool, drawer: PropTypes.bool, dialogComponentClass: PropTypes.elementType, animation: PropTypes.any, animationProps: PropTypes.object, animationTimeout: PropTypes.number, onEscapeKeyUp: PropTypes.func, onBackdropClick: PropTypes.func, onShow: PropTypes.func, onHide: PropTypes.func, onEnter: PropTypes.func, onEntering: PropTypes.func, onEntered: PropTypes.func, onExit: PropTypes.func, onExiting: PropTypes.func, onExited: PropTypes.func }; Modal.defaultProps = { size: 'sm', backdrop: true, keyboard: true, autoFocus: true, enforceFocus: true, animation: Bounce, animationTimeout: 300, dialogComponentClass: ModalDialog, overflow: true }; var EnhancedModal = defaultProps({ classPrefix: 'modal' })(Modal); setStatic('Body', ModalBody)(EnhancedModal); setStatic('Header', ModalHeader)(EnhancedModal); setStatic('Title', ModalTitle)(EnhancedModal); setStatic('Footer', ModalFooter)(EnhancedModal); setStatic('Dialog', ModalDialog)(EnhancedModal); export default EnhancedModal;