Merge remote-tracking branch 'origin/master' into 4.0-prepare

This commit is contained in:
zombiej 2019-09-02 10:12:05 +08:00
commit fc1d917c62
14 changed files with 160 additions and 101 deletions

View File

@ -10,7 +10,7 @@
一套企业级的 UI 设计语言和 React 实现。
[![Build Status](https://dev.azure.com/ant-design/ant-design/_apis/build/status/ant-design.ant-design?branchName=master)](https://dev.azure.com/ant-design/ant-design/_build/latest?definitionId=2?branchName=master) [![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
[![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![npm package](https://img.shields.io/npm/v/antd.svg?style=flat-square)](https://www.npmjs.org/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
[![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design) [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design?type=dev) [![Total alerts](https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design)](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [![Issues need help](https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open)](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
@ -130,3 +130,9 @@ $ npm start
1. [Stack Overflow](http://stackoverflow.com/questions/tagged/antd)(英文)
2. [Segment Fault](https://segmentfault.com/t/antd)(中文)
3. [![Join the chat at https://gitter.im/ant-design/ant-design](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ant-design/ant-design?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## ❤️ 赞助者 ![](https://opencollective.com/ant-design/tiers/backers/badge.svg?label=Backers&color=brightgreen) ![](https://opencollective.com/ant-design/tiers/sponsors/badge.svg?label=Sponsors&color=brightgreen)
[![](https://opencollective.com/ant-design/tiers/backers.svg?avatarHeight=36)](https://opencollective.com/ant-design#support)
[![](https://opencollective.com/ant-design/tiers/sponsors.svg?avatarHeight=36)](https://opencollective.com/ant-design#support)

View File

@ -10,7 +10,7 @@
An enterprise-class UI design language and React implementation.
[![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) [![Build Status](https://dev.azure.com/ant-design/ant-design/_apis/build/status/ant-design.ant-design?branchName=master)](https://dev.azure.com/ant-design/ant-design/_build/latest?definitionId=2?branchName=master) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![](https://flat.badgen.net/npm/v/antd?icon=npm)](https://www.npmjs.com/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
[![CircleCI branch](https://img.shields.io/circleci/project/github/ant-design/ant-design/master.svg?style=flat-square)](https://circleci.com/gh/ant-design/ant-design) [![Codecov](https://img.shields.io/codecov/c/github/ant-design/ant-design/master.svg?style=flat-square)](https://codecov.io/gh/ant-design/ant-design/branch/master) [![](https://flat.badgen.net/npm/v/antd?icon=npm)](https://www.npmjs.com/package/antd) [![NPM downloads](http://img.shields.io/npm/dm/antd.svg?style=flat-square)](http://npmjs.com/antd)
[![Dependencies](https://img.shields.io/david/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design) [![DevDependencies](https://img.shields.io/david/dev/ant-design/ant-design.svg?style=flat-square)](https://david-dm.org/ant-design/ant-design?type=dev) [![Total alerts](https://flat.badgen.net/lgtm/alerts/g/ant-design/ant-design)](https://lgtm.com/projects/g/ant-design/ant-design/alerts/) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fant-design%2Fant-design.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fant-design%2Fant-design?ref=badge_shield) [![Issues need help](https://flat.badgen.net/github/label-issues/ant-design/ant-design/help%20wanted/open)](https://github.com/ant-design/ant-design/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22)
@ -121,3 +121,9 @@ We welcome all contributions. Please read our [CONTRIBUTING.md](https://github.c
If you are a collaborator, please follow our [Pull Request principle](https://github.com/ant-design/ant-design/wiki/PR-principle) to create a Pull Request by [collaborator template](https://github.com/ant-design/ant-design/compare?expand=1&template=collaborator.md).
[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/34526884)
## ❤️ Backers and Sponsors ![](https://opencollective.com/ant-design/tiers/backers/badge.svg?label=Backers&color=brightgreen) ![](https://opencollective.com/ant-design/tiers/sponsors/badge.svg?label=Sponsors&color=brightgreen)
[![](https://opencollective.com/ant-design/tiers/backers.svg?avatarHeight=36)](https://opencollective.com/ant-design#support)
[![](https://opencollective.com/ant-design/tiers/sponsors.svg?avatarHeight=36)](https://opencollective.com/ant-design#support)

View File

@ -151,7 +151,7 @@
transition: color 0.3s;
}
a,
a:not(.@{ant-prefix}-btn),
> .anticon {
display: inline-block;
width: 100%;

View File

@ -271,10 +271,6 @@
background: @primary-2;
}
&-selected-date {
.calendar-selected-cell;
}
&-last-month-cell &-date,
&-next-month-btn-day &-date {
&,

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

@ -39,7 +39,7 @@ exports[`Descriptions Descriptions support colon 1`] = `
</DescriptionsItem>
}
colon={false}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -116,7 +116,7 @@ exports[`Descriptions Descriptions support style 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -183,7 +183,7 @@ exports[`Descriptions Descriptions.Item support className 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -241,7 +241,7 @@ exports[`Descriptions column is number 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -274,7 +274,7 @@ exports[`Descriptions column is number 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-1"
key="1"
layout="horizontal"
type="label"
>
@ -307,7 +307,7 @@ exports[`Descriptions column is number 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-2"
key="2"
layout="horizontal"
type="label"
>
@ -346,7 +346,7 @@ exports[`Descriptions column is number 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -414,7 +414,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="vertical"
type="label"
>
@ -446,7 +446,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="content-0"
key="0"
layout="vertical"
type="content"
>
@ -478,7 +478,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="vertical"
type="label"
>
@ -510,7 +510,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="content-0"
key="0"
layout="vertical"
type="content"
>
@ -542,7 +542,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="vertical"
type="label"
>
@ -574,7 +574,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="content-0"
key="0"
layout="vertical"
type="content"
>
@ -607,7 +607,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="vertical"
type="label"
>
@ -640,7 +640,7 @@ exports[`Descriptions vertical layout 1`] = `
</DescriptionsItem>
}
colon={true}
key="content-0"
key="0"
layout="vertical"
type="content"
>
@ -701,7 +701,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -739,7 +739,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -777,7 +777,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>
@ -816,7 +816,7 @@ exports[`Descriptions when item is rendered conditionally 1`] = `
</DescriptionsItem>
}
colon={true}
key="label-0"
key="0"
layout="horizontal"
type="label"
>

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}>
@ -172,4 +175,14 @@ describe('Descriptions', () => {
);
expect(wrapper).toMatchSnapshot();
});
it('keep key', () => {
const wrapper = mount(
<Descriptions>
<Descriptions.Item key="bamboo" />
</Descriptions>,
);
expect(wrapper.find('Col').key()).toBe('bamboo');
});
});

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,80 +36,84 @@ 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 || itemNode.props.span === 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>,
colItem: React.ReactElement<DescriptionsItemProps>,
type: 'label' | 'content',
idx: number,
) => (
<Col
child={childrenItem}
bordered={bordered}
colon={colon}
type={type}
key={`${type}-${idx}`}
layout={layout}
/>
);
) => {
return (
<Col
child={colItem}
bordered={bordered}
colon={colon}
type={type}
key={colItem.key || idx}
layout={layout}
/>
);
};
const cloneChildren: JSX.Element[] = [];
const cloneContentChildren: JSX.Element[] = [];
React.Children.forEach(
childrenArray,
toArray(children).forEach(
(childrenItem: React.ReactElement<DescriptionsItemProps>, idx: number) => {
cloneChildren.push(renderCol(childrenItem, 'label', idx));
if (layout === 'vertical') {
@ -220,17 +225,16 @@ class Descriptions extends React.Component<
const prefixCls = getPrefixCls('descriptions', customizePrefixCls);
const column = this.getColumn();
const cloneChildren = React.Children.map(
children,
(child: React.ReactElement<DescriptionsItemProps>) => {
const cloneChildren = toArray(children)
.map((child: React.ReactElement<DescriptionsItemProps>) => {
if (React.isValidElement(child)) {
return React.cloneElement(child, {
prefixCls,
});
}
return child;
},
);
return null;
})
.filter((node: React.ReactElement) => node);
const childrenArray: Array<
React.ReactElement<DescriptionsItemProps>[]
@ -253,8 +257,6 @@ class Descriptions extends React.Component<
index,
{
prefixCls,
column,
isLast: index + 1 === childrenArray.length,
},
bordered,
layout,

View File

@ -76,6 +76,11 @@
z-index: -1;
color: transparent;
pointer-events: none;
> span {
display: inline-block;
min-height: 1em;
}
}
// ================== Dropdown ==================

View File

@ -245,8 +245,9 @@
// Create an empty element to avoid margin collapsing
// https://github.com/ant-design/ant-design/issues/18103
&-content::before {
display: table;
display: block;
content: '';
overflow: hidden;
}
// Horizontal Content

View File

@ -81,6 +81,12 @@ class Upload extends React.Component<UploadProps, UploadState> {
onStart = (file: RcFile) => {
const { fileList } = this.state;
const { multiple } = this.props;
if (!multiple && fileList.length > 0) {
return;
}
const targetItem = fileToObject(file);
targetItem.status = 'uploading';

View File

@ -463,4 +463,28 @@ describe('Upload', () => {
);
errorSpy.mockRestore();
});
it('not allow multiple upload when multiple is false', done => {
const onChange = jest.fn();
const wrapper = mount(
<Upload
fileList={[{ uid: '903', file: 'bamboo.png' }]}
action="http://upload.com"
onChange={onChange}
multiple={false}
/>,
);
wrapper.find('input').simulate('change', {
target: {
files: [{ file: 'light.png' }],
},
});
setTimeout(() => {
expect(onChange).not.toHaveBeenCalled();
done();
});
});
});

View File

@ -190,7 +190,7 @@
"stylelint-config-standard": "^18.3.0",
"stylelint-declaration-block-no-ignored-properties": "^2.1.0",
"stylelint-order": "^3.0.0",
"typescript": "~3.5.1",
"typescript": "~3.6.2",
"xhr-mock": "^2.4.1",
"xhr2": "^0.2.0",
"yaml-front-matter": "^4.0.0"