From efea6b000e581f9c71ba98f80febace4e024910c Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 1 Mar 2022 15:16:36 +0800 Subject: [PATCH] feat: inputNumber add prefix slot --- .../__tests__/__snapshots__/demo.test.js.snap | 74 +++++++++++++++---- components/input-number/demo/formatter.vue | 4 +- components/input-number/demo/index.vue | 3 + components/input-number/demo/prefix.vue | 49 ++++++++++++ components/input-number/demo/size.vue | 9 +-- components/input-number/index.en-US.md | 4 +- components/input-number/index.tsx | 37 +++++++++- components/input-number/index.zh-CN.md | 4 +- components/input-number/style/affix.less | 64 ++++++++++++++++ components/input-number/style/index.less | 1 + 10 files changed, 218 insertions(+), 31 deletions(-) create mode 100644 components/input-number/demo/prefix.vue create mode 100644 components/input-number/style/affix.less diff --git a/components/input-number/__tests__/__snapshots__/demo.test.js.snap b/components/input-number/__tests__/__snapshots__/demo.test.js.snap index 9d2c51ced..feb4c539e 100644 --- a/components/input-number/__tests__/__snapshots__/demo.test.js.snap +++ b/components/input-number/__tests__/__snapshots__/demo.test.js.snap @@ -122,15 +122,21 @@ exports[`renders ./components/input-number/demo/disabled.vue correctly 1`] = ` `; exports[`renders ./components/input-number/demo/formatter.vue correctly 1`] = ` -
-
-
-
+
+
+
+
+
+
-
-
-
+ +
+
+
+
+
+
`; @@ -164,19 +170,55 @@ exports[`renders ./components/input-number/demo/out-of-range.vue correctly 1`] =
`; -exports[`renders ./components/input-number/demo/size.vue correctly 1`] = ` -
-
-
-
-
+exports[`renders ./components/input-number/demo/prefix.vue correctly 1`] = ` +
-
+
-
+


+
+
+
+
+
+
+
+
+
+ +
+


+
+
-
+
`; + +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';