@navinc/base-react-components
Version:
Nav's Pattern Library
61 lines (55 loc) • 1.85 kB
JavaScript
import { useMemo, useEffect } from 'react'
import Input from '../input.js'
import { useField } from 'formik'
import { phoneNumberToFormattedString, phoneNumberToE164 } from '@navinc/utils'
export const createPhoneNumberValidator = ({
isRequired = false,
requiredErrorMessage = 'Required',
lengthErrorMessage = 'We need your full 10-digit phone number',
} = {}) => (phoneNumber) =>
(isRequired && !phoneNumber && [requiredErrorMessage]) ||
(phoneNumber && phoneNumberToFormattedString(phoneNumber).length < 12 && [lengthErrorMessage])
const PhoneNumberInput = ({
name,
isRequired,
onBlur,
onChange,
requiredErrorMessage,
lengthErrorMessage,
...props
}) => {
const memoizedValidatePhoneNumber = useMemo(
() => createPhoneNumberValidator({ isRequired, requiredErrorMessage, lengthErrorMessage }),
[isRequired, requiredErrorMessage, lengthErrorMessage]
)
const [field, meta, { setValue }] = useField({ name, validate: memoizedValidatePhoneNumber })
useEffect(() => {
// Ensure initial value stored in parent form is E164 formatted
setValue(phoneNumberToE164(field.value))
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<Input
type="text"
name={name}
value={phoneNumberToFormattedString(field.value)}
onChange={(e) => {
const { target } = e
const { value } = target
target.value = phoneNumberToFormattedString(value)
setValue(phoneNumberToE164(value))
onChange && onChange(e)
}}
// eslint-disable-next-line react/jsx-handler-names
onBlur={(e) => {
field.onBlur(e)
onBlur && onBlur(e)
}}
errors={meta.touched && meta.error}
isInvalid={meta.touched && !!meta.error}
hasSpaceForErrors
{...props}
/>
)
}
export default PhoneNumberInput