Melhorando a Experiência do Usuário com Campo Numérico Personalizado em React

Em desenvolvimento web, especialmente para aplicações que dependem de dados numéricos, proporcionar uma experiência de usuário suave e sem erros é fundamental. Um componente de entrada de números bem projetado não só facilita a interação do usuário, mas também garante que os dados inseridos sejam válidos e formatados corretamente. Este artigo explora o componente React chamado CustomNumberInput, projetado para lidar com entradas numéricas de forma eficiente e melhorar a experiência do usuário.

O componente CustomNumberInput com React é um campo de entrada personalizado que permite aos usuários inserir números, incluindo valores decimais e negativos. Ele garante que os dados inseridos sigam regras de formatação específicas, como o número máximo de dígitos inteiros e decimais. Além disso, ele lida automaticamente com a validação e formatação dos valores inseridos, reduzindo a probabilidade de erros e melhorando a usabilidade.

Para usar o componente CustomNumberInput em sua aplicação, veja um exemplo rápido:

“`javascript
import { CustomNumberInput } from ‘./CustomNumberInput’;

function App() {
const handleNumberChange = (value: string | null) => {
console.log(“Entered value:”, value);
};

return (

);
}

export default App;
“`

Neste exemplo, o componente CustomNumberInput é utilizado para permitir que os usuários insiram um número com até 5 dígitos inteiros e 2 dígitos decimais. A propriedade onChange é usada para lidar com o valor inserido, que é registrado no console.

Funcionalidades e Lógica do CustomNumberInput com React

O componente CustomNumberInput oferece diversas funcionalidades que visam otimizar a experiência do usuário e garantir a integridade dos dados inseridos. Entre as principais, destacam-se a formatação de números, a validação de entradas, o controle de dígitos e o tratamento de eventos.

Formatação e Validação de Números

O componente assegura que os números inseridos sejam formatados corretamente, lidando com sinais negativos e positivos, bem como separadores decimais. A validação de entrada permite apenas caracteres numéricos, sinais de mais e menos, e separadores decimais, prevenindo a inserção de caracteres inválidos.

Essa validação é crucial para evitar erros e garantir que os dados estejam no formato esperado, especialmente em aplicações que realizam cálculos ou manipulações numéricas. A formatação também facilita a leitura e compreensão dos números pelo usuário.

O controle de dígitos permite definir o número máximo de dígitos inteiros e decimais que podem ser inseridos, sendo útil para aplicações que exigem precisão numérica. O componente também trata eventos de teclado (onKeyDown) e de mudança (onChange) para garantir que a entrada do usuário seja validada e formatada em tempo real.

Lógica de Formatação de Valores

A função formatValue é o coração do componente, formatando o valor inserido pelo usuário de acordo com as regras definidas. Ela remove caracteres inválidos utilizando uma expressão regular que exclui qualquer caractere que não seja um dígito, um sinal de mais ou menos, ou um separador decimal.

A função também garante que o sinal negativo esteja posicionado corretamente e que os sinais positivos não afetem o valor final. Além disso, converte qualquer separador decimal (ponto ou vírgula) em um ponto decimal padrão e limita o número de dígitos decimais com base na precisão definida.

Para garantir a precisão dos dados, o componente limita o número de dígitos inteiros que podem ser inseridos, assegurando que o limite definido não seja excedido. Essa funcionalidade é essencial para aplicações financeiras ou científicas onde a precisão numérica é crítica.

Tratamento de Eventos do Teclado

A função handleKeyDown garante que apenas teclas específicas relacionadas à entrada numérica sejam permitidas. Isso inclui teclas de navegação, edição e caracteres numéricos. Se o usuário tentar inserir um caractere não permitido, o evento é prevenido e o caractere não aparece no campo de entrada.

As teclas permitidas incluem: “Backspace”, “Delete”, “ArrowLeft”, “ArrowRight”, “Tab”, “Home”, “End”, “-“, “+”, “.”, “,”, “0”, “1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”. Essa restrição ajuda a manter a integridade dos dados e a evitar erros de entrada.

A função handleChange é acionada sempre que o usuário modifica o valor do campo de entrada. Ela chama formatValue para formatar o valor inserido e, em seguida, atualiza o estado do componente com o valor formatado. Adicionalmente, notifica o componente pai (através da propriedade onChange) do novo valor.

