vuecssuiant-designantdreactantantd-vueenterprisefrontendui-designvue-antdvue-antd-uivue3vuecomponent
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
3.2 KiB
102 lines
3.2 KiB
import PropTypes from '../_util/vue-types'; |
|
import classNames from '../_util/classNames'; |
|
import { isStringElement, isEmptyElement, flattenChildren } from '../_util/props-util'; |
|
import { Col } from '../grid'; |
|
import { cloneElement } from '../_util/vnode'; |
|
import { defineComponent, inject, ref } from 'vue'; |
|
import ItemMeta from './ItemMeta'; |
|
import useConfigInject from '../_util/hooks/useConfigInject'; |
|
import { ListContextKey } from './contextKey'; |
|
|
|
export const ListItemProps = { |
|
prefixCls: PropTypes.string, |
|
extra: PropTypes.any, |
|
actions: PropTypes.array, |
|
grid: PropTypes.any, |
|
colStyle: PropTypes.style, |
|
}; |
|
|
|
export default defineComponent({ |
|
name: 'AListItem', |
|
inheritAttrs: false, |
|
Meta: ItemMeta, |
|
props: ListItemProps, |
|
slots: ['actions', 'extra'], |
|
setup(props, { slots, attrs }) { |
|
const { itemLayout, grid } = inject(ListContextKey, { |
|
grid: ref(), |
|
itemLayout: ref(), |
|
}); |
|
const { prefixCls } = useConfigInject('list', props); |
|
|
|
const isItemContainsTextNodeAndNotSingular = () => { |
|
const children = slots.default?.() || []; |
|
let result; |
|
children.forEach(element => { |
|
if (isStringElement(element) && !isEmptyElement(element)) { |
|
result = true; |
|
} |
|
}); |
|
return result && children.length > 1; |
|
}; |
|
|
|
const isFlexMode = () => { |
|
const extra = props.extra ?? slots.extra?.(); |
|
if (itemLayout.value === 'vertical') { |
|
return !!extra; |
|
} |
|
return !isItemContainsTextNodeAndNotSingular(); |
|
}; |
|
|
|
return () => { |
|
const { class: className, ...restAttrs } = attrs; |
|
const pre = prefixCls.value; |
|
const extra = props.extra ?? slots.extra?.(); |
|
const children = slots.default?.(); |
|
let actions = props.actions ?? flattenChildren(slots.actions?.()); |
|
actions = actions && !Array.isArray(actions) ? [actions] : actions; |
|
const actionsContent = actions && actions.length > 0 && ( |
|
<ul class={`${pre}-item-action`} key="actions"> |
|
{actions.map((action, i) => ( |
|
<li key={`${pre}-item-action-${i}`}> |
|
{action} |
|
{i !== actions.length - 1 && <em class={`${pre}-item-action-split`} />} |
|
</li> |
|
))} |
|
</ul> |
|
); |
|
const Element = grid.value ? 'div' : 'li'; |
|
const itemChildren = ( |
|
<Element |
|
{...(restAttrs as any)} // `li` element `onCopy` prop args is not same as `div` |
|
class={classNames( |
|
`${pre}-item`, |
|
{ |
|
[`${pre}-item-no-flex`]: !isFlexMode(), |
|
}, |
|
className, |
|
)} |
|
> |
|
{itemLayout.value === 'vertical' && extra |
|
? [ |
|
<div class={`${pre}-item-main`} key="content"> |
|
{children} |
|
{actionsContent} |
|
</div>, |
|
<div class={`${pre}-item-extra`} key="extra"> |
|
{extra} |
|
</div>, |
|
] |
|
: [children, actionsContent, cloneElement(extra, { key: 'extra' })]} |
|
</Element> |
|
); |
|
return grid.value ? ( |
|
<Col flex={1} style={props.colStyle}> |
|
{itemChildren} |
|
</Col> |
|
) : ( |
|
itemChildren |
|
); |
|
}; |
|
}, |
|
});
|
|
|