"use client"; import clsx from "clsx"; import { createContext, memo, useCallback, useContext, useMemo, useState, } from "react"; import { FocusRing, useId } from "react-aria"; import useMeasure from "react-use-measure"; import ChevronDown from "../../icons/chevron-down"; import { Text } from "../Text"; import styles from "./Collapse.module.css"; interface ICollapseContext { onChange?: (val: string | React.ReactNode) => void; selected?: string; } const CollapseContext = createContext(undefined); export const CollapseGroup = ({ children }) => { const [selected, setSelected] = useState(""); const onChange = useCallback((val) => { setSelected(val); }, []); return (
{children}
); }; interface Props { title?: string | React.ReactNode; subtitle?: string | React.ReactNode; defaultExpanded?: boolean; size?: "small"; card?: boolean; } const Collapse: React.ComponentType> = memo( ({ title, subtitle, defaultExpanded, size, card, children }) => { const isSmall = size === "small"; // gets ignored if context is present const [open, setOpen] = useState(); const context = useContext(CollapseContext); const [ref, bounds] = useMeasure(); const handleClick = useCallback( (title: string | React.ReactNode) => { if (context) { if (title === context.selected) { context.onChange(undefined); } else { context.onChange(title); } } else { setOpen((s) => !s); } }, [context], ); const isOpen = useMemo( () => title === context.selected || open, [context.selected, title, open], ); return (
{children}
); }, ); Collapse.displayName = "Collapse"; export default Collapse;