Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Input.Search): add loading prop #18771

Merged
merged 4 commits into from Sep 12, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 28 additions & 4 deletions components/input/Search.tsx
Expand Up @@ -11,7 +11,8 @@ export interface SearchProps extends InputProps {
value: string,
event?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLInputElement>,
) => void;
enterButton?: boolean | React.ReactNode;
enterButton?: React.ReactNode;
loading?: boolean;
}

export default class Search extends React.Component<SearchProps, any> {
Expand Down Expand Up @@ -41,8 +42,26 @@ export default class Search extends React.Component<SearchProps, any> {
this.input.blur();
}

renderLoading = (prefixCls: string) => {
const { enterButton, size } = this.props;

if (enterButton) {
return (
<Button className={`${prefixCls}-button`} type="primary" size={size} key="enterButton">
<Icon type="loading" />
</Button>
);
}
return <Icon className={`${prefixCls}-icon`} type="loading" />;
};

renderSuffix = (prefixCls: string) => {
const { suffix, enterButton } = this.props;
const { suffix, enterButton, loading } = this.props;

if (loading && !enterButton) {
shaodahong marked this conversation as resolved.
Show resolved Hide resolved
return this.renderLoading(prefixCls);
}

if (enterButton) return suffix;

const node = (
Expand All @@ -68,10 +87,15 @@ export default class Search extends React.Component<SearchProps, any> {
};

renderAddonAfter = (prefixCls: string) => {
const { enterButton, size, disabled, addonAfter } = this.props;
if (!enterButton) return addonAfter;
const { enterButton, size, disabled, addonAfter, loading } = this.props;
const btnClassName = `${prefixCls}-button`;

if (loading && enterButton) {
shaodahong marked this conversation as resolved.
Show resolved Hide resolved
return this.renderLoading(prefixCls);
}

if (!enterButton) return addonAfter;
shaodahong marked this conversation as resolved.
Show resolved Hide resolved

let button: React.ReactNode;
const enterButtonAsElement = enterButton as React.ReactElement<any>;
if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
Expand Down
7 changes: 7 additions & 0 deletions components/input/__tests__/Search.test.js
Expand Up @@ -137,4 +137,11 @@ describe('Input.Search', () => {
expect(wrapper.render()).toMatchSnapshot();
expect(wrapperWithEnterButton.render()).toMatchSnapshot();
});

it('should support loading', () => {
const wrapper = mount(<Search loading />);
const wrapperWithEnterButton = mount(<Search loading enterButton />);
expect(wrapper.render()).toMatchSnapshot();
expect(wrapperWithEnterButton.render()).toMatchSnapshot();
});
});
79 changes: 79 additions & 0 deletions components/input/__tests__/__snapshots__/Search.test.js.snap
Expand Up @@ -150,3 +150,82 @@ exports[`Input.Search should support custom button 1`] = `
</span>
</span>
`;

exports[`Input.Search should support loading 1`] = `
<span
class="ant-input-search ant-input-affix-wrapper"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading ant-input-search-icon"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</i>
</span>
</span>
`;

exports[`Input.Search should support loading 2`] = `
<span
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-input-search-button ant-btn-primary"
type="button"
>
<i
aria-label="icon: loading"
class="anticon anticon-loading"
>
<svg
aria-hidden="true"
class="anticon-spin"
data-icon="loading"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
/>
</svg>
</i>
</button>
</span>
</span>
</span>
`;
112 changes: 112 additions & 0 deletions components/input/__tests__/__snapshots__/demo.test.js.snap
Expand Up @@ -1811,6 +1811,118 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
</div>
`;

exports[`renders ./components/input/demo/search-input-loading.md correctly 1`] = `
<div>
<span
class="ant-input-search ant-input-affix-wrapper"
style="width:200px"
>
<input
class="ant-input"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-suffix"
>
<i
aria-label="icon: search"
class="anticon anticon-search ant-input-search-icon"
tabindex="-1"
>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</i>
</span>
</span>
<br />
<br />
<span
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-input-search-button ant-btn-primary"
type="button"
>
<i
aria-label="icon: search"
class="anticon anticon-search"
>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0 0 11.6 0l43.6-43.5a8.2 8.2 0 0 0 0-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</i>
</button>
</span>
</span>
</span>
<br />
<br />
<span
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-input-search-button ant-btn-primary"
type="button"
>
<span>
Search
</span>
</button>
</span>
</span>
</span>
</div>
`;

exports[`renders ./components/input/demo/size.md correctly 1`] = `
<div
class="example-input"
Expand Down
68 changes: 68 additions & 0 deletions components/input/demo/search-input-loading.md
@@ -0,0 +1,68 @@
---
order: 5
title:
zh-CN: 搜索框 loading
en-US: Search box with loading
---

## zh-CN

搜索框 loading
shaodahong marked this conversation as resolved.
Show resolved Hide resolved

## en-US

search loading when onSearch
shaodahong marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import { Input } from 'antd';

const { Search } = Input;

class InputSearch extends React.Component {
state = {
loading: false,
};

onSearch = () => {
this.setState({
loading: true,
});
setTimeout(() => {
this.setState({
loading: false,
});
}, 2000);
};

render() {
return (
<div>
<Search
placeholder="input search text"
onSearch={this.onSearch}
style={{ width: 200 }}
loading={this.state.loading}
/>
<br />
<br />
<Search
placeholder="input search text"
onSearch={this.onSearch}
loading={this.state.loading}
enterButton
/>
<br />
<br />
<Search
placeholder="input search text"
onSearch={this.onSearch}
loading={this.state.loading}
enterButton="Search"
/>
</div>
);
}
}

ReactDOM.render(<InputSearch />, mountNode);
shaodahong marked this conversation as resolved.
Show resolved Hide resolved
```
1 change: 1 addition & 0 deletions components/input/index.en-US.md
Expand Up @@ -56,6 +56,7 @@ The rest of the props of `Input.TextArea` are the same as the original [textarea
| --- | --- | --- | --- | --- |
| enterButton | to show an enter button after input. This prop is conflict with addon. | boolean\|ReactNode | false | |
| onSearch | The callback function that is triggered when you click on the search-icon or press Enter key. | function(value, event) | | |
| loading | Search box with loading. | boolean | | |

Supports all props of `Input`.

Expand Down
1 change: 1 addition & 0 deletions components/input/index.zh-CN.md
Expand Up @@ -55,6 +55,7 @@ Input 的其他属性和 React 自带的 [input](https://facebook.github.io/reac
| --- | --- | --- | --- | --- |
| enterButton | 是否有确认按钮,可设为按钮文字。该属性会与 addon 冲突。 | boolean\|ReactNode | false | |
| onSearch | 点击搜索或按下回车键时的回调 | function(value, event) | | |
| loading | 搜索 loading | boolean | | |

其余属性和 Input 一致。

Expand Down