import { forwardRef, useRef, useState } from 'react'; import { Container, ContainerRef } from '@cleartrip/ct-design-container'; import useIsomorphicEffect from '@cleartrip/ct-design-use-isomorphic-effect'; import { useStyles, useWebMergeStyles } from '@cleartrip/ct-design-style-manager'; import type { IAccordionProps } from './type'; import staticStyles from './style'; import webStaticStyles from './webStyle'; const Accordion = forwardRef( ( { expanded = false, label, onClick, children, expandIcon, disabled = false, styleConfig, isWrappedInAccordionGroup = false, onAccordionGroupClick, }, forwardedRef, ) => { const { childrenContainer = [], icon = [], label: labelStyle = [], root = [] } = styleConfig || {}; const [isExpanded, setIsExpanded] = useState(expanded); const accordionContentRef = useRef(null); useIsomorphicEffect(() => { setIsExpanded(expanded); }, [expanded]); const onAccordionClick = () => { if (disabled) return; if (isWrappedInAccordionGroup) { onAccordionGroupClick?.(); } else { setIsExpanded((previouslyExpanded) => !previouslyExpanded); } onClick?.(); }; // Dynamic styles that depend on `isExpanded`/`disabled` and the measured // scroll height of the collapsible content. const dynamicStyles = useStyles(() => { const contentScrollHeight = accordionContentRef.current?.scrollHeight ?? 0; return { labelRow: { // cursor: disabled ? 'not-allowed' : 'pointer', }, iconTransform: { transform: isExpanded ? 'rotate(180deg)' : 'rotate(0deg)', }, contentMaxHeight: { maxHeight: isExpanded ? contentScrollHeight : 0, }, }; }, [isExpanded, disabled]); const mergedIconClassName = useWebMergeStyles( [staticStyles.iconContainer, webStaticStyles.iconTransition, dynamicStyles.iconTransform, ...icon], [staticStyles.iconContainer, dynamicStyles.iconTransform, icon], ); const mergedContentClassName = useWebMergeStyles( [ staticStyles.accordionContentRoot, webStaticStyles.contentTransition, dynamicStyles.contentMaxHeight, ...childrenContainer, ], [staticStyles.accordionContentRoot, dynamicStyles.contentMaxHeight, childrenContainer], ); return ( {label} {expandIcon &&
{expandIcon}
}
{children}
); }, ); Accordion.displayName = 'Accordion'; export default Accordion;