mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-05 21:50:07 +08:00
157 lines
4.7 KiB
Vue
157 lines
4.7 KiB
Vue
import PropTypes from '../_util/vue-types';
|
|
import classNames from '../_util/classNames';
|
|
import { getComponent, isStringElement, isEmptyElement, getSlot } from '../_util/props-util';
|
|
import { Col } from '../grid';
|
|
import { defaultConfigProvider } from '../config-provider';
|
|
import { cloneElement } from '../_util/vnode';
|
|
import { defineComponent, ExtractPropTypes, FunctionalComponent, inject } from 'vue';
|
|
|
|
export const ListItemProps = {
|
|
prefixCls: PropTypes.string,
|
|
extra: PropTypes.any,
|
|
actions: PropTypes.array,
|
|
grid: PropTypes.any,
|
|
};
|
|
|
|
export const ListItemMetaProps = {
|
|
avatar: PropTypes.any,
|
|
description: PropTypes.any,
|
|
prefixCls: PropTypes.string,
|
|
title: PropTypes.any,
|
|
};
|
|
|
|
export const ListItemMeta: FunctionalComponent<Partial<
|
|
ExtractPropTypes<typeof ListItemMetaProps>
|
|
>> = (props, { slots }) => {
|
|
const configProvider = inject('configProvider', defaultConfigProvider);
|
|
const { getPrefixCls } = configProvider;
|
|
const { prefixCls: customizePrefixCls } = props;
|
|
const prefixCls = getPrefixCls('list', customizePrefixCls);
|
|
const avatar = props.avatar || slots.avatar?.();
|
|
const title = props.title || slots.title?.();
|
|
const description = props.description || slots.description?.();
|
|
const content = (
|
|
<div class={`${prefixCls}-item-meta-content`}>
|
|
{title && <h4 class={`${prefixCls}-item-meta-title`}>{title}</h4>}
|
|
{description && <div class={`${prefixCls}-item-meta-description`}>{description}</div>}
|
|
</div>
|
|
);
|
|
return (
|
|
<div class={`${prefixCls}-item-meta`}>
|
|
{avatar && <div class={`${prefixCls}-item-meta-avatar`}>{avatar}</div>}
|
|
{(title || description) && content}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
Object.assign(ListItemMeta, {
|
|
props: ListItemMetaProps,
|
|
__ANT_LIST_ITEM_META: true,
|
|
displayName: 'AListItemMeta',
|
|
});
|
|
|
|
function getGrid(grid, t) {
|
|
return grid[t] && Math.floor(24 / grid[t]);
|
|
}
|
|
|
|
export interface ListContext {
|
|
grid?: any;
|
|
itemLayout?: string;
|
|
}
|
|
|
|
export default defineComponent({
|
|
name: 'AListItem',
|
|
inheritAttrs: false,
|
|
Meta: ListItemMeta,
|
|
props: ListItemProps,
|
|
setup() {
|
|
const listContext = inject<ListContext>('listContext', {});
|
|
const configProvider = inject('configProvider', defaultConfigProvider);
|
|
return {
|
|
listContext,
|
|
configProvider,
|
|
};
|
|
},
|
|
methods: {
|
|
isItemContainsTextNodeAndNotSingular() {
|
|
const children = getSlot(this) || [];
|
|
let result;
|
|
children.forEach(element => {
|
|
if (isStringElement(element) && !isEmptyElement(element)) {
|
|
result = true;
|
|
}
|
|
});
|
|
return result && children.length > 1;
|
|
},
|
|
|
|
isFlexMode() {
|
|
const extra = getComponent(this, 'extra');
|
|
const { itemLayout } = this.listContext;
|
|
if (itemLayout === 'vertical') {
|
|
return !!extra;
|
|
}
|
|
return !this.isItemContainsTextNodeAndNotSingular();
|
|
},
|
|
},
|
|
render() {
|
|
const { grid, itemLayout } = this.listContext;
|
|
const { prefixCls: customizePrefixCls, $attrs } = this;
|
|
const { class: _className, ...restAttrs } = $attrs;
|
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
|
const prefixCls = getPrefixCls('list', customizePrefixCls);
|
|
const extra = getComponent(this, 'extra');
|
|
let actions = getComponent(this, 'actions');
|
|
actions = actions && !Array.isArray(actions) ? [actions] : actions;
|
|
const actionsContent = actions && actions.length > 0 && (
|
|
<ul class={`${prefixCls}-item-action`} key="actions">
|
|
{actions.map((action, i) => (
|
|
<li key={`${prefixCls}-item-action-${i}`}>
|
|
{action}
|
|
{i !== actions.length - 1 && <em class={`${prefixCls}-item-action-split`} />}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
);
|
|
const children = getSlot(this);
|
|
const Tag = grid ? 'div' : 'li';
|
|
const itemChildren = (
|
|
<Tag
|
|
{...restAttrs}
|
|
class={classNames(`${prefixCls}-item`, _className, {
|
|
[`${prefixCls}-item-no-flex`]: !this.isFlexMode(),
|
|
})}
|
|
>
|
|
{itemLayout === 'vertical' && extra
|
|
? [
|
|
<div class={`${prefixCls}-item-main`} key="content">
|
|
{children}
|
|
{actionsContent}
|
|
</div>,
|
|
<div class={`${prefixCls}-item-extra`} key="extra">
|
|
{extra}
|
|
</div>,
|
|
]
|
|
: [children, actionsContent, cloneElement(extra, { key: 'extra' })]}
|
|
</Tag>
|
|
);
|
|
|
|
const mainContent = grid ? (
|
|
<Col
|
|
span={getGrid(grid, 'column')}
|
|
xs={getGrid(grid, 'xs')}
|
|
sm={getGrid(grid, 'sm')}
|
|
md={getGrid(grid, 'md')}
|
|
lg={getGrid(grid, 'lg')}
|
|
xl={getGrid(grid, 'xl')}
|
|
xxl={getGrid(grid, 'xxl')}
|
|
>
|
|
{itemChildren}
|
|
</Col>
|
|
) : (
|
|
itemChildren
|
|
);
|
|
|
|
return mainContent;
|
|
},
|
|
});
|