Skip to content

Instantly share code, notes, and snippets.

@FPDK
Last active October 16, 2021 09:18
Show Gist options
  • Save FPDK/30f7cb162ed334dce1ca94e19f931c99 to your computer and use it in GitHub Desktop.
Save FPDK/30f7cb162ed334dce1ca94e19f931c99 to your computer and use it in GitHub Desktop.
Reactstrap collapse using "React Transition Group" version 4
import React, {CSSProperties, HTMLAttributes, ReactNode, RefObject, useCallback, useRef, useState} from "react"
import {Transition, TransitionStatus} from "react-transition-group"
const transitionTimeouts = {
appear: 300,
enter: 300,
exit: 300,
}
const transitionClassNames: Record<TransitionStatus, string> = {
entering: "collapsing",
entered: "collapse show",
exiting: "collapsing",
exited: "collapse",
unmounted: "",
}
const defaultStyle: CSSProperties = {
//transition: `all ${transitionTimeouts.appear}ms ease-in-out`,
}
const Collapse4 = ({
isOpen,
tag,
className,
navbar,
children,
}: {
isOpen: boolean,
tag?: string,
className?: HTMLAttributes<HTMLDivElement>["className"],
navbar?: boolean,
children?: ReactNode,
}) => {
// State
const [height, setHeight] = useState<number | undefined>(undefined)
// Ref
const transitionNodeRef = useRef<HTMLDivElement>(null)
// Animation functions
const eventFunction = useCallback((
state: "onEntering" | "onEntered" | "onExit" | "onExiting" | "onExited",
ref: RefObject<HTMLDivElement>
) => () => {
if (state === "onEntering") {
setHeight(ref?.current?.scrollHeight ?? 0)
}
if (state === "onEntered") {
setHeight(undefined)
}
if (state === "onExit") {
setHeight(ref.current?.scrollHeight ?? 0)
}
if (state === "onExiting") {
setHeight(0)
}
if (state === "onExited") {
setHeight(0)
}
}, [])
// Render
return <Transition
in={isOpen}
timeout={transitionTimeouts}
nodeRef={transitionNodeRef}
onEntering={eventFunction("onEntering", transitionNodeRef)}
onEntered={eventFunction("onEntered", transitionNodeRef)}
onExit={eventFunction("onExit", transitionNodeRef)}
onExiting={eventFunction("onExiting", transitionNodeRef)}
onExited={eventFunction("onExited", transitionNodeRef)}
>
{state => {
return <div
ref={transitionNodeRef}
className={`${transitionClassNames[state]} ${className} ${navbar ? "navbar-collapse" : ""}`}
style={{
...defaultStyle,
...{
height: height,
}
}}
>
{children}
</div>
}}
</Transition>
}
export default Collapse4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment