269 lines
7.6 KiB
JavaScript
269 lines
7.6 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
exports.__esModule = true;
|
||
|
exports.default = exports.modes = void 0;
|
||
|
|
||
|
var _react = _interopRequireDefault(require("react"));
|
||
|
|
||
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
||
|
|
||
|
var _Transition = require("./Transition");
|
||
|
|
||
|
var _TransitionGroupContext = _interopRequireDefault(require("./TransitionGroupContext"));
|
||
|
|
||
|
var _leaveRenders, _enterRenders;
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
|
||
|
|
||
|
function areChildrenDifferent(oldChildren, newChildren) {
|
||
|
if (oldChildren === newChildren) return false;
|
||
|
|
||
|
if (_react.default.isValidElement(oldChildren) && _react.default.isValidElement(newChildren) && oldChildren.key != null && oldChildren.key === newChildren.key) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
/**
|
||
|
* Enum of modes for SwitchTransition component
|
||
|
* @enum { string }
|
||
|
*/
|
||
|
|
||
|
|
||
|
var modes = {
|
||
|
out: 'out-in',
|
||
|
in: 'in-out'
|
||
|
};
|
||
|
exports.modes = modes;
|
||
|
|
||
|
var callHook = function callHook(element, name, cb) {
|
||
|
return function () {
|
||
|
var _element$props;
|
||
|
|
||
|
element.props[name] && (_element$props = element.props)[name].apply(_element$props, arguments);
|
||
|
cb();
|
||
|
};
|
||
|
};
|
||
|
|
||
|
var leaveRenders = (_leaveRenders = {}, _leaveRenders[modes.out] = function (_ref) {
|
||
|
var current = _ref.current,
|
||
|
changeState = _ref.changeState;
|
||
|
return _react.default.cloneElement(current, {
|
||
|
in: false,
|
||
|
onExited: callHook(current, 'onExited', function () {
|
||
|
changeState(_Transition.ENTERING, null);
|
||
|
})
|
||
|
});
|
||
|
}, _leaveRenders[modes.in] = function (_ref2) {
|
||
|
var current = _ref2.current,
|
||
|
changeState = _ref2.changeState,
|
||
|
children = _ref2.children;
|
||
|
return [current, _react.default.cloneElement(children, {
|
||
|
in: true,
|
||
|
onEntered: callHook(children, 'onEntered', function () {
|
||
|
changeState(_Transition.ENTERING);
|
||
|
})
|
||
|
})];
|
||
|
}, _leaveRenders);
|
||
|
var enterRenders = (_enterRenders = {}, _enterRenders[modes.out] = function (_ref3) {
|
||
|
var children = _ref3.children,
|
||
|
changeState = _ref3.changeState;
|
||
|
return _react.default.cloneElement(children, {
|
||
|
in: true,
|
||
|
onEntered: callHook(children, 'onEntered', function () {
|
||
|
changeState(_Transition.ENTERED, _react.default.cloneElement(children, {
|
||
|
in: true
|
||
|
}));
|
||
|
})
|
||
|
});
|
||
|
}, _enterRenders[modes.in] = function (_ref4) {
|
||
|
var current = _ref4.current,
|
||
|
children = _ref4.children,
|
||
|
changeState = _ref4.changeState;
|
||
|
return [_react.default.cloneElement(current, {
|
||
|
in: false,
|
||
|
onExited: callHook(current, 'onExited', function () {
|
||
|
changeState(_Transition.ENTERED, _react.default.cloneElement(children, {
|
||
|
in: true
|
||
|
}));
|
||
|
})
|
||
|
}), _react.default.cloneElement(children, {
|
||
|
in: true
|
||
|
})];
|
||
|
}, _enterRenders);
|
||
|
/**
|
||
|
* A transition component inspired by the [vue transition modes](https://vuejs.org/v2/guide/transitions.html#Transition-Modes).
|
||
|
* You can use it when you want to control the render between state transitions.
|
||
|
* Based on the selected mode and the child's key which is the `Transition` or `CSSTransition` component, the `SwitchTransition` makes a consistent transition between them.
|
||
|
*
|
||
|
* If the `out-in` mode is selected, the `SwitchTransition` waits until the old child leaves and then inserts a new child.
|
||
|
* If the `in-out` mode is selected, the `SwitchTransition` inserts a new child first, waits for the new child to enter and then removes the old child.
|
||
|
*
|
||
|
* **Note**: If you want the animation to happen simultaneously
|
||
|
* (that is, to have the old child removed and a new child inserted **at the same time**),
|
||
|
* you should use
|
||
|
* [`TransitionGroup`](https://reactcommunity.org/react-transition-group/transition-group)
|
||
|
* instead.
|
||
|
*
|
||
|
* ```jsx
|
||
|
* function App() {
|
||
|
* const [state, setState] = useState(false);
|
||
|
* return (
|
||
|
* <SwitchTransition>
|
||
|
* <CSSTransition
|
||
|
* key={state ? "Goodbye, world!" : "Hello, world!"}
|
||
|
* addEndListener={(node, done) => node.addEventListener("transitionend", done, false)}
|
||
|
* classNames='fade'
|
||
|
* >
|
||
|
* <button onClick={() => setState(state => !state)}>
|
||
|
* {state ? "Goodbye, world!" : "Hello, world!"}
|
||
|
* </button>
|
||
|
* </CSSTransition>
|
||
|
* </SwitchTransition>
|
||
|
* );
|
||
|
* }
|
||
|
* ```
|
||
|
*
|
||
|
* ```css
|
||
|
* .fade-enter{
|
||
|
* opacity: 0;
|
||
|
* }
|
||
|
* .fade-exit{
|
||
|
* opacity: 1;
|
||
|
* }
|
||
|
* .fade-enter-active{
|
||
|
* opacity: 1;
|
||
|
* }
|
||
|
* .fade-exit-active{
|
||
|
* opacity: 0;
|
||
|
* }
|
||
|
* .fade-enter-active,
|
||
|
* .fade-exit-active{
|
||
|
* transition: opacity 500ms;
|
||
|
* }
|
||
|
* ```
|
||
|
*/
|
||
|
|
||
|
var SwitchTransition = /*#__PURE__*/function (_React$Component) {
|
||
|
_inheritsLoose(SwitchTransition, _React$Component);
|
||
|
|
||
|
function SwitchTransition() {
|
||
|
var _this;
|
||
|
|
||
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||
|
args[_key] = arguments[_key];
|
||
|
}
|
||
|
|
||
|
_this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
|
||
|
_this.state = {
|
||
|
status: _Transition.ENTERED,
|
||
|
current: null
|
||
|
};
|
||
|
_this.appeared = false;
|
||
|
|
||
|
_this.changeState = function (status, current) {
|
||
|
if (current === void 0) {
|
||
|
current = _this.state.current;
|
||
|
}
|
||
|
|
||
|
_this.setState({
|
||
|
status: status,
|
||
|
current: current
|
||
|
});
|
||
|
};
|
||
|
|
||
|
return _this;
|
||
|
}
|
||
|
|
||
|
var _proto = SwitchTransition.prototype;
|
||
|
|
||
|
_proto.componentDidMount = function componentDidMount() {
|
||
|
this.appeared = true;
|
||
|
};
|
||
|
|
||
|
SwitchTransition.getDerivedStateFromProps = function getDerivedStateFromProps(props, state) {
|
||
|
if (props.children == null) {
|
||
|
return {
|
||
|
current: null
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (state.status === _Transition.ENTERING && props.mode === modes.in) {
|
||
|
return {
|
||
|
status: _Transition.ENTERING
|
||
|
};
|
||
|
}
|
||
|
|
||
|
if (state.current && areChildrenDifferent(state.current, props.children)) {
|
||
|
return {
|
||
|
status: _Transition.EXITING
|
||
|
};
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
current: _react.default.cloneElement(props.children, {
|
||
|
in: true
|
||
|
})
|
||
|
};
|
||
|
};
|
||
|
|
||
|
_proto.render = function render() {
|
||
|
var _this$props = this.props,
|
||
|
children = _this$props.children,
|
||
|
mode = _this$props.mode,
|
||
|
_this$state = this.state,
|
||
|
status = _this$state.status,
|
||
|
current = _this$state.current;
|
||
|
var data = {
|
||
|
children: children,
|
||
|
current: current,
|
||
|
changeState: this.changeState,
|
||
|
status: status
|
||
|
};
|
||
|
var component;
|
||
|
|
||
|
switch (status) {
|
||
|
case _Transition.ENTERING:
|
||
|
component = enterRenders[mode](data);
|
||
|
break;
|
||
|
|
||
|
case _Transition.EXITING:
|
||
|
component = leaveRenders[mode](data);
|
||
|
break;
|
||
|
|
||
|
case _Transition.ENTERED:
|
||
|
component = current;
|
||
|
}
|
||
|
|
||
|
return /*#__PURE__*/_react.default.createElement(_TransitionGroupContext.default.Provider, {
|
||
|
value: {
|
||
|
isMounting: !this.appeared
|
||
|
}
|
||
|
}, component);
|
||
|
};
|
||
|
|
||
|
return SwitchTransition;
|
||
|
}(_react.default.Component);
|
||
|
|
||
|
SwitchTransition.propTypes = process.env.NODE_ENV !== "production" ? {
|
||
|
/**
|
||
|
* Transition modes.
|
||
|
* `out-in`: Current element transitions out first, then when complete, the new element transitions in.
|
||
|
* `in-out`: New element transitions in first, then when complete, the current element transitions out.
|
||
|
*
|
||
|
* @type {'out-in'|'in-out'}
|
||
|
*/
|
||
|
mode: _propTypes.default.oneOf([modes.in, modes.out]),
|
||
|
|
||
|
/**
|
||
|
* Any `Transition` or `CSSTransition` component.
|
||
|
*/
|
||
|
children: _propTypes.default.oneOfType([_propTypes.default.element.isRequired])
|
||
|
} : {};
|
||
|
SwitchTransition.defaultProps = {
|
||
|
mode: modes.out
|
||
|
};
|
||
|
var _default = SwitchTransition;
|
||
|
exports.default = _default;
|