@vertisanpro/flowbite-react
Version:
Non-Official React components built for Flowbite and Tailwind CSS
31 lines (30 loc) • 1.58 kB
JavaScript
'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,
});