import React, { ReactNode, useCallback, useRef, useState } from "react"; import classNames from "classnames"; import { Transition } from "react-spring/renderprops"; import useComponentSize from "@rehooks/component-size"; import { useId } from "@reach/auto-id"; import { BoxProps, Box } from "../Box"; import { Flex } from "../Flex"; import { Heading } from "../Heading"; import { Icon, ICON_TYPE } from "../Icon"; import { bemHOF } from "../../utilities/bem"; import { useDisclosure } from "../../hooks"; const cn = bemHOF("Accordion"); export interface AccordionProps extends BoxProps { /** * The displayed text of the `Accordion` when closed */ title: string; /** * If true, this shows a green indicator next to the title */ isActive?: boolean; /** * CSS value to define a max height of the opened Accordion content. * If the children exceed the height of the container, it will scroll. */ maxHeight?: string; /** * Whether or not the accordion item is open / visible. */ defaultIsOpen?: boolean; /** * Add an icon or integration logo to the left of the header title */ iconSlot?: ReactNode; /** * Removes padding from the Accordion's content */ removePadding?: ReactNode; } export const AccordionGroup = ({ children, className, ...rest }: { children: ReactNode; className?: string; }) => ( {children} ); export const Accordion = ({ title, isActive, maxHeight, children, defaultIsOpen = false, iconSlot, className, removePadding, ...rest }: AccordionProps) => { const { isOpen, onToggle } = useDisclosure(defaultIsOpen); const buttonRef = useRef(null); const [childrenRef, setChildrenRef] = useState< React.MutableRefObject >({ current: null }); const onRefChange = useCallback((node) => { if (node !== null) { setChildrenRef({ current: node }); } }, []); const { height } = useComponentSize(childrenRef); const heightObj = { height }; const id = `accordion:${useId()}`; const buttonId = `${id}-button`; const contentId = `${id}-content`; const [enableTransition, setEnableTransition] = useState(!defaultIsOpen); const handleItemClick = () => { if (isOpen && buttonRef.current !== null) { buttonRef.current.blur(); } onToggle(); }; return ( { if (defaultIsOpen && isOpen) { setEnableTransition(true); } }} immediate={!enableTransition} > {(show) => { return ( show && ((props) => (
{children}
)) ); }}
); }; Accordion.Group = AccordionGroup;