Use addonAfter instead of suffix when use enterButton in Input.Search (#14461)

fix #14450
This commit is contained in:
zombieJ 2019-01-25 11:06:05 +08:00 committed by GitHub
parent 18332d8e76
commit 5ac80c8e55
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 181 additions and 162 deletions

View File

@ -185,38 +185,36 @@ class Input extends React.Component<InputProps, any> {
}
renderLabeledInput(prefixCls: string, children: React.ReactElement<any>) {
const props = this.props;
const { addonBefore, addonAfter, style, size, className } = this.props;
// Not wrap when there is not addons
if (!props.addonBefore && !props.addonAfter) {
if (!addonBefore && !addonAfter) {
return children;
}
const wrapperClassName = `${prefixCls}-group`;
const addonClassName = `${wrapperClassName}-addon`;
const addonBefore = props.addonBefore ? (
<span className={addonClassName}>{props.addonBefore}</span>
) : null;
const addonAfter = props.addonAfter ? (
<span className={addonClassName}>{props.addonAfter}</span>
const addonBeforeNode = addonBefore ? (
<span className={addonClassName}>{addonBefore}</span>
) : null;
const addonAfterNode = addonAfter ? <span className={addonClassName}>{addonAfter}</span> : null;
const className = classNames(`${prefixCls}-wrapper`, {
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, {
[wrapperClassName]: addonBefore || addonAfter,
});
const groupClassName = classNames(`${prefixCls}-group-wrapper`, {
[`${prefixCls}-group-wrapper-sm`]: props.size === 'small',
[`${prefixCls}-group-wrapper-lg`]: props.size === 'large',
const mergedGroupClassName = classNames(className, `${prefixCls}-group-wrapper`, {
[`${prefixCls}-group-wrapper-sm`]: size === 'small',
[`${prefixCls}-group-wrapper-lg`]: size === 'large',
});
// Need another wrapper for changing display:table to display:inline-block
// and put style prop in wrapper
return (
<span className={groupClassName} style={props.style}>
<span className={className}>
{addonBefore}
<span className={mergedGroupClassName} style={style}>
<span className={mergedWrapperClassName}>
{addonBeforeNode}
{React.cloneElement(children, { style: null })}
{addonAfter}
{addonAfterNode}
</span>
</span>
);
@ -251,7 +249,7 @@ class Input extends React.Component<InputProps, any> {
}
renderInput(prefixCls: string) {
const { className } = this.props;
const { className, addonBefore, addonAfter } = this.props;
const { value } = this.state;
// Fix https://fb.me/react-unknown-prop
const otherProps = omit(this.props, [
@ -273,7 +271,9 @@ class Input extends React.Component<InputProps, any> {
{...otherProps}
value={fixControlledValue(value)}
onChange={this.handleChange}
className={classNames(this.getInputClassName(prefixCls), className)}
className={classNames(this.getInputClassName(prefixCls), {
[className!]: className && !addonBefore && !addonAfter,
})}
onKeyDown={this.handleKeyDown}
ref={this.saveInput}
/>,

View File

@ -41,76 +41,100 @@ export default class Search extends React.Component<SearchProps, any> {
this.input = node;
};
getButtonOrIcon(prefixCls: string) {
renderSuffix = (prefixCls: string) => {
const { suffix, enterButton } = this.props;
if (enterButton) return suffix;
const node = (
<Icon
className={`${prefixCls}-icon`}
type="search"
key="searchIcon"
onClick={this.onSearch}
/>
);
if (suffix) {
let cloneSuffix = suffix;
if (React.isValidElement(cloneSuffix) && !cloneSuffix.key) {
cloneSuffix = React.cloneElement(cloneSuffix, {
key: 'originSuffix',
});
}
return [cloneSuffix, node];
}
return node;
};
renderAddonAfter = (prefixCls: string) => {
const { enterButton, size, disabled } = this.props;
if (!enterButton) return null;
const btnClassName = `${prefixCls}-button`;
const enterButtonAsElement = enterButton as React.ReactElement<any>;
let node;
if (!enterButton) {
node = <Icon className={`${prefixCls}-icon`} type="search" key="searchIcon" />;
} else if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
node = React.cloneElement(
enterButtonAsElement,
enterButtonAsElement.type === Button
if (enterButtonAsElement.type === Button || enterButtonAsElement.type === 'button') {
return React.cloneElement(enterButtonAsElement, {
onClick: this.onSearch,
...(enterButtonAsElement.type === Button
? {
className: `${prefixCls}-button`,
className: btnClassName,
size,
}
: {},
);
} else {
node = (
<Button
className={`${prefixCls}-button`}
type="primary"
size={size}
disabled={disabled}
key="enterButton"
>
{enterButton === true ? <Icon type="search" /> : enterButton}
</Button>
);
: {}),
});
}
return React.cloneElement(node, {
onClick: this.onSearch,
});
}
return (
<Button
className={btnClassName}
type="primary"
size={size}
disabled={disabled}
key="enterButton"
onClick={this.onSearch}
>
{enterButton === true ? <Icon type="search" /> : enterButton}
</Button>
);
};
renderSearch = ({ getPrefixCls }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
inputPrefixCls: customizeInputPrefixCls,
className,
size,
suffix,
enterButton,
...others
className,
...restProps
} = this.props;
delete (others as any).onSearch;
delete (restProps as any).onSearch;
const prefixCls = getPrefixCls('input-search', customizePrefixCls);
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
const buttonOrIcon = this.getButtonOrIcon(prefixCls);
let searchSuffix = suffix ? [suffix, buttonOrIcon] : buttonOrIcon;
if (Array.isArray(searchSuffix)) {
searchSuffix = (searchSuffix as React.ReactElement<any>[]).map((item, index) => {
if (!React.isValidElement(item) || item.key) {
return item;
}
return React.cloneElement(item, { key: index });
let inputClassName;
if (enterButton) {
inputClassName = classNames(prefixCls, className, {
[`${prefixCls}-enter-button`]: !!enterButton,
[`${prefixCls}-${size}`]: !!size,
});
} else {
inputClassName = classNames(prefixCls, className);
}
const inputClassName = classNames(prefixCls, className, {
[`${prefixCls}-enter-button`]: !!enterButton,
[`${prefixCls}-${size}`]: !!size,
});
return (
<Input
onPressEnter={this.onSearch}
{...others}
{...restProps}
size={size}
className={inputClassName}
prefixCls={inputPrefixCls}
suffix={searchSuffix}
addonAfter={this.renderAddonAfter(prefixCls)}
suffix={this.renderSuffix(prefixCls)}
ref={this.saveInput}
className={inputClassName}
/>
);
};

View File

@ -2,45 +2,53 @@
exports[`Input.Search should support custom Button 1`] = `
<span
class="ant-input-search ant-input-search-enter-button ant-input-affix-wrapper"
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
class="ant-input-wrapper ant-input-group"
>
<button
class="ant-btn ant-input-search-button"
type="button"
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<span>
ok
</span>
</button>
<button
class="ant-btn ant-input-search-button"
type="button"
>
<span>
ok
</span>
</button>
</span>
</span>
</span>
`;
exports[`Input.Search should support custom button 1`] = `
<span
class="ant-input-search ant-input-search-enter-button ant-input-affix-wrapper"
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
class="ant-input-wrapper ant-input-group"
>
<button
type="button"
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
ok
</button>
<button
type="button"
>
ok
</button>
</span>
</span>
</span>
`;

View File

@ -1009,63 +1009,71 @@ exports[`renders ./components/input/demo/search-input.md correctly 1`] = `
<br />
<br />
<span
class="ant-input-search ant-input-search-enter-button ant-input-affix-wrapper"
class="ant-input-search ant-input-search-enter-button ant-input-group-wrapper"
>
<input
class="ant-input"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-suffix"
class="ant-input-wrapper ant-input-group"
>
<button
class="ant-btn ant-input-search-button ant-btn-primary"
type="button"
<input
class="ant-input"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<i
class="anticon anticon-search"
<button
class="ant-btn ant-input-search-button ant-btn-primary"
type="button"
>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
height="1em"
viewBox="64 64 896 896"
width="1em"
<i
class="anticon anticon-search"
>
<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>
<svg
aria-hidden="true"
class=""
data-icon="search"
fill="currentColor"
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-search-large ant-input-affix-wrapper ant-input-affix-wrapper-lg"
class="ant-input-search ant-input-search-enter-button ant-input-search-large ant-input-group-wrapper ant-input-group-wrapper-lg"
>
<input
class="ant-input ant-input-lg"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-suffix"
class="ant-input-wrapper ant-input-group"
>
<button
class="ant-btn ant-input-search-button ant-btn-primary ant-btn-lg"
type="button"
<input
class="ant-input ant-input-lg"
placeholder="input search text"
type="text"
value=""
/>
<span
class="ant-input-group-addon"
>
<span>
Search
</span>
</button>
<button
class="ant-btn ant-input-search-button ant-btn-primary ant-btn-lg"
type="button"
>
<span>
Search
</span>
</button>
</span>
</span>
</span>
</div>

View File

@ -351,6 +351,7 @@ exports[`Input.Search should support suffix 1`] = `
>
<Consumer>
<Input
addonAfter={null}
className="ant-input-search"
disabled={false}
onPressEnter={[Function]}

View File

@ -1,8 +1,8 @@
---
order: 2
title:
zh-CN: 前置/后置标签
en-US: Pre / Post tab
zh-CN: 前置/后置标签
en-US: Pre / Post tab
---
## zh-CN

View File

@ -1,8 +1,8 @@
---
order: 1
title:
zh-CN: 三种大小
en-US: Three sizes of Input
zh-CN: 三种大小
en-US: Three sizes of Input
---
## zh-CN

View File

@ -15,36 +15,14 @@
}
}
&:not(&-small) > .@{ant-prefix}-input-suffix {
right: @control-padding-horizontal;
}
.@{ant-prefix}-input-group-addon {
border: 0;
padding: 0;
> .@{ant-prefix}-input-suffix > .@{search-prefix}-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
> .@{iconfont-css-prefix}-search {
font-size: @font-size-lg;
}
}
&.@{search-prefix}-enter-button {
display: table;
> * {
display: table-cell;
}
> .@{ant-prefix}-input {
.input;
.@{search-prefix}-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
width: 100%;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
border-right: 0;
}
> .@{ant-prefix}-input-suffix {
position: static;
transform: none;
}
}
}