feat: Descriptions implement items API (#43483)

* feat: descriptions implement items api

* docs: add jsx debug demo

* refactor: add useRow hook

* Update components/descriptions/index.tsx

Co-authored-by: Wuxh <wxh1220@gmail.com>
Signed-off-by: 红果汁 <pingfj77@gmail.com>

* Update components/descriptions/index.zh-CN.md

Co-authored-by: Wuxh <wxh1220@gmail.com>
Signed-off-by: 红果汁 <pingfj77@gmail.com>

* Update components/descriptions/index.en-US.md

Co-authored-by: Wuxh <wxh1220@gmail.com>
Signed-off-by: 红果汁 <pingfj77@gmail.com>

* fix: decrease in coverage

* refactor: enhancement code

---------

Signed-off-by: 红果汁 <pingfj77@gmail.com>
Co-authored-by: Wuxh <wxh1220@gmail.com>
This commit is contained in:
红果汁 2023-07-17 14:48:03 +08:00 committed by GitHub
parent b0d69a6878
commit ecb36840bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1503 additions and 613 deletions

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import type { DescriptionsItemType } from '.';
import Cell from './Cell';
import type { DescriptionsContextProps } from './DescriptionsContext';
import DescriptionsContext from './DescriptionsContext';
import type { DescriptionsItemProps } from './Item';
interface CellConfig {
component: string | [string, string];
@ -12,7 +12,7 @@ interface CellConfig {
}
function renderCells(
items: React.ReactElement<DescriptionsItemProps>[],
items: DescriptionsItemType[],
{ colon, prefixCls, bordered }: RowProps,
{
component,
@ -26,16 +26,14 @@ function renderCells(
return items.map(
(
{
props: {
label,
children,
prefixCls: itemPrefixCls = prefixCls,
className,
style,
labelStyle,
contentStyle,
span = 1,
},
label,
children,
prefixCls: itemPrefixCls = prefixCls,
className,
style,
labelStyle,
contentStyle,
span = 1,
key,
},
index,
@ -89,7 +87,7 @@ function renderCells(
export interface RowProps {
prefixCls: string;
vertical: boolean;
row: React.ReactElement<DescriptionsItemProps>[];
row: DescriptionsItemType[];
bordered?: boolean;
colon: boolean;
index: number;

View File

@ -523,7 +523,7 @@ exports[`renders components/descriptions/demo/component-token.tsx extend context
colspan="1"
>
<span>
time
Time
</span>
</th>
<td
@ -720,7 +720,7 @@ exports[`renders components/descriptions/demo/component-token.tsx extend context
<span
class="ant-descriptions-item-label"
>
time
Time
</span>
<span
class="ant-descriptions-item-content"
@ -806,179 +806,317 @@ exports[`renders components/descriptions/demo/component-token.tsx extend context
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx extend context correctly 1`] = `
<div>
exports[`renders components/descriptions/demo/jsx.tsx extend context correctly 1`] = `
<div
class="ant-descriptions"
>
<div
class="ant-descriptions ant-descriptions-bordered"
class="ant-descriptions-header"
>
<div
class="ant-descriptions-header"
class="ant-descriptions-title"
>
<div
class="ant-descriptions-title"
>
Responsive Descriptions
</div>
User Info
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
UserName
</span>
<span
class="ant-descriptions-item-content"
>
Zhou Maomao
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Telephone
</span>
<span
class="ant-descriptions-item-content"
>
1810000000
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Live
</span>
<span
class="ant-descriptions-item-content"
>
Hangzhou, Zhejiang
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Remark
</span>
<span
class="ant-descriptions-item-content"
>
empty
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Address
</span>
<span
class="ant-descriptions-item-content"
>
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx extend context correctly 1`] = `
<div
class="ant-descriptions ant-descriptions-bordered"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-view"
class="ant-descriptions-title"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
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
</span>
</td>
</tr>
</tbody>
</table>
Responsive Descriptions
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
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 />
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
@ -1125,7 +1263,7 @@ exports[`renders components/descriptions/demo/size.tsx extend context correctly
colspan="1"
>
<span>
time
Time
</span>
</th>
<td
@ -1322,7 +1460,7 @@ exports[`renders components/descriptions/demo/size.tsx extend context correctly
<span
class="ant-descriptions-item-label"
>
time
Time
</span>
<span
class="ant-descriptions-item-content"

View File

@ -483,7 +483,7 @@ exports[`renders components/descriptions/demo/component-token.tsx correctly 1`]
colspan="1"
>
<span>
time
Time
</span>
</th>
<td
@ -664,7 +664,7 @@ exports[`renders components/descriptions/demo/component-token.tsx correctly 1`]
<span
class="ant-descriptions-item-label"
>
time
Time
</span>
<span
class="ant-descriptions-item-content"
@ -742,163 +742,289 @@ exports[`renders components/descriptions/demo/component-token.tsx correctly 1`]
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx correctly 1`] = `
<div>
exports[`renders components/descriptions/demo/jsx.tsx correctly 1`] = `
<div
class="ant-descriptions"
>
<div
class="ant-descriptions ant-descriptions-bordered"
class="ant-descriptions-header"
>
<div
class="ant-descriptions-header"
class="ant-descriptions-title"
>
<div
class="ant-descriptions-title"
>
Responsive Descriptions
</div>
User Info
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
UserName
</span>
<span
class="ant-descriptions-item-content"
>
Zhou Maomao
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Telephone
</span>
<span
class="ant-descriptions-item-content"
>
1810000000
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Live
</span>
<span
class="ant-descriptions-item-content"
>
Hangzhou, Zhejiang
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Remark
</span>
<span
class="ant-descriptions-item-content"
>
empty
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="2"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Address
</span>
<span
class="ant-descriptions-item-content"
>
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx correctly 1`] = `
<div
class="ant-descriptions ant-descriptions-bordered"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-view"
class="ant-descriptions-title"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="5"
>
<span>
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
</span>
</td>
</tr>
</tbody>
</table>
Responsive Descriptions
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="5"
>
<span>
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 />
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
@ -1037,7 +1163,7 @@ exports[`renders components/descriptions/demo/size.tsx correctly 1`] = `
colspan="1"
>
<span>
time
Time
</span>
</th>
<td
@ -1218,7 +1344,7 @@ exports[`renders components/descriptions/demo/size.tsx correctly 1`] = `
<span
class="ant-descriptions-item-label"
>
time
Time
</span>
<span
class="ant-descriptions-item-content"

View File

@ -249,6 +249,92 @@ exports[`Descriptions number 0 should render correct 1`] = `
</div>
`;
exports[`Descriptions should items work 1`] = `
<div>
<div
class="ant-descriptions"
>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
UserName
</span>
<span
class="ant-descriptions-item-content"
>
Zhou Maomao
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Telephone
</span>
<span
class="ant-descriptions-item-content"
>
1810000000
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Live
</span>
<span
class="ant-descriptions-item-content"
>
Hangzhou, Zhejiang
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`Descriptions should work with React Fragment 1`] = `
<div
class="ant-descriptions"

View File

@ -279,4 +279,31 @@ describe('Descriptions', () => {
);
expect(container.querySelectorAll('.ant-descriptions-small')).toHaveLength(1);
});
it('should items work', () => {
const { container } = render(
<Descriptions
items={[
{
key: '1',
label: 'UserName',
children: 'Zhou Maomao',
},
{
key: '2',
label: 'Telephone',
children: '1810000000',
},
{
key: '3',
label: 'Live',
children: 'Hangzhou, Zhejiang',
},
]}
/>,
);
expect(container.querySelector('.ant-descriptions-item')).toBeTruthy();
expect(container.querySelectorAll('.ant-descriptions-item')).toHaveLength(3);
expect(container).toMatchSnapshot();
});
});

View File

@ -1,16 +1,35 @@
import React from 'react';
import { Descriptions } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const App: React.FC = () => (
<Descriptions title="User Info">
<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>
);
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'UserName',
children: 'Zhou Maomao',
},
{
key: '2',
label: 'Telephone',
children: '1810000000',
},
{
key: '3',
label: 'Live',
children: 'Hangzhou, Zhejiang',
},
{
key: '4',
label: 'Remark',
children: 'empty',
},
{
key: '5',
label: 'Address',
children: 'No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China',
},
];
const App: React.FC = () => <Descriptions title="User Info" items={items} />;
export default App;

View File

@ -1,36 +1,77 @@
import React from 'react';
import { Badge, Descriptions } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const App: React.FC = () => (
<Descriptions title="User Info" 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={2}>
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>
);
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing Mode',
children: 'Prepaid',
},
{
key: '3',
label: 'Automatic Renewal',
children: 'YES',
},
{
key: '4',
label: 'Order time',
children: '2018-04-24 18:00:00',
},
{
key: '5',
label: 'Usage Time',
children: '2019-04-24 18:00:00',
span: 2,
},
{
key: '6',
label: 'Status',
children: <Badge status="processing" text="Running" />,
span: 3,
},
{
key: '7',
label: 'Negotiated Amount',
children: '$80.00',
},
{
key: '8',
label: 'Discount',
children: '$20.00',
},
{
key: '9',
label: 'Official Receipts',
children: '$60.00',
},
{
key: '10',
label: 'Config Info',
children: (
<>
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 />
</>
),
},
];
const App: React.FC = () => <Descriptions title="User Info" bordered items={items} />;
export default App;

View File

@ -1,7 +1,93 @@
import type { RadioChangeEvent } from 'antd';
import { Button, ConfigProvider, Descriptions, Radio } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React, { useState } from 'react';
const borderedItems: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing',
children: 'Prepaid',
},
{
key: '3',
label: 'Time',
children: '18:00:00',
},
{
key: '4',
label: 'Amount',
children: '$80.00',
},
{
key: '5',
label: 'Discount',
children: '$20.00',
},
{
key: '6',
label: 'Official',
children: '$60.00',
},
{
key: '7',
label: 'Config Info',
children: (
<>
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 />
</>
),
},
];
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing',
children: 'Prepaid',
},
{
key: '3',
label: 'Time',
children: '18:00:00',
},
{
key: '4',
label: 'Amount',
children: '$80.00',
},
{
key: '5',
label: 'Discount',
children: '$20.00',
},
{
key: '6',
label: 'Official',
children: '$60.00',
},
];
const App: React.FC = () => {
const [size, setSize] = useState<'default' | 'middle' | 'small'>('default');
@ -33,38 +119,21 @@ const App: React.FC = () => {
</Radio.Group>
<br />
<br />
<Descriptions bordered title="Custom Size" size={size} extra={<div>extra color: blue</div>}>
<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.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$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>
<Descriptions
bordered
title="Custom Size"
size={size}
extra={<div>extra color: blue</div>}
items={borderedItems}
/>
<br />
<br />
<Descriptions title="Custom Size" size={size} extra={<Button type="primary">Edit</Button>}>
<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.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
</Descriptions>
<Descriptions
title="Custom Size"
size={size}
extra={<Button type="primary">Edit</Button>}
items={items}
/>
</div>
</ConfigProvider>
);

View File

@ -0,0 +1,7 @@
## zh-CN
JSX 风格演示。
## en-US
JSX Style Demo.

View File

@ -0,0 +1,16 @@
import { Descriptions } from 'antd';
import React from 'react';
const App: React.FC = () => (
<Descriptions title="User Info">
<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>
);
export default App;

View File

@ -1,20 +1,43 @@
import React from 'react';
import { Descriptions } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const App: React.FC = () => (
<div>
<Descriptions
title="Responsive Descriptions"
bordered
column={{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }}
>
<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.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
<Descriptions.Item label="Config Info">
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing',
children: 'Prepaid',
},
{
key: '3',
label: 'Time',
children: '18:00:00',
},
{
key: '4',
label: 'Amount',
children: '$80.00',
},
{
key: '5',
label: 'Discount',
children: '$20.00',
},
{
key: '6',
label: 'Official',
children: '$60.00',
},
{
key: '7',
label: 'Config Info',
children: (
<>
Data disk type: MongoDB
<br />
Database version: 3.4
@ -26,9 +49,19 @@ const App: React.FC = () => (
Replication factor: 3
<br />
Region: East China 1
</Descriptions.Item>
</Descriptions>
</div>
<br />
</>
),
},
];
const App: React.FC = () => (
<Descriptions
title="Responsive Descriptions"
bordered
column={{ xxl: 4, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }}
items={items}
/>
);
export default App;

View File

@ -1,6 +1,93 @@
import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd';
import { Button, Descriptions, Radio } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React, { useState } from 'react';
const borderedItems: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing',
children: 'Prepaid',
},
{
key: '3',
label: 'Time',
children: '18:00:00',
},
{
key: '4',
label: 'Amount',
children: '$80.00',
},
{
key: '5',
label: 'Discount',
children: '$20.00',
},
{
key: '6',
label: 'Official',
children: '$60.00',
},
{
key: '7',
label: 'Config Info',
children: (
<>
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 />
</>
),
},
];
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing',
children: 'Prepaid',
},
{
key: '3',
label: 'Time',
children: '18:00:00',
},
{
key: '4',
label: 'Amount',
children: '$80.00',
},
{
key: '5',
label: 'Discount',
children: '$20.00',
},
{
key: '6',
label: 'Official',
children: '$60.00',
},
];
const App: React.FC = () => {
const [size, setSize] = useState<'default' | 'middle' | 'small'>('default');
@ -24,38 +111,16 @@ const App: React.FC = () => {
title="Custom Size"
size={size}
extra={<Button type="primary">Edit</Button>}
>
<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.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$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>
items={borderedItems}
/>
<br />
<br />
<Descriptions title="Custom Size" size={size} extra={<Button type="primary">Edit</Button>}>
<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.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
</Descriptions>
<Descriptions
title="Custom Size"
size={size}
extra={<Button type="primary">Edit</Button>}
items={items}
/>
</div>
);
};

View File

@ -1,11 +1,52 @@
import React, { useState } from 'react';
import { Descriptions, Divider, Radio, Switch } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React, { useState } from 'react';
const labelStyle: React.CSSProperties = { background: 'red' };
const contentStyle: React.CSSProperties = { background: 'green' };
type LayoutType = 'horizontal' | 'vertical' | undefined;
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
labelStyle,
contentStyle,
},
{
key: '2',
label: 'Billing Mode',
children: 'Prepaid',
},
{
key: '3',
label: 'Automatic Renewal',
children: 'YES',
},
];
const rootStyleItems: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing Mode',
children: 'Prepaid',
},
{
key: '3',
label: 'Automatic Renewal',
children: 'YES',
labelStyle: { color: 'orange' },
contentStyle: { color: 'blue' },
},
];
const App: React.FC = () => {
const [border, setBorder] = useState(true);
const [layout, setLayout] = useState('horizontal' as LayoutType);
@ -24,13 +65,7 @@ const App: React.FC = () => {
<Radio value="vertical">vertical</Radio>
</Radio.Group>
<Divider />
<Descriptions title="User Info" bordered={border} layout={layout}>
<Descriptions.Item label="Product" labelStyle={labelStyle} contentStyle={contentStyle}>
Cloud Database
</Descriptions.Item>
<Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
<Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
</Descriptions>
<Descriptions title="User Info" bordered={border} layout={layout} items={items} />
<Divider />
<Descriptions
title="Root style"
@ -38,17 +73,8 @@ const App: React.FC = () => {
contentStyle={contentStyle}
bordered={border}
layout={layout}
>
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
<Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
<Descriptions.Item
label="Automatic Renewal"
labelStyle={{ color: 'orange' }}
contentStyle={{ color: 'blue' }}
>
YES
</Descriptions.Item>
</Descriptions>
items={rootStyleItems}
/>
</>
);
};

View File

@ -1,5 +1,6 @@
import React from 'react';
import { Badge, Descriptions, Table } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const dataSource = [
{
@ -34,42 +35,86 @@ const columns = [
},
];
const App: React.FC = () => (
<Descriptions title="User Info" column={2}>
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
<Descriptions.Item label={<div style={{ display: 'flex' }}>Billing Mode</div>}>
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={2}>
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.Item label="Official Receipts">$60.00</Descriptions.Item>
<Descriptions.Item label="Config Info">
<Table size="small" pagination={false} dataSource={dataSource} columns={columns} />
</Descriptions.Item>
</Descriptions>
);
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: <div style={{ display: 'flex' }}>Billing Mode</div>,
children: 'Prepaid',
},
{
key: '3',
label: 'Automatic Renewal',
children: 'YES',
},
{
key: '4',
label: 'Order time',
children: '2018-04-24 18:00:00',
},
{
key: '5',
label: 'Usage Time',
span: 2,
children: '2019-04-24 18:00:00',
},
{
key: '6',
label: 'Status',
span: 3,
children: <Badge status="processing" text="Running" />,
},
{
key: '7',
label: 'Negotiated Amount',
children: '$80.00',
},
{
key: '8',
label: 'Discount',
children: '$20.00',
},
{
key: '9',
label: 'Official Receipts',
children: '$60.00',
},
{
key: '10',
label: 'Config Info',
children: (
<>
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 />
</>
),
},
{
key: '11',
label: 'Official Receipts',
children: '$60.00',
},
{
key: '12',
label: 'Config Info',
children: <Table size="small" pagination={false} dataSource={dataSource} columns={columns} />,
},
];
const App: React.FC = () => <Descriptions title="User Info" column={2} items={items} />;
export default App;

View File

@ -1,36 +1,79 @@
import React from 'react';
import { Badge, Descriptions } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'Product',
children: 'Cloud Database',
},
{
key: '2',
label: 'Billing Mode',
children: 'Prepaid',
},
{
key: '3',
label: 'Automatic Renewal',
children: 'YES',
},
{
key: '4',
label: 'Order time',
children: '2018-04-24 18:00:00',
},
{
key: '5',
label: 'Usage Time',
span: 2,
children: '2019-04-24 18:00:00',
},
{
key: '6',
label: 'Status',
span: 3,
children: <Badge status="processing" text="Running" />,
},
{
key: '7',
label: 'Negotiated Amount',
children: '$80.00',
},
{
key: '8',
label: 'Discount',
children: '$20.00',
},
{
key: '9',
label: 'Official Receipts',
children: '$60.00',
},
{
key: '10',
label: 'Config Info',
children: (
<>
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 />
</>
),
},
];
const App: React.FC = () => (
<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={2}>
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>
<Descriptions title="User Info" layout="vertical" bordered items={items} />
);
export default App;

View File

@ -1,16 +1,36 @@
import React from 'react';
import { Descriptions } from 'antd';
import type { DescriptionsProps } from 'antd/es/descriptions';
import React from 'react';
const App: React.FC = () => (
<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="Address" span={2}>
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</Descriptions.Item>
<Descriptions.Item label="Remark">empty</Descriptions.Item>
</Descriptions>
);
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'UserName',
children: 'Zhou Maomao',
},
{
key: '2',
label: 'Telephone',
children: '1810000000',
},
{
key: '3',
label: 'Live',
children: 'Hangzhou, Zhejiang',
},
{
key: '4',
label: 'Address',
span: 2,
children: 'No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China',
},
{
key: '5',
label: 'Remark',
children: 'empty',
},
];
const App: React.FC = () => <Descriptions title="User Info" layout="vertical" items={items} />;
export default App;

View File

@ -0,0 +1,80 @@
import toArray from 'rc-util/lib/Children/toArray';
import type React from 'react';
import { useMemo } from 'react';
import type { DescriptionsItemType } from '..';
import warning from '../../_util/warning';
function getFilledItem(
rowItem: DescriptionsItemType,
rowRestCol: number,
span?: number,
): DescriptionsItemType {
let clone = rowItem;
if (span === undefined || span > rowRestCol) {
clone = {
...rowItem,
span: rowRestCol,
};
warning(
span === undefined,
'Descriptions',
'Sum of column `span` in a line not match `column` of Descriptions.',
);
}
return clone;
}
// Convert children into items
const transChildren2Items = (childNodes?: React.ReactNode) =>
toArray(childNodes).map((node) => node?.props);
// Calculate the sum of span in a row
function getCalcRows(rowItems: DescriptionsItemType[], mergedColumn: number) {
const rows: DescriptionsItemType[][] = [];
let tmpRow: DescriptionsItemType[] = [];
let rowRestCol = mergedColumn;
rowItems
.filter((n) => n)
.forEach((rowItem, index) => {
const span = rowItem?.span;
const mergedSpan = span || 1;
// Additional handle last one
if (index === rowItems.length - 1) {
tmpRow.push(getFilledItem(rowItem, rowRestCol, span));
rows.push(tmpRow);
return;
}
if (mergedSpan < rowRestCol) {
rowRestCol -= mergedSpan;
tmpRow.push(rowItem);
} else {
tmpRow.push(getFilledItem(rowItem, rowRestCol, mergedSpan));
rows.push(tmpRow);
rowRestCol = mergedColumn;
tmpRow = [];
}
});
return rows;
}
const useRow = (
mergedColumn: number,
items?: DescriptionsItemType[],
children?: React.ReactNode,
) => {
const rows = useMemo(() => {
if (Array.isArray(items)) {
return getCalcRows(items, mergedColumn);
}
return getCalcRows(transChildren2Items(children), mergedColumn);
}, [items, children, mergedColumn]);
return rows;
};
export default useRow;

View File

@ -12,6 +12,52 @@ Display multiple read-only fields in groups.
Commonly displayed on the details page.
```tsx | pure
// works when >= 5.8.0, recommended ✅
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'UserName',
children: <p>Zhou Maomao</p>,
},
{
key: '2',
label: 'Telephone',
children: <p>1810000000</p>,
},
{
key: '3',
label: 'Live',
children: <p>Hangzhou, Zhejiang</p>,
},
{
key: '4',
label: 'Remark',
children: <p>empty</p>,
},
{
key: '5',
label: 'Address',
children: <p>No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China</p>,
},
];
<Descriptions title="User Info" items={items} />;
// works when <5.8.0 , deprecated when >=5.8.0 🙅🏻‍♀️
<Descriptions title="User Info">
<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>;
```
## Examples
<!-- prettier-ignore -->
@ -23,6 +69,7 @@ Commonly displayed on the details page.
<code src="./demo/vertical.tsx">Vertical</code>
<code src="./demo/vertical-border.tsx">Vertical border</code>
<code src="./demo/style.tsx" debug>Customize label & wrapper style</code>
<code src="./demo/jsx.tsx" debug>JSX demo</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API
@ -36,6 +83,7 @@ Commonly displayed on the details page.
| 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 \| [Record<Breakpoint, number>](https://github.com/ant-design/ant-design/blob/84ca0d23ae52e4f0940f20b0e22eabe743f90dca/components/descriptions/index.tsx#L111C21-L111C56) | 3 | |
| contentStyle | Customize content style | CSSProperties | - | 4.10.0 |
| extra | The action area of the description list, placed at the top-right | ReactNode | - | 4.5.0 |
| items | Describe the contents of the list item | [DescriptionsItem](#descriptionitem)[] | - | 5.8.0 |
| labelStyle | Customize label style | CSSProperties | - | 4.10.0 |
| layout | Define description layout | `horizontal` \| `vertical` | `horizontal` | |
| size | Set the size of the list. Can be set to `middle`,`small`, or not filled | `default` \| `middle` \| `small` | - | |

View File

@ -2,17 +2,16 @@
/* eslint-disable react/no-array-index-key */
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import * as React from 'react';
import { cloneElement } from '../_util/reactNode';
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserver';
import useResponsiveObserver, { responsiveArray } from '../_util/responsiveObserver';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import useSize from '../config-provider/hooks/useSize';
import DescriptionsContext from './DescriptionsContext';
import type { DescriptionsItemProps } from './Item';
import DescriptionsItem from './Item';
import Row from './Row';
import useRow from './hooks/useRow';
import useStyle from './style';
const DEFAULT_COLUMN_MAP: Record<Breakpoint, number> = {
@ -41,63 +40,14 @@ function getColumn(column: DescriptionsProps['column'], screens: ScreenMap): num
return 3;
}
function getFilledItem(
node: React.ReactElement,
rowRestCol: number,
span?: number,
): React.ReactElement {
let clone = node;
if (span === undefined || span > rowRestCol) {
clone = cloneElement(node, {
span: rowRestCol,
});
warning(
span === undefined,
'Descriptions',
'Sum of column `span` in a line not match `column` of Descriptions.',
);
}
return clone;
}
function getRows(children: React.ReactNode, column: number) {
const childNodes = toArray(children).filter((n) => n);
const rows: React.ReactElement[][] = [];
let tmpRow: React.ReactElement[] = [];
let rowRestCol = column;
childNodes.forEach((node, index) => {
const span: number = node.props?.span;
const mergedSpan = span || 1;
// Additional handle last one
if (index === childNodes.length - 1) {
tmpRow.push(getFilledItem(node, rowRestCol, span));
rows.push(tmpRow);
return;
}
if (mergedSpan < rowRestCol) {
rowRestCol -= mergedSpan;
tmpRow.push(node);
} else {
tmpRow.push(getFilledItem(node, rowRestCol, mergedSpan));
rows.push(tmpRow);
rowRestCol = column;
tmpRow = [];
}
});
return rows;
}
interface CompoundedComponent {
Item: typeof DescriptionsItem;
}
export interface DescriptionsItemType extends DescriptionsItemProps {
key?: React.Key;
}
export interface DescriptionsProps {
prefixCls?: string;
className?: string;
@ -105,6 +55,9 @@ export interface DescriptionsProps {
style?: React.CSSProperties;
bordered?: boolean;
size?: 'middle' | 'small' | 'default';
/**
* @deprecated use `items` instead
*/
children?: React.ReactNode;
title?: React.ReactNode;
extra?: React.ReactNode;
@ -113,6 +66,7 @@ export interface DescriptionsProps {
colon?: boolean;
labelStyle?: React.CSSProperties;
contentStyle?: React.CSSProperties;
items?: DescriptionsItemType[];
}
const Descriptions: React.FC<DescriptionsProps> & CompoundedComponent = (props) => {
@ -131,6 +85,7 @@ const Descriptions: React.FC<DescriptionsProps> & CompoundedComponent = (props)
size: customizeSize,
labelStyle,
contentStyle,
items,
...restProps
} = props;
const { getPrefixCls, direction, descriptions } = React.useContext(ConfigContext);
@ -139,6 +94,7 @@ const Descriptions: React.FC<DescriptionsProps> & CompoundedComponent = (props)
const mergedColumn = getColumn(column, screens);
const mergedSize = useSize(customizeSize);
const rows = useRow(mergedColumn, items, children);
const [wrapSSR, hashId] = useStyle(prefixCls);
const responsiveObserver = useResponsiveObserver();
@ -157,8 +113,7 @@ const Descriptions: React.FC<DescriptionsProps> & CompoundedComponent = (props)
};
}, []);
// Children
const rows = getRows(children, mergedColumn);
// ======================== Render ========================
const contextValue = React.useMemo(
() => ({ labelStyle, contentStyle }),
[labelStyle, contentStyle],

View File

@ -13,6 +13,52 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d27AQJrowGAAAA
常见于详情页的信息展示。
```tsx | pure
// >= 5.8.0 可用,推荐的写法 ✅
const items: DescriptionsProps['items'] = [
{
key: '1',
label: 'UserName',
children: <p>Zhou Maomao</p>,
},
{
key: '2',
label: 'Telephone',
children: <p>1810000000</p>,
},
{
key: '3',
label: 'Live',
children: <p>Hangzhou, Zhejiang</p>,
},
{
key: '4',
label: 'Remark',
children: <p>empty</p>,
},
{
key: '5',
label: 'Address',
children: <p>No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China</p>,
},
];
<Descriptions title="User Info" items={items} />;
// <5.8.0 可用>=5.8.0 时不推荐 🙅🏻‍♀️
<Descriptions title="User Info">
<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>;
```
## 代码演示
<!-- prettier-ignore -->
@ -24,6 +70,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d27AQJrowGAAAA
<code src="./demo/vertical.tsx">垂直</code>
<code src="./demo/vertical-border.tsx">垂直带边框的</code>
<code src="./demo/style.tsx" debug>自定义 label & wrapper 样式</code>
<code src="./demo/jsx.tsx" debug>JSX demo</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API
@ -37,6 +84,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d27AQJrowGAAAA
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number \| [Record<Breakpoint, number>](https://github.com/ant-design/ant-design/blob/84ca0d23ae52e4f0940f20b0e22eabe743f90dca/components/descriptions/index.tsx#L111C21-L111C56) | 3 | |
| contentStyle | 自定义内容样式 | CSSProperties | - | 4.10.0 |
| extra | 描述列表的操作区域,显示在右上方 | ReactNode | - | 4.5.0 |
| items | 描述列表项内容 | [DescriptionsItem](#descriptionitem)[] | - | 5.8.0 |
| labelStyle | 自定义标签样式 | CSSProperties | - | 4.10.0 |
| layout | 描述布局 | `horizontal` \| `vertical` | `horizontal` | |
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default` \| `middle` \| `small` | - | |