UNPKG

@vertisanpro/flowbite-react

Version:

Non-Official React components built for Flowbite and Tailwind CSS

31 lines (30 loc) 1.58 kB
'use client'; import { HiChevronDown } from '@vertisanpro/react-icons/hi'; import { twMerge } from '@vertisanpro/tailwind-merge'; import React, { Children, cloneElement, useMemo, useState } from 'react'; import { mergeDeep } from '../../helpers/merge-deep'; import { getTheme } from '../../theme-store'; import { AccordionContent } from './AccordionContent'; import { AccordionPanel } from './AccordionPanel'; import { AccordionTitle } from './AccordionTitle'; const AccordionComponent = ({ alwaysOpen = false, arrowIcon = HiChevronDown, children, flush = false, collapseAll = false, className, theme: customTheme = {}, ...props }) => { const [isOpen, setOpen] = useState(collapseAll ? -1 : 0); const panels = useMemo(() => Children.map(children, (child, i) => cloneElement(child, { alwaysOpen, arrowIcon, flush, isOpen: isOpen === i, setOpen: () => setOpen(isOpen === i ? -1 : i), })), [alwaysOpen, arrowIcon, children, flush, isOpen]); const theme = mergeDeep(getTheme().accordion.root, customTheme); return (React.createElement("div", { className: twMerge(theme.base, theme.flush[flush ? 'on' : 'off'], className), "data-testid": "flowbite-accordion", ...props }, panels)); }; AccordionComponent.displayName = 'Accordion'; AccordionPanel.displayName = 'Accordion.Panel'; AccordionTitle.displayName = 'Accordion.Title'; AccordionContent.displayName = 'Accordion.Content'; export const Accordion = Object.assign(AccordionComponent, { Panel: AccordionPanel, Title: AccordionTitle, Content: AccordionContent, });