Descriptions: add description component (#21129)

This commit is contained in:
好多大米 2021-07-08 15:26:00 +08:00 committed by GitHub
parent 68e07ca6da
commit 034da49dd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 1553 additions and 2 deletions

View File

@ -83,5 +83,7 @@
"popconfirm": "./packages/popconfirm/index.js",
"skeleton": "./packages/skeleton/index.js",
"skeleton-item": "./packages/skeleton-item/index.js",
"empty": "./packages/empty/index.js"
"empty": "./packages/empty/index.js",
"descriptions": "./packages/description/index.js",
"descriptions-item": "./packages/description-item/index.js"
}

View File

@ -0,0 +1,13 @@
.demo-block.demo-descriptions {
.margin-top {
margin-top: 20px;
}
.my-label {
background: #E1F3D8;
}
.my-content {
background: #FDE2E2;
}
}

View File

@ -45,4 +45,5 @@
@import "./avatar.scss";
@import "./drawer.scss";
@import "./skeleton.scss";
@import "./descriptions.scss";

View File

@ -0,0 +1,191 @@
## Descriptions
Display multiple fields in list form.
### Basic usage
:::demo
```html
<el-descriptions title="User Info">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Sizes
:::demo
```html
<template>
<el-radio-group v-model="size">
<el-radio label="">Default</el-radio>
<el-radio label="medium">Medium</el-radio>
<el-radio label="small">Small</el-radio>
<el-radio label="mini">Mini</el-radio>
</el-radio-group>
<el-descriptions class="margin-top" title="With border" :column="3" :size="size" border>
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-user"></i>
Username
</template>
kooriookami
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-mobile-phone"></i>
Telephone
</template>
18100000000
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-location-outline"></i>
Place
</template>
Suzhou
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-tickets"></i>
Remarks
</template>
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-office-building"></i>
Address
</template>
No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province
</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Without border" :column="3" :size="size">
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
</template>
<script>
export default {
data () {
return {
size: ''
};
}
}
</script>
```
:::
### Vertical List
:::demo
```html
<el-descriptions title="Vertical list with border" direction="vertical" :column="4" border>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Vertical list without border" :column="4" direction="vertical">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Customized Style
:::demo
```html
<el-descriptions title="Customized style list" :column="3" border>
<el-descriptions-item label="Username" label-class-name="my-label" content-class-name="my-content">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address" :content-style="{'text-align': 'right'}">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<style>
.my-label {
background: #E1F3D8;
}
.my-content {
background: #FDE2E2;
}
</style>
```
:::
### Descriptions Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| border | with or without border | boolean | — | false |
| column | numbers of `Descriptions Item` in one line | number | — | 3 |
| direction | direction of list | string | vertical / horizontal | horizontal |
| size | size of list | string | medium / small / mini | — |
| title | title text, display on the top left | string | — | — |
| extra | extra text, display on the top right | string | — | — |
| colon | change default props colon value of Descriptions Item | boolean | — | true |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Slots
| Name | Description |
|------|--------|
| title | custom title, display on the top left |
| extra | custom extra area, display on the top right |
### Descriptions Item Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| label | label text | string | — | — |
| span | colspan of column | number | — | 1 |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Item Slots
| Name | Description |
|------|--------|
| label | custom label |

View File

