'use strict'; exports.__esModule = true; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _chainFunction = require('chain-function'); var _chainFunction2 = _interopRequireDefault(_chainFunction); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _warning = require('warning'); var _warning2 = _interopRequireDefault(_warning); var _ChildMapping = require('./utils/ChildMapping'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var propTypes = { component: _propTypes2.default.any, childFactory: _propTypes2.default.func, children: _propTypes2.default.node }; var defaultProps = { component: 'span', childFactory: function childFactory(child) { return child; } }; var TransitionGroup = function (_React$Component) { _inherits(TransitionGroup, _React$Component); function TransitionGroup(props, context) { _classCallCheck(this, TransitionGroup); var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context)); _this.performAppear = function (key, component) { _this.currentlyTransitioningKeys[key] = true; if (component.componentWillAppear) { component.componentWillAppear(_this._handleDoneAppearing.bind(_this, key, component)); } else { _this._handleDoneAppearing(key, component); } }; _this._handleDoneAppearing = function (key, component) { if (component.componentDidAppear) { component.componentDidAppear(); } delete _this.currentlyTransitioningKeys[key]; var currentChildMapping = (0, _ChildMapping.getChildMapping)(_this.props.children); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully appeared. Remove it. _this.performLeave(key, component); } }; _this.performEnter = function (key, component) { _this.currentlyTransitioningKeys[key] = true; if (component.componentWillEnter) { component.componentWillEnter(_this._handleDoneEntering.bind(_this, key, component)); } else { _this._handleDoneEntering(key, component); } }; _this._handleDoneEntering = function (key, component) { if (component.componentDidEnter) { component.componentDidEnter(); } delete _this.currentlyTransitioningKeys[key]; var currentChildMapping = (0, _ChildMapping.getChildMapping)(_this.props.children); if (!currentChildMapping || !currentChildMapping.hasOwnProperty(key)) { // This was removed before it had fully entered. Remove it. _this.performLeave(key, component); } }; _this.performLeave = function (key, component) { _this.currentlyTransitioningKeys[key] = true; if (component.componentWillLeave) { component.componentWillLeave(_this._handleDoneLeaving.bind(_this, key, component)); } else { // Note that this is somewhat dangerous b/c it calls setState() // again, effectively mutating the component before all the work // is done. _this._handleDoneLeaving(key, component); } }; _this._handleDoneLeaving = function (key, component) { if (component.componentDidLeave) { component.componentDidLeave(); } delete _this.currentlyTransitioningKeys[key]; var currentChildMapping = (0, _ChildMapping.getChildMapping)(_this.props.children); if (currentChildMapping && currentChildMapping.hasOwnProperty(key)) { // This entered again before it fully left. Add it again. _this.keysToEnter.push(key); } else { _this.setState(function (state) { var newChildren = _extends({}, state.children); delete newChildren[key]; return { children: newChildren }; }); } }; _this.childRefs = Object.create(null); _this.state = { children: (0, _ChildMapping.getChildMapping)(props.children) }; return _this; } TransitionGroup.prototype.componentWillMount = function componentWillMount() { this.currentlyTransitioningKeys = {}; this.keysToEnter = []; this.keysToLeave = []; }; TransitionGroup.prototype.componentDidMount = function componentDidMount() { var initialChildMapping = this.state.children; for (var key in initialChildMapping) { if (initialChildMapping[key]) { this.performAppear(key, this.childRefs[key]); } } }; TransitionGroup.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var nextChildMapping = (0, _ChildMapping.getChildMapping)(nextProps.children); var prevChildMapping = this.state.children; this.setState({ children: (0, _ChildMapping.mergeChildMappings)(prevChildMapping, nextChildMapping) }); for (var key in nextChildMapping) { var hasPrev = prevChildMapping && prevChildMapping.hasOwnProperty(key); if (nextChildMapping[key] && !hasPrev && !this.currentlyTransitioningKeys[key]) { this.keysToEnter.push(key); } } for (var _key in prevChildMapping) { var hasNext = nextChildMapping && nextChildMapping.hasOwnProperty(_key); if (prevChildMapping[_key] && !hasNext && !this.currentlyTransitioningKeys[_key]) { this.keysToLeave.push(_key); } } // If we want to someday check for reordering, we could do it here. }; TransitionGroup.prototype.componentDidUpdate = function componentDidUpdate() { var _this2 = this; var keysToEnter = this.keysToEnter; this.keysToEnter = []; keysToEnter.forEach(function (key) { return _this2.performEnter(key, _this2.childRefs[key]); }); var keysToLeave = this.keysToLeave; this.keysToLeave = []; keysToLeave.forEach(function (key) { return _this2.performLeave(key, _this2.childRefs[key]); }); }; TransitionGroup.prototype.render = function render() { var _this3 = this; // TODO: we could get rid of the need for the wrapper node // by cloning a single child var childrenToRender = []; var _loop = function _loop(key) { var child = _this3.state.children[key]; if (child) { var isCallbackRef = typeof child.ref !== 'string'; var factoryChild = _this3.props.childFactory(child); var ref = function ref(r) { _this3.childRefs[key] = r; }; process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(isCallbackRef, 'string refs are not supported on children of TransitionGroup and will be ignored. ' + 'Please use a callback ref instead: https://facebook.github.io/react/docs/refs-and-the-dom.html#the-ref-callback-attribute') : void 0; // Always chaining the refs leads to problems when the childFactory // wraps the child. The child ref callback gets called twice with the // wrapper and the child. So we only need to chain the ref if the // factoryChild is not different from child. if (factoryChild === child && isCallbackRef) { ref = (0, _chainFunction2.default)(child.ref, ref); } // You may need to apply reactive updates to a child as it is leaving. // The normal React way to do it won't work since the child will have // already been removed. In case you need this behavior you can provide // a childFactory function to wrap every child, even the ones that are // leaving. childrenToRender.push(_react2.default.cloneElement(factoryChild, { key: key, ref: ref })); } }; for (var key in this.state.children) { _loop(key); } // Do not forward TransitionGroup props to primitive DOM nodes var props = _extends({}, this.props); delete props.transitionLeave; delete props.transitionName; delete props.transitionAppear; delete props.transitionEnter; delete props.childFactory; delete props.transitionLeaveTimeout; delete props.transitionEnterTimeout; delete props.transitionAppearTimeout; delete props.component; return _react2.default.createElement(this.props.component, props, childrenToRender); }; return TransitionGroup; }(_react2.default.Component); TransitionGroup.displayName = 'TransitionGroup'; TransitionGroup.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {}; TransitionGroup.defaultProps = defaultProps; exports.default = TransitionGroup; module.exports = exports['default'];