Melhorando a experiência de desenvolvimento com formulários inteligentes

Toda vez que eu consulto a documentação de uma biblioteca que promete facilitar o desenvolvimento de formulários, tenho uns três tipos diferentes de decepção. Não consigo acreditar que alguém olhe para a solução proposta e ache que ela realmente vai melhorar a experiência de desenvolvimento.

Eu poderia citar alguns motivos como a contra intuitividade de algumas APIs, a quantidade de código que ainda precisa ser escrito, a dificuldade no reuso do código, entre outros. Mas a causa raiz por trás de todos esses motivos é a mesma. A falta de ousadia na hora de projetar a solução. Sim, na minha opinião, as bibliotecas disponíveis atualmente parecem partir de uma lugar muito a frente de onde deveriam. Ignoram o "momento loucura", o momento "e se a gente experimentasse algo completamente diferente". As bibliotecas parecem ter admitido que desenvolver um formulário é chato, então não conseguem encontrar uma maneira de superar isso.

A partir de um determinado momento na minha carreira, eu comecei a sonhar com duas melhorias no HTML que me deixariam muito, muito, muito feliz.

A primeira delas diz respeito aos elementos que controlam dados de um formulário. Ou seja, <input>, <select> e <textarea>. O meu desejo era que eles tivessem uma propriedade chamada validations. Ela aceitaria um Array de objetos, cada um contendo os atributos isValid (função que retornaria um valor Booleano) e errorMessage (String a ser exibida no caso de isValid retornar falso). Ou seja, eu poderia efetuar diversas validações contra um campo de formulário e definir uma mensagem para cada um dos possíveis erros.

A segunda melhoria seria no elemento <form>. Em tempos de Single Page Applications, seria incrível se esse elemento oferecesse as propriedades successMessage e errorMessage. Em caso de sucesso, um toast poderia ser exibido na tela com a mensagem de sucesso. Caso a requisição falhasse, um banner ao topo do formulário exibiria a mensagem de erro junto com um botão que permitisse o reenvio dos dados.

Traduzindo o meu sonho para HTML, teríamos algo mais ou menos assim:

<form
  onsubmit="() => axios.post(…)"
  success-message="Tudo certo, obrigado!"
  error-message="Não foi possível enviar os dados. Por favor, tente novamente."
>
  <input
    aria-label="Digite uma linguagem de programação"
    validations="[{ isValid: value => value === 'JavaScript', errorMessage: 'Por favor, escolha uma mais legal.' }]"
    placeholder="Digite uma linguagem de programação"
  />
  <button type="submit">
    Enviar
  </button>
</form>

Durante três anos, minhas cartas para o Papai Noel imploraram para que esse sonho se tornasse realidade. Até que no final de 2020, com a certeza que o velhinho iria me ignorar mais uma vez, decidi arregaçar as mangas e realizá-lo na marra.

Esse foi o principal motivo por trás da criação do Taslonic. Eu o criei com a intenção de me livrar de tarefas ordinárias e assim poder focar em coisas extraordinárias. Ninguém merece perder horas preciosas da vida tendo que tratar os mesmos casos de uso em todo novo formulário que a aplicação precisar. Além do desperdício de tempo, a implementação repetitiva desses casos de uso (feedbacks de sucesso/erro/processamento) leva a inevitáveis inconsistências na experiência de uso da aplicação, pois oras serão implementados de uma maneira, oras de outra. Isso para não falar das vezes em que alguns casos de uso são esquecidos. Quem nunca ficou diante de um loader que nunca sumiu da tela mesmo após a requisição já ter falhado?

Experimente o comportamento desse formulário feito com Taslonic simulando a inscrição numa newsletter.

Inscrever-se

Aqui está tudo que precisei implementar para criar o formulário:

Abaixo, tudo que o formulário me entregou sem que eu precisasse escrever uma única linha de código:

  1. Exibe um asterisco nos labels de campos que são obrigatórios.
  2. Exibe a mensagem de erro sob um campo inválido só depois que o usuário desfoca o campo ao menos uma vez, evitando que a mensagem de erro seja exibida enquanto o campo ainda está sendo preenchido.
  3. Exibe as mensagens de erro de todos os campos inválidos caso o usuário submeta o formulário sem preenchê-los corretamente, e foca o primeiro campo inválido.
  4. Substitui o texto do botão de envio por um loader durante a requisição e o retorna ao estado inicial quando a requisição é concluída.
  5. Desabilita o botão de envio durante o processamento da requisição para evitar múltiplos envios.
  6. Lança um toast contendo uma mensagem personalizada no sucesso do envio.
  7. Exibe um banner ao topo do formulário acompanhado de um botão que permite ao usuário enviar os dados novamente caso a requisição falhe.

Foram sete casos de uso que não precisei implementar e, consequentemente, testar. Curioso para ver o código? Aqui vão alguns links:

Se gostou do que viu aqui, considere estrelar o repositório do projeto no Github para que mais pessoas conheçam o Taslonic e passem a construir formulários perdendo menos tempo.