@ -0,0 +1,191 @@
## Descriptions
Display multiple fields in list form.
### Basic usage
:::demo
```html
<el-descriptions title="User Info">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Sizes
:::demo
```html
<template>
<el-radio-group v-model="size">
<el-radio label="">Default</el-radio>
<el-radio label="medium">Medium</el-radio>
<el-radio label="small">Small</el-radio>
<el-radio label="mini">Mini</el-radio>
</el-radio-group>
<el-descriptions class="margin-top" title="With border" :column="3" :size="size" border>
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-user"></i>
Username
</template>
kooriookami
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-mobile-phone"></i>
Telephone
</template>
18100000000
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-location-outline"></i>
Place
</template>
Suzhou
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-tickets"></i>
Remarks
</template>
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-office-building"></i>
Address
</template>
No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province
</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Without border" :column="3" :size="size">
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
</template>
<script>
export default {
data () {
return {
size: ''
};
}
}
</script>
```
:::
### Vertical List
:::demo
```html
<el-descriptions title="Vertical list with border" direction="vertical" :column="4" border>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Vertical list without border" :column="4" direction="vertical">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Customized Style
:::demo
```html
<el-descriptions title="Customized style list" :column="3" border>
<el-descriptions-item label="Username" label-class-name="my-label" content-class-name="my-content">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address" :content-style="{'text-align': 'right'}">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<style>
.my-label {
background: #E1F3D8;
}
.my-content {
background: #FDE2E2;
}
</style>
```
:::
### Descriptions Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| border | with or without border | boolean | — | false |
| column | numbers of `Descriptions Item` in one line | number | — | 3 |
| direction | direction of list | string | vertical / horizontal | horizontal |
| size | size of list | string | medium / small / mini | — |
| title | title text, display on the top left | string | — | — |
| extra | extra text, display on the top right | string | — | — |
| colon | change default props colon value of Descriptions Item | boolean | — | true |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Slots
| Name | Description |
|------|--------|
| title | custom title, display on the top left |
| extra | custom extra area, display on the top right |
### Descriptions Item Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| label | label text | string | — | — |
| span | colspan of column | number | — | 1 |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Item Slots
| Name | Description |
|------|--------|
| label | custom label |

View File

