黑雨
2 years ago
committed by
GitHub
15 changed files with 447 additions and 196 deletions
@ -0,0 +1,92 @@ |
|||
import classNames from 'classnames'; |
|||
import * as React from 'react'; |
|||
import LoadingOutlined from '@ant-design/icons/LoadingOutlined'; |
|||
import TimelineItem from './TimelineItem'; |
|||
import type { TimelineProps } from './Timeline'; |
|||
import type { TimelineItemProps } from './TimelineItem'; |
|||
|
|||
const TimelineItemList: React.FC<TimelineProps & { hashId: string; direction?: string }> = ({ |
|||
prefixCls, |
|||
className, |
|||
pending = false, |
|||
children, |
|||
items, |
|||
rootClassName, |
|||
reverse = false, |
|||
direction, |
|||
hashId, |
|||
pendingDot, |
|||
mode = '' as TimelineProps['mode'], |
|||
...restProps |
|||
}) => { |
|||
const getPositionCls = (position: string, idx: number) => { |
|||
if (mode === 'alternate') { |
|||
if (position === 'right') return `${prefixCls}-item-right`; |
|||
if (position === 'left') return `${prefixCls}-item-left`; |
|||
return idx % 2 === 0 ? `${prefixCls}-item-left` : `${prefixCls}-item-right`; |
|||
} |
|||
if (mode === 'left') return `${prefixCls}-item-left`; |
|||
if (mode === 'right') return `${prefixCls}-item-right`; |
|||
if (position === 'right') return `${prefixCls}-item-right`; |
|||
return ''; |
|||
}; |
|||
const mergedItems = [...(items || [])]; |
|||
const pendingNode = typeof pending === 'boolean' ? null : pending; |
|||
|
|||
if (pending) { |
|||
mergedItems.push({ |
|||
pending: !!pending, |
|||
dot: pendingDot || <LoadingOutlined />, |
|||
children: pendingNode, |
|||
}); |
|||
} |
|||
|
|||
if (reverse) { |
|||
mergedItems.reverse(); |
|||
} |
|||
const itemsCount = mergedItems.length; |
|||
const lastCls = `${prefixCls}-item-last`; |
|||
|
|||
const itemsList = mergedItems |
|||
.filter((item: TimelineItemProps) => !!item) |
|||
.map((item: TimelineItemProps, idx: number) => { |
|||
const pendingClass = idx === itemsCount - 2 ? lastCls : ''; |
|||
const readyClass = idx === itemsCount - 1 ? lastCls : ''; |
|||
return ( |
|||
<TimelineItem |
|||
className={classNames([ |
|||
className, |
|||
!reverse && !!pending ? pendingClass : readyClass, |
|||
getPositionCls(item?.position ?? '', idx), |
|||
])} |
|||
{...item} |
|||
/* eslint-disable-next-line react/no-array-index-key */ |
|||
key={item?.key || idx} |
|||
/> |
|||
); |
|||
}); |
|||
|
|||
const hasLabelItem = mergedItems.some((item: TimelineItemProps) => !!item?.label); |
|||
|
|||
const classString = classNames( |
|||
prefixCls, |
|||
{ |
|||
[`${prefixCls}-pending`]: !!pending, |
|||
[`${prefixCls}-reverse`]: !!reverse, |
|||
[`${prefixCls}-${mode}`]: !!mode && !hasLabelItem, |
|||
[`${prefixCls}-label`]: hasLabelItem, |
|||
[`${prefixCls}-rtl`]: direction === 'rtl', |
|||
}, |
|||
className, |
|||
rootClassName, |
|||
hashId, |
|||
); |
|||
|
|||
return ( |
|||
<ul {...restProps} className={classString}> |
|||
{itemsList} |
|||
</ul> |
|||
); |
|||
}; |
|||
|
|||
export default TimelineItemList; |
@ -0,0 +1,14 @@ |
|||
import type * as React from 'react'; |
|||
import toArray from 'rc-util/lib/Children/toArray'; |
|||
import type { TimelineItemProps } from './TimelineItem'; |
|||
|
|||
function useItems(items?: TimelineItemProps[], children?: React.ReactNode): TimelineItemProps[] { |
|||
if (items && Array.isArray(items)) return items; |
|||
|
|||
return toArray(children).map((ele: React.ReactElement<any>) => ({ |
|||
children: ele?.props?.children ?? '', |
|||
...ele.props, |
|||
})); |
|||
} |
|||
|
|||
export default useItems; |
Loading…
Reference in new issue