UNPKG

rc-animate-v16

Version:
401 lines (350 loc) 12.9 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties'); var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _ChildrenUtils = require('./ChildrenUtils'); var _AnimateChild = require('./AnimateChild'); var _AnimateChild2 = _interopRequireDefault(_AnimateChild); var _util = require('./util'); var _util2 = _interopRequireDefault(_util); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var defaultKey = 'rc_animate_' + Date.now(); function getChildrenFromProps(props) { var children = props.children; if (_react2['default'].isValidElement(children)) { if (!children.key) { return _react2['default'].cloneElement(children, { key: defaultKey }); } } return children; } function noop() {} var Animate = function (_React$Component) { (0, _inherits3['default'])(Animate, _React$Component); function Animate(props) { (0, _classCallCheck3['default'])(this, Animate); var _this = (0, _possibleConstructorReturn3['default'])(this, (Animate.__proto__ || Object.getPrototypeOf(Animate)).call(this, props)); _initialiseProps.call(_this); _this.currentlyAnimatingKeys = {}; _this.keysToEnter = []; _this.keysToLeave = []; _this.state = { children: (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props)) }; _this.childrenRefs = {}; return _this; } (0, _createClass3['default'])(Animate, [{ key: 'componentDidMount', value: function componentDidMount() { var _this2 = this; var showProp = this.props.showProp; var children = this.state.children; if (showProp) { children = children.filter(function (child) { return !!child.props[showProp]; }); } children.forEach(function (child) { if (child) { _this2.performAppear(child.key); } }); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { var _this3 = this; this.nextProps = nextProps; var nextChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(nextProps)); var props = this.props; // exclusive needs immediate response if (props.exclusive) { Object.keys(this.currentlyAnimatingKeys).forEach(function (key) { _this3.stop(key); }); } var showProp = props.showProp; var currentlyAnimatingKeys = this.currentlyAnimatingKeys; // last props children if exclusive var currentChildren = props.exclusive ? (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props)) : this.state.children; // in case destroy in showProp mode var newChildren = []; if (showProp) { currentChildren.forEach(function (currentChild) { var nextChild = currentChild && (0, _ChildrenUtils.findChildInChildrenByKey)(nextChildren, currentChild.key); var newChild = void 0; if ((!nextChild || !nextChild.props[showProp]) && currentChild.props[showProp]) { newChild = _react2['default'].cloneElement(nextChild || currentChild, (0, _defineProperty3['default'])({}, showProp, true)); } else { newChild = nextChild; } if (newChild) { newChildren.push(newChild); } }); nextChildren.forEach(function (nextChild) { if (!nextChild || !(0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, nextChild.key)) { newChildren.push(nextChild); } }); } else { newChildren = (0, _ChildrenUtils.mergeChildren)(currentChildren, nextChildren); } // need render to avoid update this.setState({ children: newChildren }); nextChildren.forEach(function (child) { var key = child && child.key; if (child && currentlyAnimatingKeys[key]) { return; } var hasPrev = child && (0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, key); if (showProp) { var showInNext = child.props[showProp]; if (hasPrev) { var showInNow = (0, _ChildrenUtils.findShownChildInChildrenByKey)(currentChildren, key, showProp); if (!showInNow && showInNext) { _this3.keysToEnter.push(key); } } else if (showInNext) { _this3.keysToEnter.push(key); } } else if (!hasPrev) { _this3.keysToEnter.push(key); } }); currentChildren.forEach(function (child) { var key = child && child.key; if (child && currentlyAnimatingKeys[key]) { return; } var hasNext = child && (0, _ChildrenUtils.findChildInChildrenByKey)(nextChildren, key); if (showProp) { var showInNow = child.props[showProp]; if (hasNext) { var showInNext = (0, _ChildrenUtils.findShownChildInChildrenByKey)(nextChildren, key, showProp); if (!showInNext && showInNow) { _this3.keysToLeave.push(key); } } else if (showInNow) { _this3.keysToLeave.push(key); } } else if (!hasNext) { _this3.keysToLeave.push(key); } }); } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { var keysToEnter = this.keysToEnter; this.keysToEnter = []; keysToEnter.forEach(this.performEnter); var keysToLeave = this.keysToLeave; this.keysToLeave = []; keysToLeave.forEach(this.performLeave); } }, { key: 'isValidChildByKey', value: function isValidChildByKey(currentChildren, key) { var showProp = this.props.showProp; if (showProp) { return (0, _ChildrenUtils.findShownChildInChildrenByKey)(currentChildren, key, showProp); } return (0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, key); } }, { key: 'stop', value: function stop(key) { delete this.currentlyAnimatingKeys[key]; var component = this.childrenRefs[key]; if (component) { component.stop(); } } }, { key: 'render', value: function render() { var _this4 = this; var props = this.props; var stateChildren = this.state.children; var Component = props.component, transitionAppear = props.transitionAppear, transitionEnter = props.transitionEnter, transitionLeave = props.transitionLeave, transitionName = props.transitionName, animation = props.animation, onEnd = props.onEnd, onEnter = props.onEnter, onLeave = props.onLeave, onAppear = props.onAppear, componentProps = (0, _objectWithoutProperties3['default'])(props, ['component', 'transitionAppear', 'transitionEnter', 'transitionLeave', 'transitionName', 'animation', 'onEnd', 'onEnter', 'onLeave', 'onAppear']); var children = null; if (stateChildren) { children = stateChildren.map(function (child) { if (child === null || child === undefined) { return child; } if (!child.key) { throw new Error('must set key for <rc-animate> children'); } return _react2['default'].createElement( _AnimateChild2['default'], { key: child.key, ref: function ref(node) { return _this4.childrenRefs[child.key] = node; }, animation: animation, transitionName: transitionName, transitionEnter: transitionEnter, transitionAppear: transitionAppear, transitionLeave: transitionLeave }, child ); }); } if (Component) { var passedProps = props; if (typeof Component === 'string') { passedProps = (0, _extends3['default'])({ className: props.className, style: props.style }, componentProps); } return _react2['default'].createElement( Component, passedProps, children ); } return children; } }]); return Animate; }(_react2['default'].Component); Animate.propTypes = { component: _propTypes2['default'].any, animation: _propTypes2['default'].object, transitionName: _propTypes2['default'].oneOfType([_propTypes2['default'].string, _propTypes2['default'].object]), transitionEnter: _propTypes2['default'].bool, transitionAppear: _propTypes2['default'].bool, exclusive: _propTypes2['default'].bool, transitionLeave: _propTypes2['default'].bool, onEnd: _propTypes2['default'].func, onEnter: _propTypes2['default'].func, onLeave: _propTypes2['default'].func, onAppear: _propTypes2['default'].func, showProp: _propTypes2['default'].string }; Animate.defaultProps = { animation: {}, component: null, transitionEnter: true, transitionLeave: true, transitionAppear: false, onEnd: noop, onEnter: noop, onLeave: noop, onAppear: noop }; var _initialiseProps = function _initialiseProps() { var _this5 = this; this.performEnter = function (key) { // may already remove by exclusive if (_this5.childrenRefs[key]) { _this5.currentlyAnimatingKeys[key] = true; _this5.childrenRefs[key].componentWillEnter(_this5.handleDoneAdding.bind(_this5, key, 'enter')); } }; this.performAppear = function (key) { if (_this5.childrenRefs[key]) { _this5.currentlyAnimatingKeys[key] = true; _this5.childrenRefs[key].componentWillAppear(_this5.handleDoneAdding.bind(_this5, key, 'appear')); } }; this.handleDoneAdding = function (key, type) { var props = _this5.props; delete _this5.currentlyAnimatingKeys[key]; // if update on exclusive mode, skip check if (props.exclusive && props !== _this5.nextProps) { return; } var currentChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props)); if (!_this5.isValidChildByKey(currentChildren, key)) { // exclusive will not need this _this5.performLeave(key); } else { if (type === 'appear') { if (_util2['default'].allowAppearCallback(props)) { props.onAppear(key); props.onEnd(key, true); } } else { if (_util2['default'].allowEnterCallback(props)) { props.onEnter(key); props.onEnd(key, true); } } } }; this.performLeave = function (key) { // may already remove by exclusive if (_this5.childrenRefs[key]) { _this5.currentlyAnimatingKeys[key] = true; _this5.childrenRefs[key].componentWillLeave(_this5.handleDoneLeaving.bind(_this5, key)); } }; this.handleDoneLeaving = function (key) { var props = _this5.props; delete _this5.currentlyAnimatingKeys[key]; // if update on exclusive mode, skip check if (props.exclusive && props !== _this5.nextProps) { return; } var currentChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props)); // in case state change is too fast if (_this5.isValidChildByKey(currentChildren, key)) { _this5.performEnter(key); } else { var end = function end() { if (_util2['default'].allowLeaveCallback(props)) { props.onLeave(key); props.onEnd(key, false); } }; if (!(0, _ChildrenUtils.isSameChildren)(_this5.state.children, currentChildren, props.showProp)) { _this5.setState({ children: currentChildren }, end); } else { end(); } } }; }; exports['default'] = Animate; module.exports = exports['default'];