feat: inputNumber controls support customize upIcon/downIcon (#33914)

* feat: inputNumber controls support customize upIcon/downIcon

* feat: 修改代码格式问题

* feat: 更新snapshot,修改代码开启prettier

* feat: 更新snapshot,order 属性修改

* feat: upIcon/downIcon写法调整

* feat: 更新snapshot
This commit is contained in:
黑雨 2022-02-09 18:06:36 +08:00 committed by GitHub
parent 59ced6297d
commit ee17f7185d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 434 additions and 5 deletions

View File

@ -1008,6 +1008,90 @@ exports[`renders ./components/input-number/demo/borderless.md extend context cor
</div> </div>
`; `;
exports[`renders ./components/input-number/demo/controls.md extend context correctly 1`] = `
<div
class="ant-input-number"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-up-inner"
>
<span
aria-label="arrow-up"
class="anticon anticon-arrow-up"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M868 545.5L536.1 163a31.96 31.96 0 00-48.3 0L156 545.5a7.97 7.97 0 006 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2z"
/>
</svg>
</span>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-down-inner"
>
<span
aria-label="arrow-down"
class="anticon anticon-arrow-down"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M862 465.3h-81c-4.6 0-9 2-12.1 5.5L550 723.1V160c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v563.1L255.1 470.8c-3-3.5-7.4-5.5-12.1-5.5h-81c-6.8 0-10.5 8.1-6 13.2L487.9 861a31.96 31.96 0 0048.3 0L868 478.5c4.5-5.2.8-13.2-6-13.2z"
/>
</svg>
</span>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
`;
exports[`renders ./components/input-number/demo/digit.md extend context correctly 1`] = ` exports[`renders ./components/input-number/demo/digit.md extend context correctly 1`] = `
<div <div
class="ant-input-number" class="ant-input-number"

View File

@ -735,6 +735,90 @@ exports[`renders ./components/input-number/demo/borderless.md correctly 1`] = `
</div> </div>
`; `;
exports[`renders ./components/input-number/demo/controls.md correctly 1`] = `
<div
class="ant-input-number"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-up-inner"
>
<span
aria-label="arrow-up"
class="anticon anticon-arrow-up"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M868 545.5L536.1 163a31.96 31.96 0 00-48.3 0L156 545.5a7.97 7.97 0 006 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2z"
/>
</svg>
</span>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-down-inner"
>
<span
aria-label="arrow-down"
class="anticon anticon-arrow-down"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M862 465.3h-81c-4.6 0-9 2-12.1 5.5L550 723.1V160c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v563.1L255.1 470.8c-3-3.5-7.4-5.5-12.1-5.5h-81c-6.8 0-10.5 8.1-6 13.2L487.9 861a31.96 31.96 0 0048.3 0L868 478.5c4.5-5.2.8-13.2-6-13.2z"
/>
</svg>
</span>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
`;
exports[`renders ./components/input-number/demo/digit.md correctly 1`] = ` exports[`renders ./components/input-number/demo/digit.md correctly 1`] = `
<div <div
class="ant-input-number" class="ant-input-number"

View File

@ -1,5 +1,183 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`InputNumber renders correctly when controls has custom upIcon and downIcon 1`] = `
<div
class="ant-input-number"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-up-inner"
>
<span
aria-label="arrow-up"
class="anticon anticon-arrow-up"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M868 545.5L536.1 163a31.96 31.96 0 00-48.3 0L156 545.5a7.97 7.97 0 006 13.2h81c4.6 0 9-2 12.1-5.5L474 300.9V864c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V300.9l218.9 252.3c3 3.5 7.4 5.5 12.1 5.5h81c6.8 0 10.5-8 6-13.2z"
/>
</svg>
</span>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
class="ant-input-number-handler-down-inner"
>
<span
aria-label="arrow-down"
class="anticon anticon-arrow-down"
role="img"
>
<svg
aria-hidden="true"
data-icon="arrow-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M862 465.3h-81c-4.6 0-9 2-12.1 5.5L550 723.1V160c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v563.1L255.1 470.8c-3-3.5-7.4-5.5-12.1-5.5h-81c-6.8 0-10.5 8.1-6 13.2L487.9 861a31.96 31.96 0 0048.3 0L868 478.5c4.5-5.2.8-13.2-6-13.2z"
/>
</svg>
</span>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
`;
exports[`InputNumber renders correctly when controls is {} 1`] = `
<div
class="ant-input-number"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
`;
exports[`InputNumber renders correctly when controls is boolean 1`] = `
<div
class="ant-input-number"
>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
`;
exports[`InputNumber rtl render component should be rendered correctly in RTL direction 1`] = ` exports[`InputNumber rtl render component should be rendered correctly in RTL direction 1`] = `
<div <div
class="ant-input-number ant-input-number-rtl" class="ant-input-number ant-input-number-rtl"

View File

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
import InputNumber from '..'; import InputNumber from '..';
import focusTest from '../../../tests/shared/focusTest'; import focusTest from '../../../tests/shared/focusTest';
import mountTest from '../../../tests/shared/mountTest'; import mountTest from '../../../tests/shared/mountTest';
@ -28,4 +29,41 @@ describe('InputNumber', () => {
expect(onStep).toBeCalledTimes(2); expect(onStep).toBeCalledTimes(2);
expect(onStep).toHaveBeenLastCalledWith(1, { offset: 1, type: 'down' }); expect(onStep).toHaveBeenLastCalledWith(1, { offset: 1, type: 'down' });
}); });
it('renders correctly when controls is boolean', () => {
expect(mount(<InputNumber controls={false} />).render()).toMatchSnapshot();
});
it('renders correctly when controls is {}', () => {
expect(mount(<InputNumber controls={{}} />).render()).toMatchSnapshot();
});
it('renders correctly when controls has custom upIcon and downIcon', () => {
const wrapper = mount(
<InputNumber
controls={{
upIcon: <ArrowUpOutlined />,
downIcon: <ArrowDownOutlined />,
}}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
});
it('should support className', () => {
const wrapper = mount(
<InputNumber
controls={{
upIcon: <ArrowUpOutlined className="my-class-name" />,
downIcon: <ArrowDownOutlined className="my-class-name" />,
}}
/>,
);
expect(wrapper.find('.anticon-arrow-up').getDOMNode().className.includes('my-class-name')).toBe(
true,
);
expect(
wrapper.find('.anticon-arrow-down').getDOMNode().className.includes('my-class-name'),
).toBe(true);
});
}); });

