mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-12-02 12:09:14 +08:00
feat: desc support root level label & content style (#28613)
This commit is contained in:
parent
6ae70059c9
commit
a211756e6b
@ -1,6 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { DescriptionsItemProps } from './Item';
|
||||
import Cell from './Cell';
|
||||
import { DescriptionsContext, DescriptionsContextProps } from '.';
|
||||
|
||||
interface CellConfig {
|
||||
component: string | [string, string];
|
||||
@ -12,7 +13,14 @@ interface CellConfig {
|
||||
function renderCells(
|
||||
items: React.ReactElement<DescriptionsItemProps>[],
|
||||
{ colon, prefixCls, bordered }: RowProps,
|
||||
{ component, type, showLabel, showContent }: CellConfig,
|
||||
{
|
||||
component,
|
||||
type,
|
||||
showLabel,
|
||||
showContent,
|
||||
labelStyle: rootLabelStyle,
|
||||
contentStyle: rootContentStyle,
|
||||
}: CellConfig & DescriptionsContextProps,
|
||||
) {
|
||||
return items.map(
|
||||
(
|
||||
@ -37,8 +45,8 @@ function renderCells(
|
||||
key={`${type}-${key || index}`}
|
||||
className={className}
|
||||
style={style}
|
||||
labelStyle={labelStyle}
|
||||
contentStyle={contentStyle}
|
||||
labelStyle={{ ...rootLabelStyle, ...labelStyle }}
|
||||
contentStyle={{ ...rootContentStyle, ...contentStyle }}
|
||||
span={span}
|
||||
colon={colon}
|
||||
component={component}
|
||||
@ -54,7 +62,7 @@ function renderCells(
|
||||
<Cell
|
||||
key={`label-${key || index}`}
|
||||
className={className}
|
||||
style={{ ...style, ...labelStyle }}
|
||||
style={{ ...rootLabelStyle, ...style, ...labelStyle }}
|
||||
span={1}
|
||||
colon={colon}
|
||||
component={component[0]}
|
||||
@ -65,7 +73,7 @@ function renderCells(
|
||||
<Cell
|
||||
key={`content-${key || index}`}
|
||||
className={className}
|
||||
style={{ ...style, ...contentStyle }}
|
||||
style={{ ...rootContentStyle, ...style, ...contentStyle }}
|
||||
span={span * 2 - 1}
|
||||
component={component[1]}
|
||||
itemPrefixCls={itemPrefixCls}
|
||||
@ -87,18 +95,26 @@ export interface RowProps {
|
||||
}
|
||||
|
||||
const Row: React.FC<RowProps> = props => {
|
||||
const descContext = React.useContext(DescriptionsContext);
|
||||
|
||||
const { prefixCls, vertical, row, index, bordered } = props;
|
||||
if (vertical) {
|
||||
return (
|
||||
<>
|
||||
<tr key={`label-${index}`} className={`${prefixCls}-row`}>
|
||||
{renderCells(row, props, { component: 'th', type: 'label', showLabel: true })}
|
||||
{renderCells(row, props, {
|
||||
component: 'th',
|
||||
type: 'label',
|
||||
showLabel: true,
|
||||
...descContext,
|
||||
})}
|
||||
</tr>
|
||||
<tr key={`content-${index}`} className={`${prefixCls}-row`}>
|
||||
{renderCells(row, props, {
|
||||
component: 'td',
|
||||
type: 'content',
|
||||
showContent: true,
|
||||
...descContext,
|
||||
})}
|
||||
</tr>
|
||||
</>
|
||||
@ -112,6 +128,7 @@ const Row: React.FC<RowProps> = props => {
|
||||
type: 'item',
|
||||
showLabel: true,
|
||||
showContent: true,
|
||||
...descContext,
|
||||
})}
|
||||
</tr>
|
||||
);
|
||||
|
@ -960,6 +960,165 @@ Array [
|
||||
</table>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal"
|
||||
role="separator"
|
||||
/>,
|
||||
<div
|
||||
class="ant-descriptions"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-header"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-title"
|
||||
>
|
||||
Root style
|
||||
</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"
|
||||
style="background:red"
|
||||
>
|
||||
Product
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
style="background:green"
|
||||
>
|
||||
Cloud Database
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-item-container"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
style="background:red"
|
||||
>
|
||||
Billing Mode
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
style="background:green"
|
||||
>
|
||||
Prepaid
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item"
|
||||
colspan="1"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-item-container"
|
||||
>
|
||||
<span
|
||||
class="ant-descriptions-item-label"
|
||||
style="background:red;color:orange"
|
||||
>
|
||||
Automatic Renewal
|
||||
</span>
|
||||
<span
|
||||
class="ant-descriptions-item-content"
|
||||
style="background:green;color:blue"
|
||||
>
|
||||
YES
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-descriptions ant-descriptions-bordered"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-header"
|
||||
>
|
||||
<div
|
||||
class="ant-descriptions-title"
|
||||
>
|
||||
Root style
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-descriptions-view"
|
||||
>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr
|
||||
class="ant-descriptions-row"
|
||||
>
|
||||
<th
|
||||
class="ant-descriptions-item-label"
|
||||
colspan="1"
|
||||
style="background:red"
|
||||
>
|
||||
Product
|
||||
</th>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
style="background:green"
|
||||
>
|
||||
Cloud Database
|
||||
</td>
|
||||
<th
|
||||
class="ant-descriptions-item-label"
|
||||
colspan="1"
|
||||
style="background:red"
|
||||
>
|
||||
Billing Mode
|
||||
</th>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
style="background:green"
|
||||
>
|
||||
Prepaid
|
||||
</td>
|
||||
<th
|
||||
class="ant-descriptions-item-label"
|
||||
colspan="1"
|
||||
style="background:red;color:orange"
|
||||
>
|
||||
Automatic Renewal
|
||||
</th>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="1"
|
||||
style="background:green;color:blue"
|
||||
>
|
||||
YES
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
|
@ -15,28 +15,53 @@ debug: true
|
||||
Customize label & wrapper style
|
||||
|
||||
```tsx
|
||||
import { Descriptions } from 'antd';
|
||||
import { Descriptions, Divider } from 'antd';
|
||||
|
||||
const labelStyle: React.CSSProperties = { background: 'red' };
|
||||
const contentStyle: React.CSSProperties = { background: 'green' };
|
||||
|
||||
function renderCelledDesc(bordered?: boolean) {
|
||||
return (
|
||||
<Descriptions title="User Info" bordered={bordered}>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
function renderRootDesc(bordered?: boolean) {
|
||||
return (
|
||||
<Descriptions
|
||||
title="Root style"
|
||||
labelStyle={labelStyle}
|
||||
contentStyle={contentStyle}
|
||||
bordered={bordered}
|
||||
>
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<>
|
||||
<Descriptions title="User Info">
|
||||
<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>
|
||||
{renderCelledDesc()}
|
||||
{renderCelledDesc(true)}
|
||||
|
||||
<Descriptions title="User Info" bordered>
|
||||
<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>
|
||||
<Divider />
|
||||
|
||||
{renderRootDesc()}
|
||||
{renderRootDesc(true)}
|
||||
</>,
|
||||
mountNode,
|
||||
);
|
||||
|
@ -21,7 +21,9 @@ Commonly displayed on the details page.
|
||||
| bordered | Whether to display the border | boolean | false | |
|
||||
| colon | Change default props `colon` value of Descriptions.Item | boolean | true | |
|
||||
| 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 | |
|
||||
| contentStyle | Customize label style | CSSProperties | - | 4.10.0 |
|
||||
| extra | The action area of the description list, placed at the top-right | ReactNode | - | 4.5.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` | - | |
|
||||
| title | The title of the description list, placed at the top | ReactNode | - | |
|
||||
|
@ -13,6 +13,13 @@ import Row from './Row';
|
||||
import DescriptionsItem from './Item';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
|
||||
export interface DescriptionsContextProps {
|
||||
labelStyle?: React.CSSProperties;
|
||||
contentStyle?: React.CSSProperties;
|
||||
}
|
||||
|
||||
export const DescriptionsContext = React.createContext<DescriptionsContextProps>({});
|
||||
|
||||
const DEFAULT_COLUMN_MAP: Record<Breakpoint, number> = {
|
||||
xxl: 3,
|
||||
xl: 3,
|
||||
@ -104,6 +111,8 @@ export interface DescriptionsProps {
|
||||
column?: number | Partial<Record<Breakpoint, number>>;
|
||||
layout?: 'horizontal' | 'vertical';
|
||||
colon?: boolean;
|
||||
labelStyle?: React.CSSProperties;
|
||||
contentStyle?: React.CSSProperties;
|
||||
}
|
||||
|
||||
function Descriptions({
|
||||
@ -118,6 +127,8 @@ function Descriptions({
|
||||
className,
|
||||
style,
|
||||
size,
|
||||
labelStyle,
|
||||
contentStyle,
|
||||
}: DescriptionsProps) {
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
|
||||
@ -142,43 +153,45 @@ function Descriptions({
|
||||
const rows = getRows(children, mergedColumn);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${size}`]: size && size !== 'default',
|
||||
[`${prefixCls}-bordered`]: !!bordered,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
{(title || extra) && (
|
||||
<div className={`${prefixCls}-header`}>
|
||||
{title && <div className={`${prefixCls}-title`}>{title}</div>}
|
||||
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
)}
|
||||
<DescriptionsContext.Provider value={{ labelStyle, contentStyle }}>
|
||||
<div
|
||||
className={classNames(
|
||||
prefixCls,
|
||||
{
|
||||
[`${prefixCls}-${size}`]: size && size !== 'default',
|
||||
[`${prefixCls}-bordered`]: !!bordered,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
},
|
||||
className,
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
{(title || extra) && (
|
||||
<div className={`${prefixCls}-header`}>
|
||||
{title && <div className={`${prefixCls}-title`}>{title}</div>}
|
||||
{extra && <div className={`${prefixCls}-extra`}>{extra}</div>}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={`${prefixCls}-view`}>
|
||||
<table>
|
||||
<tbody>
|
||||
{rows.map((row, index) => (
|
||||
<Row
|
||||
key={index}
|
||||
index={index}
|
||||
colon={colon}
|
||||
prefixCls={prefixCls}
|
||||
vertical={layout === 'vertical'}
|
||||
bordered={bordered}
|
||||
row={row}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
<div className={`${prefixCls}-view`}>
|
||||
<table>
|
||||
<tbody>
|
||||
{rows.map((row, index) => (
|
||||
<Row
|
||||
key={index}
|
||||
index={index}
|
||||
colon={colon}
|
||||
prefixCls={prefixCls}
|
||||
vertical={layout === 'vertical'}
|
||||
bordered={bordered}
|
||||
row={row}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DescriptionsContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,9 @@ cover: https://gw.alipayobjects.com/zos/alicdn/MjtG9_FOI/Descriptions.svg
|
||||
| bordered | 是否展示边框 | boolean | false | |
|
||||
| colon | 配置 `Descriptions.Item` 的 `colon` 的默认值 | boolean | true | |
|
||||
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 | |
|
||||
| contentStyle | 自定义内容样式 | CSSProperties | - | 4.10.0 |
|
||||
| extra | 描述列表的操作区域,显示在右上方 | ReactNode | - | 4.5.0 |
|
||||
| labelStyle | 自定义标签样式 | CSSProperties | - | 4.10.0 |
|
||||
| layout | 描述布局 | `horizontal` \| `vertical` | `horizontal` | |
|
||||
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default` \| `middle` \| `small` | - | |
|
||||
| title | 描述列表的标题,显示在最顶部 | ReactNode | - | |
|
||||
|
Loading…
Reference in New Issue
Block a user