Skip to content

Commit 5cca28a

Browse files
committed
feat: add list component
1 parent 4d881ac commit 5cca28a

25 files changed

+1916
-3
lines changed

components/_util/props-util.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ const getSlots = (ele) => {
5959
return slots
6060
}
6161
const getSlotOptions = (ele) => {
62+
if (ele.fnOptions) { // 函数式组件
63+
return ele.fnOptions
64+
}
6265
let componentOptions = ele.componentOptions
6366
if (ele.$vnode) {
6467
componentOptions = ele.$vnode.componentOptions

components/index.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import { default as InputNumber } from './input-number'
6060

6161
import { default as Layout } from './layout'
6262

63-
// import { default as List } from './list'
63+
import { default as List } from './list'
6464

6565
import { default as LocaleProvider } from './locale-provider'
6666

@@ -163,6 +163,9 @@ const components = [
163163
Layout.Footer,
164164
Layout.Sider,
165165
Layout.Content,
166+
List,
167+
List.Item,
168+
List.Item.Meta,
166169
LocaleProvider,
167170
Menu,
168171
Menu.Item,
@@ -247,6 +250,7 @@ export {
247250
Input,
248251
InputNumber,
249252
Layout,
253+
List,
250254
LocaleProvider,
251255
Menu,
252256
Modal,

components/list/Item.jsx

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import PropTypes from '../_util/vue-types'
2+
import classNames from 'classnames'
3+
import { getSlotOptions, getComponentFromProp, isEmptyElement } from '../_util/props-util'
4+
import { Col } from '../grid'
5+
import { ListGridType } from './index'
6+
7+
export const ListItemProps = {
8+
prefixCls: PropTypes.string,
9+
extra: PropTypes.any,
10+
actions: PropTypes.arrayOf(PropTypes.any),
11+
grid: ListGridType,
12+
}
13+
14+
export const ListItemMetaProps = {
15+
avatar: PropTypes.any,
16+
description: PropTypes.any,
17+
prefixCls: PropTypes.string,
18+
title: PropTypes.any,
19+
}
20+
21+
export const Meta = {
22+
functional: true,
23+
name: 'AListItemMeta',
24+
__ANT_LIST_ITEM_META: true,
25+
render (h, context) {
26+
const { props, slots, listeners } = context
27+
const slotsMap = slots()
28+
const {
29+
prefixCls = 'ant-list',
30+
} = props
31+
const avatar = props.avatar || slotsMap.avatar
32+
const title = props.title || slotsMap.title
33+
const description = props.description || slotsMap.description
34+
const content = (
35+
<div class={`${prefixCls}-item-meta-content`}>
36+
{title && <h4 class={`${prefixCls}-item-meta-title`}>{title}</h4>}
37+
{description && <div class={`${prefixCls}-item-meta-description`}>{description}</div>}
38+
</div>
39+
)
40+
return (
41+
<div {...{ on: listeners }} class={`${prefixCls}-item-meta`}>
42+
{avatar && <div class={`${prefixCls}-item-meta-avatar`}>{avatar}</div>}
43+
{(title || description) && content}
44+
</div>
45+
)
46+
},
47+
48+
}
49+
50+
function getGrid (grid, t) {
51+
return grid[t] && Math.floor(24 / grid[t])
52+
}
53+
54+
export default {
55+
name: 'AListItem',
56+
Meta,
57+
props: ListItemProps,
58+
inject: {
59+
listContext: { default: {}},
60+
},
61+
62+
render () {
63+
const { grid } = this.listContext
64+
const { prefixCls = 'ant-list', $slots, $listeners } = this
65+
const classString = `${prefixCls}-item`
66+
const extra = getComponentFromProp(this, 'extra')
67+
const actions = getComponentFromProp(this, 'actions')
68+
const metaContent = []
69+
const otherContent = []
70+
71+
;($slots.default || []).forEach((element) => {
72+
if (!isEmptyElement(element)) {
73+
if (getSlotOptions(element).__ANT_LIST_ITEM_META) {
74+
metaContent.push(element)
75+
} else {
76+
otherContent.push(element)
77+
}
78+
}
79+
})
80+
81+
const contentClassString = classNames(`${prefixCls}-item-content`, {
82+
[`${prefixCls}-item-content-single`]: (metaContent.length < 1),
83+
})
84+
const content = otherContent.length > 0 ? (
85+
<div class={contentClassString}>
86+
{otherContent}
87+
</div>) : null
88+
89+
let actionsContent
90+
if (actions && actions.length > 0) {
91+
const actionsContentItem = (action, i) => (
92+
<li key={`${prefixCls}-item-action-${i}`}>
93+
{action}
94+
{i !== (actions.length - 1) && <em class={`${prefixCls}-item-action-split`}/>}
95+
</li>
96+
)
97+
actionsContent = (
98+
<ul class={`${prefixCls}-item-action`}>
99+
{actions.map((action, i) => actionsContentItem(action, i))}
100+
</ul>
101+
)
102+
}
103+
104+
const extraContent = (
105+
<div class={`${prefixCls}-item-extra-wrap`}>
106+
<div class={`${prefixCls}-item-main`}>
107+
{metaContent}
108+
{content}
109+
{actionsContent}
110+
</div>
111+
<div class={`${prefixCls}-item-extra`}>{extra}</div>
112+
</div>
113+
)
114+
115+
const mainContent = grid ? (
116+
<Col
117+
span={getGrid(grid, 'column')}
118+
xs={getGrid(grid, 'xs')}
119+
sm={getGrid(grid, 'sm')}
120+
md={getGrid(grid, 'md')}
121+
lg={getGrid(grid, 'lg')}
122+
xl={getGrid(grid, 'xl')}
123+
xxl={getGrid(grid, 'xxl')}
124+
>
125+
<div {...{ on: $listeners }} class={classString}>
126+
{extra && extraContent}
127+
{!extra && metaContent}
128+
{!extra && content}
129+
{!extra && actionsContent}
130+
</div>
131+
</Col>
132+
) : (
133+
<div {...{ on: $listeners }} class={classString}>
134+
{extra && extraContent}
135+
{!extra && metaContent}
136+
{!extra && content}
137+
{!extra && actionsContent}
138+
</div>
139+
)
140+
141+
return mainContent
142+
},
143+
}

0 commit comments

Comments
 (0)