@ -0,0 +1,191 @@
## Descriptions
Display multiple fields in list form.
### Basic usage
:::demo
```html
<el-descriptions title="User Info">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Sizes
:::demo
```html
<template>
<el-radio-group v-model="size">
<el-radio label="">Default</el-radio>
<el-radio label="medium">Medium</el-radio>
<el-radio label="small">Small</el-radio>
<el-radio label="mini">Mini</el-radio>
</el-radio-group>
<el-descriptions class="margin-top" title="With border" :column="3" :size="size" border>
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-user"></i>
Username
</template>
kooriookami
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-mobile-phone"></i>
Telephone
</template>
18100000000
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-location-outline"></i>
Place
</template>
Suzhou
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-tickets"></i>
Remarks
</template>
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-office-building"></i>
Address
</template>
No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province
</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Without border" :column="3" :size="size">
<template slot="extra">
<el-button type="primary" size="small">Operation</el-button>
</template>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
</template>
<script>
export default {
data () {
return {
size: ''
};
}
}
</script>
```
:::
### Vertical List
:::demo
```html
<el-descriptions title="Vertical list with border" direction="vertical" :column="4" border>
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="Vertical list without border" :column="4" direction="vertical">
<el-descriptions-item label="Username">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place" :span="2">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
```
:::
### Customized Style
:::demo
```html
<el-descriptions title="Customized style list" :column="3" border>
<el-descriptions-item label="Username" label-class-name="my-label" content-class-name="my-content">kooriookami</el-descriptions-item>
<el-descriptions-item label="Telephone">18100000000</el-descriptions-item>
<el-descriptions-item label="Place">Suzhou</el-descriptions-item>
<el-descriptions-item label="Remarks">
<el-tag size="small">School</el-tag>
</el-descriptions-item>
<el-descriptions-item label="Address" :content-style="{'text-align': 'right'}">No.1188, Wuzhong Avenue, Wuzhong District, Suzhou, Jiangsu Province</el-descriptions-item>
</el-descriptions>
<style>
.my-label {
background: #E1F3D8;
}
.my-content {
background: #FDE2E2;
}
</style>
```
:::
### Descriptions Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| border | with or without border | boolean | — | false |
| column | numbers of `Descriptions Item` in one line | number | — | 3 |
| direction | direction of list | string | vertical / horizontal | horizontal |
| size | size of list | string | medium / small / mini | — |
| title | title text, display on the top left | string | — | — |
| extra | extra text, display on the top right | string | — | — |
| colon | change default props colon value of Descriptions Item | boolean | — | true |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Slots
| Name | Description |
|------|--------|
| title | custom title, display on the top left |
| extra | custom extra area, display on the top right |
### Descriptions Item Attributes
| Attribute | Description | Type | Accepted Values | Default |
|------------- |---------------- |---------------- |---------------------- |-------- |
| label | label text | string | — | — |
| span | colspan of column | number | — | 1 |
| labelClassName | custom label class name | string | — | — |
| contentClassName | custom content class name | string | — | — |
| labelStyle | custom label style | object | — | — |
| contentStyle | custom content style | object | — | — |
### Descriptions Item Slots
| Name | Description |
|------|--------|
| label | custom label |

View File

@ -0,0 +1,191 @@
## Descriptions 描述列表
列表形式展示多个字段。
### 基础用法
:::demo
```html
<el-descriptions title="用户信息">
<el-descriptions-item label="用户名">kooriookami</el-descriptions-item>
<el-descriptions-item label="手机号">18100000000</el-descriptions-item>
<el-descriptions-item label="居住地">苏州市</el-descriptions-item>
<el-descriptions-item label="备注">
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item label="联系地址">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item>
</el-descriptions>
```
:::
### 不同尺寸
:::demo
```html
<template>
<el-radio-group v-model="size">
<el-radio label="">默认</el-radio>
<el-radio label="medium">中等</el-radio>
<el-radio label="small">小型</el-radio>
<el-radio label="mini">超小</el-radio>
</el-radio-group>
<el-descriptions class="margin-top" title="带边框列表" :column="3" :size="size" border>
<template slot="extra">
<el-button type="primary" size="small">操作</el-button>
</template>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-user"></i>
用户名
</template>
kooriookami
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-mobile-phone"></i>
手机号
</template>
18100000000
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-location-outline"></i>
居住地
</template>
苏州市
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-tickets"></i>
备注
</template>
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label">
<i class="el-icon-office-building"></i>
联系地址
</template>
江苏省苏州市吴中区吴中大道 1188 号
</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="无边框列表" :column="3" :size="size">
<template slot="extra">
<el-button type="primary" size="small">操作</el-button>
</template>
<el-descriptions-item label="用户名">kooriookami</el-descriptions-item>
<el-descriptions-item label="手机号">18100000000</el-descriptions-item>
<el-descriptions-item label="居住地">苏州市</el-descriptions-item>
<el-descriptions-item label="备注">
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item label="联系地址">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item>
</el-descriptions>
</template>
<script>
export default {
data () {
return {
size: ''
};
}
}
</script>
```
:::
### 垂直列表
:::demo
```html
<el-descriptions title="垂直带边框列表" direction="vertical" :column="4" border>
<el-descriptions-item label="用户名">kooriookami</el-descriptions-item>
<el-descriptions-item label="手机号">18100000000</el-descriptions-item>
<el-descriptions-item label="居住地" :span="2">苏州市</el-descriptions-item>
<el-descriptions-item label="备注">
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item label="联系地址">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item>
</el-descriptions>
<el-descriptions class="margin-top" title="垂直无边框列表" :column="4" direction="vertical">
<el-descriptions-item label="用户名">kooriookami</el-descriptions-item>
<el-descriptions-item label="手机号">18100000000</el-descriptions-item>
<el-descriptions-item label="居住地" :span="2">苏州市</el-descriptions-item>
<el-descriptions-item label="备注">
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item label="联系地址">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item>
</el-descriptions>
```
:::
### 自定义样式
:::demo
```html
<el-descriptions title="自定义样式列表" :column="3" border>
<el-descriptions-item label="用户名" label-class-name="my-label" content-class-name="my-content">kooriookami</el-descriptions-item>
<el-descriptions-item label="手机号">18100000000</el-descriptions-item>
<el-descriptions-item label="居住地">苏州市</el-descriptions-item>
<el-descriptions-item label="备注">
<el-tag size="small">学校</el-tag>
</el-descriptions-item>
<el-descriptions-item label="联系地址" :contentStyle="{'text-align': 'right'}">江苏省苏州市吴中区吴中大道 1188 号</el-descriptions-item>
</el-descriptions>
<style>
.my-label {
background: #E1F3D8;
}
.my-content {
background: #FDE2E2;
}
</style>
```
:::
### Descriptions Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------------- |---------------- |---------------- |---------------------- |-------- |
| border | 是否带有边框 | boolean | — | false |
| column | 一行 `Descriptions Item` 的数量 | number | — | 3 |
| direction | 排列的方向 | string | vertical / horizontal | horizontal |
| size | 列表的尺寸 | string | medium / small / mini | — |
| title | 标题文本,显示在左上方 | string | — | — |
| extra | 操作区文本,显示在右上方 | string | — | — |
| colon | 是否显示冒号 | boolean | — | true |
| labelClassName | 自定义标签类名 | string | — | — |
| contentClassName | 自定义内容类名 | string | — | — |
| labelStyle | 自定义标签样式 | object | — | — |
| contentStyle | 自定义内容样式 | object | — | — |
### Descriptions Slots
| Name | 说明 |
|------|--------|
| title | 自定义标题,显示在左上方 |
| extra | 自定义操作区,显示在右上方 |
### Descriptions Item Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|------------- |---------------- |---------------- |---------------------- |-------- |
| label | 标签文本 | string | — | — |
| span | 列的数量 | number | — | 1 |
| labelClassName | 自定义标签类名 | string | — | — |
| contentClassName | 自定义内容类名 | string | — | — |
| labelStyle | 自定义标签样式 | object | — | — |
| contentStyle | 自定义内容样式 | object | — | — |
### Descriptions Item Slots
| Name | 说明 |
|------|--------|
| label | 自定义标签文本 |

View File

@ -184,6 +184,10 @@
{
"path": "/empty",
"title": "Empty 空状态"
},
{
"path": "/descriptions",
"title": "Descriptions 描述列表"
}
]
},
@ -486,6 +490,10 @@
{
"path": "/empty",
"title": "Empty"
},
{
"path": "/descriptions",
"title": "Descriptions"
}
]
},
@ -792,6 +800,10 @@
{
"path": "/empty",
"title": "Empty"
},
{
"path": "/descriptions",
"title": "Descriptions"
}
]
},
@ -1098,6 +1110,10 @@
{
"path": "/empty",
"title": "Empty"
},
{
"path": "/descriptions",
"title": "Descriptions"
}
]
},

View File

@ -0,0 +1,8 @@
import DescriptionsItem from '../descriptions/src/description-item';
/* istanbul ignore next */
DescriptionsItem.install = function install(Vue) {
Vue.component(DescriptionsItem.name, DescriptionsItem);
};
export default DescriptionsItem;

View File

@ -0,0 +1,8 @@
import Descriptions from './src/index';
/* istanbul ignore next */
Descriptions.install = function install(Vue) {
Vue.component(Descriptions.name, Descriptions);
};
export default Descriptions;

View File

@ -0,0 +1,30 @@
export default {
name: 'ElDescriptionsItem',
props: {
label: {
type: String,
default: ''
},
span: {
type: Number,
default: 1
},
contentClassName: {
type: String,
default: ''
},
contentStyle: {
type: Object
},
labelClassName: {
type: String,
default: ''
},
labelStyle: {
type: Object
}
},
render() {
return null;
}
};

View File

@ -0,0 +1,115 @@
export default {
name: 'ElDescriptionsRow',
props: {
row: {
type: Array
}
},
inject: ['elDescriptions'],
render(h) {
const { elDescriptions } = this;
const row = (this.row || []).map(item => {
return {
...item,
label: item.slots.label || item.props.label,
...['labelClassName', 'contentClassName', 'labelStyle', 'contentStyle'].reduce((res, key) => {
res[key] = item.props[key] || elDescriptions[key];
return res;
}, {})
};
});
if (elDescriptions.direction === 'vertical') {
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item => {
return (
<th
class={{
'el-descriptions-item__label': true,
'has-colon': elDescriptions.border ? false : elDescriptions.colon,
'is-bordered-label': elDescriptions.border,
[item.labelClassName]: true
}}
style={item.labelStyle}
colSpan={item.props.span}
>{item.label}</th>
);
})
}
</tr>
<tr class="el-descriptions-row">
{
row.map(item =>{
return (
<td
class="el-descriptions-item__content"
class={['el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
colSpan={item.props.span}
>{item.slots.default}</td>
);
})
}
</tr>
</tbody>
);
}
if (elDescriptions.border) {
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item=> {
return ([
<th
class={{
'el-descriptions-item__label': true,
'is-bordered-label': elDescriptions.border,
[item.labelClassName]: true
}}
style={item.labelStyle}
colSpan="1"
>{item.label}</th>,
<td
class={['el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
colSpan={item.props.span * 2 - 1}
>{item.slots.default}</td>
]);
})
}
</tr>
</tbody>
);
}
return (
<tbody>
<tr class="el-descriptions-row">
{
row.map(item=> {
return (
<td class="el-descriptions-item" colSpan={item.props.span}>
<div class="el-descriptions-item__container">
<span
class={{
'el-descriptions-item__label': true,
'has-colon': elDescriptions.colon,
[item.labelClassName]: true
}}
style={item.labelStyle}
>{item.props.label}</span>
<span
class={['el-descriptions-item__content', item.contentClassName]}
style={item.contentStyle}
>{item.slots.default}</span>
</div>
</td>);
})
}
</tr>
</tbody>
);
}
};

View File

@ -0,0 +1,180 @@
import DescriptionsRow from './descriptions-row';
import { isFunction } from 'element-ui/src/utils/types';
export default {
name: 'ElDescriptions',
components: {
[DescriptionsRow.name]: DescriptionsRow
},
props: {
border: {
type: Boolean,
default: false
},
column: {
type: Number,
default: 3
},
direction: {
type: String,
default: 'horizontal'
},
size: {
type: String
// validator: isValidComponentSize,
},
title: {
type: String,
default: ''
},
extra: {
type: String,
default: ''
},
labelStyle: {
type: Object
},
contentStyle: {
type: Object
},
labelClassName: {
type: String,
default: ''
},
contentClassName: {
type: String,
default: ''
},
colon: {
type: Boolean,
default: true
}
},
computed: {
descriptionsSize() {
return this.size || (this.$ELEMENT || {}).size;
}
},
provide() {
return {
elDescriptions: this
};
},
methods: {
getOptionProps(vnode) {
if (vnode.componentOptions) {
const componentOptions = vnode.componentOptions;
const { propsData = {}, Ctor = {} } = componentOptions;
const props = (Ctor.options || {}).props || {};
const res = {};
for (const k in props) {
const v = props[k];
const defaultValue = v.default;
if (defaultValue !== undefined) {
res[k] = isFunction(defaultValue) ? defaultValue.call(vnode) : defaultValue;
}
}
return { ...res, ...propsData };
}
return {};
},
getSlots(vnode) {
let componentOptions = vnode.componentOptions || {};
const children = vnode.children || componentOptions.children || [];
const slots = {};
children.forEach(child => {
if (!this.isEmptyElement(child)) {
const name = (child.data && child.data.slot) || 'default';
slots[name] = slots[name] || [];
if (child.tag === 'template') {
slots[name].push(child.children);
} else {
slots[name].push(child);
}
}
});
return { ...slots };
},
isEmptyElement(c) {
return !(c.tag || (c.text && c.text.trim() !== ''));
},
filledNode(node, span, count, isLast = false) {
if (!node.props) {
node.props = {};
}
if (span > count) {
node.props.span = count;
}
if (isLast) {
// set the max span, cause of the last td
node.props.span = count;
}
return node;
},
getRows() {
const children = ((this.$slots.default || []).filter(vnode => vnode.tag &&
vnode.componentOptions && vnode.componentOptions.Ctor.options.name === 'ElDescriptionsItem'));
const nodes = children.map(vnode => {
return {
props: this.getOptionProps(vnode),
slots: this.getSlots(vnode),
vnode
};
});
const rows = [];
let temp = [];
let count = this.column;
nodes.forEach((node, index) => {
const span = node.props.span || 1;
if (index === children.length - 1) {
temp.push(this.filledNode(node, span, count, true));
rows.push(temp);
return;
}
if (span < count) {
count -= span;
temp.push(node);
} else {
temp.push(this.filledNode(node, span, count));
rows.push(temp);
count = this.column;
temp = [];
}
});
return rows;
}
},
render() {
const { title, extra, border, descriptionsSize, $slots } = this;
const rows = this.getRows();
return (
<div class="el-descriptions">
{
(title || extra || $slots.title || $slots.extra)
? <div class="el-descriptions__header">
<div class="el-descriptions__title">
{ $slots.title ? $slots.title : title}
</div>
<div class="el-descriptions__extra">
{ $slots.extra ? $slots.extra : extra }
</div>
</div>
: null
}
<div class="el-descriptions__body">
<table class={[{'is-bordered': border}, descriptionsSize ? `el-descriptions--${descriptionsSize}` : '']}>
{rows.map(row => (
<DescriptionsRow row={row}></DescriptionsRow>
))}
</table>
</div>
</div>
);
}
};

View File

@ -971,6 +971,13 @@ $--empty-image-width: 160px !default;
$--empty-description-margin-top: 20px !default;
$--empty-bottom-margin-top: 20px !default;
/* Descriptions
-------------------------- */
$--descriptions-header-margin-bottom: 20px !default;
$--descriptions-title-font-size: 16px !default;
$--descriptions-table-border: 1px solid $--border-color-lighter !default;
$--descriptions-item-bordered-label-background: #fafafa !default;
/* Skeleton
--------------------------*/
$--skeleton-color: #f2f2f2 !default;

View File

@ -0,0 +1,32 @@
@import 'mixins/mixins';
@import 'common/var';
@include b(descriptions-item) {
@include e(container) {
display: flex;
}
@include e(label) {
&.has-colon {
&::after {
content: ':';
position: relative;
top: -0.5px;
}
}
&.is-bordered-label {
font-weight: bold;
color: $--color-text-secondary;
background: $--descriptions-item-bordered-label-background;
}
&:not(.is-bordered-label) {
margin-right: 10px;
}
}
@include e(content) {
}
}

View File

@ -0,0 +1,111 @@
@import 'mixins/mixins';
@import 'common/var';
@import 'descriptions-item';
@include b(descriptions) {
box-sizing: border-box;
font-size: $--font-size-base;
color: $--color-text-primary;
@include e(header) {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: $--descriptions-header-margin-bottom;
@include e(title) {
font-size: $--descriptions-title-font-size;
font-weight: bold;
}
}
@include e(body) {
color: $--color-text-regular;
background-color: $--color-white;
table {
border-collapse: collapse;
width: 100%;
table-layout: fixed;
th, td {
box-sizing: border-box;
text-align: left;
font-weight: normal;
line-height: 1.5;
@include when(left) {
text-align: left;
}
@include when(center) {
text-align: center;
}
@include when(right) {
text-align: right;
}
}
}
}
.is-bordered {
table-layout: auto;
th, td {
border: $--descriptions-table-border;
padding: 12px 10px;
}
}
:not(.is-bordered) {
th, td {
padding-bottom: 12px;
}
}
@include m(medium) {
&.is-bordered {
th, td {
padding: 10px;
}
}
&:not(.is-bordered) {
th, td {
padding-bottom: 10px;
}
}
}
@include m(small) {
font-size: 12px;
&.is-bordered {
th, td {
padding: 8px 10px;
}
}
&:not(.is-bordered) {
th, td {
padding-bottom: 8px;
}
}
}
@include m(mini) {
font-size: 12px;
&.is-bordered {
th, td {
padding: 6px 10px;
}
}
&:not(.is-bordered) {
th, td {
padding-bottom: 6px;
}
}
}
}

View File

@ -81,3 +81,5 @@
@import "./skeleton.scss";
@import "./skeleton-item.scss";
@import "./empty.scss";
@import "./descriptions.scss";
@import "./descriptions-item.scss";

View File

@ -85,6 +85,8 @@ import Popconfirm from '../packages/popconfirm/index.js';
import Skeleton from '../packages/skeleton/index.js';
import SkeletonItem from '../packages/skeleton-item/index.js';
import Empty from '../packages/empty/index.js';
import Descriptions from '../packages/descriptions/index.js';
import DescriptionsItem from '../packages/descriptions-item/index.js';
import locale from 'element-ui/src/locale';
import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
@ -169,6 +171,8 @@ const components = [
Skeleton,
SkeletonItem,
Empty,
Descriptions,
DescriptionsItem,
CollapseTransition
];
@ -293,5 +297,7 @@ export default {
Popconfirm,
Skeleton,
SkeletonItem,
Empty
Empty,
Descriptions,
DescriptionsItem
};

View File

@ -0,0 +1,159 @@
// import Descriptions from 'packages/descriptions';
// import DescriptionsItem from '../src/description-item';
// import { createTest, destroyVM, createVue, waitImmediate, wait} from '../util';
import { destroyVM, createVue, waitImmediate } from '../util';
describe('Descriptions', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('render test', () => {
vm = createVue(
{
template: `
<el-descriptions title="title" extra="extra">
<el-descriptions-item v-for="item in 4"></el-descriptions-item>
</el-descriptions>
`
},
true
);
const el = vm.$el;
expect(el.querySelector('.el-descriptions__title').textContent).to.equal('title');
expect(el.querySelector('.el-descriptions__extra').textContent).to.equal('extra');
expect(el.querySelectorAll('.el-descriptions-item__label').length).to.equal(4);
});
it('should render border props', () => {
vm = createVue(
{
template: `
<el-descriptions border>
<el-descriptions-item v-for="item in 3" :label="item">{{ item }}</el-descriptions-item>
</el-descriptions
`
},
true
);
const el = vm.$el;
expect(Array.from(el.querySelector('table').classList)).to.contain('is-bordered');
});
it('should render class props', () => {
vm = createVue(
{
template: `
<el-descriptions border label-class-name="label-class-name" content-class-name="content-class-name">
<el-descriptions-item v-for="item in 3" :label="item">{{ item }}</el-descriptions-item>
</el-descriptions>
`
},
true);
expect(Array.from(vm.$el.querySelector('.el-descriptions-item__label').classList)).to.contain('label-class-name');
expect(Array.from(vm.$el.querySelector('.el-descriptions-item__content').classList)).to.contain('content-class-name');
});
it('should render column props', async() => {
vm = createVue({
template: `
<el-descriptions :column="5" :border="border">
<el-descriptions-item v-for="item in 10" :label="item">{{ item }}</el-descriptions-item>
</el-descriptions>
`,
data() {
return {
border: false
};
}
}, true);
expect(vm.$el.querySelector('tr').children.length).to.equal(5);
vm.border = true;
await waitImmediate();
expect(vm.$el.querySelector('tr').children.length).to.equal(10);
});
it('should render direction props', async() => {
vm = createVue({
template: `
<el-descriptions :column="5" :direction="direction" border>
<el-descriptions-item v-for="item in 10" :label="item">{{ item }}</el-descriptions-item>
</el-descriptions>
`,
data() {
return {
direction: 'horizontal'
};
}
}, true);
expect(vm.$el.querySelector('tr').children.length).to.equal(10);
expect(vm.$el.querySelectorAll('tr')[0].children[0].innerHTML).to.equal(vm.$el.querySelectorAll('tr')[0].children[1].innerHTML);
vm.direction = 'vertical';
await waitImmediate();
expect(vm.$el.querySelector('tr').children.length).to.equal(5);
expect(vm.$el.querySelectorAll('tr')[0].children[0].innerHTML).to.equal(vm.$el.querySelectorAll('tr')[1].children[0].innerHTML);
});
it('should render title slots', async() => {
vm = createVue({
template: `
<el-descriptions>
<template slot="title">title</template>
<el-descriptions-item v-for="item in 10" :label="item">{{ item }}</el-descriptions-item>
</el-descriptions>
`
}, true);
expect(vm.$el.querySelector('.el-descriptions__title').innerText).to.equal('title');
});
it('should render span props', async() => {
vm = createVue({
template: `
<el-descriptions :column="3">
<el-descriptions-item label="1">1</el-descriptions-item>
<el-descriptions-item label="2" :span="2">2</el-descriptions-item>
<el-descriptions-item label="3">3</el-descriptions-item>
</el-descriptions>
`
}, true);
expect(vm.$el.querySelectorAll('td')[1].getAttribute('colSpan')).to.equal('2');
});
it('re-rendered when slots is updated', async() => {
const CHANGE_VALUE = 'company';
vm = createVue({
template: `
<div>
<el-descriptions v-for="(remark,index) in remarks" :key="index" :title="remark">
<el-descriptions-item label="remark">
<el-tag size="small">{{remark}}</el-tag>
</el-descriptions-item>
</el-descriptions>
<button @click="onClick">click</button>
</div>
`,
data() {
return {
remarks: ['school', 'hospital']
};
},
methods: {
onClick() {
this.$set(this.remarks, 0, CHANGE_VALUE);
}
}
}, true);
vm.$el.querySelector('button').click();
await waitImmediate();
expect(vm.$el.querySelector('.el-tag').innerText).to.equal(CHANGE_VALUE);
});
});

37
types/descriptions-item.d.ts vendored Normal file
View File

@ -0,0 +1,37 @@
import { ElementUIComponent } from './component'
import { VNode } from 'vue'
interface ElDescriptionsItemSlots {
/* label slot: custom label */
label: VNode[]
/* default slot: custom content */
default: VNode[]
[key: string]: VNode[]
}
/** description item. **/
export declare class ElDescriptionsItem extends ElementUIComponent {
/* label text */
label: string
/* the number of columns included */
span: number
/* custom label class name */
labelClassName: string
/* custom content class name */
contentClassName: string
/* custom label style */
labelStyle: object
/* custom content style */
contentStyle: object
$slots: ElDescriptionsItemSlots
}

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

@ -0,0 +1,52 @@
import { ElementUIComponent } from './component'
import { VNode } from 'vue'
interface ElDescriptionsSlots {
/* title slot: custom title, display on the top left */
title: VNode[]
/* title slot: custom extra area, display on the top right */
extra: VNode[]
[key: string]: VNode[]
}
/** Display multiple fields in list form. **/
export declare class ElDescriptions extends ElementUIComponent {
/* with or without border */
border: boolean
/* numbers of Descriptions Item in one line */
column: number
/* direction of list */
direction: 'vertical' | 'horizontal'
/* size of list */
size: 'medium' | 'small' | 'mini'
/* title text, display on the top left */
title: string
/* extra text, display on the top right */
extra: string
/* change default props colon value of Descriptions Item */
colon: boolean
/* custom label class name */
labelClassName: string
/* custom content class name */
contentClassName: string
/* custom label style */
labelStyle: object
/* custom content style */
contentStyle: object
$slots: ElDescriptionsSlots
}

View File

@ -85,6 +85,8 @@ import { ElSkeletonItem } from './skeleton-item'
import { ElCascaderPanel } from './cascader-panel'
import { ElEmpty } from './empty'
import { ElSpinner } from './spinner'
import { ElDescriptions } from './descriptions'
import { ElDescriptionsItem } from './descriptions-item'
export interface InstallationOptions {
locale: any,
@ -364,3 +366,9 @@ export class Empty extends ElEmpty {}
/** Spinner Component */
export class Spinner extends ElSpinner {}
/** Description Component */
export class Descripitions extends ElDescriptions {}
/** Description Item Component */
export class DescripitionsItem extends ElDescriptionsItem {}