Browse Source

🐛 Fix Descriptions items not working with React.Fragment (#20019)

close #19887
pull/20021/head
偏右 5 years ago
committed by GitHub
parent
commit
d7e81027d6
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 72
      components/descriptions/__tests__/__snapshots__/index.test.js.snap
  2. 18
      components/descriptions/__tests__/index.test.js
  3. 26
      components/descriptions/index.tsx

72
components/descriptions/__tests__/__snapshots__/index.test.js.snap

@ -376,6 +376,78 @@ exports[`Descriptions column is number 1`] = `
</Descriptions>
`;
exports[`Descriptions should work with React Fragment 1`] = `
<div
class="ant-descriptions"
>
<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 ant-descriptions-item-colon"
>
bamboo
</span>
<span
class="ant-descriptions-item-content"
>
bamboo
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<span
class="ant-descriptions-item-label ant-descriptions-item-colon"
>
bamboo
</span>
<span
class="ant-descriptions-item-content"
>
bamboo
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<span
class="ant-descriptions-item-label ant-descriptions-item-colon"
>
bamboo
</span>
<span
class="ant-descriptions-item-content"
>
bamboo
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;
exports[`Descriptions vertical layout 1`] = `
<Descriptions
column={

18
components/descriptions/__tests__/index.test.js

@ -185,4 +185,22 @@ describe('Descriptions', () => {
expect(wrapper.find('Col').key()).toBe('label-bamboo');
});
// https://github.com/ant-design/ant-design/issues/19887
it('should work with React Fragment', () => {
if (!React.Fragment) {
return;
}
const wrapper = mount(
<Descriptions>
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
<>
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
<Descriptions.Item label="bamboo">bamboo</Descriptions.Item>
</>
</Descriptions>,
);
expect(wrapper.render()).toMatchSnapshot();
});
});

26
components/descriptions/index.tsx

@ -10,6 +10,20 @@ import ResponsiveObserve, {
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Col from './Col';
// https://github.com/smooth-code/react-flatten-children/
function flattenChildren(children: React.ReactNode): JSX.Element[] {
if (!children) {
return [];
}
return toArray(children).reduce((flatChildren: JSX.Element[], child: JSX.Element) => {
if (child && child.type === React.Fragment) {
return flatChildren.concat(flattenChildren(child.props.children));
}
flatChildren.push(child);
return flatChildren;
}, []);
}
export interface DescriptionsItemProps {
prefixCls?: string;
className?: string;
@ -47,7 +61,7 @@ const generateChildrenRows = (
let columns: React.ReactElement<DescriptionsItemProps>[] | null = null;
let leftSpans: number;
const itemNodes = toArray(children);
const itemNodes = flattenChildren(children);
itemNodes.forEach((node: React.ReactElement<DescriptionsItemProps>, index: number) => {
let itemNode = node;
@ -113,7 +127,7 @@ const renderRow = (
const cloneChildren: JSX.Element[] = [];
const cloneContentChildren: JSX.Element[] = [];
toArray(children).forEach(
flattenChildren(children).forEach(
(childrenItem: React.ReactElement<DescriptionsItemProps>, idx: number) => {
cloneChildren.push(renderCol(childrenItem, 'label', idx));
if (layout === 'vertical') {
@ -225,7 +239,7 @@ class Descriptions extends React.Component<
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
const column = this.getColumn();
const cloneChildren = toArray(children)
const cloneChildren = flattenChildren(children)
.map((child: React.ReactElement<DescriptionsItemProps>) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, {
@ -236,9 +250,9 @@ class Descriptions extends React.Component<
})
.filter((node: React.ReactElement) => node);
const childrenArray: Array<
React.ReactElement<DescriptionsItemProps>[]
> = generateChildrenRows(cloneChildren, column);
const childrenArray: Array<React.ReactElement<
DescriptionsItemProps
>[]> = generateChildrenRows(cloneChildren, column);
return (
<div
className={classNames(prefixCls, className, {

Loading…
Cancel
Save