fix: transition animation (#2974)
switched to using headlessui transition instead of react-css-transition due to new version breaking the animationpull/2979/head
parent
baf1ea95a3
commit
98028bf2f4
@ -1,120 +0,0 @@
|
||||
import React, { useContext, useEffect, useRef } from 'react';
|
||||
import { CSSTransition as ReactCSSTransition } from 'react-transition-group';
|
||||
|
||||
interface CSSTransitionProps {
|
||||
show?: boolean;
|
||||
enter?: string;
|
||||
enterFrom?: string;
|
||||
enterTo?: string;
|
||||
leave?: string;
|
||||
leaveFrom?: string;
|
||||
leaveTo?: string;
|
||||
appear?: boolean;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const TransitionContext = React.createContext<{
|
||||
parent: { show?: boolean; isInitialRender?: boolean; appear?: boolean };
|
||||
}>({
|
||||
parent: {},
|
||||
});
|
||||
|
||||
function useIsInitialRender() {
|
||||
const isInitialRender = useRef(true);
|
||||
useEffect(() => {
|
||||
isInitialRender.current = false;
|
||||
}, []);
|
||||
return isInitialRender.current;
|
||||
}
|
||||
|
||||
const CSSTransition = ({
|
||||
show,
|
||||
enter = '',
|
||||
enterFrom = '',
|
||||
enterTo = '',
|
||||
leave = '',
|
||||
leaveFrom = '',
|
||||
leaveTo = '',
|
||||
appear,
|
||||
children,
|
||||
}: CSSTransitionProps) => {
|
||||
const enterClasses = enter.split(' ').filter((s) => s.length);
|
||||
const enterFromClasses = enterFrom.split(' ').filter((s) => s.length);
|
||||
const enterToClasses = enterTo.split(' ').filter((s) => s.length);
|
||||
const leaveClasses = leave.split(' ').filter((s) => s.length);
|
||||
const leaveFromClasses = leaveFrom.split(' ').filter((s) => s.length);
|
||||
const leaveToClasses = leaveTo.split(' ').filter((s) => s.length);
|
||||
|
||||
const addClasses = (node: HTMLElement, classes: string[]) => {
|
||||
classes.length && node.classList.add(...classes);
|
||||
};
|
||||
|
||||
const removeClasses = (node: HTMLElement, classes: string[]) => {
|
||||
classes.length && node.classList.remove(...classes);
|
||||
};
|
||||
|
||||
return (
|
||||
<ReactCSSTransition
|
||||
appear={appear}
|
||||
unmountOnExit
|
||||
in={show}
|
||||
addEndListener={(node, done) => {
|
||||
node.addEventListener('transitionend', done, false);
|
||||
}}
|
||||
onEnter={(node: HTMLElement) => {
|
||||
addClasses(node, [...enterClasses, ...enterFromClasses]);
|
||||
}}
|
||||
onEntering={(node: HTMLElement) => {
|
||||
removeClasses(node, enterFromClasses);
|
||||
addClasses(node, enterToClasses);
|
||||
}}
|
||||
onEntered={(node: HTMLElement) => {
|
||||
removeClasses(node, [...enterToClasses, ...enterClasses]);
|
||||
}}
|
||||
onExit={(node) => {
|
||||
addClasses(node, [...leaveClasses, ...leaveFromClasses]);
|
||||
}}
|
||||
onExiting={(node) => {
|
||||
removeClasses(node, leaveFromClasses);
|
||||
addClasses(node, leaveToClasses);
|
||||
}}
|
||||
onExited={(node) => {
|
||||
removeClasses(node, [...leaveToClasses, ...leaveClasses]);
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</ReactCSSTransition>
|
||||
);
|
||||
};
|
||||
|
||||
const Transition = ({ show, appear, ...rest }: CSSTransitionProps) => {
|
||||
const { parent } = useContext(TransitionContext);
|
||||
const isInitialRender = useIsInitialRender();
|
||||
const isChild = show === undefined;
|
||||
|
||||
if (isChild) {
|
||||
return (
|
||||
<CSSTransition
|
||||
appear={parent.appear || !parent.isInitialRender}
|
||||
show={parent.show}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TransitionContext.Provider
|
||||
value={{
|
||||
parent: {
|
||||
show,
|
||||
isInitialRender,
|
||||
appear,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CSSTransition appear={appear} show={show} {...rest} />
|
||||
</TransitionContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default Transition;
|
Loading…
Reference in new issue