Essa notificação permite uma integração perfeita com outros componentes e facilita a utilização do valor formatado em outras partes da aplicação. O componente também oferece a flexibilidade de ajustar o número de dígitos inteiros e decimais permitidos e pode ser estendido para atender necessidades específicas.

O componente CustomNumberInput foi criado para melhorar a experiência do usuário ao inserir números em uma aplicação. Ao lidar automaticamente com a validação e formatação, ele reduz a carga cognitiva sobre o usuário e minimiza os erros de entrada. Isso é especialmente útil em contextos financeiros, científicos ou qualquer outro onde a precisão numérica é crucial. Para quem busca otimizar a interface e garantir a qualidade dos dados, essa ferramenta pode ser um diferencial. Além disso, com a crescente necessidade de aplicações acessíveis e fáceis de usar, investir em componentes bem projetados é sempre uma boa ideia.

“`javascript
import * as React from “react”
import { type ClassValue, clsx } from “clsx”;
import { twMerge } from “tailwind-merge”;

type DecimalPrecision = {
integerDigits: number
decimalDigits: number
}

export interface CustomNumberInputProps
extends Omit, ‘onChange’> {
className?: string,
decimalPrecision?: DecimalPrecision
onChange?: (value: string | null) => void
}

const DEFAULT_PRECISION: DecimalPrecision = {
integerDigits: 10,
decimalDigits: 2
}

const DECIMAL_SEPARATOR = “.”

const CustomNumberInput = React.forwardRef(
({
className,
decimalPrecision = DEFAULT_PRECISION,
onChange,
…props
}, ref) => {
const [valueInput, setValueInput] = React.useState(“”)

const formatValue = React.useCallback((input: string): string => {
let formatted = input.replace(/[^\d-+,.]/, “”)

if (formatted.includes(“-“)) {
formatted = formatted.replace(/-/g, “”)
formatted = formatted.startsWith(“-“) ? formatted : `-${formatted}`
}

if (formatted.includes(“+”)) {
formatted = formatted.replace(/-/g, “”)
formatted = formatted.replace(/\+/g, “”)
}

if (formatted.includes(“.”) || formatted.includes(“,”)) {
formatted = formatted.replace(“.”, DECIMAL_SEPARATOR)
formatted = formatted.replace(“,”, DECIMAL_SEPARATOR)

const [intPart, …rest] = formatted.split(DECIMAL_SEPARATOR)
const decPart = rest.join(“”)

const limitedDecPart = decPart.slice(0, decimalPrecision.decimalDigits)
const formattedIntPart = !intPart || intPart === “-” ? `0${intPart}` : intPart

formatted = `${formattedIntPart}${DECIMAL_SEPARATOR}${limitedDecPart}`
} else {
const isNegative = formatted.startsWith(“-“)
const digits = isNegative ? formatted.slice(1) : formatted
if (digits.length > decimalPrecision.integerDigits) {
formatted = isNegative
? `-${digits.slice(0, decimalPrecision.integerDigits)}`
: digits.slice(0, decimalPrecision.integerDigits)
}
}

return formatted
}, [decimalPrecision])

const handleKeyDown = (e: React.KeyboardEvent) => {
const allowedKeys = [
“Backspace”, “Delete”, “ArrowLeft”, “ArrowRight”,
“Tab”, “Home”, “End”, “-“, “+”, “.”, “,”, “0”,
“1”, “2”, “3”, “4”, “5”, “6”, “7”, “8”, “9”
]

if (!allowedKeys.includes(e.key)) {
e.preventDefault()
} else if (valueInput.includes(DECIMAL_SEPARATOR) && (e.key === “.” || e.key === “,”)) {
e.preventDefault()
}
}

const handleChange = (e: React.ChangeEvent) => {
const newValue = formatValue(e.target.value)
setValueInput(newValue)
onChange?.(newValue === ” ? null : newValue)
}

const cn = (…inputs: ClassValue[]) => {
return twMerge(clsx(inputs));
}

return (

)
}
)

CustomNumberInput.displayName = “CustomNumberInput”

export { CustomNumberInput }
“`

Este conteúdo foi auxiliado por Inteligência Artificiado, mas escrito e revisado por um humano.

Via Dev.to

Leave a Comment

Exit mobile version