import React from 'react'; import cls from 'classnames'; import PropTypes from 'prop-types'; import { cssClasses, strings } from '@douyinfe/semi-foundation/list/constants'; import { noop } from 'lodash'; import '@douyinfe/semi-foundation/list/list.scss'; import LocaleConsumer from '../locale/localeConsumer'; import { Locale } from '../locale/interface'; import ListItem from './item'; import { Row } from '../grid'; import Spin from '../spin'; import ListContext, { Grid } from './list-context'; import BaseComponent from '../_base/baseComponent'; export { ListItemProps } from './item'; export interface ListProps { style?: React.CSSProperties; className?: string; children?: React.ReactNode; bordered?: boolean; footer?: React.ReactNode; header?: React.ReactNode; layout?: 'vertical' | 'horizontal'; size?: 'small' | 'large' | 'default'; split?: boolean; emptyContent?: React.ReactNode; dataSource?: T[]; renderItem?: (item: T, ind: number) => React.ReactNode; grid?: Grid; loading?: boolean; loadMore?: React.ReactNode; onClick?: React.MouseEventHandler; onRightClick?: React.MouseEventHandler; } const prefixCls = cssClasses.PREFIX; class List extends BaseComponent> { static Item = ListItem; static propTypes = { style: PropTypes.object, className: PropTypes.string, bordered: PropTypes.bool, footer: PropTypes.node, header: PropTypes.node, layout: PropTypes.oneOf(strings.LAYOUT), size: PropTypes.oneOf(strings.SIZE), split: PropTypes.bool, emptyContent: PropTypes.node, dataSource: PropTypes.array, renderItem: PropTypes.func, grid: PropTypes.object, loading: PropTypes.bool, loadMore: PropTypes.node, onRightClick: PropTypes.func, onClick: PropTypes.func, }; static defaultProps = { bordered: false, split: true, loading: false, layout: 'vertical', size: 'default', onRightClick: noop, onClick: noop, }; renderEmpty = () => { const { emptyContent } = this.props; if (emptyContent) { return (
{emptyContent}
); } else { return ( { (locale: Locale['List']) => (
{locale.emptyText}
) }
); } }; wrapChildren(childrenList: React.ReactNode, children: React.ReactNode) { const { grid } = this.props; if (grid) { const rowProps = {}; ['align', 'gutter', 'justify', 'type'].forEach(key => { if (key in grid) { rowProps[key] = grid[key]; } }); return ( {childrenList ? childrenList : null} {children} ); } return (
    {childrenList ? childrenList : null} {children}
); } render() { const { style, className, header, loading, onRightClick, onClick, footer, layout, grid, size, split, loadMore, bordered, dataSource, renderItem, children } = this.props; const wrapperCls = cls(prefixCls, className, { [`${prefixCls}-flex`]: layout === 'horizontal', [`${prefixCls}-${size}`]: size, [`${prefixCls}-grid`]: grid, [`${prefixCls}-split`]: split, [`${prefixCls}-bordered`]: bordered, }); let childrenList; if (dataSource && dataSource.length) { childrenList = []; const items = renderItem ? dataSource.map((item, index) => renderItem(item, index)) : []; React.Children.forEach(items as any, (child, index) => { const itemKey = child.key || `list-item-${index}`; childrenList.push( React.cloneElement(child, { key: itemKey, }) ); }); } else if (!children && !loading) { childrenList = this.renderEmpty(); } return (
{header ? (
{header}
) : null} {this.wrapChildren(childrenList, children)} {footer ? (
{footer}
) : null} {loadMore ? loadMore : null}
); } } export default List;