View File

@ -0,0 +1,26 @@
---
order: 99
debug: true
title:
zh-CN: 图标按钮
en-US: Icon
---
## zh-CN
可以扩展 `controls` 属性用以设置自定义图标。
## en-US
When you need to use a custom `Icon`, you can set the `Icon` component as the property value of `upIcon` and `downIcon`.
```jsx
import { InputNumber } from 'antd';
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
ReactDOM.render(
<InputNumber
controls={{ upIcon: <ArrowUpOutlined />, downIcon: <ArrowDownOutlined/> }}
/>
, mountNode);
```

View File

@ -19,7 +19,7 @@ When a numeric value needs to be provided.
| addonBefore | The label text displayed before (on the left side of) the input field | ReactNode | - | | | addonBefore | The label text displayed before (on the left side of) the input field | ReactNode | - | |
| autoFocus | If get focus when component mounted | boolean | false | - | | autoFocus | If get focus when component mounted | boolean | false | - |
| bordered | Whether has border style | boolean | true | 4.12.0 | | bordered | Whether has border style | boolean | true | 4.12.0 |
| controls | Whether to show `+-` controls | boolean | true | 4.17.0 | | controls | Whether to show `+-` controls, or set custom arrows icon | boolean \| { upIcon?: React.ReactNode; downIcon?: React.ReactNode; } | - | 4.19.0 |
| decimalSeparator | Decimal separator | string | - | - | | decimalSeparator | Decimal separator | string | - | - |
| defaultValue | The initial value | number | - | - | | defaultValue | The initial value | number | - | - |
| disabled | If disable the input | boolean | false | - | | disabled | If disable the input | boolean | false | - |

