import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import Animate from 'rc-animate'; import isCssAnimationSupported from '../_util/isCssAnimationSupported'; import omit from 'omit.js'; export interface SpinProps { prefixCls?: string; className?: string; spinning?: boolean; style?: React.CSSProperties; size?: 'small' | 'default' | 'large'; tip?: string; delay?: number; wrapperClassName?: string; } export default class Spin extends React.Component { static defaultProps = { prefixCls: 'ant-spin', spinning: true, size: 'default', wrapperClassName: '', }; static propTypes = { prefixCls: PropTypes.string, className: PropTypes.string, spinning: PropTypes.bool, size: PropTypes.oneOf(['small', 'default', 'large']), wrapperClassName: PropTypes.string, }; debounceTimeout: number; delayTimeout: number; constructor(props) { super(props); const spinning = props.spinning; this.state = { spinning, }; } isNestedPattern() { return !!(this.props && this.props.children); } componentDidMount() { if (!isCssAnimationSupported()) { // Show text in IE8/9 this.setState({ notCssAnimationSupported: true, }); } } componentWillUnmount() { if (this.debounceTimeout) { clearTimeout(this.debounceTimeout); } if (this.delayTimeout) { clearTimeout(this.delayTimeout); } } componentWillReceiveProps(nextProps) { const currentSpinning = this.props.spinning; const spinning = nextProps.spinning; const { delay } = this.props; if (this.debounceTimeout) { clearTimeout(this.debounceTimeout); } if (currentSpinning && !spinning) { this.debounceTimeout = setTimeout(() => this.setState({ spinning }), 200); if (this.delayTimeout) { clearTimeout(this.delayTimeout); } } else { if (spinning && delay && !isNaN(Number(delay))) { if (this.delayTimeout) { clearTimeout(this.delayTimeout); } this.delayTimeout = setTimeout(() => this.setState({ spinning }), delay); } else { this.setState({ spinning }); } } } render() { const { className, size, prefixCls, tip, wrapperClassName, ...restProps } = this.props; const { spinning, notCssAnimationSupported } = this.state; const spinClassName = classNames(prefixCls, { [`${prefixCls}-sm`]: size === 'small', [`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-spinning`]: spinning, [`${prefixCls}-show-text`]: !!tip || notCssAnimationSupported, }, className); // fix https://fb.me/react-unknown-prop const divProps = omit(restProps, [ 'spinning', 'delay', ]); const spinElement = (
{tip ?
{tip}
: null}
); if (this.isNestedPattern()) { let animateClassName = prefixCls + '-nested-loading'; if (wrapperClassName) { animateClassName += ' ' + wrapperClassName; } const containerClassName = classNames({ [`${prefixCls}-container`]: true, [`${prefixCls}-blur`]: spinning, }); return ( {spinning &&
{spinElement}
}
{this.props.children}
); } return spinElement; } }