react-animated-list
Version:
Simple way of animating when components are added or removed from an array
100 lines (93 loc) • 5.35 kB
JavaScript
import { useState, useEffect, createElement, Fragment, useRef } from 'react';
import Grow from '@material-ui/core/Grow';
import Fade from '@material-ui/core/Fade';
import Slide from '@material-ui/core/Slide';
import Zoom from '@material-ui/core/Zoom';
import Collapse from '@material-ui/core/Collapse';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function usePrevious(value) {
var ref = useRef();
useEffect(function () {
ref.current = value;
});
return ref.current || [];
}
function AnimatedListItem(_a) {
var shown = _a.shown, children = _a.children, timeout = _a.timeout, onExited = _a.onExited, animationProps = _a.animationProps, animation = _a.animation;
useEffect(function () { }, [shown]);
var componentMap = {
grow: Grow,
fade: Fade,
slide: Slide,
zoom: Zoom,
collapse: Collapse,
};
var SelectedComponent = componentMap[animation];
return (createElement(SelectedComponent, __assign({}, animationProps, { timeout: timeout, in: shown, onExiting: onExited }),
createElement("div", null, children)));
}
var AnimatedList = function (_a) {
var children = _a.children, _b = _a.animation, animation = _b === void 0 ? "grow" : _b, animationProps = _a.animationProps, _c = _a.initialAnimationDuration, initialAnimationDuration = _c === void 0 ? 750 : _c;
var previousChildren = usePrevious(children);
var _d = useState([]), removed = _d[0], setRemoved = _d[1];
var _e = useState([]), removedShown = _e[0], setRemovedShown = _e[1];
var removeChildren = function () {
var newlyRemoved = previousChildren.filter(function (c) { return children.findIndex(function (oc) { return oc.key === c.key; }) === -1; });
newlyRemoved.forEach(function (r) {
var _a, _b;
var index = previousChildren.findIndex(function (rr) { return r.key === rr.key; });
setRemoved(__assign(__assign({}, removed), (_a = {}, _a[index] = r, _a)));
setRemovedShown(__assign(__assign({}, removedShown), (_b = {}, _b[index] = r, _b)));
setTimeout(function () {
delete removedShown[index];
setRemovedShown(__assign({}, removedShown));
}, 100);
});
};
useEffect(function () {
if (previousChildren.length > children.length) {
removeChildren();
}
}, [children]);
var handleExit = function (index) {
setTimeout(function () {
delete removed[index];
setRemoved(__assign({}, removed));
}, 300);
};
var getEnterDelayTime = function (index) {
var delayTime = initialAnimationDuration * ((index + 1) / (children.length || 1));
return delayTime;
};
return (createElement(Fragment, null, children.length === 0 && removed[0] ? (createElement(AnimatedListItem, { onExited: function () { return handleExit(0); }, key: removed[0].key, shown: removedShown[0] !== undefined, timeout: { enter: 0 }, animation: animation, animationProps: animationProps }, removed[0])) : (children.map(function (Child, i) { return (createElement(Fragment, { key: i },
i === 0 && removed[i] && (createElement(AnimatedListItem, { animation: animation, onExited: function () { return handleExit(i); }, key: removed[i].key, shown: removedShown[i] !== undefined, timeout: { enter: 0, exit: 200 } }, removed[i])),
createElement(AnimatedListItem, { animation: animation, animationProps: animationProps, shown: true, key: Child.key || i, onExited: function () { return handleExit(Child.key); }, timeout: {
enter: previousChildren.find(function (p) { return p.key === Child.key; })
? 0
: getEnterDelayTime(i),
} }, Child),
removed[i + 1] && (createElement(AnimatedListItem, { animation: animation, animationProps: animationProps, onExited: function () { return handleExit(i + 1); }, key: removed[i + 1].key, shown: removedShown[i + 1] !== undefined, timeout: { enter: 0, exit: 500 } }, removed[i + 1])))); }))));
};
export { AnimatedList };
//# sourceMappingURL=index.es.js.map