¥
-
+
+
+
`;
+
+exports[`renders ./components/input-number/demo/size.vue correctly 1`] = `
+
+`;
diff --git a/components/input-number/demo/formatter.vue b/components/input-number/demo/formatter.vue
index 33f482cd2..58e8673c1 100644
--- a/components/input-number/demo/formatter.vue
+++ b/components/input-number/demo/formatter.vue
@@ -17,7 +17,7 @@ Display value within it's situation with `formatter`, and we usually use `parser
-
+
diff --git a/components/input-number/demo/size.vue b/components/input-number/demo/size.vue
index 47109c999..4b31fc377 100644
--- a/components/input-number/demo/size.vue
+++ b/components/input-number/demo/size.vue
@@ -17,11 +17,11 @@ There are three sizes available to a numeric input box. By default, the size is
-
+
-
diff --git a/components/input-number/index.en-US.md b/components/input-number/index.en-US.md
index 399b67ebd..54e3723f5 100644
--- a/components/input-number/index.en-US.md
+++ b/components/input-number/index.en-US.md
@@ -18,7 +18,7 @@ When a numeric value needs to be provided.
| autofocus | get focus when component mounted | boolean | false |
| defaultValue | initial value | number | |
| disabled | disable the input | boolean | false |
-| formatter | Specifies the format of the value presented | function(value: number \| string): string | - |
+| formatter | Specifies the format of the value presented | function(value: number \| string, info: { userTyping: boolean, input: string }): string | - | info: 3.0 |
| max | max value | number | Infinity |
| min | min value | number | -Infinity |
| parser | Specifies the value extracted from formatter | function( string): number | - |
@@ -33,6 +33,8 @@ When a numeric value needs to be provided.
| controls | Whether to show `+-` controls | boolean | true | 3.0 |
| keyboard | If enable keyboard behavior | boolean | true | 3.0 |
| stringMode | Set value as string to support high precision decimals. Will return string value by `change` | boolean | false | 3.0 |
+| controls | Whether to show `+-` controls | boolean | true | 3.0 |
+| prefix | The prefix icon for the Input | slot | - | 3.0 |
### events
diff --git a/components/input-number/index.tsx b/components/input-number/index.tsx
index 14221e357..149bf5cfa 100644
--- a/components/input-number/index.tsx
+++ b/components/input-number/index.tsx
@@ -21,6 +21,7 @@ export const inputNumberProps = {
type: String,
addonBefore: PropTypes.any,
addonAfter: PropTypes.any,
+ prefix: PropTypes.any,
'update:value': baseInputNumberProps.onChange,
};
@@ -31,11 +32,12 @@ const InputNumber = defineComponent({
inheritAttrs: false,
props: inputNumberProps,
emits: ['focus', 'blur', 'change', 'input', 'update:value'],
- slots: ['addonBefore', 'addonAfter'],
+ slots: ['addonBefore', 'addonAfter', 'prefix'],
setup(props, { emit, expose, attrs, slots }) {
const formItemContext = useInjectFormItemContext();
const { prefixCls, size, direction } = useConfigInject('input-number', props);
const mergedValue = ref(props.value === undefined ? props.defaultValue : props.value);
+ const focused = ref(false);
watch(
() => props.value,
() => {
@@ -62,10 +64,12 @@ const InputNumber = defineComponent({
formItemContext.onFieldChange();
};
const handleBlur = () => {
+ focused.value = false;
emit('blur');
formItemContext.onFieldBlur();
};
const handleFocus = () => {
+ focused.value = true;
emit('focus');
};
onMounted(() => {
@@ -85,6 +89,7 @@ const InputNumber = defineComponent({
style,
addonBefore = slots.addonBefore?.(),
addonAfter = slots.addonAfter?.(),
+ prefix = slots.prefix?.(),
...others
} = { ...(attrs as HTMLAttributes), ...props };
@@ -102,7 +107,7 @@ const InputNumber = defineComponent({
className,
);
- const element = (
+ let element = (
);
+ const hasAddon = isValidValue(addonBefore) || isValidValue(addonAfter);
+ if (isValidValue(prefix)) {
+ const affixWrapperCls = classNames(`${preCls}-affix-wrapper`, {
+ [`${preCls}-affix-wrapper-focused`]: focused.value,
+ [`${preCls}-affix-wrapper-disabled`]: props.disabled,
+ [`${preCls}-affix-wrapper-sm`]: size.value === 'small',
+ [`${preCls}-affix-wrapper-lg`]: size.value === 'large',
+ [`${preCls}-affix-wrapper-rtl`]: direction.value === 'rtl',
+ [`${preCls}-affix-wrapper-readonly`]: readonly,
+ [`${preCls}-affix-wrapper-borderless`]: !bordered,
+ // className will go to addon wrapper
+ [`${className}`]: !hasAddon && className,
+ });
+ element = (
+
inputNumberRef.value!.focus()}
+ >
+ {prefix}
+ {element}
+
+ );
+ }
- if (isValidValue(addonBefore) || isValidValue(addonAfter)) {
+ if (hasAddon) {
const wrapperClassName = `${preCls}-group`;
const addonClassName = `${wrapperClassName}-addon`;
const addonBeforeNode = addonBefore ? (
@@ -141,7 +170,7 @@ const InputNumber = defineComponent({
},
className,
);
- return (
+ element = (
{addonBeforeNode}
diff --git a/components/input-number/index.zh-CN.md b/components/input-number/index.zh-CN.md
index 88b1ab824..1a2fb6c53 100644
--- a/components/input-number/index.zh-CN.md
+++ b/components/input-number/index.zh-CN.md
@@ -21,7 +21,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
| autofocus | 自动获取焦点 | boolean | false | |
| defaultValue | 初始值 | number | | |
| disabled | 禁用 | boolean | false | |
-| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - | |
+| formatter | 指定输入框展示值的格式 | function(value: number \| string, info: { userTyping: boolean, input: string }): string | - | info: 3.0 |
| max | 最大值 | number | Infinity | |
| min | 最小值 | number | -Infinity | |
| parser | 指定从 formatter 里转换回数字的方式,和 formatter 搭配使用 | function( string): number | - | |
@@ -36,6 +36,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
| controls | 是否显示增减按钮 | boolean | true | 3.0 |
| keyboard | 是否启用键盘快捷行为 | boolean | true | 3.0 |
| stringMode | 字符值模式,开启后支持高精度小数。同时 `change` 事件将返回 string 类型 | boolean | false | 3.0 |
+| controls | 是否显示增减按钮 | boolean | true | 3.0 |
+| prefix | 带有前缀图标的 input | slot | - | 3.0 |
### 事件
diff --git a/components/input-number/style/affix.less b/components/input-number/style/affix.less
new file mode 100644
index 000000000..372490728
--- /dev/null
+++ b/components/input-number/style/affix.less
@@ -0,0 +1,64 @@
+@import '../../input/style/mixin';
+@import (reference) '../../style/themes/index';
+@input-prefix-cls: ~'@{ant-prefix}-input';
+
+@input-affix-margin: 4px;
+
+.@{ant-prefix}-input-number {
+ &-affix-wrapper {
+ .input();
+ // or number handler will cover form status
+ position: static;
+ display: inline-flex;
+ width: 90px;
+ padding: 0;
+ padding-inline-start: @input-padding-horizontal-base;
+
+ &:not(&-disabled):hover {
+ .hover();
+ z-index: 1;
+ }
+
+ &-focused,
+ &:focus {
+ z-index: 1;
+ }
+
+ &-disabled {
+ .@{ant-prefix}-input-number[disabled] {
+ background: transparent;
+ }
+ }
+
+ > div.@{ant-prefix}-input-number {
+ width: 100%;
+ border: none;
+ outline: none;
+
+ &.@{ant-prefix}-input-number-focused {
+ box-shadow: none !important;
+ }
+ }
+
+ input.@{ant-prefix}-input-number-input {
+ padding: 0;
+ }
+
+ &::before {
+ width: 0;
+ visibility: hidden;
+ content: '\a0';
+ }
+ }
+
+ &-prefix {
+ display: flex;
+ flex: none;
+ align-items: center;
+ margin-inline-end: @input-affix-margin;
+ }
+}
+
+.@{ant-prefix}-input-number-group-wrapper .@{ant-prefix}-input-number-affix-wrapper {
+ width: 100%;
+}
diff --git a/components/input-number/style/index.less b/components/input-number/style/index.less
index b5f8663d3..fd17e7fda 100644
--- a/components/input-number/style/index.less
+++ b/components/input-number/style/index.less
@@ -1,6 +1,7 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@import '../../input/style/mixin';
+@import './affix';
@input-number-prefix-cls: ~'@{ant-prefix}-input-number';
@form-item-prefix-cls: ~'@{ant-prefix}-form-item';