Skip to content

Instantly share code, notes, and snippets.

@stevecastaneda
Created June 10, 2020 02:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevecastaneda/899e83d47fa27397c447e2e6ae3d7771 to your computer and use it in GitHub Desktop.
Save stevecastaneda/899e83d47fa27397c447e2e6ae3d7771 to your computer and use it in GitHub Desktop.
A CSS Transition component to use as a child of TransitionGroup.
// http://reactcommunity.org/react-transition-group/transition
// http://reactcommunity.org/react-transition-group/transition-group
import React, { ReactNode } from "react";
import { Transition as ReactTransition } from "react-transition-group";
interface TransitionProps {
in?: boolean;
timeout: number | { appear?: number; enter?: number; exit?: number };
enter?: string;
enterFrom?: string;
enterTo?: string;
leave?: string;
leaveFrom?: string;
leaveTo?: string;
children: ReactNode;
}
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);
function splitClasses(string: string | undefined): string[] {
if (string) return string.split(" ").filter((s) => s.length);
return [];
}
function addClasses(classes: string[]) {
nodeRef.current?.classList.add(...classes);
}
function removeClasses(classes: string[]) {
nodeRef.current?.classList.remove(...classes);
}
return (
<ReactTransition
in={props.in}
nodeRef={nodeRef}
unmountOnExit
timeout={props.timeout}
onEnter={() => {
addClasses([...enterClasses, ...enterFromClasses]);
}}
onEntering={() => {
removeClasses(enterFromClasses);
addClasses(enterToClasses);
}}
onEntered={() => {
removeClasses([...enterToClasses, ...enterClasses]);
}}
onExit={() => {
addClasses([...leaveClasses, ...leaveFromClasses]);
}}
onExiting={() => {
removeClasses(leaveFromClasses);
addClasses(leaveToClasses);
}}
onExited={() => {
removeClasses([...leaveToClasses, ...leaveClasses]);
}}
>
<div ref={nodeRef}>{props.children}</div>
</ReactTransition>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment