Feat descriptions (#1251)

* feat: add descriptions

* fix: add descriptions types and fix docs

* fix: lint change code

* fix: demo warning

* fix: update demo, snapshot and remove classnames
pull/1498/head
zkwolf 2019-10-10 20:07:56 -07:00 committed by tangjinzhou
parent 237b620fec
commit dff0951dcd
26 changed files with 1309 additions and 0 deletions

View File

@ -0,0 +1,96 @@
// matchMedia polyfill for
// https://github.com/WickyNilliams/enquire.js/issues/82
let enquire;
// TODO: Will be removed in antd 4.0 because we will no longer support ie9
if (typeof window !== 'undefined') {
const matchMediaPolyfill = (mediaQuery) => {
return {
media: mediaQuery,
matches: false,
addListener() {},
removeListener() {},
};
};
// ref: https://github.com/ant-design/ant-design/issues/18774
if (!window.matchMedia) window.matchMedia = matchMediaPolyfill;
// eslint-disable-next-line global-require
enquire = require('enquire.js');
}
export const responsiveArray = ['xxl', 'xl', 'lg', 'md', 'sm', 'xs'];
export const responsiveMap = {
xs: '(max-width: 575px)',
sm: '(min-width: 576px)',
md: '(min-width: 768px)',
lg: '(min-width: 992px)',
xl: '(min-width: 1200px)',
xxl: '(min-width: 1600px)',
};
let subscribers = [];
let subUid = -1;
let screens = {};
const responsiveObserve = {
dispatch(pointMap) {
screens = pointMap;
if (subscribers.length < 1) {
return false;
}
subscribers.forEach(item => {
item.func(screens);
});
return true;
},
subscribe(func) {
if (subscribers.length === 0) {
this.register();
}
const token = (++subUid).toString();
subscribers.push({
token,
func,
});
func(screens);
return token;
},
unsubscribe(token) {
subscribers = subscribers.filter(item => item.token !== token);
if (subscribers.length === 0) {
this.unregister();
}
},
unregister() {
Object.keys(responsiveMap).map((screen) =>
enquire.unregister(responsiveMap[screen]),
);
},
register() {
Object.keys(responsiveMap).map((screen) =>
enquire.register(responsiveMap[screen], {
match: () => {
const pointMap = {
...screens,
[screen]: true,
};
this.dispatch(pointMap);
},
unmatch: () => {
const pointMap = {
...screens,
[screen]: false,
};
this.dispatch(pointMap);
},
// Keep a empty destory to avoid triggering unmatch when unregister
destroy() {},
}),
);
},
};
export default responsiveObserve;

View File

@ -0,0 +1,74 @@
import PropTypes from '../_util/vue-types';
import { getOptionProps, getSlots, getComponentFromProp } from '../_util/props-util';
const ColProps = {
child: PropTypes.any,
bordered: PropTypes.bool,
colon: PropTypes.bool,
type: PropTypes.oneOf(['label', 'content']),
layout: PropTypes.oneOf(['horizontal', 'vertical']),
};
const Col = {
props: ColProps,
render() {
const { child, bordered, colon, type, layout } = this.$props;
const { prefixCls, span = 1 } = getOptionProps(child);
const label = getComponentFromProp(child, 'label');
const slots = getSlots(child);
const labelProps = {
attrs: {},
class: [`${prefixCls}-item-label`, {
[`${prefixCls}-item-colon`]: colon,
[`${prefixCls}-item-no-label`]: !label,
}],
key: 'label',
};
if (layout === 'vertical') {
labelProps.attrs.colSpan = span * 2 - 1;
}
if (bordered) {
if (type === 'label') {
return <th {...labelProps}>{label}</th>;
}
return (
<td class={`${prefixCls}-item-content`} key="content" colSpan={span * 2 - 1}>
{slots.default}
</td>
);
}
if (layout === 'vertical') {
if (type === 'content') {
return (
<td colSpan={span} class={`${prefixCls}-item`}>
<span class={`${prefixCls}-item-content`} key="content">
{slots.default}
</span>
</td>
);
}
return (
<td colSpan={span} class={`${prefixCls}-item`}>
<span
class={[`${prefixCls}-item-label`, { [`${prefixCls}-item-colon`]: colon }]}
key="label"
>
{label}
</span>
</td>
);
}
return (
<td colSpan={span} class={`${prefixCls}-item`}>
<span {...labelProps}>{label}</span>
<span class={`${prefixCls}-item-content`} key="content">
{slots.default}
</span>
</td>
);
},
};
export default Col;

View File

@ -0,0 +1,287 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders ./components/descriptions/demo/basic.md correctly 1`] = `
<div class="ant-descriptions">
<div class="ant-descriptions-title">User Info</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">UserName</span><span class="ant-descriptions-item-content">Zhou Maomao</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Telephone</span><span class="ant-descriptions-item-content">1810000000</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Live</span><span class="ant-descriptions-item-content">Hangzhou, Zhejiang</span></td>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Remark</span><span class="ant-descriptions-item-content">empty</span></td>
<td colspan="2" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Address</span><span class="ant-descriptions-item-content">
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</span></td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`renders ./components/descriptions/demo/border.md correctly 1`] = `
<div class="ant-descriptions ant-descriptions-bordered">
<div class="ant-descriptions-title">User Info</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Product</th>
<td colspan="1" class="ant-descriptions-item-content">Cloud Database</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Billing Mode</th>
<td colspan="1" class="ant-descriptions-item-content">Prepaid</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Automatic Renewal</th>
<td colspan="1" class="ant-descriptions-item-content">YES</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Order time</th>
<td colspan="1" class="ant-descriptions-item-content">2018-04-24 18:00:00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Usage Time</th>
<td colspan="3" class="ant-descriptions-item-content">
2019-04-24 18:00:00
</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Status</th>
<td colspan="5" class="ant-descriptions-item-content"><span class="ant-badge ant-badge-status ant-badge-not-a-wrapper"><span class="ant-badge-status-dot ant-badge-status-processing"></span><span class="ant-badge-status-text">Running</span></span></td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Negotiated Amount</th>
<td colspan="1" class="ant-descriptions-item-content">$80.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Discount</th>
<td colspan="1" class="ant-descriptions-item-content">$20.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Official Receipts</th>
<td colspan="1" class="ant-descriptions-item-content">$60.00</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Config Info</th>
<td colspan="5" class="ant-descriptions-item-content">
Data disk type: MongoDB
<br>
Database version: 3.4
<br>
Package: dds.mongo.mid
<br>
Storage space: 10 GB
<br>
Replication_factor:3
<br>
Region: East China 1<br></td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`renders ./components/descriptions/demo/responsive.md correctly 1`] = `
<div>
<div class="ant-descriptions ant-descriptions-bordered">
<div class="ant-descriptions-title">Responsive Descriptions</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Product</th>
<td colspan="1" class="ant-descriptions-item-content">Cloud Database</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</th>
<td colspan="1" class="ant-descriptions-item-content">Prepaid</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">time</th>
<td colspan="1" class="ant-descriptions-item-content">18:00:00</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</th>
<td colspan="1" class="ant-descriptions-item-content">$80.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Discount</th>
<td colspan="1" class="ant-descriptions-item-content">$20.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Official</th>
<td colspan="1" class="ant-descriptions-item-content">$60.00</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Config Info</th>
<td colspan="5" class="ant-descriptions-item-content">
Data disk type: MongoDB
<br>
Database version: 3.4
<br>
Package: dds.mongo.mid
<br>
Storage space: 10 GB
<br>
Replication_factor:3
<br>
Region: East China 1
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
<div>
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-wrapper ant-radio-wrapper-checked"><span class="ant-radio ant-radio-checked"><input type="radio" class="ant-radio-input" value="default"><span class="ant-radio-inner"></span></span><span>default</span></label><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="middle"><span class="ant-radio-inner"></span></span><span>middle</span></label><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="small"><span class="ant-radio-inner"></span></span><span>small</span></label></div> <br> <br>
<div class="ant-descriptions ant-descriptions-bordered">
<div class="ant-descriptions-title">Custom Size</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Product</th>
<td colspan="1" class="ant-descriptions-item-content">Cloud Database</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</th>
<td colspan="1" class="ant-descriptions-item-content">Prepaid</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">time</th>
<td colspan="1" class="ant-descriptions-item-content">18:00:00</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</th>
<td colspan="1" class="ant-descriptions-item-content">$80.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Discount</th>
<td colspan="1" class="ant-descriptions-item-content">$20.00</td>
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Official</th>
<td colspan="1" class="ant-descriptions-item-content">$60.00</td>
</tr>
<tr class="ant-descriptions-row">
<th class="ant-descriptions-item-label ant-descriptions-item-colon">Config Info</th>
<td colspan="5" class="ant-descriptions-item-content">
Data disk type: MongoDB
<br>
Database version: 3.4
<br>
Package: dds.mongo.mid
<br>
Storage space: 10 GB
<br>
Replication_factor:3
<br>
Region: East China 1<br></td>
</tr>
</tbody>
</table>
</div>
</div> <br> <br>
<div class="ant-descriptions">
<div class="ant-descriptions-title">Custom Size</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Product</span><span class="ant-descriptions-item-content">Cloud Database</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Billing</span><span class="ant-descriptions-item-content">Prepaid</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">time</span><span class="ant-descriptions-item-content">18:00:00</span></td>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Amount</span><span class="ant-descriptions-item-content">$80.00</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Discount</span><span class="ant-descriptions-item-content">$20.00</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Official</span><span class="ant-descriptions-item-content">$60.00</span></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`renders ./components/descriptions/demo/vertical.md correctly 1`] = `
<div class="ant-descriptions">
<div class="ant-descriptions-title">User Info</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">UserName</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Telephone</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Live</span></td>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">Zhou Maomao</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">1810000000</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">Hangzhou, Zhejiang</span></td>
</tr>
<tr class="ant-descriptions-row">
<td colspan="2" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Address</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-label ant-descriptions-item-colon">Remark</span></td>
</tr>
<tr class="ant-descriptions-row">
<td colspan="2" class="ant-descriptions-item"><span class="ant-descriptions-item-content">
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</span></td>
<td colspan="1" class="ant-descriptions-item"><span class="ant-descriptions-item-content">empty</span></td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`] = `
<div class="ant-descriptions ant-descriptions-bordered">
<div class="ant-descriptions-title">User Info</div>
<div class="ant-descriptions-view">
<table>
<tbody>
<tr class="ant-descriptions-row">
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Product</th>
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Billing Mode</th>
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Automatic Renewal</th>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item-content">Cloud Database</td>
<td colspan="1" class="ant-descriptions-item-content">Prepaid</td>
<td colspan="1" class="ant-descriptions-item-content">YES</td>
</tr>
<tr class="ant-descriptions-row">
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Order time</th>
<th colspan="3" class="ant-descriptions-item-label ant-descriptions-item-colon">Usage Time</th>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item-content">2018-04-24 18:00:00</td>
<td colspan="3" class="ant-descriptions-item-content">
2019-04-24 18:00:00
</td>
</tr>
<tr class="ant-descriptions-row">
<th colspan="5" class="ant-descriptions-item-label ant-descriptions-item-colon">Status</th>
</tr>
<tr class="ant-descriptions-row">
<td colspan="5" class="ant-descriptions-item-content"><span class="ant-badge ant-badge-status ant-badge-not-a-wrapper"><span class="ant-badge-status-dot ant-badge-status-processing"></span><span class="ant-badge-status-text">Running</span></span></td>
</tr>
<tr class="ant-descriptions-row">
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Negotiated Amount</th>
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Discount</th>
<th colspan="1" class="ant-descriptions-item-label ant-descriptions-item-colon">Official Receipts</th>
</tr>
<tr class="ant-descriptions-row">
<td colspan="1" class="ant-descriptions-item-content">$80.00</td>
<td colspan="1" class="ant-descriptions-item-content">$20.00</td>
<td colspan="1" class="ant-descriptions-item-content">$60.00</td>
</tr>
<tr class="ant-descriptions-row">
<th colspan="5" class="ant-descriptions-item-label ant-descriptions-item-colon">Config Info</th>
</tr>
<tr class="ant-descriptions-row">
<td colspan="5" class="ant-descriptions-item-content">
Data disk type: MongoDB
<br>
Database version: 3.4
<br>
Package: dds.mongo.mid
<br>
Storage space: 10 GB
<br>
Replication_factor:3
<br>
Region: East China 1<br></td>
</tr>
</tbody>
</table>
</div>
</div>
`;

View File

@ -0,0 +1,3 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('descriptions');

View File

@ -0,0 +1,23 @@
<cn>
#### 基本
简单的展示。
</cn>
<us>
#### Basic
Simplest Usage.
</us>
```tpl
<template>
<a-descriptions title="User Info">
<a-descriptions-item label="UserName">Zhou Maomao</a-descriptions-item>
<a-descriptions-item label="Telephone">1810000000</a-descriptions-item>
<a-descriptions-item label="Live">Hangzhou, Zhejiang</a-descriptions-item>
<a-descriptions-item label="Remark">empty</a-descriptions-item>
<a-descriptions-item label="Address">
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</a-descriptions-item>
</a-descriptions>
</template>
```

View File

@ -0,0 +1,41 @@
<cn>
#### 带边框的
</cn>
<us>
#### border
Descriptions with border and background color.
</us>
```tpl
<template>
<a-descriptions title="User Info" bordered>
<a-descriptions-item label="Product">Cloud Database</a-descriptions-item>
<a-descriptions-item label="Billing Mode">Prepaid</a-descriptions-item>
<a-descriptions-item label="Automatic Renewal">YES</a-descriptions-item>
<a-descriptions-item label="Order time">2018-04-24 18:00:00</a-descriptions-item>
<a-descriptions-item label="Usage Time" :span="2">
2019-04-24 18:00:00
</a-descriptions-item>
<a-descriptions-item label="Status" :span="3">
<a-badge status="processing" text="Running" />
</a-descriptions-item>
<a-descriptions-item label="Negotiated Amount">$80.00</a-descriptions-item>
<a-descriptions-item label="Discount">$20.00</a-descriptions-item>
<a-descriptions-item label="Official Receipts">$60.00</a-descriptions-item>
<a-descriptions-item label="Config Info">
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication_factor:3
<br />
Region: East China 1<br />
</a-descriptions-item>
</a-descriptions>
</template>
```

View File

@ -0,0 +1,53 @@
<script>
import Basic from './basic.md';
import Border from './border.md';
import Responsive from './responsive.md';
import Size from './size.md';
import VerticalBorder from './vertical-border.md';
import Vertical from './vertical.md';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
import '../style';
const md = {
cn: `# Descriptions 描述列表
成组展示多个只读字段
## 何时使用
常见于详情页的信息展示
## 代码演示
`,
us: `# Descriptions
Display multiple read-only fields in groups.
## When To Use
Commonly displayed on the details page.
## Examples
`,
};
export default {
category: 'Components',
type: 'Data Display',
zhType: '数据展示',
title: 'Descriptions',
subtitle: '描述列表',
cols: 1,
render() {
return (
<div>
<md cn={md.cn} us={md.us} />
<Basic />
<Border />
<Size />
<Responsive />
<Vertical />
<VerticalBorder />
<api>
<CN slot="cn" />
<US />
</api>
</div>
);
},
};
</script>

View File

@ -0,0 +1,41 @@
<cn>
#### 响应式
通过响应式的配置可以实现在小屏幕设备上的完美呈现。
</cn>
<us>
#### responsive
通过响应式的配置可以实现在小屏幕设备上的完美呈现。
</us>
```tpl
<template>
<div>
<a-descriptions
title="Responsive Descriptions"
bordered
:column="{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }"
>
<a-descriptions-item label="Product">Cloud Database</a-descriptions-item>
<a-descriptions-item label="Billing">Prepaid</a-descriptions-item>
<a-descriptions-item label="time">18:00:00</a-descriptions-item>
<a-descriptions-item label="Amount">$80.00</a-descriptions-item>
<a-descriptions-item label="Discount">$20.00</a-descriptions-item>
<a-descriptions-item label="Official">$60.00</a-descriptions-item>
<a-descriptions-item label="Config Info">
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication_factor:3
<br />
Region: East China 1
</a-descriptions-item>
</a-descriptions>
</div>
</template>
```

View File

@ -0,0 +1,69 @@
<cn>
#### 自定义尺寸
自定义尺寸,适应在各种容器中展示。
</cn>
<us>
#### Custom size
Custom sizes to fit in a variety of containers.
</us>
```tpl
<template>
<div>
<a-radio-group @change="onChange" v-model="size">
<a-radio value="default">default</a-radio>
<a-radio value="middle">middle</a-radio>
<a-radio value="small">small</a-radio>
</a-radio-group>
<br />
<br />
<a-descriptions bordered title="Custom Size" :size="size">
<a-descriptions-item label="Product">Cloud Database</a-descriptions-item>
<a-descriptions-item label="Billing">Prepaid</a-descriptions-item>
<a-descriptions-item label="time">18:00:00</a-descriptions-item>
<a-descriptions-item label="Amount">$80.00</a-descriptions-item>
<a-descriptions-item label="Discount">$20.00</a-descriptions-item>
<a-descriptions-item label="Official">$60.00</a-descriptions-item>
<a-descriptions-item label="Config Info">
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication_factor:3
<br />
Region: East China 1<br />
</a-descriptions-item>
</a-descriptions>
<br />
<br />
<a-descriptions title="Custom Size" :size="size">
<a-descriptions-item label="Product">Cloud Database</a-descriptions-item>
<a-descriptions-item label="Billing">Prepaid</a-descriptions-item>
<a-descriptions-item label="time">18:00:00</a-descriptions-item>
<a-descriptions-item label="Amount">$80.00</a-descriptions-item>
<a-descriptions-item label="Discount">$20.00</a-descriptions-item>
<a-descriptions-item label="Official">$60.00</a-descriptions-item>
</a-descriptions>
</div>
</template>
<script>
export default {
data() {
return {
size: 'default',
};
},
methods: {
onChange(e) {
console.log('size checked', e.target.value);
this.size= e.target.value
},
},
};
</script>
```

View File

@ -0,0 +1,42 @@
<cn>
#### 垂直带边框的
垂直带边框和背景颜色的列表。
</cn>
<us>
#### Vertical border
Descriptions with border and background color.
</us>
```tpl
<template>
<a-descriptions title="User Info" layout="vertical" bordered>
<a-descriptions-item label="Product">Cloud Database</a-descriptions-item>
<a-descriptions-item label="Billing Mode">Prepaid</a-descriptions-item>
<a-descriptions-item label="Automatic Renewal">YES</a-descriptions-item>
<a-descriptions-item label="Order time">2018-04-24 18:00:00</a-descriptions-item>
<a-descriptions-item label="Usage Time" :span="2">
2019-04-24 18:00:00
</a-descriptions-item>
<a-descriptions-item label="Status" :span="3">
<a-badge status="processing" text="Running" />
</a-descriptions-item>
<a-descriptions-item label="Negotiated Amount">$80.00</a-descriptions-item>
<a-descriptions-item label="Discount">$20.00</a-descriptions-item>
<a-descriptions-item label="Official Receipts">$60.00</a-descriptions-item>
<a-descriptions-item label="Config Info">
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication_factor:3
<br />
Region: East China 1<br />
</a-descriptions-item>
</a-descriptions>
</template>
```

View File

@ -0,0 +1,23 @@
<cn>
#### 垂直
垂直的列表。
</cn>
<us>
#### Vertical
Simplest Usage.
</us>
```tpl
<template>
<a-descriptions title="User Info" layout="vertical">
<a-descriptions-item label="UserName">Zhou Maomao</a-descriptions-item>
<a-descriptions-item label="Telephone">1810000000</a-descriptions-item>
<a-descriptions-item label="Live">Hangzhou, Zhejiang</a-descriptions-item>
<a-descriptions-item label="Address" span="2">
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</a-descriptions-item>
<a-descriptions-item label="Remark">empty</a-descriptions-item>
</a-descriptions>
</template>
```

View File

@ -0,0 +1,21 @@
## API
### Descriptions props
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| title | The title of the description list, placed at the top | string \| VNode \| v-slot:title | - |
| bordered | whether to display the border | boolean | false |
| column | the number of `DescriptionItems` in a row,could be a number or a object like `{ xs: 8, sm: 16, md: 24}`,(Only set `bordered={true}` to take effect) | number | 3 |
| size | set the size of the list. Can be set to `middle`,`small`, or not filled | `default | middle | small` | `default` |
| layout | Define description layout | `horizontal | vertical` | `horizontal` |
| colon | change default props `colon` value of `Descriptions.Item` | boolean | true |
### Item props
| Property | Description | Type | Default |
| -------- | ------------------------------ | ------------------------------- | ------- |
| label | description of the content | string \| VNode \| v-slot:label | - |
| span | The number of columns included | number | 1 |
> The number of span Descriptions.Item. span={2} takes up the width of two DescriptionsItems.

View File

@ -0,0 +1,264 @@
import warning from '../_util/warning';
import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import { ConfigConsumerProps } from '../config-provider';
import Col from './Col';
import PropTypes from '../_util/vue-types';
import {
initDefaultProps,
isValidElement,
getOptionProps,
getComponentFromProp,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin';
import Base from '../base';
import { cloneElement } from '../_util/vnode';
export const DescriptionsItemProps = {
prefixCls: PropTypes.string,
label: PropTypes.any,
span: PropTypes.number,
};
function toArray(value) {
let ret = value;
if (value === undefined) {
ret = [];
} else if (!Array.isArray(value)) {
ret = [value];
}
return ret;
}
export const DescriptionsItem = {
name: 'ADescriptionsItem',
props: initDefaultProps(DescriptionsItemProps, { span: 1 }),
};
export const DescriptionsProps = {
prefixCls: PropTypes.string,
bordered: PropTypes.bool,
size: PropTypes.oneOf(['default', 'middle', 'small']).def('default'),
title: PropTypes.any,
column: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
layout: PropTypes.oneOf(['horizontal', 'vertical']),
colon: PropTypes.bool,
};
/**
* Convert children into `column` groups.
* @param children: DescriptionsItem
* @param column: number
*/
const generateChildrenRows = (children, column) => {
const rows = [];
let columns = null;
let leftSpans;
const itemNodes = toArray(children);
itemNodes.forEach((node, index) => {
const itemProps = getOptionProps(node);
let itemNode = node;
if (!columns) {
leftSpans = column;
columns = [];
rows.push(columns);
}
// Always set last span to align the end of Descriptions
const lastItem = index === itemNodes.length - 1;
let lastSpanSame = true;
if (lastItem) {
lastSpanSame = !itemProps.span || itemProps.span === leftSpans;
itemNode = cloneElement(itemNode, {
props: {
span: leftSpans,
},
});
}
// Calculate left fill span
const { span = 1 } = itemProps;
columns.push(itemNode);
leftSpans -= span;
if (leftSpans <= 0) {
columns = null;
warning(
leftSpans === 0 && lastSpanSame,
'Descriptions: Sum of column `span` in a line exceeds `column` of Descriptions.',
);
}
});
return rows;
};
const defaultColumnMap = {
xxl: 3,
xl: 3,
lg: 3,
md: 3,
sm: 2,
xs: 1,
};
const Descriptions = {
name: 'ADescriptions',
Item: DescriptionsItem,
mixins: [BaseMixin],
inject: {
configProvider: { default: () => ConfigConsumerProps },
},
props: initDefaultProps(DescriptionsProps, {
column: defaultColumnMap,
}),
data() {
return {
screens: {},
token: undefined,
};
},
methods: {
getColumn() {
const { column } = this.$props;
if (typeof column === 'object') {
for (let i = 0; i < responsiveArray.length; i++) {
const breakpoint = responsiveArray[i];
if (this.screens[breakpoint] && column[breakpoint] !== undefined) {
return column[breakpoint] || defaultColumnMap[breakpoint];
}
}
}
// If the configuration is not an object, it is a number, return number
if (typeof column === 'number') {
return column;
}
// If it is an object, but no response is found, this happens only in the test.
// Maybe there are some strange environments
return 3;
},
renderRow(children, index, { prefixCls }, bordered, layout, colon) {
const renderCol = (colItem, type, idx) => {
return (
<Col
child={colItem}
bordered={bordered}
colon={colon}
type={type}
key={`${type}-${colItem.key || idx}`}
layout={layout}
/>
);
};
const cloneChildren = [];
const cloneContentChildren = [];
toArray(children).forEach((childrenItem, idx) => {
cloneChildren.push(renderCol(childrenItem, 'label', idx));
if (layout === 'vertical') {
cloneContentChildren.push(renderCol(childrenItem, 'content', idx));
} else if (bordered) {
cloneChildren.push(renderCol(childrenItem, 'content', idx));
}
});
if (layout === 'vertical') {
return [
<tr class={`${prefixCls}-row`} key={`label-${index}`}>
{cloneChildren}
</tr>,
<tr class={`${prefixCls}-row`} key={`content-${index}`}>
{cloneContentChildren}
</tr>,
];
}
return (
<tr class={`${prefixCls}-row`} key={index}>
{cloneChildren}
</tr>
);
},
},
mounted() {
const { column } = this.$props;
this.token = ResponsiveObserve.subscribe(screens => {
if (typeof column !== 'object') {
return;
}
this.setState({
screens,
});
});
},
beforeDestory() {
ResponsiveObserve.unsubscribe(this.token);
},
render() {
const {
prefixCls: customizePrefixCls,
size,
bordered = false,
layout = 'horizontal',
colon = true,
} = this.$props;
const title = getComponentFromProp(this, 'title') || null;
const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
const column = this.getColumn();
const children = this.$slots.default;
const cloneChildren = toArray(children)
.map(child => {
if (isValidElement(child)) {
return cloneElement(child, {
props: {
prefixCls,
},
});
}
return null;
})
.filter(node => node);
const childrenArray = generateChildrenRows(cloneChildren, column);
return (
<div
class={[prefixCls, {
[`${prefixCls}-${size}`]: size !== 'default',
[`${prefixCls}-bordered`]: !!bordered,
}]}
>
{title && <div class={`${prefixCls}-title`}>{title}</div>}
<div class={`${prefixCls}-view`}>
<table>
<tbody>
{childrenArray.map((child, index) =>
this.renderRow(
child,
index,
{
prefixCls,
},
bordered,
layout,
colon,
),
)}
</tbody>
</table>
</div>
</div>
);
},
};
Descriptions.install = function(Vue) {
Vue.use(Base);
Vue.component(Descriptions.name, Descriptions);
Vue.component(Descriptions.Item.name, Descriptions.Item);
};
export default Descriptions;

View File

@ -0,0 +1,21 @@
## API
### Descriptions props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| title | 描述列表的标题,显示在最顶部 | string \| VNode \| v-slot:title | - |
| bordered | 是否展示边框 | boolean | false |
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 |
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default | middle | small` | `default` |
| layout | 描述布局 | `horizontal | vertical` | `horizontal` |
| colon | 配置 `Descriptions.Item``colon` 的默认值 | boolean | true |
### Item props
| 参数 | 说明 | 类型 | 默认值 |
| ----- | ------------ | ------------------------------- | ------ |
| label | 内容的描述 | string \| VNode \| v-slot:label | - |
| span | 包含列的数量 | number | 1 |
> span 是 Descriptions.Item 的数量。 span={2} 会占用两个 DescriptionsItem 的宽度。

View File

@ -0,0 +1,2 @@
import '../../style/index.less';
import './index.less';

View File

@ -0,0 +1,145 @@
@import '../../style/themes/default';
@import '../../style/mixins/index';
@descriptions-prefix-cls: ~'@{ant-prefix}-descriptions';
@descriptions-default-padding: 16px 24px;
@descriptions-middle-padding: 12px 24px;
@descriptions-small-padding: 8px 16px;
.@{descriptions-prefix-cls} {
&-title {
margin-bottom: 20px;
color: @heading-color;
font-weight: bold;
font-size: @font-size-lg;
line-height: @line-height-base;
}
&-view {
width: 100%;
overflow: hidden;
border-radius: @border-radius-base;
table {
width: 100%;
table-layout: fixed;
}
}
&-row {
> th,
> td {
padding-bottom: 16px;
}
&:last-child {
border-bottom: none;
}
}
&-item-label {
color: @heading-color;
font-weight: normal;
font-size: @font-size-base;
line-height: @line-height-base;
white-space: nowrap;
&::after {
position: relative;
top: -0.5px;
margin: 0 8px 0 2px;
content: ' ';
}
}
&-item-colon {
&::after {
content: ':';
}
}
&-item-no-label {
&::after {
margin: 0;
content: '';
}
}
&-item-content {
display: table-cell;
color: @text-color;
font-size: @font-size-base;
line-height: @line-height-base;
}
&-item {
padding-bottom: 0;
> span {
display: inline-block;
}
}
&-middle {
.@{descriptions-prefix-cls}-row {
> th,
> td {
padding-bottom: 12px;
}
}
}
&-small {
.@{descriptions-prefix-cls}-row {
> th,
> td {
padding-bottom: 8px;
}
}
}
&-bordered {
.@{descriptions-prefix-cls}-view {
border: 1px solid @border-color-split;
> table {
table-layout: auto;
}
}
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-default-padding;
border-right: 1px solid @border-color-split;
&:last-child {
border-right: none;
}
}
.@{descriptions-prefix-cls}-item-label {
background-color: @descriptions-bg;
&::after {
display: none;
}
}
.@{descriptions-prefix-cls}-row {
border-bottom: 1px solid @border-color-split;
&:last-child {
border-bottom: none;
}
}
&.@{descriptions-prefix-cls}-middle {
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-middle-padding;
}
}
&.@{descriptions-prefix-cls}-small {
.@{descriptions-prefix-cls}-item-label,
.@{descriptions-prefix-cls}-item-content {
padding: @descriptions-small-padding;
}
}
}
}

