Merge pull request #26655 from ant-design/master

chore: Feature merge master
This commit is contained in:
二货机器人 2020-09-09 15:34:35 +08:00 committed by GitHub
commit ca46793593
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 87 additions and 34 deletions

View File

@ -24,6 +24,8 @@ When there is a need for autocomplete functionality.
| defaultActiveFirstOption | Whether active first option by default | boolean | true | | | defaultActiveFirstOption | Whether active first option by default | boolean | true | |
| defaultValue | Initial selected option | string | - | | | defaultValue | Initial selected option | string | - | |
| disabled | Whether disabled select | boolean | false | | | disabled | Whether disabled select | boolean | false | |
| dropdownClassName | The className of dropdown menu | string | - | |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| function(inputValue, option) | true | | | filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| function(inputValue, option) | true | |
| placeholder | The placeholder of input | string | - | | | placeholder | The placeholder of input | string | - | |
| value | Selected option | string | - | | | value | Selected option | string | - | |
@ -34,6 +36,7 @@ When there is a need for autocomplete functionality.
| onSelect | Called when a option is selected. param is option's value and option instance | function(value, option) | - | | | onSelect | Called when a option is selected. param is option's value and option instance | function(value, option) | - | |
| defaultOpen | Initial open state of dropdown | boolean | - | | | defaultOpen | Initial open state of dropdown | boolean | - | |
| open | Controlled open state of dropdown | boolean | - | | | open | Controlled open state of dropdown | boolean | - | |
| options | Select options. Will get better perf than jsx definition | { label, value }[] | - | |
| onDropdownVisibleChange | Call when dropdown open | function(open) | - | | | onDropdownVisibleChange | Call when dropdown open | function(open) | - | |
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | | | notFoundContent | Specify content to show when no result matches | string | `Not Found` | |

View File

@ -25,6 +25,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/qtJm4yt45/AutoComplete.svg
| defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | | | defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | |
| defaultValue | 指定默认选中的条目 | string | - | | | defaultValue | 指定默认选中的条目 | string | - | |
| disabled | 是否禁用 | boolean | false | | | disabled | 是否禁用 | boolean | false | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true反之则返回 false | boolean \| function(inputValue, option) | true | | | filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true反之则返回 false | boolean \| function(inputValue, option) | true | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |
| placeholder | 输入框提示 | string | - | | | placeholder | 输入框提示 | string | - | |
@ -36,6 +38,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/qtJm4yt45/AutoComplete.svg
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - | | | onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | | | defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| open | 是否展开下拉菜单 | boolean | - | | | open | 是否展开下拉菜单 | boolean | - | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }[] | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | | | onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | | | notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | |

View File

@ -241,6 +241,7 @@ exports[`Cascader can be selected 3`] = `
<div> <div>
<div <div
class="ant-cascader-menus ant-cascader-menus-hidden" class="ant-cascader-menus ant-cascader-menus-hidden"
style="pointer-events:none"
> >
<div> <div>
<ul <ul
@ -669,6 +670,7 @@ exports[`Cascader popup correctly when panel is hidden 1`] = `
<div> <div>
<div <div
class="ant-cascader-menus ant-cascader-menus-empty ant-cascader-menus-hidden" class="ant-cascader-menus ant-cascader-menus-empty ant-cascader-menus-hidden"
style="pointer-events:none"
> >
<div /> <div />
</div> </div>

View File

