UNPKG

react-animated-list

Version:

Simple way of animating when components are added or removed from an array

100 lines (93 loc) 5.35 kB
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