import { ButtonHTMLAttributes, DetailedHTMLProps, Dispatch, HTMLAttributes, SetStateAction, createContext, useContext, useId, useState, } from 'react' interface IAccordion { id: string open: boolean toggle: Dispatch> } const AccordionContext = createContext({ id: '', open: false, toggle: () => {}, }) interface AccordionProps extends Omit< DetailedHTMLProps, HTMLElement>, 'children' > { defaultOpen?: boolean children: React.ReactNode | ((props: { open: boolean }) => React.ReactNode) } export const Accordion = ({ children, defaultOpen = false, ...rest }: AccordionProps) => { const [open, toggle] = useState(defaultOpen) const id = useId() return (
{typeof children === 'function' ? children({ open }) : children}
) } interface HeaderProps extends DetailedHTMLProps< ButtonHTMLAttributes, HTMLButtonElement > {} const Header = ({ children, className, ...rest }: HeaderProps) => { const { id, open, toggle } = useContext(AccordionContext) return (

) } interface BodyProps extends DetailedHTMLProps, HTMLDivElement> {} const Body = ({ children, className, ...rest }: BodyProps) => { const { id, open } = useContext(AccordionContext) return (
{children}
) } Accordion.Header = Header Accordion.Body = Body /** * Usage * Header Body ---------------------------- {({ open }) => ( <> Header Body )} */