import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import type { BaseSyntheticEvent, PropsWithChildren, ReactNode, JSX } from 'react'; import type { PanelHeaderProps } from '@redocly/theme/components/Panel/PanelHeader'; import { PanelBody } from '@redocly/theme/components/Panel/PanelBody'; import { PanelHeader } from '@redocly/theme/components/Panel/PanelHeader'; import { PanelHeaderTitle } from '@redocly/theme/components/Panel/PanelHeaderTitle'; import { ChevronDownIcon } from '@redocly/theme/icons/ChevronDownIcon/ChevronDownIcon'; import { ChevronRightIcon } from '@redocly/theme/icons/ChevronRightIcon/ChevronRightIcon'; export type PanelProps = { expanded?: boolean; isExpandable?: boolean; className?: string; renderChildrenHidden?: boolean; header?: ReactNode | ((props: PanelHeaderProps) => ReactNode); footer?: ReactNode; onToggle?: (expanded: boolean) => void; description?: React.ReactNode; }; export function Panel({ expanded = true, isExpandable = true, renderChildrenHidden = false, header, footer, className = 'panel-default', children, onToggle, description, }: 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, toggle }) ) : ( {header} {isExpandable && (isExpanded ? ( ) : ( ))} {description} ))} {(isExpanded || renderChildrenHidden) && ( )} {footer} ); } const PanelWrapper = styled.div` background-color: var(--panel-bg-color); color: var(--panel-text-color); font-family: var(--panel-font-family-local); font-size: var(--panel-font-size-local); font-weight: var(--panel-font-weight-local); border-radius: var(--panel-border-radius-local); border: var(--panel-border-local); ${PanelHeader} + ${PanelBody} { border-top-left-radius: 0; border-top-right-radius: 0; } &:not(:last-child) { margin-bottom: var(--panel-gap-vertical); } `; const InlineBox = styled.div` display: inline-flex; align-items: center; `;