UNPKG

@moxy/react-page-swapper

Version:

An orchestrator that eases out the implementation of page transitions

109 lines (90 loc) 3.22 kB
import _omit from "lodash/omit"; function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import { Component } from 'react'; import PropTypes from 'prop-types'; import shallowequal from 'shallowequal'; import memoizeOne from 'memoize-one'; import once from 'once'; export default class SwapTransition extends Component { constructor(...args) { super(...args); _defineProperty(this, "state", { transitioning: false }); _defineProperty(this, "wrapOnEntered", memoizeOne(onEntered => once(async () => { const { in: inProp, transitioning } = this.state; if (!inProp || !transitioning) { return; } await Promise.resolve(); this.setState({ transitioning: false }, () => { onEntered === null || onEntered === void 0 ? void 0 : onEntered(); }); }))); _defineProperty(this, "wrapOnExited", memoizeOne(onExited => once(async () => { const { in: inProp, transitioning } = this.state; if (inProp || !transitioning) { return; } await Promise.resolve(); // `transitioning` is not changed to false as the view will be unmounted afterwards // This effectively avoids one useless re-render onExited === null || onExited === void 0 ? void 0 : onExited(); }))); } static getDerivedStateFromProps(props, state) { let transitioning; // Transitioning is set to true if the `in` prop changed // There's an exception which is when mounting, which we take into consideration the `hasPrevNode` prop if (props.in !== state.in) { transitioning = state.in == null ? !!props.prevNodeKey : true; } else { transitioning = state.transitioning; } return { // TransitionGroup adds the properties below, so we filter them out ..._omit(props, ['appear', 'enter', 'exit', 'onExited']), // TransitionGroup changes `onExited` in every render unnecessarily, // so we keep it constant to avoid re-renders onExited: state.onExited || props.onExited, transitioning }; } shouldComponentUpdate(prevProps, prevState) { // Only update when state changes, which was derived in `getDerivedStateFromProps` return !shallowequal(this.state, prevState); } render() { const { children, onEntered, onExited, ...rest } = this.state; return children({ ...rest, onEntered: this.wrapOnEntered(onEntered), onExited: this.wrapOnExited(onExited) }); } // eslint-disable-next-line react/sort-comp } _defineProperty(SwapTransition, "propTypes", { node: PropTypes.element.isRequired, nodeKey: PropTypes.string.isRequired, prevNodeKey: PropTypes.string, mode: PropTypes.oneOf(['simultaneous', 'out-in']).isRequired, animation: PropTypes.string, in: PropTypes.bool, style: PropTypes.object, onEntered: PropTypes.func, onExited: PropTypes.func, children: PropTypes.func.isRequired }); _defineProperty(SwapTransition, "defaultProps", { in: false, style: {} });