mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 22:36:31 +08:00
feat: Descriptions add vertical layout
This commit is contained in:
parent
6d26675947
commit
2a9da95a92
@ -609,3 +609,331 @@ exports[`renders ./components/descriptions/demo/size.md correctly 1`] = `
|
||||
</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
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
UserName
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Telephone
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Live
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Zhou Maomao
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
1810000000
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
Hangzhou, Zhejiang
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Remark
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="2"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Address
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
>
|
||||
empty
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="2"
|
||||
>
|
||||
<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/vertical-border.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-descriptions bordered"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-title"
|
||||
>
|
||||
User Info
|
||||
</div>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Product
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Billing Mode
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Automatic Renewal
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
Cloud Database
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
Prepaid
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
YES
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Order time
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Usage Time
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
2018-04-24 18:00:00
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="5"
|
||||
>
|
||||
2019-04-24 18:00:00
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Status
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="5"
|
||||
>
|
||||
<span
|
||||
class="ant-badge ant-badge-status ant-badge-not-a-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-badge-status-dot ant-badge-status-processing"
|
||||
/>
|
||||
<span
|
||||
class="ant-badge-status-text"
|
||||
>
|
||||
Running
|
||||
</span>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Negotiated Amount
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Discount
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Official Receipts
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
$80.00
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
$20.00
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
>
|
||||
$60.00
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-label"
|
||||
>
|
||||
Config Info
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="5"
|
||||
>
|
||||
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>
|
||||
`;
|
||||
|
@ -100,6 +100,164 @@ exports[`Descriptions column is number 1`] = `
|
||||
</Descriptions>
|
||||
`;
|
||||
|
||||
exports[`Descriptions vertical layout 1`] = `
|
||||
<Descriptions
|
||||
column={
|
||||
Object {
|
||||
"lg": 3,
|
||||
"md": 3,
|
||||
"sm": 2,
|
||||
"xl": 3,
|
||||
"xs": 1,
|
||||
"xxl": 3,
|
||||
}
|
||||
}
|
||||
layout="vertical"
|
||||
size="default"
|
||||
>
|
||||
<div
|
||||
className="ant-descriptions"
|
||||
>
|
||||
<div
|
||||
className="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="label-0"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-label"
|
||||
key="label"
|
||||
>
|
||||
Product
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="content-0"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-content"
|
||||
key="content"
|
||||
>
|
||||
Cloud Database
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="label-1"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-label"
|
||||
key="label"
|
||||
>
|
||||
Billing
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="content-1"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-content"
|
||||
key="content"
|
||||
>
|
||||
Prepaid
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="label-2"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-label"
|
||||
key="label"
|
||||
>
|
||||
time
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="content-2"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-content"
|
||||
key="content"
|
||||
>
|
||||
18:00:00
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="label-3"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-label"
|
||||
key="label"
|
||||
>
|
||||
Amount
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
className="ant-descriptions-row"
|
||||
key="content-3"
|
||||
>
|
||||
<td
|
||||
className="ant-descriptions-item"
|
||||
colSpan={1}
|
||||
>
|
||||
<span
|
||||
className="ant-descriptions-item-content"
|
||||
key="content"
|
||||
>
|
||||
$80.00
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</Descriptions>
|
||||
`;
|
||||
|
||||
exports[`Descriptions when item is rendered conditionally 1`] = `
|
||||
<Descriptions
|
||||
column={
|
||||
|
@ -124,4 +124,18 @@ describe('Descriptions', () => {
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
wrapper.unmount();
|
||||
});
|
||||
|
||||
it('vertical layout', () => {
|
||||
// eslint-disable-next-line global-require
|
||||
const wrapper = mount(
|
||||
<Descriptions layout="vertical">
|
||||
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
|
||||
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
|
||||
<Descriptions.Item label="Amount">$80.00</Descriptions.Item>
|
||||
</Descriptions>,
|
||||
);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
wrapper.unmount();
|
||||
});
|
||||
});
|
||||
|
50
components/descriptions/demo/vertical-border.md
Normal file
50
components/descriptions/demo/vertical-border.md
Normal file
@ -0,0 +1,50 @@
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 垂直带边框的
|
||||
en-US: Vertical border
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
带边框和背景颜色列表。
|
||||
|
||||
## en-US
|
||||
|
||||
Descriptions with border and background color.
|
||||
|
||||
```jsx
|
||||
import { Descriptions, Badge } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Descriptions title="User Info" layout="vertical" bordered>
|
||||
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
|
||||
<Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
|
||||
<Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
|
||||
<Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item>
|
||||
<Descriptions.Item label="Usage Time" span={3}>
|
||||
2019-04-24 18:00:00
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Status" span={3}>
|
||||
<Badge status="processing" text="Running" />
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Negotiated Amount">$80.00</Descriptions.Item>
|
||||
<Descriptions.Item label="Discount">$20.00</Descriptions.Item>
|
||||
<Descriptions.Item label="Official Receipts">$60.00</Descriptions.Item>
|
||||
<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 />
|
||||
</Descriptions.Item>
|
||||
</Descriptions>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
31
components/descriptions/demo/vertical.md
Normal file
31
components/descriptions/demo/vertical.md
Normal file
@ -0,0 +1,31 @@
|
||||
---
|
||||
order: 4
|
||||
title:
|
||||
zh-CN: 垂直
|
||||
en-US: Vertical
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
简单的展示。
|
||||
|
||||
## en-US
|
||||
|
||||
Simplest Usage.
|
||||
|
||||
```jsx
|
||||
import { Descriptions } from 'antd';
|
||||
|
||||
ReactDOM.render(
|
||||
<Descriptions title="User Info" layout="vertical">
|
||||
<Descriptions.Item label="UserName">Zhou Maomao</Descriptions.Item>
|
||||
<Descriptions.Item label="Telephone">1810000000</Descriptions.Item>
|
||||
<Descriptions.Item label="Live">Hangzhou, Zhejiang</Descriptions.Item>
|
||||
<Descriptions.Item label="Remark">empty</Descriptions.Item>
|
||||
<Descriptions.Item label="Address">
|
||||
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
|
||||
</Descriptions.Item>
|
||||
</Descriptions>,
|
||||
mountNode,
|
||||
);
|
||||
```
|
@ -21,6 +21,7 @@ Commonly displayed on the details page.
|
||||
| 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` | false |
|
||||
| layout | Define description layout | `horizontal | vertical` | 'horizontal' |
|
||||
|
||||
### DescriptionItem
|
||||
|
||||
|
@ -27,6 +27,7 @@ export interface DescriptionsProps {
|
||||
children?: React.ReactNode;
|
||||
title?: string;
|
||||
column?: number | Partial<Record<Breakpoint, number>>;
|
||||
layout?: 'horizontal' | 'vertical';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,11 +102,48 @@ const renderCol = (child: React.ReactElement<DescriptionsItemProps>, bordered: b
|
||||
);
|
||||
};
|
||||
|
||||
const renderLabelCol = (child: React.ReactElement<DescriptionsItemProps>, bordered: boolean) => {
|
||||
const { prefixCls, label, span = 1 } = child.props;
|
||||
if (bordered) {
|
||||
return (
|
||||
<td className={`${prefixCls}-item-label`} key="label">
|
||||
{label}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<td colSpan={span} className={`${prefixCls}-item`}>
|
||||
<span className={`${prefixCls}-item-label`} key="label">
|
||||
{label}
|
||||
</span>
|
||||
</td>
|
||||
);
|
||||
};
|
||||
|
||||
const renderContentCol = (child: React.ReactElement<DescriptionsItemProps>, bordered: boolean) => {
|
||||
const { prefixCls, children, span = 1 } = child.props;
|
||||
if (bordered) {
|
||||
return (
|
||||
<td className={`${prefixCls}-item-content`} key="content" colSpan={span * 2 - 1}>
|
||||
{children}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<td colSpan={span} className={`${prefixCls}-item`}>
|
||||
<span className={`${prefixCls}-item-content`} key="content">
|
||||
{children}
|
||||
</span>
|
||||
</td>
|
||||
);
|
||||
};
|
||||
|
||||
const renderRow = (
|
||||
children: React.ReactElement<DescriptionsItemProps>[],
|
||||
index: number,
|
||||
{ prefixCls, column, isLast }: { prefixCls: string; column: number; isLast: boolean },
|
||||
bordered: boolean,
|
||||
layout: string,
|
||||
) => {
|
||||
// copy children,prevent changes to incoming parameters
|
||||
const childrenArray = [...children];
|
||||
@ -116,6 +154,31 @@ const renderRow = (
|
||||
span,
|
||||
});
|
||||
}
|
||||
|
||||
if (layout === 'vertical') {
|
||||
const cloneLabelChildren = React.Children.map(
|
||||
childrenArray,
|
||||
(childrenItem: React.ReactElement<DescriptionsItemProps>) => {
|
||||
return renderLabelCol(childrenItem, bordered);
|
||||
},
|
||||
);
|
||||
const cloneContentChildren = React.Children.map(
|
||||
childrenArray,
|
||||
(childrenItem: React.ReactElement<DescriptionsItemProps>) => {
|
||||
return renderContentCol(childrenItem, bordered);
|
||||
},
|
||||
);
|
||||
return [
|
||||
<tr className={`${prefixCls}-row`} key={`label-${index}`}>
|
||||
{cloneLabelChildren}
|
||||
{renderLabelCol(lastChildren, bordered)}
|
||||
</tr>,
|
||||
<tr className={`${prefixCls}-row`} key={`content-${index}`}>
|
||||
{cloneContentChildren}
|
||||
{renderContentCol(lastChildren, bordered)}
|
||||
</tr>,
|
||||
];
|
||||
}
|
||||
const cloneChildren = React.Children.map(
|
||||
childrenArray,
|
||||
(childrenItem: React.ReactElement<DescriptionsItemProps>) => {
|
||||
@ -202,6 +265,7 @@ class Descriptions extends React.Component<
|
||||
size,
|
||||
children,
|
||||
bordered = false,
|
||||
layout = 'horizontal',
|
||||
} = this.props;
|
||||
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
|
||||
|
||||
@ -242,6 +306,7 @@ class Descriptions extends React.Component<
|
||||
isLast: index + 1 === childrenArray.length,
|
||||
},
|
||||
bordered,
|
||||
layout,
|
||||
),
|
||||
)}
|
||||
</tbody>
|
||||
|
@ -22,6 +22,7 @@ cols: 1
|
||||
| bordered | 是否展示边框 | boolean | false |
|
||||
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 |
|
||||
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default | middle | small` | false |
|
||||
| layout | 描述布局 | `horizontal | vertical` | 'horizontal' |
|
||||
|
||||
### DescriptionItem
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user