You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

395 lines
12 KiB

  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _extends2 = require('babel-runtime/helpers/extends');
  6. var _extends3 = _interopRequireDefault(_extends2);
  7. var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
  8. var _defineProperty3 = _interopRequireDefault(_defineProperty2);
  9. var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
  10. var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
  11. var _createClass2 = require('babel-runtime/helpers/createClass');
  12. var _createClass3 = _interopRequireDefault(_createClass2);
  13. var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
  14. var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
  15. var _inherits2 = require('babel-runtime/helpers/inherits');
  16. var _inherits3 = _interopRequireDefault(_inherits2);
  17. var _react = require('react');
  18. var _react2 = _interopRequireDefault(_react);
  19. var _propTypes = require('prop-types');
  20. var _propTypes2 = _interopRequireDefault(_propTypes);
  21. var _unsafeLifecyclesPolyfill = require('rc-util/lib/unsafeLifecyclesPolyfill');
  22. var _unsafeLifecyclesPolyfill2 = _interopRequireDefault(_unsafeLifecyclesPolyfill);
  23. var _ChildrenUtils = require('./ChildrenUtils');
  24. var _AnimateChild = require('./AnimateChild');
  25. var _AnimateChild2 = _interopRequireDefault(_AnimateChild);
  26. var _animate = require('./util/animate');
  27. var _animate2 = _interopRequireDefault(_animate);
  28. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
  29. var defaultKey = 'rc_animate_' + Date.now();
  30. function getChildrenFromProps(props) {
  31. var children = props.children;
  32. if (_react2['default'].isValidElement(children)) {
  33. if (!children.key) {
  34. return _react2['default'].cloneElement(children, {
  35. key: defaultKey
  36. });
  37. }
  38. }
  39. return children;
  40. }
  41. function noop() {}
  42. var Animate = function (_React$Component) {
  43. (0, _inherits3['default'])(Animate, _React$Component);
  44. // eslint-disable-line
  45. function Animate(props) {
  46. (0, _classCallCheck3['default'])(this, Animate);
  47. var _this = (0, _possibleConstructorReturn3['default'])(this, (Animate.__proto__ || Object.getPrototypeOf(Animate)).call(this, props));
  48. _initialiseProps.call(_this);
  49. _this.currentlyAnimatingKeys = {};
  50. _this.keysToEnter = [];
  51. _this.keysToLeave = [];
  52. _this.state = {
  53. children: (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props))
  54. };
  55. _this.childrenRefs = {};
  56. return _this;
  57. }
  58. (0, _createClass3['default'])(Animate, [{
  59. key: 'componentDidMount',
  60. value: function componentDidMount() {
  61. var _this2 = this;
  62. var showProp = this.props.showProp;
  63. var children = this.state.children;
  64. if (showProp) {
  65. children = children.filter(function (child) {
  66. return !!child.props[showProp];
  67. });
  68. }
  69. children.forEach(function (child) {
  70. if (child) {
  71. _this2.performAppear(child.key);
  72. }
  73. });
  74. }
  75. }, {
  76. key: 'componentWillReceiveProps',
  77. value: function componentWillReceiveProps(nextProps) {
  78. var _this3 = this;
  79. this.nextProps = nextProps;
  80. var nextChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(nextProps));
  81. var props = this.props;
  82. // exclusive needs immediate response
  83. if (props.exclusive) {
  84. Object.keys(this.currentlyAnimatingKeys).forEach(function (key) {
  85. _this3.stop(key);
  86. });
  87. }
  88. var showProp = props.showProp;
  89. var currentlyAnimatingKeys = this.currentlyAnimatingKeys;
  90. // last props children if exclusive
  91. var currentChildren = props.exclusive ? (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props)) : this.state.children;
  92. // in case destroy in showProp mode
  93. var newChildren = [];
  94. if (showProp) {
  95. currentChildren.forEach(function (currentChild) {
  96. var nextChild = currentChild && (0, _ChildrenUtils.findChildInChildrenByKey)(nextChildren, currentChild.key);
  97. var newChild = void 0;
  98. if ((!nextChild || !nextChild.props[showProp]) && currentChild.props[showProp]) {
  99. newChild = _react2['default'].cloneElement(nextChild || currentChild, (0, _defineProperty3['default'])({}, showProp, true));
  100. } else {
  101. newChild = nextChild;
  102. }
  103. if (newChild) {
  104. newChildren.push(newChild);
  105. }
  106. });
  107. nextChildren.forEach(function (nextChild) {
  108. if (!nextChild || !(0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, nextChild.key)) {
  109. newChildren.push(nextChild);
  110. }
  111. });
  112. } else {
  113. newChildren = (0, _ChildrenUtils.mergeChildren)(currentChildren, nextChildren);
  114. }
  115. // need render to avoid update
  116. this.setState({
  117. children: newChildren
  118. });
  119. nextChildren.forEach(function (child) {
  120. var key = child && child.key;
  121. if (child && currentlyAnimatingKeys[key]) {
  122. return;
  123. }
  124. var hasPrev = child && (0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, key);
  125. if (showProp) {
  126. var showInNext = child.props[showProp];
  127. if (hasPrev) {
  128. var showInNow = (0, _ChildrenUtils.findShownChildInChildrenByKey)(currentChildren, key, showProp);
  129. if (!showInNow && showInNext) {
  130. _this3.keysToEnter.push(key);
  131. }
  132. } else if (showInNext) {
  133. _this3.keysToEnter.push(key);
  134. }
  135. } else if (!hasPrev) {
  136. _this3.keysToEnter.push(key);
  137. }
  138. });
  139. currentChildren.forEach(function (child) {
  140. var key = child && child.key;
  141. if (child && currentlyAnimatingKeys[key]) {
  142. return;
  143. }
  144. var hasNext = child && (0, _ChildrenUtils.findChildInChildrenByKey)(nextChildren, key);
  145. if (showProp) {
  146. var showInNow = child.props[showProp];
  147. if (hasNext) {
  148. var showInNext = (0, _ChildrenUtils.findShownChildInChildrenByKey)(nextChildren, key, showProp);
  149. if (!showInNext && showInNow) {
  150. _this3.keysToLeave.push(key);
  151. }
  152. } else if (showInNow) {
  153. _this3.keysToLeave.push(key);
  154. }
  155. } else if (!hasNext) {
  156. _this3.keysToLeave.push(key);
  157. }
  158. });
  159. }
  160. }, {
  161. key: 'componentDidUpdate',
  162. value: function componentDidUpdate() {
  163. var keysToEnter = this.keysToEnter;
  164. this.keysToEnter = [];
  165. keysToEnter.forEach(this.performEnter);
  166. var keysToLeave = this.keysToLeave;
  167. this.keysToLeave = [];
  168. keysToLeave.forEach(this.performLeave);
  169. }
  170. }, {
  171. key: 'isValidChildByKey',
  172. value: function isValidChildByKey(currentChildren, key) {
  173. var showProp = this.props.showProp;
  174. if (showProp) {
  175. return (0, _ChildrenUtils.findShownChildInChildrenByKey)(currentChildren, key, showProp);
  176. }
  177. return (0, _ChildrenUtils.findChildInChildrenByKey)(currentChildren, key);
  178. }
  179. }, {
  180. key: 'stop',
  181. value: function stop(key) {
  182. delete this.currentlyAnimatingKeys[key];
  183. var component = this.childrenRefs[key];
  184. if (component) {
  185. component.stop();
  186. }
  187. }
  188. }, {
  189. key: 'render',
  190. value: function render() {
  191. var _this4 = this;
  192. var props = this.props;
  193. this.nextProps = props;
  194. var stateChildren = this.state.children;
  195. var children = null;
  196. if (stateChildren) {
  197. children = stateChildren.map(function (child) {
  198. if (child === null || child === undefined) {
  199. return child;
  200. }
  201. if (!child.key) {
  202. throw new Error('must set key for <rc-animate> children');
  203. }
  204. return _react2['default'].createElement(
  205. _AnimateChild2['default'],
  206. {
  207. key: child.key,
  208. ref: function ref(node) {
  209. _this4.childrenRefs[child.key] = node;
  210. },
  211. animation: props.animation,
  212. transitionName: props.transitionName,
  213. transitionEnter: props.transitionEnter,
  214. transitionAppear: props.transitionAppear,
  215. transitionLeave: props.transitionLeave
  216. },
  217. child
  218. );
  219. });
  220. }
  221. var Component = props.component;
  222. if (Component) {
  223. var passedProps = props;
  224. if (typeof Component === 'string') {
  225. passedProps = (0, _extends3['default'])({
  226. className: props.className,
  227. style: props.style
  228. }, props.componentProps);
  229. }
  230. return _react2['default'].createElement(
  231. Component,
  232. passedProps,
  233. children
  234. );
  235. }
  236. return children[0] || null;
  237. }
  238. }]);
  239. return Animate;
  240. }(_react2['default'].Component);
  241. Animate.isAnimate = true;
  242. Animate.propTypes = {
  243. className: _propTypes2['default'].string,
  244. style: _propTypes2['default'].object,
  245. component: _propTypes2['default'].any,
  246. componentProps: _propTypes2['default'].object,
  247. animation: _propTypes2['default'].object,
  248. transitionName: _propTypes2['default'].oneOfType([_propTypes2['default'].string, _propTypes2['default'].object]),
  249. transitionEnter: _propTypes2['default'].bool,
  250. transitionAppear: _propTypes2['default'].bool,
  251. exclusive: _propTypes2['default'].bool,
  252. transitionLeave: _propTypes2['default'].bool,
  253. onEnd: _propTypes2['default'].func,
  254. onEnter: _propTypes2['default'].func,
  255. onLeave: _propTypes2['default'].func,
  256. onAppear: _propTypes2['default'].func,
  257. showProp: _propTypes2['default'].string,
  258. children: _propTypes2['default'].node
  259. };
  260. Animate.defaultProps = {
  261. animation: {},
  262. component: 'span',
  263. componentProps: {},
  264. transitionEnter: true,
  265. transitionLeave: true,
  266. transitionAppear: false,
  267. onEnd: noop,
  268. onEnter: noop,
  269. onLeave: noop,
  270. onAppear: noop
  271. };
  272. var _initialiseProps = function _initialiseProps() {
  273. var _this5 = this;
  274. this.performEnter = function (key) {
  275. // may already remove by exclusive
  276. if (_this5.childrenRefs[key]) {
  277. _this5.currentlyAnimatingKeys[key] = true;
  278. _this5.childrenRefs[key].componentWillEnter(_this5.handleDoneAdding.bind(_this5, key, 'enter'));
  279. }
  280. };
  281. this.performAppear = function (key) {
  282. if (_this5.childrenRefs[key]) {
  283. _this5.currentlyAnimatingKeys[key] = true;
  284. _this5.childrenRefs[key].componentWillAppear(_this5.handleDoneAdding.bind(_this5, key, 'appear'));
  285. }
  286. };
  287. this.handleDoneAdding = function (key, type) {
  288. var props = _this5.props;
  289. delete _this5.currentlyAnimatingKeys[key];
  290. // if update on exclusive mode, skip check
  291. if (props.exclusive && props !== _this5.nextProps) {
  292. return;
  293. }
  294. var currentChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props));
  295. if (!_this5.isValidChildByKey(currentChildren, key)) {
  296. // exclusive will not need this
  297. _this5.performLeave(key);
  298. } else if (type === 'appear') {
  299. if (_animate2['default'].allowAppearCallback(props)) {
  300. props.onAppear(key);
  301. props.onEnd(key, true);
  302. }
  303. } else if (_animate2['default'].allowEnterCallback(props)) {
  304. props.onEnter(key);
  305. props.onEnd(key, true);
  306. }
  307. };
  308. this.performLeave = function (key) {
  309. // may already remove by exclusive
  310. if (_this5.childrenRefs[key]) {
  311. _this5.currentlyAnimatingKeys[key] = true;
  312. _this5.childrenRefs[key].componentWillLeave(_this5.handleDoneLeaving.bind(_this5, key));
  313. }
  314. };
  315. this.handleDoneLeaving = function (key) {
  316. var props = _this5.props;
  317. delete _this5.currentlyAnimatingKeys[key];
  318. // if update on exclusive mode, skip check
  319. if (props.exclusive && props !== _this5.nextProps) {
  320. return;
  321. }
  322. var currentChildren = (0, _ChildrenUtils.toArrayChildren)(getChildrenFromProps(props));
  323. // in case state change is too fast
  324. if (_this5.isValidChildByKey(currentChildren, key)) {
  325. _this5.performEnter(key);
  326. } else {
  327. var end = function end() {
  328. if (_animate2['default'].allowLeaveCallback(props)) {
  329. props.onLeave(key);
  330. props.onEnd(key, false);
  331. }
  332. };
  333. if (!(0, _ChildrenUtils.isSameChildren)(_this5.state.children, currentChildren, props.showProp)) {
  334. _this5.setState({
  335. children: currentChildren
  336. }, end);
  337. } else {
  338. end();
  339. }
  340. }
  341. };
  342. };
  343. exports['default'] = (0, _unsafeLifecyclesPolyfill2['default'])(Animate);
  344. module.exports = exports['default'];