@libsdomau/valisk
v1.0.6
Published
Mascaras UNCONTROLLED, CONTROLLED e integração com REACT-HOOK-FORMS
Downloads
5
Maintainers
Readme
Valisk
É uma biblioteca feita para campos UNCONTROLLED e CONTROLLED, incluindo várias máscaras para serem utilizadas de uma maneira muito fácil e performática.
EXTRA: Quando integrada ao
react-hook-form
, ela consegue trabalhar da melhor forma possivel, misturando as validações e controles dos campos, ás máscaras com personalização e sem renderizações desnecessárias.
Tipos de uso
UNCONTROLLED
| CONTROLLED
| REACT-HOOK-FORMS
Linguagens
JAVASCRIPT
| TYPESCRIPT
Introdução
A ideia da construção da biblioteca já existia a muito tempo, porém, apenas depois de adquirir conhecimento das técnologias da modernidade que fui capaz de realiza-lá.
Valisk trabalha com campos CONTROLLED
e UNCONTROLLED
, ou seja, te dando a possiblidade de controllar a renderização sem se precoupar com a usabilidade do usuário
, essa responsabilidade
é da lib
.
A biblitoeca disponibiliza métodos e tipos, apenas o necessário para o desenvolvimento. Qualquer dúvida, basta navegar até a sessão -> API de Referência e procurar pela questão em especial ou ainda, mandar uma issue.
Agora segue abaixo o menu para um roadmap de refencia sobre a Lib:
Mapa da documentação
Instalação
Para sua utilização é necessário a instalação do pacote, para isso existem algumas possibilidades até o momento, entre elas:
NPM
Link para a página oficial https://www.npmjs.com/package/@libsdomau/valisk
npm i @libsdomau/valisk
Yarn
Link para a página oficial https://yarn.pm/@libsdomau/valisk
yarn add @libsdomau/valisk
PNPM
Link para a página oficial https://www.npmjs.com/package/@libsdomau/valisk
pnpm add @libsdomau/valisk
Casos de uso
Aqui iremos entrar em alguns exemplos de uso, porém o foco é apenas a apresentação da lib com algumas ilustrações.
Obeservação: Todos exemplos abaixos conterão typescript
, caso queira utilizar com javascript, basta remover as tipagens.
Uncontrolled
Nesse exemplo será utilizado uma demonstração apenas com o
_masks
,_getValues
, com as propriedadescpf
emoney
.import { CSSProperties, FormEvent } from "react"; import { useValisk } from "@libsdomau/valisk"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "flex-start", alignItems: "center", gap: "1rem", color: "#fff", }; let renderCounter = 0; function App() { console.log(`Renderizou ${++renderCounter}`); interface Inputs { campo1: string; campo2: string; } const { _masks, _getValues } = useValisk<Inputs>({ cpf: { name: "campo1" }, money: { name: "campo2", typeMoney: "real", explictMask: true }, }); const showValues = (data: Inputs) => { evt.preventDefault(); console.log(data); }; return ( <form style={globalStyle} onSubmit={_getValues(showValues)}> <input type="text" {..._masks("campo1")} /> <input type="text" {..._masks("campo2")} /> <button>Mostrar</button> </form> ); } export default App;
Output:
| 123.124.123-51 | 0,52 | Mostrar | | :------------- | :--- | :------ |
Console:
1 Renderização! {campo1: '123.124.123-51', campo2: '0,52'}
Neste caso, iremos alterar o valor do campo para mostrar o valor normal apenas com o método
_forceUpdate
e um estado do button, fazendo assim alterar de escondido para o valor normal, tudo de forma uncontrolled.import { CSSProperties, useEffect, useState } from "react"; import { useValisk } from "@libsdomau/valisk"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "center", flexDirection: "column", alignItems: "flex-start", gap: "1rem", color: "#fff", }; let renderCounter = 0; function App() { console.log(`${++renderCounter} Renderização`); const [hideValue, setHideValue] = useState(true); interface Inputs { passwordInput: string; } const { _masks, _forceUpdate } = useValisk<Inputs>({ password: { name: "passwordInput", hideValue: hideValue }, }); const textButton = hideValue ? "Mostrar" : "Esconder"; useEffect(() => { _forceUpdate({ inputName: "passwordInput", inputType: "uncontrolled" }); }, [hideValue]); return ( <form style={globalStyle} onSubmit={(evt) => evt.preventDefault()}> <input type="text" {..._masks("passwordInput")} /> <button onClick={() => setHideValue(!hideValue)}>{textButton}</button> </form> ); } export default App;
Output:
| 123456789 | Esconder | | :-------- | :------- |
Console:
1 Renderização! 2 Renderização!
Controlled
Aqui foi utilizado apenas o
_masks
e a propriedadephone
, com renderização no campo para alterar a lista.import { CSSProperties, useState } from "react"; import { useValisk } from "@libsdomau/valisk"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "center", flexDirection: "column", alignItems: "flex-start", gap: "1rem", color: "#fff", }; let renderCounter = 0; function App() { console.log(`${++renderCounter} Renderização!`); interface Inputs { phoneInput: string; } const randomNumbers = [...Array(10)].map( () => `+${Math.round(Math.random() * 100000000)}` ); const [data] = useState(randomNumbers); const [phoneInput, setPhoneInput] = useState(""); const filtredPhones = data.filter((number) => number.includes(phoneInput)); const { _masks } = useValisk<Inputs>({ phone: { name: "phoneInput", typePhone: "phoneMovel", showDDD: true }, }); return ( <div style={globalStyle}> <form> <input type="text" id="cnpj1" value={phoneInput} onChange={(evt) => setPhoneInput(evt.target.value)} {..._masks("phoneInput")} /> </form> <ul> {filtredPhones.map((numbers, indNumbers) => ( <li key={indNumbers}>{numbers}</li> ))} </ul> </div> ); } export default App;
Output:
| +64 | | :-- |
- +64044127
- +64203623
Console:
1 Renderização! 2 Renderização! 3 Renderização!
Aqui foi utilizado o
_masks
e as propriedadescep
ecnpj
, possibilidando utilizar múltiplas vezes o mesmo tipo de valor.import { CSSProperties, useState } from "react"; import { useValisk } from "@libsdomau/valisk"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "center", flexDirection: "column", alignItems: "flex-start", gap: "1rem", color: "#fff", }; let renderCounter = 0; function App() { console.log(`${++renderCounter} Renderização`); interface Inputs { cnpj1: string; cnpj2: string; cep1: string; cep2: string; } const [inputs, setInputs] = useState([ { id: "cnpj1", value: "" }, { id: "cnpj2", value: "" }, { id: "cep1", value: "" }, { id: "cep2", value: "" }, ]); const { _masks } = useValisk<Inputs>({ cnpj: [{ name: "cnpj1", explictMask: true }, { name: "cnpj2" }], cep: [{ name: "cep1", explictMask: true }, { name: "cep2" }], }); const objectInput = (id: keyof Inputs) => inputs.find((obj) => obj.id === id); const changeInputValue = (value: string, id: keyof Inputs) => { setInputs((prev) => prev.map((obj) => (obj.id === id ? { ...obj, value } : obj)) ); }; return ( <form style={globalStyle}> <label htmlFor="cnpj1">cnpj1</label> <input type="text" id="cnpj1" value={objectInput("cnpj1")?.value} onChange={(evt) => changeInputValue(evt.target.value, "cnpj1")} {..._masks("cnpj1")} /> <label htmlFor="cnpj1">cnpj2</label> <input type="text" id="cnpj2" value={objectInput("cnpj2")?.value} onChange={(evt) => changeInputValue(evt.target.value, "cnpj2")} {..._masks("cnpj2")} /> <label htmlFor="cep1">cep1</label> <input type="text" id="cep1" value={objectInput("cep1")?.value} onChange={(evt) => changeInputValue(evt.target.value, "cep1")} {..._masks("cep1")} /> <label htmlFor="cep1">cep2</label> <input type="text" id="cep2" value={objectInput("cep2")?.value} onChange={(evt) => changeInputValue(evt.target.value, "cep2")} {..._masks("cep2")} /> </form> ); } export default App;
Output:
| cnpj1 | cnpj2 | cep1 | cep2 | | :----------------------- | :-------- | :----------- | :------ | | 12.__.__/___-__ | 12.341.23 | 67786-___ | 23334-5 |
Console:
1 Renderização 2 Renderização 3 Renderização ... 10 Renderização 12 Renderização ... 22 Renderização
React-Hook-Form
Nesse exemplo, iremos apenas integrar a lib com o
react-hook-form
colocando um valor inicial.import { CSSProperties, useEffect } from "react"; import { useValisk } from "@libsdomau/valisk"; import { useForm } from "react-hook-form"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "center", flexDirection: "column", alignItems: "flex-start", gap: "1rem", color: "#fff", }; let renderCounter = 0; function App() { console.log(`${++renderCounter} Renderização`); interface Inputs { firstInput: string; secondInput: string; } const { register, setValue } = useForm<Inputs>({ defaultValues: { firstInput: "123", secondInput: "456" }, }); const { _masks, _forceUpdate } = useValisk<Inputs>({ phone: [ { name: "firstInput", typePhone: "phoneFixo", explictMask: true, showDDD: true, }, { name: "secondInput", typePhone: "phoneMovel", showDDD: true, showPrefix: true, }, ], }); useEffect(() => { _forceUpdate([ { inputName: "firstInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, { inputName: "secondInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, ]); }, []); return ( <form style={globalStyle} onSubmit={(evt) => evt.preventDefault()}> <input type="text" {...register("firstInput")} {..._masks("firstInput")} /> <input type="text" {...register("secondInput")} {..._masks("secondInput")} /> </form> ); } export default App;
Output:
| +12 3___-____ | +45 6 | | :------------------- | :---- |
Console:
1 Renderização
import { CSSProperties, useEffect, useState } from "react"; import { useValisk } from "@libsdomau/valisk"; import { useForm, SubmitHandler } from "react-hook-form"; const globalStyle: CSSProperties = { display: "flex", width: "100%", height: "100vh", margin: "0", justifyContent: "center", flexDirection: "column", alignItems: "flex-start", gap: "1rem", color: "#fff", }; const formStyle: CSSProperties = { display: "flex", flexDirection: "column", gap: "1rem", }; let renderCounter = 0; function App() { console.log(`${++renderCounter} Renderização`); const [hideValue, setHideValue] = useState(false); interface Inputs { firstInput: string; secondInput: string; thirtyInput: string; fourtyInput: string; fiftyInput: string; } const { register, setValue, handleSubmit } = useForm<Inputs>({ defaultValues: { firstInput: "123", secondInput: "456" }, }); const { _masks, _forceUpdate, _cleanVal } = useValisk<Inputs>({ phone: [ { name: "firstInput", typePhone: "phoneFixo", explictMask: true, showDDD: true, }, { name: "secondInput", typePhone: "phoneMovel", showDDD: true, showPrefix: true, }, ], password: { name: "thirtyInput", hideValue: hideValue, }, money: [ { name: "fourtyInput", typeMoney: "real", explictMask: true, explictSimbol: true, }, { name: "fiftyInput", typeMoney: "dollar", explictMask: true, explictSimbol: false, }, ], }); const showValues: SubmitHandler<Inputs> = (data) => { console.log(data); console.log(_cleanVal(data)); }; useEffect(() => { _forceUpdate([ { inputName: "firstInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, { inputName: "secondInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, { inputName: "fourtyInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, { inputName: "fiftyInput", inputType: "react_hook_form", dispatchSetValue: setValue, }, ]); }, []); useEffect(() => { _forceUpdate({ inputName: "thirtyInput", inputType: "react_hook_form", dispatchSetValue: setValue, }); }, [hideValue]); return ( <div style={globalStyle}> <form onSubmit={handleSubmit(showValues)} style={formStyle}> <input type="text" {...register("firstInput")} {..._masks("firstInput")} /> <input type="text" {...register("secondInput")} {..._masks("secondInput")} /> <input type="text" {...register("thirtyInput")} {..._masks("thirtyInput")} /> <input type="text" {...register("fourtyInput")} {..._masks("fourtyInput")} /> <input type="text" {...register("fiftyInput")} {..._masks("fiftyInput")} /> <button>Mostrar Valores</button> </form> <button onClick={() => setHideValue(!hideValue)}> {hideValue ? "Mostrar" : "Ocultar"} Senha </button> </div> ); } export default App;
Output:
| +12 3323-444_ | +45 61 2 | •••••••••• | R$ 0,00 | 1,234.12 | Mostrar Valores | Mostrar Senha | | :------------- | :------- | :--------- | :------ | :------- | :-------------- | ------------- |
Console:
1 Renderização 2 Renderização { fiftyInput: "1,234.12", firstInput: "+12 3323-444_", fourtyInput: "R$ 44,55", secondInput: "+45 61 2", thirtyInput: "1255555563" } { fiftyInput: "123412", firstInput: "123323444", fourtyInput: "4455", secondInput: "45612", thirtyInput: "1255555563" }
Outros Exemplos
novo
Aqui será usado apenas o componente TextField do
Material UI
, porém o mesmo vale para todos outros.OBS: Caso você tenha percebido, ao utilizar o componente do MUI, é necessário passar o _masks da seguinte forma:
InputProps: { inputsProps: { ..._masks(...) } }
Isso é necessário pois caso passe o _masks apenas para o primeiro inputProps, não acontecerá nada em tela, mas no console você verá a mensagem de erro da sessão abaixo.
Mensagem de erro + V-check
O motivo disso é devido a tipo de elemento na qual o masks está sendo colocado, nesse caso, seria uma Div, invés de um Input, por conta disso é necessário essa utilização redundante.
import { useEffect, useState, FC, ReactNode } from "react"; import { TextField, IconButton } from "@mui/material"; import { useValisk } from "@libsdomau/valisk"; const Form: FC<ReactNode> = (children) => { return <>{children}</> } function App() { const [hideValue, setHideValue] = useState(true); type Inputs = { campo1: string; }; const methodsValisk = useValisk<Inputs>({ password: { name: "campo1", hideValue }, }); console.log("1 Renderização"); const { _masks, _cleanValues, _forceUpdate, _getValues } = methodsValisk; useEffect(() => { _forceUpdate({ inputName: "campo1", inputType: "uncontrolled", }); }, [hideValue]); return ( <div className="border border-red-600 h-screen items-center justify-center flex"> <Form> <TextField label="teste" defaultValue="bah" InputProps={{ inputProps: { ..._masks("campo1") }, endAdornment: ( <IconButton onClick={() => setHideValue(!hideValue)}> O </IconButton> ), }} /> </Form> </div> ); } export default App;
Output:
| *** | O | | :----- | :-- |
Console:
1 Renderização
V-Check | Checagem de Elemento nova sessão
Antes de partir para as referências, é importante entender do que se trata esse atributo.
_:"v-check" é um atributo encontrado em todos os elementos que receberam o _masks("...")
, ele serve como uma identificação dentro do body da página.
Ele não possui nenhuma outra utilidade, apenas serve para mostrar quais elementos receberam o método mencionado acima.
Sua criação é justamente para previr qualquer tipo de inserção em algum elemento que não seja um campo de texto.
Então, caso a máscara não esteja funcionando do campo de texto em específico, recomendo que verifique se o v-check está incluido nesse input, caso não esteja, provavelmente seu componente possui algum elemento superior.
Mas não fique precoupado, será informado no console caso o elemento que possui o _masks("...")
não seja um campo de texto, por isso, fique de olho no console.
API de Referência
Nessa sessão você poderá tirar todas suas dúvidas quanto a parametros ou retornos dos métodos, assim como ententer os tipos e até mesmo verificar a sintaxe de utilização para variados casos de uso.
Antes de continuar com a referência, lembre-se que é possível trabalhar de diversas formas com a lib, isso para atender aos mais variados casos de uso, porém, ela foi projetada para ser integrada ao react-hook-form
, isso pois essa lib já resolve de forma muito eficiênte validações e controle sobre os campos, por isso, valisk realmente brilha com a sua utilização em conjunto.
Mesmo, a lib sendo incrivelmente poderosa com o react-hook-forms, ela pode ser utilizada sozinha da mesma forma, um exemplo disso é o método _getValues
, na qual faz a mesma coisa que o onSubmit do react-hook-form
, justamente para ser utilizado em conjunto com o _cleanValues
, obtendo assim, todos os valores de forma limpa.
Por baixo dos panos, a lib realiza de forma uncontrolled a colocação da mascára nos campos, utilizando evento padrões do Javascript e eficiêntes códigos para gerar as máscarás.
Agora, vamos para os métodos.
@ Types
Aqui você poderá encontrar a finalidade e retorno dos tipos, mas é importante saber que os nomes foram colocados de forma intuitiva para lembrarmos justamente disso.
Parâmetros
| Nomes | Valor do tipo | | :---------------------------- | :--------------------------------------------------------------------------------------------------- | | ValiskEntryType<Campos> |
Array<...> \| { cep: {...}, cpf: {...}, cnpj: {...}, password: {...}, money: {...}, phone: {...} }
| | ConfigEntryType<Campos> |{ name: keyof Campos, props?: ListWithoutNameProp<Campos> }
| | ForceUpdateEntryType<Campos> |Array<...> \| { inputName: '...', inputType: "controlled", dispatchSetValue: function }
|Métodos
| Nomes | Valor do tipo | | :----------------------- | :--------------------------------------------------------------------------------------------------------------- | | CleanValuesType<Campos> |
(props: Campos) => Campos
| | ForceUpdateType<Campos> |(props: ForceUpdateEntryType<Campos>) => void;
| | GetValuesType<Campos> |(func: (data: Campos) => void) => (evt: React.FormEvent<HTMLFormElement>) => React.FormEvent<HTMLFormElement>;
| | MasksType<Campos> |(key: keyof Campos) => DetailsHTML;
|
@ useValisk
Hook que será utilizado para informar quais serão as máscaras e quais métodos de retorno serão necessários.
Entrada
Caso você esteja utilizando
javascript
, pode ignorar essa parte, ela será apenas importante paratypescript
. Agora, caso seja este o caso, é importante enter a funcionalidade abaixo.useValisk<campos>
Essa declaração é necessária para que o typescript possa utilizar os nomes dos campo de texto e assim, deixar de maneira explicita qual será o campo a possuir a máscara.
Sintaxe:
interface Inputs { teste1: string; teste2: string; } const { ... } = useValisk /* Aqui -> */<Inputs>(...)
Assim como o
react-hook-form
, o Valisk também precisa desses de entrada, ou seja, é possivel utilizar essa mesma tipagem para ambas bibliotecas.Após colocar como entrada do hook a tipagem dos campos, você já irá notar que todos os parâmetros e propriedades que precisam do nome do campo, irão retornar todos os campos, facilitando o processo de escolher qual nome do campo que precisa de tal máscara.
Sabendo disso, apenas informe sempre os tipos dos campos e deixe que o typescript e o valisk façam esse trabalho por você!
Parâmetros
Aqui estára todas as possibilidades de máscaras para serem inseridas, em breve terão mais outras para serem incluidas.
CPF
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//000.000.000-00
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ cpf: { name: "...", //nome do campo explictMask: false }, // ou cpf: [ { name: "...", explictMask: false }, { name: "...", explictMask: false } ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :------------ | :-------------------- | :-------------- | :---------- | :--------------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |explictMask
| boolean / undefined | false | Não | Utilização da máscara de forma explicita |CNPJ
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//00.000.000/0000-00
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ cnpj: { name: "...", //nome do campo explictMask: false }, // ou cnpj: [ { name: "...", explictMask: false }, { name: "...", explictMask: false } ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :------------ | :-------------------- | :-------------- | :---------- | :--------------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |explictMask
| boolean / undefined | false | Não | Utilização da máscara de forma explicita |CEP
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//00000-000
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ cep: { name: "...", //nome do campo explictMask: false }, // ou cep: [ { name: "...", explictMask: false }, { name: "...", explictMask: false } ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :------------ | :-------------------- | :-------------- | :---------- | :--------------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |explictMask
| boolean / undefined | false | Não | Utilização da máscara de forma explicita |MONEY
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//R$ 0,00 - Com Simbolo //0,00 //US$ 0.00 - Com Simbolo //0.00 //€ 0.00 - Com Simbolo //0.00
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ money: { name: "...", //nome do campo typeMoney: "real", explictMask: true, explictSimbol: true, }, // ou cep: [ { name: "...", typeMoney: "real", explictMask: true, explictSimbol: true, }, { name: "...", typeMoney: "real", explictMask: true, explictSimbol: true, }, ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :-------------- | :--------------------------- | :-------------- | :---------- | :--------------------------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |typeMoney
| "real" | "dollar" | "euro" | "real" | Sim | Tipo de moeda para máscara | |explictMask
| boolean / undefined | false | Não | Utilização da máscara de forma explicita | |explictSimbol
| boolean / undefined | false | Não | Mostra o simbolo da moeda escolhida ao lado esquerdo |PHONE
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//Celular Completo //+00 (00) 0 0000-0000 //Celular Com Prefixo //(00) 0 0000-0000 //Celular Com DDD //+00 0 0000-0000 //Celular //0 0000-0000 //Telefone Completo //+00 (00) 0000-0000 //Telefone Com Prefixo //(00) 0000-0000 //Telefone Com DDD //+00 0000-0000 //Telefone //0000-0000
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ phone: { name: "...", //nome do campo typePhone: "phoneMovel", explictMask: false, showDDD: false, showPrefix: false }, // ou phone: [ { name: "...", //nome do campo typePhone: "phoneMovel", explictMask: false, showDDD: false, showPrefix: false }, { name: "...", //nome do campo typePhone: "phoneMovel", explictMask: false, showDDD: false, showPrefix: false }, ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :------------ | :-------------------------- | :-------------- | :---------- | :---------------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |typePhone
| "phoneMovel" | "phoneFixo" | "phoneMovel" | Sim | Seleciona o tipo de fone que será o campo | |explictMask
| boolean / undefined | false | Não | Utilização da máscara de forma explicita | |showDDD
| boolean / undefined | false | Não | Fará o papel de mostrar ou esconder o DDD | |showPrefix
| boolean / undefined | false | Não | Mostra ou esconde o Prefixo do campo |PASSWORD
- [x] Máscara Válida;
- [x] Possibilidade de personalização;
- [x]
CTRL-C / CTRL-V
com ou sem máscara; - [x] Incremento mesmo com
Autocomplete dos navegadores
;
//•••••••••••• //ou //123241231254
import { useValisk } from "@libsdomau/valisk"; ... const { _masks, _forceUpdate, _cleanVal, _getValues } = useValisk({ password: { name: "...", //nome do campo hideValue: true }, // ou password: [ { name: "...", //nome do campo hideValue: true }, { name: "...", //nome do campo hideValue: true }, ] });
| Propriedades | Tipos | Valores Padrões | Obrigatório | Descrição | | :----------- | :-------------------- | :-------------- | :---------- | :----------------------------------- | |
name
| Campos | "" | Sim | Nome do campo | |hideValue
| boolean / undefined | true | Não | Opção de mostrar ou esconder o valor |
Retornos
Métodos que serão desestruturados para serem utilizados para diversas funcionalidades.
_masks
- [x] Utilizado por todos campos;
- [x] Necessario ser usado de forma única em cada campo;
- [x] Não causa uma renderização por sua utilização`;
- [x] Insere de forma automática a tag name caso não o elemento não possua;
Este é sem sombra de dúvidas o método mais importante da biblioteca, sendo ele o responsavel por gerar a máscara para cada um dos campos, por isso é necessário utilizar do
operador rest
para funcionar as máscaras.Além disso, assim como o
register
doreact-hook-form
, o_masks
também precisa receber o nome do campo que irá receber a máscara configurada no hook.Assim facilitando muito o aprendizado para quem já utilizava a outra biblioteca.
import { useValisk } from "@libsdomau/valisk"; ... interface Campos { campo1: string; campo2: string; } const { _masks } = useValisk<Campos>({...}); return ( <> <input type="text" {...masks("campo1")}/> </> );
| Opções | Tipo | Descrição | | :---------- | :-------------- | :------------------------------------------------------------------------------- | | Propriedade | keyof <Campos> | Sendo preciso escolher somente um para cada _masks | | Retorno | DetailsHTML | Propriedades do elemento Input, utilizando assim algumas tag do próprio elemento |
_forceUpdate
- [x] Os campos que precisam desse efeito, precisam ser declaros de forma clara;
- [x] Pode ser usados quantas vezes forem necessárias com diversos campo em uma atualização ou apenas um;
- [x] Não causa uma renderização por sua utilização;
- [x] É usado na maioria da vezes em conjunto com o useEffect nativo do react.
- [x] Usado para trocar o valor da senha ou para carregar todas os campos com máscara como valor inicial.
Esse método possui a função de atualizar o valor de todos os campo inseridos, ele faz isso por meio de eventos e funcionalidades internas do campo, ou seja,
ele não causa nenhuma renderização
, para mudar o valor de forma defitiva é necessário carregar o componente novamente com as propriedades já alteradas, por conta disso, ele é normalmente utilizado com ouseEffect
do react, pois, assim que o componente é carregado novamente, ele captura todos os valores alterados erealiza as mudaças
sem precisar realizar uma nova renderização.Em seus parametros é necessário indicar algumas
props
, para que a lib possa fazer a atualização do camposem causar uma nova renderização
.import { useEffect } from "react"; import { useValisk } from "@libsdomau/valisk"; import { useForm } from "react-hook-form"; ... interface Campos { campo1: string; campo2: string; } const [hideValue, setHideValue] = useState(false); const { register, setValue } = useForm<Campos>(); const { _masks _forceUpdate } = useValisk<Campos>({...}); useEffect(() => { _forceUpdate({ inputName: "campo2" inputType: "uncontrolled" }) }, []); useEffect(() => { _forceUpdate({ inputName: "campo1" inputType: "react-hook-form", dispatchSetValue: setValue, }) }, [hideValue]); return ( <> <input type="text" {...register("campo1")} {...masks("campo1")}/> </> );
| Opções | Tipo | Descrição | | :---------- | :------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Propriedade | { inputName: keyof <Campos>, inputType: "controlled" | "uncontrolled" | "react-hook-form", dispatchSetValue: Function } | Aqui é preciso informar de forma exata os campos que serão atualizados, mesmo que não cause uma renderização, é importante colocar apenas aquele que necessitam de uma alguma atualização de valor. Lembrando que é possível inserir um array de objetos, além de apenas um objeto. | | Retorno | void | Esse método não retorna nenhum tipo de valor, apenas realiza seus processos. |
_cleanValues
- [x] Mostra todos os valores em forma de objeto da mesma maneira que foram declarados;
- [x] Necessita receber os dados e realiza a conversão deles para dados sem máscaras, apenas em formato de números e letras;
- [x] Todos valores que não foram configurados para possuirem máscara serão retornados sem alteração;
- [x] Pode ser usado com o
handleSubmit
doreact-hook-form
para mostrar tudo sem máscara.
Este é método que limpa o valor de todos as propriedades do objeto que possuem algum tipo de máscara e foram indicados nas configurações da lib, ele apenas remove tudo o que não seja letra ou número do valor.
Já os campos que não possuem a configuração, são retornados igualmente, porém, sem nenhum tipo de remoção.
import { useValisk } from "@libsdomau/valisk"; ... interface Campos { campo1: string; } const showValues: Campos = (data) => { console.log(_cleanVal(data)); }; const { _masks, _cleanValues, _getValues } = useValisk<Campos>({...}); return ( <form onSubmit={_getValues(showValues)}> <input type="text" {...masks("campo1")}/> </form> );
| Opções | Tipo | Descrição | | :---------- | :-------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Propriedade | <Campos> | Aqui é preciso informar a data obtida através do
onSubmit
, sendo pelo_getValues
ou pelohandleSubmit
| | Retorno | <Campos> (Formatado) | O retorno desse método é básicamente o mesmo objeto passado porém, com remoções de máscaras caso algum campo tenha sido registrado no hook, caso o contrário, apenas é retornado da maneira que é passado. |
_getValues
- [x] Captura o valor de todos os campos dentro do form.
- [x] Os campos não precisam possuir o
_masks
, porém precisam estar declarados no Tipo de Entrada; - [x] Ele retorna um objeto com todos o valores dos campos, essa tipagem é a mesma de entrada no hook;
- [x] Funciona igual o
handleSubmit
doreact-hook-form
, precisando passar um função dentro e ela possuirá os valores retornados.
Este método funciona como um auxiliar, uma função que captura todos valores dos campos que são exclusivamente filhos do Form. Após pegar os valores, ela converte eles em um objeto utilizando o nome do campo como key e o valor como value.
É necessário passar uma outra função para dentro desse método, ela que irá receber o valor dos campos em formato de objeto atráves do parâmetro.
Caso você tenha utilizado o
react-hook-form
, ela funciona igual ohandleSubmit
.import { useValisk } from "@libsdomau/valisk"; ... interface Campos { campo1: string; } const { _masks, _getValues } = useValisk<Campos>({...}); const showValues: Campos = (data) => console.log(data); return ( <form onSubmit={_getValues(showValues)}> <input type="text" {...masks("campo1")}/> </form> ); <!-- Ou --> return ( <form onSubmit={_getValues((data) => console.log(data))}> <input type="text" {...masks("campo1")}/> </form> );
| Opções | Tipo | Descrição | | :---------- | :------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- | | Propriedade | Função | Essa função será executada recebendo por parâmetro o objeto com todos os valores dos campos, ela precisa ser do tipo void, ou seja, sem retorno. | | Retorno | FormEvent | É retornado o evento para que seja possível capturar o evento do submit. |
@ useConfigEntry novo
Este hook fará o trabalho pesado para você, caso precise organizar os dados dos campos de uma maneira diferente da forma que o useValisk
pede, é só utilizar este hook, a finalidade dele é organizar, independente da estrutura as máscaras para os campo corretos.
OBSERVAÇÃO: É necessário utilizar o tipo <ConfigEntryType> no lugar onde será declarado a máscara e o nome do campo, porém é possivel criar todas outras estruturas ao redor da maneira que achar melhor.
Entrada
Essa declaração é necessária para que o typescript possa utilizar os nomes dos campo de texto e assim, deixar de maneira explicita qual será o campo a possuir a máscara.
Sintaxe:
interface Inputs { teste1: string; teste2: string; } const { ... } = useConfigEntry /* Aqui -> */<Inputs>(...)
Parâmetros
Aqui estára todas as possibilidades de máscaras para serem inseridas, em breve terão mais outras para serem incluidas.
Any
- [x] Fará a conversão de uma estrutura de dados para outra;
- [x] Não altera nenhum dado;
O principal motivo desse método receber any é porque ele literalmente aceita qualquer estutura de dados.
Desde um array com vários arrays dentro, até apenas um único objeto. Todas essa possibilidades fazem o método ser muito versatil.
Porém é necessário a utilização do tipo ConfigEntryType caso não crie o objeto diretamente no parâmetro.
Isso porque a ideia principal desse hook é converter a estrutura de dados que será utilizado como fonte para o hook
useValisk
para algo que o próprio possa aceitar, ou seja, você acaba tendo liberdade para criar vários tipos de estruturas, mas com a obrigação de incluir um objeto do tipo ConfigEntryType.Vamos ao exemplo da sua utilização, nela existe uma estrutura de uma array com um array e assim o nosso objeto que precisamos, assim declaramos e como podemos ver, a opção
props
não é obrigatória, isso funciona muito bem pois o valisk não irá gerar erro mesmo que não exista uma configuração de mascará para um nome de campo, ele apenas irá colocar o name no campo e não irá informar erro algum.import { useValisk, useConfigEntry, ConfigEntryType } from "@libsdomau/valisk"; ... interface Inputs { campo1: string; campo2: string; campo3: string; } type Dados = Array< Array<React.HTMLAttributes<HTMLInputElement> & /* Aqui é usado --> */ConfigEntryType<Inputs>> >; const dados: Dados = [ [ { name: "campo1", id: "campo1", defaultValue: "aaaa", props: { money: { typeMoney: "real", explictMask: true }, cpf: { explictMask: true } /* <-- Isso aqui não irá funcionar, ele pega apenas o primeiro */ }, }, { name: "campo2", placeholder: "teste1", }, ], [ { name: "campo3", props: { cnpj: { explictMask: true } }, }, ], ]; const configMasks = useConfigEntry<Inputs>(dados); const methodsValisk = useValisk<Inputs>(configMasks);
Retornos
Métodos que serão desestruturados para serem utilizados para diversas funcionalidades.
ValiskEntryType
O retorno do hook será sempre o parâmetro de entrada do
useValisk
, isso porque ele serve de auxiliar para uma estrutura diferente de dados.Usando o mesmo exemplo anteriores teriamos a seguinte resposta:
const configMasks = useConfigEntry<Inputs>(dados); const methodsValisk = useValisk<Inputs>(configMasks); console.log(configMasks); /* cnpj:{ "name": "campo3", "explictMask": true }, money:{ "name": "campo1", "typeMoney": "real", "explictMask": true } */
@ ValiskProvider novo
Inspirado no FormProvider
do react-hook-form
, o ValiskProvider tem a funcionalidade de reutilização dos métodos do useValisk. É necessário apenas envolver esse componente entorno dos campos que precisam utilizar os métodos.
Parâmetros
Ao utilizar o componente, é necessário passar um valor, esse é obtido através da utilização do método useValisk, assim, basta passar o valor retornado para dentro do componente pela destruturação.
Sintaxe:
const methodsValisk = useValisk<Inputs>(...); const { _masks, _forceUpdate, _getValues, _cleanValues } = methodsValisk; <ValiskProvider {...methodsValisk}> ... </ValiskProvider>
@ useValiskContext novo
Entrada
Essa declaração é necessária para que o typescript possa utilizar os nomes dos campo de texto e assim, deixar de maneira explicita qual será o campo a possuir a máscara.
Sintaxe:
interface Inputs { teste1: string; teste2: string; } const { ... } = useValiskContext /* Aqui -> */<Inputs>()
Retornos
Todos os métodos que são retornados serão a partir do valor do
ValiskProvider
, ou seja, serão os mesmo métodos do hookuseValisk
.Sintaxe:
... type Inputs = { campo1: string; campo2: string; campo3: string; campo4: string; } ... return ( <ValiskProvider {...methodsValisk}> <InputComponent /> </ValiskProvider> ); const InputComponent = () => { const { _masks, _forceUpdate, _cleanValues, _getValues } = useValiskContext<Inputs>(); return <input {..._masks('...')}/> }
Erros Comuns nova sessão
Essa sessão foi criada para mostrar todos os erros comuns que podem acontecer com o uso da biblioteca, porém, caso sua dúvida não esteja aqui, faça uma issue, agradeço.
Existe uma grande chance de, neste caso, o problema estar no elemento superior, isso acontece normalmente com componentes que possuem algum campo de texto.
O problema aqui é que o elemento que está recebendo o método _masks(...)
não é o campo de texto, mas sim algum outro elemento dentro do componente (caso seja um componente).
Para identificar isso, basta procurar pelos elemento que possuem o atributo v-check
dentro do inspecionar da página, caso algum elemento não seja um campo de texto, ele não funcionará.
Nesse caso, também haverá uma mensagem no console falando qual elemento está recebendo o método em específico.
Dúvidas
Aqui estão as melhores maneiras de contribuir com o projeto, caso tenha alguma coisa não explicada com as dúvidas abaixo, entre em contato.
Issue: https://github.com/MauMuller/valisk/issues/new
Pull Request: https://github.com/MauMuller/valisk/pulls