GoScrobble/web/node_modules/react-transition-group/esm/SwitchTransition.js

257 lines
6.9 KiB
JavaScript
Raw Normal View History

2022-04-25 02:47:15 +00:00
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
var _leaveRenders, _enterRenders;
import React from 'react';
import PropTypes from 'prop-types';
import { ENTERED, ENTERING, EXITING } from './Transition';
import TransitionGroupContext from './TransitionGroupContext';
function areChildrenDifferent(oldChildren, newChildren) {
if (oldChildren === newChildren) return false;
if (React.isValidElement(oldChildren) && React.isValidElement(newChildren) && oldChildren.key != null && oldChildren.key === newChildren.key) {
return false;
}
return true;
}
/**
* Enum of modes for SwitchTransition component
* @enum { string }
*/
export var modes = {
out: 'out-in',
in: 'in-out'
};
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.cloneElement(current, {
in: false,
onExited: callHook(current, 'onExited', function () {
changeState(ENTERING, null);
})
});
}, _leaveRenders[modes.in] = function (_ref2) {
var current = _ref2.current,
changeState = _ref2.changeState,
children = _ref2.children;
return [current, React.cloneElement(children, {
in: true,
onEntered: callHook(children, 'onEntered', function () {
changeState(ENTERING);
})
})];
}, _leaveRenders);
var enterRenders = (_enterRenders = {}, _enterRenders[modes.out] = function (_ref3) {
var children = _ref3.children,
changeState = _ref3.changeState;
return React.cloneElement(children, {
in: true,
onEntered: callHook(children, 'onEntered', function () {
changeState(ENTERED, React.cloneElement(children, {
in: true
}));
})
});
}, _enterRenders[modes.in] = function (_ref4) {
var current = _ref4.current,
children = _ref4.children,
changeState = _ref4.changeState;
return [React.cloneElement(current, {
in: false,
onExited: callHook(current, 'onExited', function () {
changeState(ENTERED, React.cloneElement(children, {
in: true
}));
})
}), React.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: 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 === ENTERING && props.mode === modes.in) {
return {
status: ENTERING
};
}
if (state.current && areChildrenDifferent(state.current, props.children)) {
return {
status: EXITING
};
}
return {
current: React.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 ENTERING:
component = enterRenders[mode](data);
break;
case EXITING:
component = leaveRenders[mode](data);
break;
case ENTERED:
component = current;
}
return /*#__PURE__*/React.createElement(TransitionGroupContext.Provider, {
value: {
isMounting: !this.appeared
}
}, component);
};
return SwitchTransition;
}(React.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.oneOf([modes.in, modes.out]),
/**
* Any `Transition` or `CSSTransition` component.
*/
children: PropTypes.oneOfType([PropTypes.element.isRequired])
} : {};
SwitchTransition.defaultProps = {
mode: modes.out
};
export default SwitchTransition;