npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@kenero/use-validate

v1.0.25

Published

Uma forma fácil de validar inputs e aplicar várias mascaras como CPF, CNPJ, Data, Telefone, etc.

Readme

@kenero/use-validate

Validação simples, máscaras em tempo real e exibição de erros para formulários React — com uma API minimalista e tipada.

Stack: React + TypeScript

Use cases: checkouts, cadastros, pagamentos, formulários com muitos inputs.


🚀 Instalação

npm i @kenero/use-validate
# ou
yarn add @kenero/use-validate

⚡️ Comece rápido

import { ValidationProvider, useValidation } from "@kenero/use-validate";

export default function App() {
  return (
    <ValidationProvider>
      <CheckoutForm />
    </ValidationProvider>
  );
}

function CheckoutForm() {
  const { register, trigger, errors, resetErros } = useValidation();

  const onSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    if (trigger()) {
      // Envie os dados com segurança
      console.log("Form válido!");
    }
  };

  return (
    <form onSubmit={onSubmit}>
      {/* CPF com máscara + required */}
      <input
        {...register("cpf", () => {}, { required: true, mask: "cpf" })}
        placeholder="CPF"
      />
      {errors?.cpf?.error && <small>{errors.cpf.message}</small>}

      {/* Telefone com máscara */}
      <input
        {...register("phone", () => {}, { mask: "phone" })}
        placeholder="Telefone"
      />
      {errors?.phone?.error && <small>{errors.phone.message}</small>}

      <button type="submit">Enviar</button>
      <button type="button" onClick={() => resetErros()}>Limpar erros</button>
    </form>
  );
}

🧠 Conceitos

  • ValidationProvider: provê o contexto de validação e máscaras.

  • useValidation(): acessa a API do formulário atual.

  • register(id, onChange, options): conecta qualquer <input> ou <select>.

    • Retorna { ref, onBlur, onChange } para plugar diretamente no elemento.
  • trigger(keys?): valida todos os campos (ou apenas os informados).

  • resetErros(keys?): limpa erros globalmente (ou seletivamente).

  • errors: dicionário { [id]: { error: boolean; message: string } }.


📦 API (Tipos)

interface ErrosValidation {
  [key: string]: { error: boolean; message: string } | undefined | null;
}

interface Options {
  cpf?: boolean;               // valida padrão CPF
  cnpj?: boolean;              // valida padrão CNPJ
  nameAndLastName?: boolean;   // exige nome e sobrenome
  required?: boolean;          // campo obrigatório
  nameOptional?: string;       // nome legível do campo para mensagens
  minLength?: number;          // tamanho mínimo
  mask?:
    | "cpf"
    | "phone"
    | "card-number"
    | "card-data"
    | "name"
    | "cpf-cnpj"
    | "cnpj"
    | "plate"
    | "chassi"
    | "cep";
}

type TypeRegister = <T extends HTMLInputElement | HTMLSelectElement>(
  id: string,
  onChange: (e: React.ChangeEvent<T>) => void,
  options?: Options
) => {
  ref: React.RefObject<T>;
  onBlur: (e: React.ChangeEvent<T>) => void;
  onChange: (e: React.ChangeEvent<T>) => void;
};

Contexto e Provider

declare const ValidationContext: React.Context<ValidationContext>;

declare const ValidationProvider: React.ForwardRefExoticComponent<
  (ValidationProviderProps | ValidationProviderElementProps) &
  React.RefAttributes<ValidationContext | undefined>
>;

declare const useValidation: () => ValidationContext;

🧩 ValidationProvider — duas formas de usar

1) Como wrapper padrão (children como nós React)

<ValidationProvider>
  <MeuForm />
</ValidationProvider>

2) Como render prop (acesso direto ao contexto)

<ValidationProvider>
  {(ctx) => <MeuForm ctx={ctx} />}
</ValidationProvider>

Use o formato que preferir — ambos expõem a mesma API por useValidation() ou pelo parâmetro ctx.


🧰 register em detalhe

<input
  {...register(
    "email",
    (e) => {
      // Seu estado/controlador também recebe o onChange
      // Ex: setEmail(e.target.value)
    },
    { required: true, minLength: 5, nameOptional: "E-mail" }
  )}
  placeholder="E-mail"
/>
{errors?.email?.error && <span role="alert">{errors.email.message}</span>}

O que acontece por baixo:

  • Aplica máscara (se houver) a cada onChange.
  • Executa validações declarativas conforme options.
  • Em onBlur, revalida e atualiza errors[id].

Dica: se você já controla o estado do campo (controlled input), continue usando seu setState dentro do onChange que você passa para o register.


🧪 trigger e resetErros

trigger();           // valida tudo
trigger(["cpf"]);    // valida só alguns campos
resetErros();        // limpa todos os erros
resetErros(["cpf"]);// limpa erros selecionados

trigger() retorna true se todos os campos validados estiverem ok.


🔤 Máscaras disponíveis

