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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@libsdomau/valisk

v1.0.6

Published

Mascaras UNCONTROLLED, CONTROLLED e integração com REACT-HOOK-FORMS

Downloads

4

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:

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 propriedades cpf e money.

    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 propriedade phone, 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 propriedades cep e cnpj, 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.

Error

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 para typescript. 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 do react-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 o useEffect do react, pois, assim que o componente é carregado novamente, ele captura todos os valores alterados e realiza 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 campo sem 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 do react-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 pelo handleSubmit | | 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 do react-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 o handleSubmit.

        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 hook useValisk.

    • 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