import React, { useContext, useMemo } from 'react'; import { List, Avatar, Skeleton, ConfigProvider } from 'antd'; import type { ProCardProps } from '@ant-design/pro-card'; import type { GetComponentProps } from './index'; import ProCard from '@ant-design/pro-card'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; import type { ListGridType } from 'antd/lib/list'; import type { ExpandableConfig } from 'antd/lib/table/interface'; import { RightOutlined } from '@ant-design/icons'; import classNames from 'classnames'; export type RenderExpandIconProps = { prefixCls: string; expanded: boolean; expandIcon: | React.ReactNode | ((props: { onExpand: (expanded: boolean) => void; expanded: boolean; record: RecordType; }) => React.ReactNode); onExpand: (expanded: boolean) => void; record: RecordType; }; export function renderExpandIcon({ prefixCls, expandIcon = , onExpand, expanded, record, }: RenderExpandIconProps) { let icon = expandIcon; const expandClassName = `${prefixCls}-row-expand-icon`; const onClick: React.MouseEventHandler = (event) => { onExpand(!expanded); event.stopPropagation(); }; if (typeof expandIcon === 'function') { icon = expandIcon({ expanded, onExpand, record }); } return ( {icon} ); } export type ItemProps = { title?: React.ReactNode; subTitle?: React.ReactNode; checkbox?: React.ReactNode; className?: string; prefixCls?: string; item?: any; subheader?: { title: React.ReactNode; actions: React.ReactNode[]; }; index?: number; selected?: boolean; avatar?: React.ReactNode; extra?: React.ReactNode; content?: React.ReactNode; actions?: React.ReactNode[]; description?: React.ReactNode; loading?: boolean; style?: React.CSSProperties; grid?: ListGridType; expand?: boolean; rowSupportExpand?: boolean; onExpand?: (expand: boolean) => void; expandable?: ExpandableConfig; showActions?: 'hover' | 'always'; showExtra?: 'hover' | 'always'; type?: 'new' | 'top' | 'inline' | 'subheader'; isEditable: boolean; recordKey: string | number | undefined; cardProps?: ProCardProps; record: RecordType; onRow?: GetComponentProps; itemHeaderRender?: | ((item: RecordType, index: number, defaultDom: JSX.Element | null) => React.ReactNode) | false; itemTitleRender?: | ((item: RecordType, index: number, defaultDom: JSX.Element | null) => React.ReactNode) | false; }; function ProListItem(props: ItemProps) { const { prefixCls: customizePrefixCls } = props; const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); const prefixCls = getPrefixCls('pro-list', customizePrefixCls); const defaultClassName = `${prefixCls}-row`; const { title, subTitle, content, itemTitleRender, prefixCls: restPrefixCls, actions, item, recordKey, avatar, cardProps, description, isEditable, checkbox, index = 0, selected, loading, expand: propsExpand, onExpand: propsOnExpand, expandable: expandableConfig, rowSupportExpand, showActions, showExtra, type, style, className: propsClassName = defaultClassName, record, extra, onRow, itemHeaderRender, ...rest } = props; const { expandedRowRender, expandIcon, expandRowByClick, indentSize = 8, expandedRowClassName, } = expandableConfig || {}; const [expanded, onExpand] = useMergedState(!!propsExpand, { value: propsExpand, onChange: propsOnExpand, }); const className = classNames( { [`${propsClassName}-selected`]: selected, [`${propsClassName}-show-action-hover`]: showActions === 'hover', [`${propsClassName}-type-${type}`]: !!type, [`${propsClassName}-editable`]: isEditable, [`${propsClassName}-show-extra-hover`]: showExtra === 'hover', }, propsClassName, ); const extraClassName = classNames({ [`${propsClassName}-extra`]: showExtra === 'hover', }); const needExpanded = expanded || Object.values(expandableConfig || {}).length === 0; const expandedRowDom = expandedRowRender && expandedRowRender(record, index, indentSize, expanded); const actionsDom = useMemo(() => { if (actions) { return [
e.stopPropagation()}> {actions}
, ]; } return []; }, [actions]); const titleDom = title || subTitle ? (
{title &&
{title}
} {subTitle &&
{subTitle}
}
) : null; const metaDom = title || avatar || subTitle || description ? ( {description} } /> ) : null; const defaultDom = !cardProps ? ( {extra}} {...rest} {...onRow?.(record, index)} onClick={(e) => { onRow?.(record, index)?.onClick?.(e); if (expandRowByClick) { onExpand(!expanded); } }} >
{checkbox &&
{checkbox}
} {Object.values(expandableConfig || {}).length > 0 && rowSupportExpand && renderExpandIcon({ prefixCls, expandIcon, onExpand, expanded, record, })}
{(itemHeaderRender && itemHeaderRender?.(record, index, metaDom)) ?? metaDom}
{needExpanded && (content || expandedRowDom) && (
{content} {expandedRowRender && rowSupportExpand && (
{expandedRowDom}
)}
)}
) : ( {title} } subTitle={subTitle} extra={actionsDom} > {content} ); return (
{defaultDom}
); } export default ProListItem;