View File

@ -11,13 +11,14 @@ import { cloneElement } from '../_util/reactNode';
type ValueType = string | number; type ValueType = string | number;
export interface InputNumberProps<T extends ValueType = ValueType> export interface InputNumberProps<T extends ValueType = ValueType>
extends Omit<RcInputNumberProps<T>, 'prefix' | 'size'> { extends Omit<RcInputNumberProps<T>, 'prefix' | 'size' | 'controls'> {
prefixCls?: string; prefixCls?: string;
addonBefore?: React.ReactNode; addonBefore?: React.ReactNode;
addonAfter?: React.ReactNode; addonAfter?: React.ReactNode;
prefix?: React.ReactNode; prefix?: React.ReactNode;
size?: SizeType; size?: SizeType;
bordered?: boolean; bordered?: boolean;
controls?: boolean | { upIcon?: React.ReactNode; downIcon?: React.ReactNode };
} }
const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props, ref) => { const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props, ref) => {
@ -37,12 +38,29 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
prefix, prefix,
bordered = true, bordered = true,
readOnly, readOnly,
controls,
...others ...others
} = props; } = props;
const prefixCls = getPrefixCls('input-number', customizePrefixCls); const prefixCls = getPrefixCls('input-number', customizePrefixCls);
const upIcon = <UpOutlined className={`${prefixCls}-handler-up-inner`} />; let upIcon = <UpOutlined className={`${prefixCls}-handler-up-inner`} />;
const downIcon = <DownOutlined className={`${prefixCls}-handler-down-inner`} />; let downIcon = <DownOutlined className={`${prefixCls}-handler-down-inner`} />;
const controlsTemp = typeof controls === 'boolean' ? controls : undefined;
if (typeof controls === 'object') {
upIcon =
typeof controls.upIcon === 'undefined' ? (
upIcon
) : (
<span className={`${prefixCls}-handler-up-inner`}>{controls.upIcon}</span>
);
downIcon =
typeof controls.downIcon === 'undefined' ? (
downIcon
) : (
<span className={`${prefixCls}-handler-down-inner`}>{controls.downIcon}</span>
);
}
const mergeSize = customizeSize || size; const mergeSize = customizeSize || size;
const inputNumberClass = classNames( const inputNumberClass = classNames(
@ -64,6 +82,7 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
downHandler={downIcon} downHandler={downIcon}
prefixCls={prefixCls} prefixCls={prefixCls}
readOnly={readOnly} readOnly={readOnly}
controls={controlsTemp}
{...others} {...others}
/> />
); );

View File

@ -22,7 +22,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
| addonBefore | 带标签的 input设置前置标签 | ReactNode | - | 4.17.0 | | addonBefore | 带标签的 input设置前置标签 | ReactNode | - | 4.17.0 |
| autoFocus | 自动获取焦点 | boolean | false | - | | autoFocus | 自动获取焦点 | boolean | false | - |
| bordered | 是否有边框 | boolean | true | 4.12.0 | | bordered | 是否有边框 | boolean | true | 4.12.0 |
| controls | 是否显示增减按钮 | boolean | true | 4.17.0 | | controls | 是否显示增减按钮,也可设置自定义箭头图标 | boolean \| { upIcon?: React.ReactNode; downIcon?: React.ReactNode; } | - | 4.19.0 |
| decimalSeparator | 小数点 | string | - | - | | decimalSeparator | 小数点 | string | - | - |
| defaultValue | 初始值 | number | - | - | | defaultValue | 初始值 | number | - | - |
| disabled | 禁用 | boolean | false | - | | disabled | 禁用 | boolean | false | - |