mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-09 02:49:18 +08:00
100 lines
2.6 KiB
TypeScript
100 lines
2.6 KiB
TypeScript
import * as React from 'react';
|
|
import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
|
|
import { toArray } from '@rc-component/util';
|
|
import { clsx } from 'clsx';
|
|
|
|
import { genCssVar } from '../theme/util/genStyleUtils';
|
|
import type { TimelineItemType, TimelineMode, TimelineProps } from './Timeline';
|
|
|
|
const useItems = (
|
|
rootPrefixCls: string,
|
|
prefixCls: string,
|
|
mode: TimelineMode,
|
|
items?: TimelineItemType[],
|
|
children?: React.ReactNode,
|
|
pending?: TimelineProps['pending'],
|
|
pendingDot?: TimelineProps['pendingDot'],
|
|
) => {
|
|
const itemCls = `${prefixCls}-item`;
|
|
|
|
const [varName] = genCssVar(rootPrefixCls, 'cmp-steps');
|
|
|
|
// Merge items and children
|
|
const parseItems = React.useMemo<TimelineItemType[]>(() => {
|
|
return Array.isArray(items)
|
|
? items
|
|
: toArray(children).map((ele: React.ReactElement<any>) => ({ ...ele.props }));
|
|
}, [items, children]);
|
|
|
|
// convert legacy type
|
|
return React.useMemo(() => {
|
|
const mergedItems = parseItems.map<TimelineItemType>((item, index) => {
|
|
const {
|
|
label,
|
|
children,
|
|
title,
|
|
content,
|
|
color,
|
|
className,
|
|
style,
|
|
icon,
|
|
dot,
|
|
placement,
|
|
position,
|
|
loading,
|
|
...restProps
|
|
} = item;
|
|
|
|
let mergedStyle = style;
|
|
let mergedClassName = className;
|
|
|
|
if (color) {
|
|
if (['blue', 'red', 'green', 'gray'].includes(color)) {
|
|
mergedClassName = clsx(className, `${itemCls}-color-${color}`);
|
|
} else {
|
|
mergedStyle = {
|
|
[varName('item-icon-dot-color')]: color,
|
|
...style,
|
|
};
|
|
}
|
|
}
|
|
|
|
// Placement
|
|
const mergedPlacement =
|
|
placement ??
|
|
position ??
|
|
(mode === 'alternate' ? (index % 2 === 0 ? 'start' : 'end') : mode);
|
|
|
|
mergedClassName = clsx(mergedClassName, `${itemCls}-placement-${mergedPlacement}`);
|
|
|
|
// Icon
|
|
let mergedIcon = icon ?? dot;
|
|
if (!mergedIcon && loading) {
|
|
mergedIcon = <LoadingOutlined />;
|
|
}
|
|
|
|
return {
|
|
...restProps,
|
|
title: title ?? label,
|
|
content: content ?? children,
|
|
style: mergedStyle,
|
|
className: mergedClassName,
|
|
icon: mergedIcon,
|
|
status: loading ? 'process' : 'finish',
|
|
};
|
|
});
|
|
|
|
if (pending) {
|
|
mergedItems.push({
|
|
icon: pendingDot ?? <LoadingOutlined />,
|
|
content: pending,
|
|
status: 'process',
|
|
} as TimelineItemType);
|
|
}
|
|
|
|
return mergedItems;
|
|
}, [parseItems, pending, mode, itemCls, varName, pendingDot]);
|
|
};
|
|
|
|
export default useItems;
|