Created
September 9, 2023 03:11
-
-
Save jameskerr/bf93075667e6539ace88582c3b080d57 to your computer and use it in GitHub Desktop.
React Debut: A component for animating elements in an out as they mount and unmount.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {CSSTransition} from "react-transition-group" | |
import {forwardRef, useImperativeHandle, useRef, useState} from "react" | |
import {call} from "src/util/call" | |
export function useDebut(args: {enter?: () => any; exit: () => any}) { | |
const ref = useRef<any>() | |
const api = { | |
props: { | |
ref, | |
onExit: args.exit, | |
}, | |
enter() { | |
ref.current?.setExiting(false) | |
call(args.enter) | |
}, | |
exit() { | |
ref.current?.setExiting(true) | |
}, | |
toggle() { | |
if (!ref.current) { | |
// Not mounted, so enter | |
call(args.enter) | |
} else if (ref.current.exiting) { | |
// Is exiting, so cancel exit | |
ref.current.setExiting(false) | |
} else { | |
// Is entered, so exit | |
ref.current.setExiting(true) | |
} | |
}, | |
isExiting: ref.current?.exiting ?? false, | |
} | |
return api | |
} | |
export const Debut = forwardRef(function Debut(props: {onExit; children}, ref) { | |
const [exiting, setExiting] = useState(false) | |
useImperativeHandle(ref, () => ({exiting, setExiting}), [exiting, props]) | |
return ( | |
<CSSTransition | |
appear | |
in={!exiting} | |
// @ts-ignore | |
addEndListener={(node, done) => | |
node.addEventListener("transitionend", done, false) | |
} | |
onExited={() => { | |
call(props.onExit) | |
setExiting(false) | |
}} | |
> | |
{props.children} | |
</CSSTransition> | |
) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment