UNPKG

dora-ui

Version:

A React.js Mobile UI Library

189 lines (162 loc) 5.75 kB
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; import _createClass from "@babel/runtime/helpers/esm/createClass"; import _possibleConstructorReturn from "@babel/runtime/helpers/esm/possibleConstructorReturn"; import _getPrototypeOf from "@babel/runtime/helpers/esm/getPrototypeOf"; import _assertThisInitialized from "@babel/runtime/helpers/esm/assertThisInitialized"; import _inherits from "@babel/runtime/helpers/esm/inherits"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import React, { Component, cloneElement } from 'react'; import { CSSTransition } from 'react-transition-group'; import PropTypes from 'prop-types'; import cx from 'classnames'; import debounce from 'lodash/debounce'; import Portal from '../portal'; import Spinner from '../spinner'; // 是否延迟spinning function shouldDelay(spinning, delay) { /* eslint-disable-next-line no-restricted-globals */ return !!spinning && !!delay && !isNaN(Number(delay)); } var prefixCls = 'dora-spin'; var Spin = /*#__PURE__*/ function (_Component) { _inherits(Spin, _Component); function Spin(_props) { var _this; _classCallCheck(this, Spin); _this = _possibleConstructorReturn(this, _getPrototypeOf(Spin).call(this, _props)); _defineProperty(_assertThisInitialized(_this), "debouncifyUpdateSpinning", function (props) { var delay = props.delay; if (delay) { // 取消防抖函数的执行 _this.cancelExistingSpin(); _this.updateSpinning = debounce(_this.updateSpinning, delay); } }); _defineProperty(_assertThisInitialized(_this), "updateSpinning", function () { var spinning = _this.props.spinning; var currentSpinning = _this.state.spinning; if (currentSpinning !== spinning) { _this.setState({ spinning: spinning }); } }); var _spinning = _props.spinning, _delay = _props.delay; var shouldBeDelayed = shouldDelay(_spinning, _delay); _this.state = { spinning: _spinning && !shouldBeDelayed }; _this.debouncifyUpdateSpinning(_props); return _this; } _createClass(Spin, [{ key: "componentDidMount", value: function componentDidMount() { this.updateSpinning(); } /** * antd Spin组件每次didupdate中 取消防抖updateSpinning函数的执行 随后重新创建防抖updateSpinning函数进行执行 * 未直接使用 didmount 中创建的防抖updateSpinning函数 的防抖特性 可参见antd源码3.20.5 * 此处进行优化: 利用防抖函数特性,无需重复取消创建防抖updateSpinning函数 */ }, { key: "componentDidUpdate", value: function componentDidUpdate() { this.updateSpinning(); } /** * 避免组件卸载后 spinning状态变化而setState报错 * 参考antd,相关issue https://github.com/ant-design/ant-design/pull/16081 */ }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.cancelExistingSpin(); } }, { key: "cancelExistingSpin", value: function cancelExistingSpin() { var updateSpinning = this.updateSpinning; var copyUpdateSpinning = updateSpinning; if (copyUpdateSpinning && copyUpdateSpinning.cancel) { copyUpdateSpinning.cancel(); } } }, { key: "getSpinElement", value: function getSpinElement() { var _this$props = this.props, spinner = _this$props.spinner, tip = _this$props.tip, size = _this$props.size, fullScreen = _this$props.fullScreen, transition = _this$props.transition; var isDefaultSpinner = spinner.type === Spinner; var spinning = this.state.spinning; var spinnerContainerCls = cx("".concat(prefixCls, "-spinner-container"), _defineProperty({}, "".concat(prefixCls, "-spinner-container__full"), fullScreen)); var tipCls = cx("".concat(prefixCls, "-text"), "".concat(prefixCls, "-text-").concat(size)); var spinElement = React.createElement("div", { className: spinnerContainerCls }, isDefaultSpinner ? cloneElement(spinner, { size: size }) : spinner, tip && React.createElement("div", { className: tipCls }, tip)); /* 是否为全屏展示 */ if (fullScreen) { spinElement = React.createElement(Portal, null, spinElement); } /* 是否存在过渡效果 */ if (transition) { return React.createElement(CSSTransition, { in: spinning, classNames: "dora-fade", timeout: 300, unmountOnExit: true }, spinElement); } if (spinning) { return spinElement; } return null; } }, { key: "render", value: function render() { var _this$props2 = this.props, wrapperClassName = _this$props2.wrapperClassName, children = _this$props2.children; var wrapperCls = cx(wrapperClassName, prefixCls); return React.createElement("div", { className: wrapperCls }, this.getSpinElement(), children); } }]); return Spin; }(Component); _defineProperty(Spin, "propTypes", { spinning: PropTypes.bool.isRequired, fullScreen: PropTypes.bool, size: PropTypes.oneOf(['sm', 'md', 'lg']), children: PropTypes.node, spinner: PropTypes.element, tip: PropTypes.string, wrapperClassName: PropTypes.string, transition: PropTypes.bool, delay: PropTypes.number }); _defineProperty(Spin, "defaultProps", { fullScreen: true, size: 'md', tip: '', wrapperClassName: '', transition: true, delay: 0, spinner: React.createElement(Spinner, { type: "wave" }) }); export default Spin;