feat : ajouts du composant input amount
This commit is contained in:
@@ -117,26 +117,26 @@ describe('MalioInputAmount', () => {
|
|||||||
expect(wrapper.get('input').element.value).toBe('0.5')
|
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 wrapper = mountInputAmount()
|
||||||
const input = wrapper.get('input')
|
const input = wrapper.get('input')
|
||||||
|
|
||||||
await input.setValue('12.5')
|
await input.setValue('12.5')
|
||||||
await input.trigger('blur')
|
await input.trigger('blur')
|
||||||
|
|
||||||
expect(wrapper.emitted('update:modelValue')?.[1]).toEqual(['12.50'])
|
expect(wrapper.emitted('update:modelValue')).toEqual([['12.5']])
|
||||||
expect(input.element.value).toBe('12.50')
|
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 wrapper = mountInputAmount()
|
||||||
const input = wrapper.get('input')
|
const input = wrapper.get('input')
|
||||||
|
|
||||||
await input.setValue('12')
|
await input.setValue('12')
|
||||||
await input.trigger('blur')
|
await input.trigger('blur')
|
||||||
|
|
||||||
expect(wrapper.emitted('update:modelValue')?.[1]).toEqual(['12.00'])
|
expect(wrapper.emitted('update:modelValue')).toEqual([['12']])
|
||||||
expect(input.element.value).toBe('12.00')
|
expect(input.element.value).toBe('12')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('keeps an empty value empty on blur', async () => {
|
it('keeps an empty value empty on blur', async () => {
|
||||||
|
|||||||
@@ -176,15 +176,11 @@ const emit = defineEmits<{
|
|||||||
(event: 'update:modelValue', value: string): void
|
(event: 'update:modelValue', value: string): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
// Normalize user input into a decimal amount string using "." as separator.
|
|
||||||
const normalizeAmount = (value: string) => {
|
const normalizeAmount = (value: string) => {
|
||||||
const sanitizedValue = value
|
const sanitizedValue = value
|
||||||
.replace(/\s+/g, '')
|
.replace(/\s+/g, '')
|
||||||
.replace(/,/g, '.')
|
.replace(/,/g, '.')
|
||||||
.replace(/[^\d.]/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 [integerPartRaw = '', ...decimalParts] = sanitizedValue.split('.')
|
||||||
const integerPart = integerPartRaw.replace(/^0+(?=\d)/, '')
|
const integerPart = integerPartRaw.replace(/^0+(?=\d)/, '')
|
||||||
const decimalPart = decimalParts.join('').slice(0, 2)
|
const decimalPart = decimalParts.join('').slice(0, 2)
|
||||||
@@ -196,20 +192,6 @@ const normalizeAmount = (value: string) => {
|
|||||||
return integerPart
|
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.
|
// Keep the DOM input value, local state, and v-model emission in sync.
|
||||||
const updateValue = (target: HTMLInputElement, value: string) => {
|
const updateValue = (target: HTMLInputElement, value: string) => {
|
||||||
target.value = value
|
target.value = value
|
||||||
@@ -225,16 +207,9 @@ const onInput = (event: Event) => {
|
|||||||
updateValue(target, normalizeAmount(target.value))
|
updateValue(target, normalizeAmount(target.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize the amount format with exactly two decimals on blur.
|
// Keep the blur handler only for focus-driven UI state.
|
||||||
const onBlur = (event: Event) => {
|
const onBlur = () => {
|
||||||
isFocused.value = false
|
isFocused.value = false
|
||||||
|
|
||||||
const target = event.target as HTMLInputElement
|
|
||||||
const formattedValue = formatAmountForBlur(target.value)
|
|
||||||
|
|
||||||
if (formattedValue !== target.value) {
|
|
||||||
updateValue(target, formattedValue)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconInputPaddingClass = computed(() => {
|
const iconInputPaddingClass = computed(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user