"...0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png" did not exist on "master"
Newer
Older
import React, { useEffect, useRef, useState } from "react";
import "./collapsible.css";
interface CollapsibleProps {
open?: boolean;
header: string | React.ReactNode;
children?: React.ReactNode | React.ReactNode[];
heightTransition?: boolean;
// Implementation details partially from https://medium.com/edonec/build-a-react-collapsible-component-from-scratch-using-react-hooks-typescript-73dfd02c9208
/**
* Collapisble section
* @param open Sets the default state of the collapsible section
* @param header Title text
* @param children React child elements
* @param color Optional bottom border color
* @param heightTransition Weather or not this section should render a smooth transition if the content height changes.
* @constructor
*/
function Collapsible({
open,
header,
children,
color = "gray",
const [isOpen, setIsOpen] = useState(open);
const [height, setHeight] = useState<number | undefined>(
open ? undefined : 0
);
const toggleOpen = () => {
setIsOpen((prev) => !prev);
};
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!height || !isOpen || !ref.current) return undefined;
const resizeObserver = new ResizeObserver((el) => {
setHeight(el[0].contentRect.height);
});
resizeObserver.observe(ref.current);
return () => {
resizeObserver.disconnect();
};
}, [height, isOpen]);
useEffect(() => {
if (isOpen) setHeight(ref.current?.getBoundingClientRect().height);
else setHeight(0);
}, [isOpen]);
const borderBottom = "1px solid " + color;
return (
<>
<div className={"collapsible-card"}>
<div>
<button
type="button"
className={`collapsible-button ${
isOpen ? "" : "collapsed"
}`}
onClick={toggleOpen}
<div
className={`collapsible-content ${
heightTransition ? "collapsible-transition-height" : ""
}`}
style={{ height }}
>