'use client'; /* eslint-disable react/no-array-index-key */ import classNames from 'classnames'; import * as React from 'react'; import type { Breakpoint, ScreenMap } from '../_util/responsiveObserver'; import useResponsiveObserver, { responsiveArray } from '../_util/responsiveObserver'; import { ConfigContext } from '../config-provider'; import useSize from '../config-provider/hooks/useSize'; import DescriptionsContext from './DescriptionsContext'; import type { DescriptionsItemProps } from './Item'; import DescriptionsItem from './Item'; import Row from './Row'; import useRow from './hooks/useRow'; import useStyle from './style'; const DEFAULT_COLUMN_MAP: Record = { xxl: 3, xl: 3, lg: 3, md: 3, sm: 2, xs: 1, }; function getColumn(column: DescriptionsProps['column'], screens: ScreenMap): number { if (typeof column === 'number') { return column; } if (typeof column === 'object') { for (let i = 0; i < responsiveArray.length; i++) { const breakpoint: Breakpoint = responsiveArray[i]; if (screens[breakpoint] && column[breakpoint] !== undefined) { return column[breakpoint] || DEFAULT_COLUMN_MAP[breakpoint]; } } } return 3; } interface CompoundedComponent { Item: typeof DescriptionsItem; } export interface DescriptionsItemType extends DescriptionsItemProps { key?: React.Key; } export interface DescriptionsProps { prefixCls?: string; className?: string; rootClassName?: string; style?: React.CSSProperties; bordered?: boolean; size?: 'middle' | 'small' | 'default'; /** * @deprecated use `items` instead */ children?: React.ReactNode; title?: React.ReactNode; extra?: React.ReactNode; column?: number | Partial>; layout?: 'horizontal' | 'vertical'; colon?: boolean; labelStyle?: React.CSSProperties; contentStyle?: React.CSSProperties; items?: DescriptionsItemType[]; } const Descriptions: React.FC & CompoundedComponent = (props) => { const { prefixCls: customizePrefixCls, title, extra, column = DEFAULT_COLUMN_MAP, colon = true, bordered, layout, children, className, rootClassName, style, size: customizeSize, labelStyle, contentStyle, items, ...restProps } = props; const { getPrefixCls, direction, descriptions } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('descriptions', customizePrefixCls); const [screens, setScreens] = React.useState({}); const mergedColumn = getColumn(column, screens); const mergedSize = useSize(customizeSize); const rows = useRow(mergedColumn, items, children); const [wrapSSR, hashId] = useStyle(prefixCls); const responsiveObserver = useResponsiveObserver(); // Responsive React.useEffect(() => { const token = responsiveObserver.subscribe((newScreens) => { if (typeof column !== 'object') { return; } setScreens(newScreens); }); return () => { responsiveObserver.unsubscribe(token); }; }, []); // ======================== Render ======================== const contextValue = React.useMemo( () => ({ labelStyle, contentStyle }), [labelStyle, contentStyle], ); return wrapSSR(
{(title || extra) && (
{title &&
{title}
} {extra &&
{extra}
}
)}
{rows.map((row, index) => ( ))}
, ); }; if (process.env.NODE_ENV !== 'production') { Descriptions.displayName = 'Descriptions'; } export type { DescriptionsContextProps } from './DescriptionsContext'; export { DescriptionsContext }; Descriptions.Item = DescriptionsItem; export default Descriptions;