Explicação Inicial 📚
O código define um componente InputCpf que utiliza o React Hook Form para controle de formulários e aplica uma formatação automática ao CPF enquanto o usuário digita. O CPF é formatado como xxx.xxx.xxx-xx
e é validado para garantir que apenas números sejam inseridos.
Funções Auxiliares 📦
Primeiramente, vamos analisar as funções auxiliares que formatam o CPF.
Função formatCpf
✍️
const formatCpf = (value) => {
value = value.replace(/\D/g, '') // Remove todos os caracteres não numéricos
value = value.slice(0, 11) // Garante que o valor tenha no máximo 11 caracteres
value = value.replace(/(\d{3})(\d)/, '$1.$2') // Adiciona o primeiro ponto após 3 dígitos
value = value.replace(/(\d{3})(\d)/, '$1.$2') // Adiciona o segundo ponto
value = value.replace(/(\d{3})(\d{1,2})$/, '$1-$2') // Adiciona o hífen
return value // Retorna o CPF formatado
}
A função formatCpf faz a formatação do CPF durante a digitação:
- replace(/\D/g, ''): Remove tudo que não for número.
- slice(0, 11): Limita o CPF a 11 caracteres.
- replace(/(\d{3})(\d)/, '$1.$2'): Adiciona o ponto após o terceiro dígito e repete o processo.
- replace(/(\d{3})(\d{1,2})$/, '$1-$2'): Adiciona o hífen antes dos dois últimos dígitos.
Função removeCpfFormatting
✂️
const removeCpfFormatting = (value) => {
return value.replace(/\D/g, '').slice(0, 11) // Remove formatação e limita a 11 dígitos
}
A função removeCpfFormatting remove toda a formatação do CPF, deixando apenas os números, e garante que ele tenha exatamente 11 dígitos.
Componente InputCpf
🎯
Agora, vamos para o componente principal.
const InputCpf = ({ control, name }) => {
const {
field: { onChange, onBlur, value, ref },
fieldState: { error },
} = useController({
name,
control,
})
- O InputCpf recebe duas props: control (para integração com React Hook Form) e name (para identificar o campo no formulário).
- O hook useController é utilizado para controlar o estado do campo, obtendo funções como onChange, onBlur, value, ref, e error.
Componente de Entrada 📥
return (
<div>
<Input
ref={ref}
value={formatCpf(value)} // Aplica a formatação
onChange={(e) => onChange(removeCpfFormatting(e.target.value))} // Atualiza o valor sem a formatação
onBlur={onBlur} // Evento quando o campo perde o foco
placeholder="Digite seu CPF"
maxLength={14} // Limita o número de caracteres para o formato correto
/>
</div>
)
}
- O campo de Input é renderizado com o valor formatado pelo formatCpf.
- O onChange remove a formatação ao atualizar o valor do campo.
- onBlur é acionado quando o campo perde o foco (usado para validação, por exemplo).
- O placeholder exibe o texto "Digite seu CPF" até que o usuário comece a digitar.
- maxLength={14}: Limita o número máximo de caracteres para o formato de CPF (
xxx.xxx.xxx-xx
).
Código Completo 🖥️
import React from 'react'
import { Input } from '@/components/ui/input'
import { useController } from 'react-hook-form'
const formatCpf = (value) => {
value = value.replace(/\D/g, '') // Remove todos os caracteres não numéricos
value = value.slice(0, 11) // Garante que o valor tenha no máximo 11 caracteres
value = value.replace(/(\d{3})(\d)/, '$1.$2') // Adiciona o primeiro ponto após 3 dígitos
value = value.replace(/(\d{3})(\d)/, '$1.$2') // Adiciona o segundo ponto
value = value.replace(/(\d{3})(\d{1,2})$/, '$1-$2') // Adiciona o hífen
return value // Retorna o CPF formatado
}
const InputCpf = ({ control, name }) => {
const {
field: { onChange, onBlur, value, ref },
fieldState: { error },
} = useController({
name,
control,
})
const removeCpfFormatting = (value) => {
return value.replace(/\D/g, '').slice(0, 11) // Remove formatação e limita a 11 dígitos
}
return (
<div>
<Input
ref={ref}
value={formatCpf(value)} // Aplica a formatação
onChange={(e) => onChange(removeCpfFormatting(e.target.value))} // Atualiza o valor sem a formatação
onBlur={onBlur} // Evento quando o campo perde o foco
placeholder="Digite seu CPF"
maxLength={14} // Limita o número de caracteres para o formato correto
/>
</div>
)
}
export default InputCpf