Skip to content

Commit

Permalink
fix(MaskedInput): make cleanedValue contain leading zeroes (#2610)
Browse files Browse the repository at this point in the history
More
[info](https://dnb-it.slack.com/archives/G01RK37BMR8/p1693399952666769).

---------

Co-authored-by: Tobias Høegh <[email protected]>
  • Loading branch information
joakbjerk and tujoworker authored Sep 7, 2023
1 parent 9292305 commit 86ad122
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,9 @@ const useCallEvent = ({ setLocalValue }) => {

const numberValue = Number(num)

// We may have to check against a negative value: && 1 / +0 === 1 / numberValue
const cleanedValue = numberValue === 0 ? '' : num
// Return '' (empty string) when the user has entered something invalid
const cleanedValue =
numberValue === 0 && String(num).charAt(0) !== '0' ? '' : num

if (name === 'on_change' && numberValue === 0) {
correctCaretPosition(event.target, maskParams, props)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import React from 'react'
import { loadScss, wait } from '../../../core/jest/jestSetup'
import { render, fireEvent } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import InputMasked, { InputMaskedProps } from '../InputMasked'
import Provider from '../../../shared/Provider'
import * as helpers from '../../../shared/helpers'
Expand Down Expand Up @@ -651,35 +652,6 @@ describe('InputMasked component', () => {
).not.toBeInTheDocument()
})

it('should show placeholder chars when show_mask is true', () => {
render(
<InputMasked
show_mask
placeholder_char="_"
mask={[
'0',
'0',
/[4]/, // have to start with 4
/[5-7]/, // can be 5,6 or 7
' ',
/[49]/, // have to start with 4 or 9
/\d/,
' ',
/\d/,
/\d/,
' ',
/\d/,
/\d/,
' ',
/\d/,
/\d/,
]}
/>
)

expect(document.querySelector('input').value).toBe('00__ __ __ __ __')
})

it('should set caret position before suffix', async () => {
render(
<InputMasked
Expand Down Expand Up @@ -1734,7 +1706,9 @@ describe('InputMasked component as_currency', () => {
'dnb-input--vertical',
])
})
})

describe('InputMasked with custom mask', () => {
it('should set correct cursor position on focus and mouseUp', async () => {
render(
<InputMasked value={12} mask={[/\d/, /\d/, '–', '–', /\d/, /\d/]} />
Expand Down Expand Up @@ -1773,6 +1747,126 @@ describe('InputMasked component as_currency', () => {

expect(element.value).toBe('12––​​')
})

it('should show placeholder chars when show_mask is true', () => {
render(
<InputMasked
show_mask
placeholder_char="_"
mask={[
'0',
'0',
/[4]/, // have to start with 4
/[5-7]/, // can be 5,6 or 7
' ',
/[49]/, // have to start with 4 or 9
/\d/,
' ',
/\d/,
/\d/,
' ',
/\d/,
/\d/,
' ',
/\d/,
/\d/,
]}
/>
)

expect(document.querySelector('input').value).toBe('00__ __ __ __ __')
})

it('should handle leading zeros gracefully', async () => {
const onChange = jest.fn()

render(
<InputMasked
mask={[/\d/, ' ', /\d/, ' ', /\d/, ',', /\d/, /\d/]}
on_change={onChange}
/>
)

const input = document.querySelector('input')

{
await userEvent.type(input, '123,56')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('1 2 3,56')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('123.56')
expect(onChange.mock.calls[last][0].numberValue).toBe(123.56)
}

{
await userEvent.type(
input,
'{backspace}{backspace}{backspace}{backspace}'
)
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('1 ​ ​,​​')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('1.')
expect(onChange.mock.calls[last][0].numberValue).toBe(1)
}

{
await userEvent.type(
input,
'{backspace}{backspace}{backspace}{backspace}{backspace}'
)
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('')
expect(onChange.mock.calls[last][0].numberValue).toBe(0)
}

{
await userEvent.type(input, '0')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('0 ​ ​,​​')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('0.')
expect(onChange.mock.calls[last][0].numberValue).toBe(0)
}

{
await userEvent.clear(input)
await userEvent.type(input, '00000')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('0 0 0,00')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('000.00')
expect(onChange.mock.calls[last][0].numberValue).toBe(0)
}

{
await userEvent.clear(input)
await userEvent.type(input, '000')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('0 0 0,​​')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('000.')
expect(onChange.mock.calls[last][0].numberValue).toBe(0)
}

{
await userEvent.clear(input)
await userEvent.type(input, '045,67')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('0 4 5,67')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('045.67')
expect(onChange.mock.calls[last][0].numberValue).toBe(45.67)
}

{
await userEvent.clear(input)
await userEvent.type(input, 'abc')
const last = onChange.mock.calls.length - 1
expect(onChange.mock.calls[last][0].value).toBe('')
expect(onChange.mock.calls[last][0].cleanedValue).toBe('')
expect(onChange.mock.calls[last][0].numberValue).toBe(0)
}

expect(onChange).toHaveBeenCalledTimes(34)

await userEvent.clear(input)
})
})

describe('InputMasked scss', () => {
Expand Down
6 changes: 1 addition & 5 deletions packages/dnb-eufemia/src/extensions/forms/Field/String.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,7 @@ function StringComponent(props: Props) {
if (value === '') {
return props.emptyValue
}
if (value.charAt(0) === '0' && cleanedValue === '') {
// Special case - Since InputMasked sends out empty string when entering the digit 0 as first character (possibly changing in the future)
return '0'
}

// Cleaned value for masked
return cleanedValue ?? value
},
width: props.width ?? 'large',
Expand Down

0 comments on commit 86ad122

Please sign in to comment.