Skip to content

Instantly share code, notes, and snippets.

@stevecastaneda
Last active May 10, 2024 19:02
Show Gist options
  • Save stevecastaneda/61c05f3ccc5c532f26cc40593bbeeb01 to your computer and use it in GitHub Desktop.
Save stevecastaneda/61c05f3ccc5c532f26cc40593bbeeb01 to your computer and use it in GitHub Desktop.
CSSTransition component (Typescript). This one allows you use TransitionGroup with Tailwind, animating in a list of items.
import React, { ReactNode } from "react";
import { CSSTransition as ReactTransition } from "react-transition-group";
interface TransitionProps {
in?: boolean;
timeout: number;
enter?: string;
enterFrom?: string;
enterTo?: string;
leave?: string;
leaveFrom?: string;
leaveTo?: string;
children: ReactNode;
}
function addClasses(classes: string[], ref: React.RefObject<HTMLDivElement>) {
ref.current?.classList.add(...classes);
}
function removeClasses(classes: string[], ref: React.RefObject<HTMLDivElement>) {
ref.current?.classList.remove(...classes);
}
export function CSSTransition(props: TransitionProps) {
const { enter, enterFrom, enterTo, leave, leaveFrom, leaveTo } = props;
const nodeRef = React.useRef<HTMLDivElement>(null);
const enterClasses = splitClasses(enter);
const enterFromClasses = splitClasses(enterFrom);
const enterToClasses = splitClasses(enterTo);
const leaveClasses = splitClasses(leave);
const leaveFromClasses = splitClasses(leaveFrom);
const leaveToClasses = splitClasses(leaveTo);
return (
<ReactTransition
in={props.in}
nodeRef={nodeRef}
timeout={props.timeout}
unmountOnExit
onEnter={() => {
addClasses([...enterClasses, ...enterFromClasses], nodeRef);
}}
onEntering={() => {
removeClasses(enterFromClasses, nodeRef);
addClasses(enterToClasses, nodeRef);
}}
onEntered={() => {
removeClasses([...enterToClasses, ...enterClasses], nodeRef);
}}
onExit={() => {
addClasses([...leaveClasses, ...leaveFromClasses], nodeRef);
}}
onExiting={() => {
removeClasses(leaveFromClasses, nodeRef);
addClasses(leaveToClasses, nodeRef);
}}
onExited={() => {
removeClasses([...leaveToClasses, ...leaveClasses], nodeRef);
}}
>
<div ref={nodeRef}>{props.children}</div>
</ReactTransition>
);
}
function splitClasses(string: string = ""): string[] {
return string.split(" ").filter((s) => s.length);
}
@jonathanlal
Copy link

good stuff thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment