fix: Adjust Descriptions column calcuation logic (#18568)

* fix: Span calculation logic

* update spanshot
This commit is contained in:
二货机器人 2019-08-30 12:31:10 +08:00 committed by GitHub
parent e6091cfe6e
commit 76fd80634b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 55 deletions

View File

@ -784,16 +784,6 @@ exports[`renders ./components/descriptions/demo/vertical.md correctly 1`] = `
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<span
class="ant-descriptions-item-label ant-descriptions-item-colon"
>
Remark
</span>
</td>
<td
class="ant-descriptions-item"
colspan="2"
@ -804,20 +794,20 @@ exports[`renders ./components/descriptions/demo/vertical.md correctly 1`] = `
Address
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<span
class="ant-descriptions-item-content"
class="ant-descriptions-item-label ant-descriptions-item-colon"
>
empty
Remark
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="2"
@ -828,6 +818,16 @@ exports[`renders ./components/descriptions/demo/vertical.md correctly 1`] = `
No. 18, Wantang Road, Xihu District, Hangzhou, Zhejiang, China
</span>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<span
class="ant-descriptions-item-content"
>
empty
</span>
</td>
</tr>
</tbody>
</table>

View File

@ -3,6 +3,7 @@ import MockDate from 'mockdate';
import { mount } from 'enzyme';
import Descriptions from '..';
import mountTest from '../../../tests/shared/mountTest';
import { resetWarned } from '../../_util/warning';
jest.mock('enquire.js', () => {
let that;
@ -100,6 +101,8 @@ describe('Descriptions', () => {
});
it('warning if ecceed the row span', () => {
resetWarned();
mount(
<Descriptions column={3}>
<Descriptions.Item label="Product" span={2}>

View File

@ -21,10 +21,10 @@ ReactDOM.render(
<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">
<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>,
mountNode,
);

View File

@ -1,5 +1,6 @@
import * as React from 'react';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import warning from '../_util/warning';
import ResponsiveObserve, {
Breakpoint,
@ -35,61 +36,64 @@ export interface DescriptionsProps {
/**
* Convert children into `column` groups.
* @param cloneChildren: DescriptionsItem
* @param children: DescriptionsItem
* @param column: number
*/
const generateChildrenRows = (
cloneChildren: React.ReactNode,
children: React.ReactNode,
column: number,
): React.ReactElement<DescriptionsItemProps>[][] => {
const childrenArray: React.ReactElement<DescriptionsItemProps>[][] = [];
let columnArray: React.ReactElement<DescriptionsItemProps>[] = [];
let totalRowSpan = 0;
React.Children.forEach(cloneChildren, (node: React.ReactElement<DescriptionsItemProps>) => {
columnArray.push(node);
if (node.props.span) {
totalRowSpan += node.props.span;
} else {
totalRowSpan += 1;
const rows: React.ReactElement<DescriptionsItemProps>[][] = [];
let columns: React.ReactElement<DescriptionsItemProps>[] | null = null;
let leftSpans: number;
const itemNodes = toArray(children);
itemNodes.forEach((node: React.ReactElement<DescriptionsItemProps>, index: number) => {
let itemNode = node;
if (!columns) {
leftSpans = column;
columns = [];
rows.push(columns);
}
if (totalRowSpan >= column) {
// Always set last span to align the end of Descriptions
const lastItem = index === itemNodes.length - 1;
let lastSpanSame = true;
if (lastItem) {
lastSpanSame = (itemNode.props.span || 1) === leftSpans;
itemNode = React.cloneElement(itemNode, {
span: leftSpans,
});
}
// Calculate left fill span
const { span = 1 } = itemNode.props;
columns.push(itemNode);
leftSpans -= span;
if (leftSpans <= 0) {
columns = null;
warning(
totalRowSpan <= column,
leftSpans === 0 && lastSpanSame,
'Descriptions',
'Sum of column `span` in a line exceeds `column` of Descriptions.',
);
childrenArray.push(columnArray);
columnArray = [];
totalRowSpan = 0;
}
});
if (columnArray.length > 0) {
childrenArray.push(columnArray);
columnArray = [];
}
return childrenArray;
return rows;
};
const renderRow = (
children: React.ReactElement<DescriptionsItemProps>[],
index: number,
{ prefixCls, column, isLast }: { prefixCls: string; column: number; isLast: boolean },
{ prefixCls }: { prefixCls: string },
bordered: boolean,
layout: 'horizontal' | 'vertical',
colon: boolean,
) => {
// copy children,prevent changes to incoming parameters
const childrenArray = [...children];
let lastChildren = childrenArray.pop() as React.ReactElement<DescriptionsItemProps>;
const span = column - childrenArray.length;
if (isLast) {
lastChildren = React.cloneElement(lastChildren as React.ReactElement<DescriptionsItemProps>, {
span,
});
}
childrenArray.push(lastChildren);
const renderCol = (
childrenItem: React.ReactElement<DescriptionsItemProps>,
type: 'label' | 'content',
@ -108,7 +112,7 @@ const renderRow = (
const cloneChildren: JSX.Element[] = [];
const cloneContentChildren: JSX.Element[] = [];
React.Children.forEach(
childrenArray,
children,
(childrenItem: React.ReactElement<DescriptionsItemProps>, idx: number) => {
cloneChildren.push(renderCol(childrenItem, 'label', idx));
if (layout === 'vertical') {
@ -253,8 +257,6 @@ class Descriptions extends React.Component<
index,
{
prefixCls,
column,
isLast: index + 1 === childrenArray.length,
},
bordered,
layout,