import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react'; import type { AccordionHeaderProps } from '@redocly/theme/components/Accordion/AccordionHeader'; import { AccordionBody } from '@redocly/theme/components/Accordion/AccordionBody'; import { AccordionHeader } from '@redocly/theme/components/Accordion/AccordionHeader'; import { AccordionTitle } from '@redocly/theme/components/Accordion/AccordionTitle'; import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon'; import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon'; export type AccordionProps = { expanded?: boolean; isExpandable?: boolean; className?: string; renderChildrenHidden?: boolean; header?: ReactNode | ((props: AccordionHeaderProps) => ReactNode); onToggle?: (expanded: boolean) => void; dataTestId?: string; }; export function Accordion({ expanded = true, isExpandable = true, renderChildrenHidden = false, header, className, children, onToggle, dataTestId, }: PropsWithChildren): JSX.Element { const [isExpanded, setExpanded] = useState(expanded); const [animate, setAnimate] = useState(false); const toggle = ({ target }: BaseSyntheticEvent): void => { if (target instanceof HTMLAnchorElement || !isExpandable) return; setAnimate(true); setExpanded(!isExpanded); onToggle?.(!isExpanded); }; useEffect(() => setExpanded(expanded), [expanded]); return ( {header && (typeof header === 'function' ? ( header({ expanded: isExpanded }) ) : ( {header} {isExpandable && (isExpanded ? ( ) : ( ))} ))} {(isExpanded || renderChildrenHidden) && ( )} ); } const AccordionWrapper = styled.div` background-color: transparent; font-family: var(--accordion-font-family); font-size: var(--accordion-font-size); font-weight: var(--accordion-font-weight); border-radius: var(--accordion-border-radius); border: var(--accordion-border); &:not(:last-child) { margin-bottom: var(--accordion-gap); } `; const HeaderContent = styled.div` display: flex; align-items: center; width: 100%; gap: var(--spacing-xs); `;