View File

@ -139,6 +139,8 @@ import { default as Empty } from './empty';
import { default as Result } from './result';
import { default as Descriptions } from './descriptions';
const components = [
Base,
Affix,
@ -198,6 +200,7 @@ const components = [
ConfigProvider,
Empty,
Result,
Descriptions,
];
const install = function(Vue) {
@ -283,6 +286,7 @@ export {
ConfigProvider,
Empty,
Result,
Descriptions,
};
export default {

View File

@ -56,3 +56,4 @@ import './config-provider/style';
import './empty/style';
import './statistic/style';
import './result/style';
import './descriptions/style';

View File

@ -174,6 +174,9 @@
@checkbox-check-color: #fff;
@checkbox-border-width: @border-width-base;
// Descriptions
@descriptions-bg: #fafafa;
// Empty
@empty-font-size: @font-size-base;

View File

@ -62,6 +62,7 @@ import {
Empty,
Base,
Result,
Descriptions,
} from 'ant-design-vue';
Vue.prototype.$message = message;
@ -132,6 +133,7 @@ Vue.use(Comment);
Vue.use(ConfigProvider);
Vue.use(Empty);
Vue.use(Result);
Vue.use(Descriptions);
/* v1.1.2 registration methods */
// Vue.component(Affix.name, Affix) // a-affix

View File

@ -364,4 +364,10 @@ export default {
type: 'Data Display',
title: 'Statistic',
},
descriptions: {
category: 'Components',
subtitle: '描述列表',
type: 'Data Display',
title: 'Descriptions'
}
};

View File

@ -463,4 +463,12 @@ export default [
path: 'result-cn',
component: () => import('../components/result/demo/index.vue'),
},
{
path: 'descriptions',
component: () => import('../components/descriptions/demo/index.vue'),
},
{
path: 'descriptions-cn',
component: () => import('../components/descriptions/demo/index.vue'),
},
];

View File

@ -63,6 +63,7 @@ Array [
"Comment",
"ConfigProvider",
"Empty",
"Descriptions",
"default",
]
`;

View File

@ -62,6 +62,7 @@ import { Timeline } from './timeline/timeline';
import { Tooltip } from './tootip/tooltip';
import { Upload } from './upload';
import { Result } from './result';
import { Descriptions } from './descriptions/descriptions'
/**
* Install all ant-design-vue components into Vue.
@ -131,4 +132,5 @@ export {
Drawer,
Skeleton,
Result,
Descriptions,
};

View File

@ -0,0 +1,20 @@
// Project: https://github.com/vueComponent/ant-design-vue
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from '../component';
export declare class DescriptionsItem extends AntdComponent {
/**
* the label of descriptions item
* @type any
*/
label: any;
/**
* can be set to small large or omitted
* @default 1
* @type number
*/
span: number;
}

57
types/descriptions/descriptions.d.ts vendored Normal file
View File

@ -0,0 +1,57 @@
// Project: https://github.com/vueComponent/ant-design-vue
// Definitions by: akki-jat <https://github.com/akki-jat>
// Definitions: https://github.com/vueComponent/ant-design-vue/types
import { AntdComponent } from '../component';
import { DescriptionsItem } from './descriptions-item';
export declare class Descriptions extends AntdComponent {
static Item: typeof DescriptionsItem;
/**
* descriptions size type
* @default 'default'
* @type string
*/
size: 'default' | 'middle' | 'small';
/**
* custom prefixCls
* @type string
*/
prefixCls: string;
/**
* whether descriptions have border
* @default false
* @type boolean
*/
bordered: boolean;
/**
* custom title
* @type any
*/
title: any;
/**
* the number of descriptionsitem in one line
* @default 3
* @type number | object
*/
column: number | object;
/**
* descriptions layout
* @default 'horizontal'
* @type string
*/
layout: 'horizontal' | 'vertical';
/**
* whether have colon in descriptionsitem
* @default true
* @type boolean
*/
colon: boolean;
}