diff --git a/app/components/malio/InputAmount.test.ts b/app/components/malio/InputAmount.test.ts index 2e62907..222ce8a 100644 --- a/app/components/malio/InputAmount.test.ts +++ b/app/components/malio/InputAmount.test.ts @@ -117,26 +117,26 @@ describe('MalioInputAmount', () => { expect(wrapper.get('input').element.value).toBe('0.5') }) - it('formats the value with two decimals on blur', async () => { + it('keeps the normalized decimal value on blur', async () => { const wrapper = mountInputAmount() const input = wrapper.get('input') await input.setValue('12.5') await input.trigger('blur') - expect(wrapper.emitted('update:modelValue')?.[1]).toEqual(['12.50']) - expect(input.element.value).toBe('12.50') + expect(wrapper.emitted('update:modelValue')).toEqual([['12.5']]) + expect(input.element.value).toBe('12.5') }) - it('formats integer values with trailing decimals on blur', async () => { + it('keeps integer values unchanged on blur', async () => { const wrapper = mountInputAmount() const input = wrapper.get('input') await input.setValue('12') await input.trigger('blur') - expect(wrapper.emitted('update:modelValue')?.[1]).toEqual(['12.00']) - expect(input.element.value).toBe('12.00') + expect(wrapper.emitted('update:modelValue')).toEqual([['12']]) + expect(input.element.value).toBe('12') }) it('keeps an empty value empty on blur', async () => { diff --git a/app/components/malio/InputAmount.vue b/app/components/malio/InputAmount.vue index f082699..ed3a4d7 100644 --- a/app/components/malio/InputAmount.vue +++ b/app/components/malio/InputAmount.vue @@ -176,15 +176,11 @@ const emit = defineEmits<{ (event: 'update:modelValue', value: string): void }>() -// Normalize user input into a decimal amount string using "." as separator. const normalizeAmount = (value: string) => { const sanitizedValue = value .replace(/\s+/g, '') .replace(/,/g, '.') .replace(/[^\d.]/g, '') - - // Keep the first decimal separator and collapse the remaining parts into - // the decimal portion, limited to two digits. const [integerPartRaw = '', ...decimalParts] = sanitizedValue.split('.') const integerPart = integerPartRaw.replace(/^0+(?=\d)/, '') const decimalPart = decimalParts.join('').slice(0, 2) @@ -196,20 +192,6 @@ const normalizeAmount = (value: string) => { return integerPart } -// Apply the final display format when the field loses focus. -// Examples: -// "12" -> "12.00" -// "12.5" -> "12.50" -const formatAmountForBlur = (value: string) => { - const normalizedValue = normalizeAmount(value) - - if (!normalizedValue) return '' - - const [integerPart = '0', decimalPart = ''] = normalizedValue.split('.') - - return `${integerPart}.${decimalPart.padEnd(2, '0').slice(0, 2)}` -} - // Keep the DOM input value, local state, and v-model emission in sync. const updateValue = (target: HTMLInputElement, value: string) => { target.value = value @@ -225,16 +207,9 @@ const onInput = (event: Event) => { updateValue(target, normalizeAmount(target.value)) } -// Finalize the amount format with exactly two decimals on blur. -const onBlur = (event: Event) => { +// Keep the blur handler only for focus-driven UI state. +const onBlur = () => { isFocused.value = false - - const target = event.target as HTMLInputElement - const formattedValue = formatAmountForBlur(target.value) - - if (formattedValue !== target.value) { - updateValue(target, formattedValue) - } } const iconInputPaddingClass = computed(() => {