UNPKG

@moxy/react-page-swapper

Version:

An orchestrator that eases out the implementation of page transitions

127 lines (98 loc) 3.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _omit2 = _interopRequireDefault(require("lodash/omit")); var _react = require("react"); var _propTypes = _interopRequireDefault(require("prop-types")); var _shallowequal = _interopRequireDefault(require("shallowequal")); var _memoizeOne = _interopRequireDefault(require("memoize-one")); var _once = _interopRequireDefault(require("once")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } class SwapTransition extends _react.Component { constructor(...args) { super(...args); _defineProperty(this, "state", { transitioning: false }); _defineProperty(this, "wrapOnEntered", (0, _memoizeOne.default)(onEntered => (0, _once.default)(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", (0, _memoizeOne.default)(onExited => (0, _once.default)(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 ...(0, _omit2.default)(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 !(0, _shallowequal.default)(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 } exports.default = SwapTransition; _defineProperty(SwapTransition, "propTypes", { node: _propTypes.default.element.isRequired, nodeKey: _propTypes.default.string.isRequired, prevNodeKey: _propTypes.default.string, mode: _propTypes.default.oneOf(['simultaneous', 'out-in']).isRequired, animation: _propTypes.default.string, in: _propTypes.default.bool, style: _propTypes.default.object, onEntered: _propTypes.default.func, onExited: _propTypes.default.func, children: _propTypes.default.func.isRequired }); _defineProperty(SwapTransition, "defaultProps", { in: false, style: {} }); module.exports = exports.default;