Skip to content

Commit

Permalink
Add credit card and cvv masks
Browse files Browse the repository at this point in the history
  • Loading branch information
markdoeswork committed Jan 6, 2025
1 parent 250dd82 commit 8521f6d
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const TextInputMask = (props) => {
zipCode: '',
postalCode: '',
ssn: '',
creditCard: '',
cvv: ''
})

const handleOnChangeFormField = ({ target }) => {
Expand Down Expand Up @@ -57,6 +59,22 @@ const TextInputMask = (props) => {
value={formFields.ssn}
{...props}
/>
<TextInput
label="Credit Card"
mask="creditCard"
name="creditCard"
onChange={handleOnChangeFormField}
value={formFields.creditCard}
{...props}
/>
<TextInput
label="CVV"
mask="cvv"
name="cvv"
onChange={handleOnChangeFormField}
value={formFields.cvv}
{...props}
/>

<br />
<br />
Expand Down
23 changes: 22 additions & 1 deletion playbook/app/pb_kits/playbook/pb_text_input/inputMask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type InputMask = {
}

type InputMaskDictionary = {
[key in 'currency' | 'zipCode' | 'postalCode' | 'ssn']: InputMask
[key in 'currency' | 'zipCode' | 'postalCode' | 'ssn' | 'creditCard' | 'cvv']: InputMask
}

const formatCurrencyDefaultValue = (value: string): string => {
Expand Down Expand Up @@ -58,6 +58,15 @@ const formatSSN = (value: string): string => {
.replace(/(\d{3})(?=\d)/, '$1-')
}

const formatCreditCard = (value: string): string => {
const cleaned = value.replace(/\D/g, '').slice(0, 16)
return cleaned.replace(/(\d{4})(?=\d)/g, '$1 ')
}

const formatCVV = (value: string): string => {
return value.replace(/\D/g, '').slice(0, 4)
}

export const INPUTMASKS: InputMaskDictionary = {
currency: {
format: formatCurrency,
Expand All @@ -84,4 +93,16 @@ export const INPUTMASKS: InputMaskDictionary = {
pattern: '\\d{3}-\\d{2}-\\d{4}',
placeholder: '123-45-6789',
},
creditCard: {
format: formatCreditCard,
formatDefaultValue: formatCreditCard,
pattern: '\\d{4} \\d{4} \\d{4} \\d{4}',
placeholder: '1234 5678 9012 3456',
},
cvv: {
format: formatCVV,
formatDefaultValue: formatCVV,
pattern: '\\d{3,4}',
placeholder: '123',
},
}
80 changes: 80 additions & 0 deletions playbook/app/pb_kits/playbook/pb_text_input/text_input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,83 @@ test('returns masked ssn value', () => {

expect(input.value).toBe('123-45-6789')
})

const TextInputCreditCardMask = (props) => {
const [creditCard, setValue] = useState('')
const handleOnChange = ({ target }) => {
setValue(target.value)
}

return (
<TextInput
mask="creditCard"
onChange={handleOnChange}
value={creditCard}
{...props}
/>
)
}

test('returns masked credit card value', () => {
render(
<TextInputCreditCardMask
data={{ testid: testId }}
/>
)

const kit = screen.getByTestId(testId)

const input = within(kit).getByRole('textbox')

fireEvent.change(input, { target: { value: '1234567890123456' } })

expect(input.value).toBe('1234 5678 9012 3456')

fireEvent.change(input, { target: { value: '1234' } })

expect(input.value).toBe('1234')

fireEvent.change(input, { target: { value: '' } })

expect(input.value).toBe('')
})

const TextInputCVVMask = (props) => {
const [cvv, setValue] = useState('')
const handleOnChange = ({ target }) => {
setValue(target.value)
}

return (
<TextInput
mask="cvv"
onChange={handleOnChange}
value={cvv}
{...props}
/>
)
}

test('returns masked CVV value', () => {
render(
<TextInputCVVMask
data={{ testid: testId }}
/>
)

const kit = screen.getByTestId(testId)

const input = within(kit).getByRole('textbox')

fireEvent.change(input, { target: { value: '1234' } })

expect(input.value).toBe('1234')

fireEvent.change(input, { target: { value: '123' } })

expect(input.value).toBe('123')

fireEvent.change(input, { target: { value: '' } })

expect(input.value).toBe('')
})

0 comments on commit 8521f6d

Please sign in to comment.