@ -13,6 +13,8 @@ export interface TextAreaProps extends RcTextAreaProps {
export interface TextAreaState { export interface TextAreaState {
value: any; value: any;
/** `value` from prev props */
prevValue: any;
} }
class TextArea extends React.Component<TextAreaProps, TextAreaState> { class TextArea extends React.Component<TextAreaProps, TextAreaState> {
@ -25,16 +27,17 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
const value = typeof props.value === 'undefined' ? props.defaultValue : props.value; const value = typeof props.value === 'undefined' ? props.defaultValue : props.value;
this.state = { this.state = {
value, value,
// eslint-disable-next-line react/no-unused-state
prevValue: props.value,
}; };
} }
static getDerivedStateFromProps(nextProps: TextAreaProps) { static getDerivedStateFromProps(nextProps: TextAreaProps, { prevValue }: TextAreaState) {
if (nextProps.value !== undefined) { const newState: Partial<TextAreaState> = { prevValue: nextProps.value };
return { if (nextProps.value !== undefined || prevValue !== nextProps.value) {
value: nextProps.value, newState.value = nextProps.value;
};
} }
return null; return newState;
} }
setValue(value: string, callback?: () => void) { setValue(value: string, callback?: () => void) {

View File

@ -124,6 +124,14 @@ describe('TextArea', () => {
}), }),
); );
}); });
it('should works same as Input', async () => {
const input = mount(<Input value="111" />);
const textarea = mount(<TextArea value="111" />);
input.setProps({ value: undefined });
textarea.setProps({ value: undefined });
expect(textarea.getDOMNode().value).toBe(input.getDOMNode().value);
});
}); });
describe('TextArea allowClear', () => { describe('TextArea allowClear', () => {

View File

@ -398,7 +398,7 @@ exports[`List.pagination should change page size work 2`] = `
<div> <div>
<div <div
class="ant-select-dropdown" class="ant-select-dropdown"
style="min-width: 0; opacity: 0; pointer-events: none;" style="pointer-events: none; min-width: 0; opacity: 0;"
> >
<div> <div>
<div <div

View File

@ -90,9 +90,9 @@
&-selection-placeholder { &-selection-placeholder {
flex: 1; flex: 1;
overflow: hidden; overflow: hidden;
color: @input-placeholder-color;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
opacity: 0.4;
// IE11 css hack. `*::-ms-backdrop,` is a must have // IE11 css hack. `*::-ms-backdrop,` is a must have
@media all and (-ms-high-contrast: none) { @media all and (-ms-high-contrast: none) {

View File

@ -67,7 +67,7 @@
// Opacity selection if open // Opacity selection if open
&.@{select-prefix-cls}-open .@{select-prefix-cls}-selection-item { &.@{select-prefix-cls}-open .@{select-prefix-cls}-selection-item {
opacity: 0.4; color: @input-placeholder-color;
} }
// ========================== Input ========================== // ========================== Input ==========================

View File

@ -115,6 +115,7 @@ exports[`Slider should show correct placement tooltip when set tooltipPlacement
<div> <div>
<div <div
class="ant-tooltip ant-slider-tooltip ant-tooltip-hidden" class="ant-tooltip ant-slider-tooltip ant-tooltip-hidden"
style="pointer-events:none"
> >
<div <div
class="ant-tooltip-content" class="ant-tooltip-content"
@ -168,6 +169,7 @@ exports[`Slider should show tooltip when hovering slider handler 2`] = `
<div> <div>
<div <div
class="ant-tooltip ant-slider-tooltip ant-tooltip-hidden" class="ant-tooltip ant-slider-tooltip ant-tooltip-hidden"
style="pointer-events:none"
> >
<div <div
class="ant-tooltip-content" class="ant-tooltip-content"

View File

@ -5,6 +5,10 @@
transform: scale(0); // need this by yiminghe transform: scale(0); // need this by yiminghe
opacity: 0; opacity: 0;
animation-timing-function: @ease-out-circ; animation-timing-function: @ease-out-circ;
&-prepare {
transform: none;
}
} }
.@{className}-leave { .@{className}-leave {
animation-timing-function: @ease-in-out-circ; animation-timing-function: @ease-in-out-circ;

View File

@ -36,6 +36,7 @@ exports[`Table.filter renders custom content correctly 1`] = `
<div> <div>
<div <div
class="ant-dropdown ant-dropdown-hidden" class="ant-dropdown ant-dropdown-hidden"
style="pointer-events: none;"
> >
<div <div
class="ant-table-filter-dropdown" class="ant-table-filter-dropdown"
@ -543,6 +544,7 @@ exports[`Table.filter renders menu correctly 1`] = `
<div> <div>
<div <div
class="ant-dropdown ant-dropdown-hidden" class="ant-dropdown ant-dropdown-hidden"
style="pointer-events: none;"
> >
<div <div
class="ant-table-filter-dropdown" class="ant-table-filter-dropdown"
@ -647,6 +649,7 @@ exports[`Table.filter renders radio filter correctly 1`] = `
<div> <div>
<div <div
class="ant-dropdown ant-dropdown-hidden" class="ant-dropdown ant-dropdown-hidden"
style="pointer-events: none;"
> >
<div <div
class="ant-table-filter-dropdown" class="ant-table-filter-dropdown"

View File

@ -929,6 +929,7 @@ exports[`Table.rowSelection render with default selection correctly 1`] = `
<div> <div>
<div <div
class="ant-dropdown ant-dropdown-hidden" class="ant-dropdown ant-dropdown-hidden"
style="pointer-events:none"
> >
<ul <ul
class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical" class="ant-dropdown-menu ant-dropdown-menu-light ant-dropdown-menu-root ant-dropdown-menu-vertical"

View File

@ -61,7 +61,7 @@ const columns = [
## API ## API
另外我们封装了 [ProTable](https://protable.ant.design/),在 `antd` Table 之上扩展了更多便捷易用的功能,内置搜索、筛选、刷新等常用表格行为,并为多种类型数据展示提供了内置格式化,欢迎尝试使用。 另外我们封装了 [ProTable](https://procomponents.ant.design/components/table),在 `antd` Table 之上扩展了更多便捷易用的功能,内置搜索、筛选、刷新等常用表格行为,并为多种类型数据展示提供了内置格式化,欢迎尝试使用。
### Table ### Table

View File

@ -18,14 +18,13 @@ describe('Upload', () => {
afterEach(() => teardown()); afterEach(() => teardown());
// Mock for rc-util raf // Mock for rc-util raf
window.requestAnimationFrame = (callback) => { window.requestAnimationFrame = callback => {
window.setTimeout(callback, 16); window.setTimeout(callback, 16);
}; };
window.cancelAnimationFrame = (id) => { window.cancelAnimationFrame = id => {
window.clearTimeout(id); window.clearTimeout(id);
}; };
// https://github.com/react-component/upload/issues/36 // https://github.com/react-component/upload/issues/36
it('should get refs inside Upload in componentDidMount', () => { it('should get refs inside Upload in componentDidMount', () => {
let ref; let ref;

View File

@ -807,30 +807,36 @@ describe('Upload List', () => {
}); });
describe('thumbUrl support for non-image', () => { describe('thumbUrl support for non-image', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
const nonImageFile = new File([''], 'foo.7z', { type: 'application/x-7z-compressed' }); const nonImageFile = new File([''], 'foo.7z', { type: 'application/x-7z-compressed' });
it('should render <img /> when upload non-image file and configure thumbUrl in onChange', done => {
/** Wait for a long promise since `rc-util` internal has at least 3 promise wait */
async function waitPromise() {
/* eslint-disable no-await-in-loop */
for (let i = 0; i < 10; i += 1) {
await Promise.resolve();
}
/* eslint-enable */
}
it('should render <img /> when upload non-image file and configure thumbUrl in onChange', async () => {
let wrapper; let wrapper;
const onChange = async ({ file, fileList: files }) => { const onChange = jest.fn(({ fileList: files }) => {
const newFileList = files.map(item => ({ const newFileList = files.map(item => ({
...item, ...item,
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
})); }));
wrapper.setProps({ fileList: newFileList }); wrapper.setProps({ fileList: newFileList });
if (file.status === 'uploading') {
return;
}
act(async () => {
await sleep();
wrapper.update();
}); });
const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img');
expect(imgNode.length).toBe(1);
done();
};
wrapper = mount( wrapper = mount(
<Upload <Upload
action="http://jsonplaceholder.typicode.com/posts/" action="http://jsonplaceholder.typicode.com/posts/"
@ -843,8 +849,27 @@ describe('Upload List', () => {
</Upload>, </Upload>,
); );
const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img'); const imgNode = wrapper.find('.ant-upload-list-item-thumbnail img');
expect(imgNode.length).toBe(0); expect(imgNode.length).toBeFalsy();
// Simulate change is a timeout change
wrapper.find('input').simulate('change', { target: { files: [nonImageFile] } }); wrapper.find('input').simulate('change', { target: { files: [nonImageFile] } });
// Wait for `rc-upload` process file
await waitPromise();
// Wait for mock request finish request
jest.runAllTimers();
// Basic called times
expect(onChange).toHaveBeenCalled();
// Check for images
act(() => {
jest.runAllTimers();
wrapper.update();
});
const afterImgNode = wrapper.find('.ant-upload-list-item-thumbnail img');
expect(afterImgNode.length).toBeTruthy();
}); });
it('should not render <img /> when upload non-image file without thumbUrl in onChange', done => { it('should not render <img /> when upload non-image file without thumbUrl in onChange', done => {

View File

@ -43,7 +43,7 @@ Sea Hare's color matching system is inspired by Ant Design's application of colo
### Default Asset Colors of Sea Hare ### Default Asset Colors of Sea Hare
<img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*t4D6QaFM2DAAAAAAAAAAAABkARQnAQ" /> <img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*0Dv9Rrp7GtMAAAAAAAAAAAAAARQnAQ" />
Through research, we discovered blue and white accounts for a large proportion among enterprise products. We chose Geek Blue as our primary color for its technological, exploration and focused vibes. Through research, we discovered blue and white accounts for a large proportion among enterprise products. We chose Geek Blue as our primary color for its technological, exploration and focused vibes.

View File

@ -43,7 +43,7 @@ title:
### 海兔默认资产颜色 ### 海兔默认资产颜色
<img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*t4D6QaFM2DAAAAAAAAAAAABkARQnAQ" /> <img class="preview-img no-padding" align="right" src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*0Dv9Rrp7GtMAAAAAAAAAAAAAARQnAQ" />
通过搜资调研,我们发现在企业级产品中。色彩的使用上蓝色,白色会占很大的比重。我们选取了色板中最具科技感,且代表着探索,钻研感的极客蓝作为我们的主色。 通过搜资调研,我们发现在企业级产品中。色彩的使用上蓝色,白色会占很大的比重。我们选取了色板中最具科技感,且代表着探索,钻研感的极客蓝作为我们的主色。

View File

@ -129,7 +129,7 @@
"rc-input-number": "~6.0.0", "rc-input-number": "~6.0.0",
"rc-mentions": "~1.4.0", "rc-mentions": "~1.4.0",
"rc-menu": "~8.5.2", "rc-menu": "~8.5.2",
"rc-motion": "^1.1.1", "rc-motion": "^2.0.0",
"rc-notification": "~4.4.0", "rc-notification": "~4.4.0",
"rc-pagination": "~3.0.3", "rc-pagination": "~3.0.3",
"rc-picker": "~2.0.6", "rc-picker": "~2.0.6",
@ -143,10 +143,10 @@
"rc-table": "~7.9.2", "rc-table": "~7.9.2",
"rc-tabs": "~11.6.0", "rc-tabs": "~11.6.0",
"rc-textarea": "~0.3.0", "rc-textarea": "~0.3.0",
"rc-tooltip": "~4.2.0", "rc-tooltip": "~5.0.0",
"rc-tree": "~3.9.0", "rc-tree": "~3.9.0",
"rc-tree-select": "~4.1.1", "rc-tree-select": "~4.1.1",
"rc-trigger": "~4.4.0", "rc-trigger": "~5.0.3",
"rc-upload": "~3.3.1", "rc-upload": "~3.3.1",
"rc-util": "^5.1.0", "rc-util": "^5.1.0",
"scroll-into-view-if-needed": "^2.2.25", "scroll-into-view-if-needed": "^2.2.25",