diff --git a/dist/react-flip-move.js b/dist/react-flip-move.js index 882030c..9b7f517 100644 --- a/dist/react-flip-move.js +++ b/dist/react-flip-move.js @@ -254,20 +254,13 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: 'componentDidUpdate', value: function componentDidUpdate(previousProps) { - var childKeys = this.props.children.map(function (c) { - return c.key; - }).join(''); - var prevChildKeys = previousProps.children.map(function (c) { - return c.key; - }).join(''); - - // If the children have been re-arranged or added/removed, trigger the - // main FLIP animation. + // If the children have been re-arranged, moved, or added/removed, + // trigger the main FLIP animation. // // This check is required so that we don't trigger a re-animation when the // `onFinishAll` handler is called, at the end of the animation, to remove // exited nodes. - if (childKeys !== prevChildKeys) { + if (this.props.children !== previousProps.children) { this.calculateAndAnimateChildren(); } } diff --git a/dist/react-flip-move.min.js b/dist/react-flip-move.min.js index 570501d..20e21f7 100644 --- a/dist/react-flip-move.min.js +++ b/dist/react-flip-move.min.js @@ -1 +1 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("react-dom")):"function"==typeof define&&define.amd?define(["react","react-dom"],t):"object"==typeof exports?exports.FlipMove=t(require("react"),require("react-dom")):e.FlipMove=t(e.React,e.ReactDOM)}(this,function(e,t){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";e.exports=n(3)},function(e,t){"use strict";function n(e,t){var n="string"==typeof e?parseInt(e):e;return isNaN(n)&&console.error("Invalid prop '"+t+"' supplied to FlipMove. Expected a number, or a string that can easily be resolved to a number (eg. \"100\"). Instead, received '"+e+"'."),n}function r(){for(var e=arguments.length,t=Array(e),r=0;e>r;r++)t[r]=arguments[r];return t.map(n)}function o(e,t){var n=arguments.length<=2||void 0===arguments[2]?"key":arguments[2];return t.filter(function(t){return!e.find(function(e){return e[n]===t[n]})})}function i(e,t){Object.keys(t).forEach(function(n){e.style[n]=t[n]})}function a(){var e={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};if("undefined"==typeof document)return"";var t=document.createElement("fakeelement");for(var n in e)if(void 0!==t.style[n])return e[n]}Object.defineProperty(t,"__esModule",{value:!0}),t.convertToInt=n,t.convertAllToInt=r,t.filterNewItems=o,t.applyStylesToDOMNode=i,t.whichTransitionEvent=a},function(t,n){t.exports=e},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var l,u=function(){function e(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(l){o=!0,i=l}finally{try{!r&&s.return&&s.return()}finally{if(o)throw i}}return n}return function(t,n){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),p=Object.assign||function(e){for(var t=1;t>>0,o=arguments[1],i=0;r>i;i++)if(t=n[i],e.call(o,t,i,n))return t})},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){var t,n;return n=t=function(t){function n(){return o(this,n),i(this,Object.getPrototypeOf(n).apply(this,arguments))}return a(n,t),p(n,[{key:"convertProps",value:function(e){var t=u({},e),n=["duration","delay","staggerDurationBy","staggerDelayBy"];return n.forEach(function(e){return t[e]=(0,d.convertToInt)(t[e],e)}),t.children=c.default.Children.toArray(this.props.children),t.enterAnimation=this.convertAnimationProp(t.enterAnimation,y.enterPresets),t.leaveAnimation=this.convertAnimationProp(t.leaveAnimation,y.leavePresets),"undefined"!=typeof e.disableAnimations&&(console.warn("Warning, via react-flip-move: `disableAnimations` is deprecated. Please switch to use `disableAllAnimations`. This will become a silent error in future versions."),t.disableAnimations=void 0,t.disableAllAnimations=e.disableAnimations),t}},{key:"convertAnimationProp",value:function(e,t){var n=void 0;switch("undefined"==typeof e?"undefined":l(e)){case"boolean":n=t[e?y.defaultPreset:y.disablePreset];break;case"string":var r=Object.keys(t);-1===r.indexOf(e)?(console.warn("Warning, via react-flip-move: You supplied an invalid preset name of '"+e+"'. The accepted values are: "+r.join(", ")+". Defaulting to "+y.defaultPreset),n=t[y.defaultPreset]):n=t[e];break;case"object":("object"!==l(e.from)||"object"!==l(e.to))&&console.error("Error, via react-flip-move: Please provide `from` and `to` properties when supplying a custom animation object, or use a preset."),n=e}return n}},{key:"render",value:function(){return c.default.createElement(e,this.convertProps(this.props))}}]),n}(f.Component),t.propTypes={children:f.PropTypes.oneOfType([f.PropTypes.array,f.PropTypes.object]).isRequired,easing:f.PropTypes.string,duration:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),delay:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),staggerDurationBy:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),staggerDelayBy:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),onStart:f.PropTypes.func,onFinish:f.PropTypes.func,onFinishAll:f.PropTypes.func,className:f.PropTypes.string,typeName:f.PropTypes.string,disableAllAnimations:f.PropTypes.bool,enterAnimation:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool,f.PropTypes.object]),leaveAnimation:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool,f.PropTypes.object])},t.defaultProps={easing:"ease-in-out",duration:350,delay:0,staggerDurationBy:0,staggerDelayBy:0,typeName:"div",enterAnimation:y.defaultPreset,leaveAnimation:y.defaultPreset},n}var l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},u=Object.assign||function(e){for(var t=1;tr;r++)t[r]=arguments[r];return t.map(n)}function o(e,t){var n=arguments.length<=2||void 0===arguments[2]?"key":arguments[2];return t.filter(function(t){return!e.find(function(e){return e[n]===t[n]})})}function i(e,t){Object.keys(t).forEach(function(n){e.style[n]=t[n]})}function a(){var e={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};if("undefined"==typeof document)return"";var t=document.createElement("fakeelement");for(var n in e)if(void 0!==t.style[n])return e[n]}Object.defineProperty(t,"__esModule",{value:!0}),t.convertToInt=n,t.convertAllToInt=r,t.filterNewItems=o,t.applyStylesToDOMNode=i,t.whichTransitionEvent=a},function(t,n){t.exports=e},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}var l,u=function(){function e(e,t){var n=[],r=!0,o=!1,i=void 0;try{for(var a,s=e[Symbol.iterator]();!(r=(a=s.next()).done)&&(n.push(a.value),!t||n.length!==t);r=!0);}catch(l){o=!0,i=l}finally{try{!r&&s.return&&s.return()}finally{if(o)throw i}}return n}return function(t,n){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),p=Object.assign||function(e){for(var t=1;t>>0,o=arguments[1],i=0;r>i;i++)if(t=n[i],e.call(o,t,i,n))return t})},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function s(e){var t,n;return n=t=function(t){function n(){return o(this,n),i(this,Object.getPrototypeOf(n).apply(this,arguments))}return a(n,t),p(n,[{key:"convertProps",value:function(e){var t=u({},e),n=["duration","delay","staggerDurationBy","staggerDelayBy"];return n.forEach(function(e){return t[e]=(0,d.convertToInt)(t[e],e)}),t.children=c.default.Children.toArray(this.props.children),t.enterAnimation=this.convertAnimationProp(t.enterAnimation,y.enterPresets),t.leaveAnimation=this.convertAnimationProp(t.leaveAnimation,y.leavePresets),"undefined"!=typeof e.disableAnimations&&(console.warn("Warning, via react-flip-move: `disableAnimations` is deprecated. Please switch to use `disableAllAnimations`. This will become a silent error in future versions."),t.disableAnimations=void 0,t.disableAllAnimations=e.disableAnimations),t}},{key:"convertAnimationProp",value:function(e,t){var n=void 0;switch("undefined"==typeof e?"undefined":l(e)){case"boolean":n=t[e?y.defaultPreset:y.disablePreset];break;case"string":var r=Object.keys(t);-1===r.indexOf(e)?(console.warn("Warning, via react-flip-move: You supplied an invalid preset name of '"+e+"'. The accepted values are: "+r.join(", ")+". Defaulting to "+y.defaultPreset),n=t[y.defaultPreset]):n=t[e];break;case"object":("object"!==l(e.from)||"object"!==l(e.to))&&console.error("Error, via react-flip-move: Please provide `from` and `to` properties when supplying a custom animation object, or use a preset."),n=e}return n}},{key:"render",value:function(){return c.default.createElement(e,this.convertProps(this.props))}}]),n}(f.Component),t.propTypes={children:f.PropTypes.oneOfType([f.PropTypes.array,f.PropTypes.object]).isRequired,easing:f.PropTypes.string,duration:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),delay:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),staggerDurationBy:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),staggerDelayBy:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.number]),onStart:f.PropTypes.func,onFinish:f.PropTypes.func,onFinishAll:f.PropTypes.func,className:f.PropTypes.string,typeName:f.PropTypes.string,disableAllAnimations:f.PropTypes.bool,enterAnimation:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool,f.PropTypes.object]),leaveAnimation:f.PropTypes.oneOfType([f.PropTypes.string,f.PropTypes.bool,f.PropTypes.object])},t.defaultProps={easing:"ease-in-out",duration:350,delay:0,staggerDurationBy:0,staggerDelayBy:0,typeName:"div",enterAnimation:y.defaultPreset,leaveAnimation:y.defaultPreset},n}var l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e},u=Object.assign||function(e){for(var t=1;t c.key).join(''); - const prevChildKeys = previousProps.children.map( c => c.key).join(''); - - // If the children have been re-arranged or added/removed, trigger the - // main FLIP animation. + // If the children have been re-arranged, moved, or added/removed, + // trigger the main FLIP animation. // // This check is required so that we don't trigger a re-animation when the // `onFinishAll` handler is called, at the end of the animation, to remove // exited nodes. - if ( childKeys !== prevChildKeys ) { + if ( this.props.children !== previousProps.children ) { this.calculateAndAnimateChildren(); } } diff --git a/stories/index.js b/stories/index.js index 439f6ab..ee82954 100644 --- a/stories/index.js +++ b/stories/index.js @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { storiesOf, action } from '@kadira/storybook'; import shuffle from 'lodash/shuffle'; import sampleSize from 'lodash/sampleSize'; +import range from 'lodash/range'; import FlipMove from '../src/FlipMove.js'; @@ -62,20 +63,12 @@ storiesOf('FlipMove', module) )) @@ -83,24 +76,18 @@ storiesOf('FlipMove', module) )) + .add('when prop keys do not change, but items rearrange', () => ( + + )) // Controlling component const items = [ @@ -204,3 +191,40 @@ class Controls extends Component { ); } } + +class StaticItems extends Component { + renderItems() { + return range(4).map( i => { + let left = Math.floor(Math.random() * 100) + 'px'; + let top = Math.floor(Math.random() * 100) + 'px'; + + return ( +
+ Item! +
+ ); + }) + } + + render() { + return ( +
+ + + { this.renderItems() } + +
+ ); + } +}