@moxy/react-page-swapper
Version:
An orchestrator that eases out the implementation of page transitions
127 lines (98 loc) • 3.8 kB
JavaScript
;
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;