| Máscara | ID em mask | Comportamento (exemplo) | | ----------- | --------------- | ---------------------------------- | | CPF | "cpf" | 123.456.789-09 | | CNPJ | "cnpj" | 12.345.678/0001-90 | | CPF ou CNPJ | "cpf-cnpj" | Detecta pelo tamanho e formata | | Telefone | "phone" | (**) * ****-**** (dinâmico) | | Cartão nº | "card-number" | #### #### #### #### | | Cartão data | "card-data" | MM/AA | | Nome | "name" | Remove números/sinais; capitaliza | | Placa | "plate" | Padrão brasileiro (ex.: ABC1D23) | | Chassi | "chassi" | Limita e normaliza alfanumérico | | CEP | "cep" | #####-### |

A máscara é aplicada durante o onChange. Em onBlur, a validação final ajusta mensagens de erro se necessário.


✅ Regras de validação prontas

  • required: não permite vazio.
  • minLength: impõe tamanho mínimo.
  • cpf: valida estrutura/dígitos do CPF.
  • cnpj: valida estrutura/dígitos do CNPJ.
  • nameAndLastName: exige ao menos duas palavras válidas.
  • nameOptional: rótulo amigável usado em mensagens (ex.: "O campo E-mail é obrigatório").

Combine regras livremente com qualquer máscara.


🧩 Exemplos práticos

CPF obrigatório + mensagem customizada

<input
  {...register("cpf", () => {}, { required: true, mask: "cpf", nameOptional: "CPF" })}
  placeholder="CPF"
/>
{errors?.cpf?.error && <small>{errors.cpf.message}</small>}

Nome e sobrenome, com limpeza de caracteres

<input
  {...register("nome", () => {}, { nameAndLastName: true, mask: "name", required: true })}
  placeholder="Nome completo"
/>

Telefone dinâmico (8/9 dígitos)

<input
  {...register("phone", () => {}, { mask: "phone", required: true })}
  placeholder="(00) 0 0000-0000"
/>

CEP com busca posterior (ex.: preencher endereço)

<input
  {...register("cep", () => {}, { mask: "cep", required: true })}
  placeholder="00000-000"
  onBlur={(e) => {
    // opcional: fetch do endereço pelo CEP limpo
  }}
/>

Select com validação

<select
  {...register("uf", () => {}, { required: true, nameOptional: "Estado" })}
  defaultValue=""
>
  <option value="" disabled>Selecione</option>
  <option value="SP">SP</option>
  <option value="RJ">RJ</option>
</select>
{errors?.uf?.error && <small>{errors.uf.message}</small>}

♿ Acessibilidade

  • Exiba mensagens de erro com role="alert" quando aplicável.
  • Associe label/htmlFor e id de cada campo registrado.
  • Use aria-invalid={errors?.[id]?.error || false} nos inputs para sinalizar estado.

🧪 Padrões de uso (UI libs)

shadcn/ui + Tailwind (exemplo)

import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";

function FieldCPF() {
  const { register, errors } = useValidation();

  return (
    <div className="grid gap-1">
      <Label htmlFor="cpf">CPF</Label>
      <Input id="cpf" {...register("cpf", () => {}, { mask: "cpf", required: true })} />
      {errors?.cpf?.error && (
        <p role="alert" className="text-sm text-red-600">{errors.cpf.message}</p>
      )}
    </div>
  );
}

🧩 Dicas & Boas práticas

  • IDs únicos: o primeiro parâmetro do register é a chave em errors — mantenha-o estável.
  • onBlur remove erros: quando o campo volta a ficar válido, o erro correspondente é limpo automaticamente ao perder o foco.
  • Controlled inputs: continue controlando seu estado normal; o register apenas adiciona máscara/validação.
  • Validação seletiva: use trigger(["campo1", "campo2"]) em etapas do formulário.

❓FAQ

Preciso usar useState para todos os campos? Não é obrigatório. O register já aplica máscara/validação. Use estado próprio se precisar ler valores no ato.

Consigo validar apenas uma parte do formulário? Sim, passe as chaves para trigger(["cpf", "cep"]).

Como limpo mensagens de erro após corrigir o valor? Erros são atualizados em onBlur. Para limpar globalmente, use resetErros(); para casos específicos, resetErros(["id"]).


🔌 API Completa (Resumo)

ValidationProvider

  • Aceita children como nós React ou como função (ctx) => JSX.

useValidation()ValidationContext

  • register: TypeRegister
  • trigger(keys?: string[]): boolean
  • resetErros(keys?: string[]): void
  • errors: ErrosValidation

TypeRegister

  • Parâmetros: (id, onChange, options?)
  • Retorno: { ref, onBlur, onChange }

🗺️ Roadmap

  • Mensagens de erro totalmente customizáveis por regra.
  • Hooks utilitários para extrair valores mascarados/limpos.
  • Suporte a mais máscaras nacionais.

📄 Licença

MIT