import * as React from 'react'; import RightOutlined from '@ant-design/icons/RightOutlined'; import type { CollapseProps as RcCollapseProps } from '@rc-component/collapse'; import RcCollapse from '@rc-component/collapse'; import type { CSSMotionProps } from '@rc-component/motion'; import toArray from '@rc-component/util/lib/Children/toArray'; import omit from '@rc-component/util/lib/omit'; import classNames from 'classnames'; import initCollapseMotion from '../_util/motion'; import { cloneElement } from '../_util/reactNode'; import { devUseWarning } from '../_util/warning'; import { useComponentConfig } from '../config-provider/context'; import useSize from '../config-provider/hooks/useSize'; import type { SizeType } from '../config-provider/SizeContext'; import type { CollapsibleType } from './CollapsePanel'; import CollapsePanel from './CollapsePanel'; import useStyle from './style'; export type ExpandIconPosition = 'start' | 'end' | undefined; export type SemanticName = 'root' | 'header' | 'title' | 'body' | 'icon'; export interface CollapseProps extends Pick { activeKey?: Array | string | number; defaultActiveKey?: Array | string | number; /** 手风琴效果 */ accordion?: boolean; /** @deprecated Please use `destroyOnHidden` instead */ destroyInactivePanel?: boolean; /** * @since 5.25.0 */ destroyOnHidden?: boolean; onChange?: (key: string[]) => void; style?: React.CSSProperties; className?: string; rootClassName?: string; bordered?: boolean; prefixCls?: string; expandIcon?: (panelProps: PanelProps) => React.ReactNode; expandIconPosition?: ExpandIconPosition; ghost?: boolean; size?: SizeType; collapsible?: CollapsibleType; /** * @deprecated use `items` instead */ children?: React.ReactNode; classNames?: Partial>; styles?: Partial>; } interface PanelProps { isActive?: boolean; header?: React.ReactNode; className?: string; style?: React.CSSProperties; showArrow?: boolean; forceRender?: boolean; extra?: React.ReactNode; collapsible?: CollapsibleType; classNames?: Partial>; styles?: Partial>; } const Collapse = React.forwardRef((props, ref) => { const { getPrefixCls, direction, expandIcon: contextExpandIcon, className: contextClassName, style: contextStyle, classNames: contextClassNames, styles: contextStyles, } = useComponentConfig('collapse'); const { prefixCls: customizePrefixCls, className, rootClassName, style, bordered = true, ghost, size: customizeSize, expandIconPosition = 'start', children, destroyInactivePanel, destroyOnHidden, expandIcon, classNames: collapseClassNames, styles, } = props; const mergedSize = useSize((ctx) => customizeSize ?? ctx ?? 'middle'); const prefixCls = getPrefixCls('collapse', customizePrefixCls); const rootPrefixCls = getPrefixCls(); const [hashId, cssVarCls] = useStyle(prefixCls); const mergedExpandIcon = expandIcon ?? contextExpandIcon; if (process.env.NODE_ENV !== 'production') { const warning = devUseWarning('Collapse'); warning.deprecated( !('destroyInactivePanel' in props), 'destroyInactivePanel', 'destroyOnHidden', ); } const renderExpandIcon = React.useCallback( (panelProps: PanelProps = {}) => { const icon = typeof mergedExpandIcon === 'function' ? ( mergedExpandIcon(panelProps) ) : ( ); return cloneElement(icon, () => ({ className: classNames( ( icon as React.ReactElement<{ className?: string; }> )?.props?.className, contextClassNames.icon, collapseClassNames?.icon, `${prefixCls}-arrow`, ), style: { ...contextStyles.icon, ...styles?.icon, }, })); }, [mergedExpandIcon, prefixCls], ); const collapseClassName = classNames( `${prefixCls}-icon-position-${expandIconPosition}`, { [`${prefixCls}-borderless`]: !bordered, [`${prefixCls}-rtl`]: direction === 'rtl', [`${prefixCls}-ghost`]: !!ghost, [`${prefixCls}-${mergedSize}`]: mergedSize !== 'middle', }, contextClassName, className, rootClassName, hashId, cssVarCls, contextClassNames.root, collapseClassNames?.root, ); const openMotion: CSSMotionProps = { ...initCollapseMotion(rootPrefixCls), motionAppear: false, leavedClassName: `${prefixCls}-panel-hidden`, }; const items = React.useMemo(() => { if (children) { return toArray(children).map((child) => child); } return null; }, [children]); return ( // @ts-ignore {items} ); }); if (process.env.NODE_ENV !== 'production') { Collapse.displayName = 'Collapse'; } export default Object.assign(Collapse, { Panel: CollapsePanel });