wix-style-react
Version:
wix-style-react
87 lines • 4.22 kB
JavaScript
import React, { Children, useEffect, useMemo, useState, } from 'react';
import PropTypes from 'prop-types';
import { TransitionGroup, Transition as ReactTransition, } from 'react-transition-group';
import { dataHooks } from './constants';
import { getTimeout, getTransitionStyles } from './utils/utils';
/** Transition is a wrapper that allows animations of other components. */
const Transition = ({ animateOnLoad = false, dataHook, children, enterAnimation, exitAnimation, mountOnEnter, unmountOnExit, onEnd, onStart, show, className, }) => {
const [dimensions, setDimensions] = useState({});
const [ref, setRef] = useState(null);
useEffect(() => {
if (ref) {
setDimensions({
height: ref.scrollHeight,
width: ref.scrollWidth,
});
}
}, [ref]);
const { fade, move, scale, toggle } = useMemo(() => {
if (dimensions) {
return getTransitionStyles(dimensions, enterAnimation, exitAnimation);
}
return {
fade: {},
move: {},
scale: {},
toggle: {},
};
}, [enterAnimation, exitAnimation, dimensions]);
const timeout = useMemo(() => {
return getTimeout(enterAnimation, exitAnimation);
}, [enterAnimation, exitAnimation]);
const childrenClone = Children.map(children, child => {
if (React.isValidElement(child) && (show === undefined || !!show)) {
return React.cloneElement(child);
}
return;
});
const handleStart = () => {
onStart?.();
};
const handleEnd = () => {
onEnd?.();
};
return (React.createElement("div", { "data-hook": dataHook, className: className },
React.createElement(TransitionGroup, { appear: animateOnLoad }, childrenClone &&
childrenClone.map(child => {
return (React.createElement(ReactTransition
// Transition component needs React key property to find correct child in the list
, {
// Transition component needs React key property to find correct child in the list
key: child.key, "data-hook": dataHooks.transition, mountOnEnter: mountOnEnter, unmountOnExit: unmountOnExit, in: show, timeout: {
// Transition component won't show enter animation when enter timeout is set
enter: 0,
exit: timeout.exit,
}, onEntering: handleStart, onExiting: handleStart, onEntered: handleEnd, onExited: handleEnd }, (state) => {
return (React.createElement("div", { "data-hook": dataHooks.fadeStyles, style: fade[state] },
React.createElement("div", { "data-hook": dataHooks.moveStyles, style: move[state] },
React.createElement("div", { "data-hook": dataHooks.scaleStyles, style: scale[state] },
React.createElement("div", { "data-hook": dataHooks.toggleStyles, style: toggle[state], ref: callback => setRef(callback) }, child)))));
}));
}))));
};
Transition.displayName = 'Transition';
Transition.propTypes = {
animateOnLoad: PropTypes.bool,
children: PropTypes.node,
dataHook: PropTypes.string,
enterAnimation: PropTypes.shape({
fadeIn: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
moveIn: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
expand: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
scaleUp: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
}),
exitAnimation: PropTypes.shape({
fadeOut: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
moveOut: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
collapse: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
scaleDown: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
}),
mountOnEnter: PropTypes.bool,
onStart: PropTypes.func,
onEnd: PropTypes.func,
show: PropTypes.bool,
unmountOnExit: PropTypes.bool,
};
export default Transition;
//# sourceMappingURL=Transition.js.map