https://a.storyblok.com/f/270183/17390/2847c2d88d/blog_open_wc_1200x600.png

Criação de um componente da Web com o Open-WC

Publicado em November 7, 2020

Tempo de leitura: 7 minutos

Nos episódios anteriores desta série, abordamos o que são os Web Components e algumas ferramentas usadas para criá-los. Agora, vamos criar um Web Component, publicá-lo e usá-lo em uma página da web.

O que vamos criar? Um componente de teclado utilizando Componentes da Web do Material Design. Vamos criar um Web Component composto por Web Components — bem meta, eu sei.

A ideia é conseguir inserir um teclado numérico em um projeto com o mínimo de complicações possível. Com apenas algumas linhas de código, o usuário pode ter uma maneira de inserir números em um aplicativo para fazer uma ligação, ajustar a temperatura, selecionar uma resposta em um questionário, votar e muitas outras Applications.

Vamos listar os recursos do componente de teclado que será desenvolvido:

  • O Web Component pronto para uso exibirá um visor e, abaixo dele, botões com os dígitos de 0 a 9, * e #.

  • O usuário poderá ocultar o visor e os botões * e # definindo atributos e propriedades.

  • Quando um usuário clicar em um botão, um caractere será adicionado a um display. Ao mesmo tempo, um evento personalizado será enviado para que o aplicativo fora do componente saiba que um botão foi pressionado.

  • Haverá um botão “Ação” que enviará todos os dígitos digitados como um evento personalizado para que a aplicação principal o processe da maneira que achar melhor. O texto do botão pode ser definido pelo usuário por meio de uma propriedade.

  • Haverá outro botão à disposição do usuário para “Encerrar” a ação. O texto desse botão também poderá ser personalizado. Ao ser pressionado, a tela será apagada e mais um evento personalizado será enviado ao aplicativo para que ele seja notificado.

  • O Componente Web terá um método público disponível para que o aplicativo possa passar para o estado “ativo”, o que, por sua vez, exibirá o botão “Fim”.

  • Para dar um toque de estilo ao componente da Web, serão utilizados os componentes de botão e campo de texto do Material Design.

Veja o componente da Web em ação

Aqui está um exemplo funcional no CodePen

Veja a Pen teclado-como-você-quiser por conshus do OUR show (@conshus) no CodePen.

Vá em frente, digite alguns dígitos e pressione Enter. Clique em “OK” no aviso e, em seguida, clique em “Cancelar”.

Criação de componentes com o Open Web Components

Como vamos criar esse componente de teclado? Usaremos o lit-html por meio do Open Web Components (Open-WC). Conforme indicado no site:

O objetivo do Open Web Components é proporcionar a todos uma estrutura robusta e comprovada para o compartilhamento de componentes web de código aberto. Buscamos alcançar isso oferecendo um conjunto de recomendações e configurações padrão para facilitar o desenvolvimento do seu projeto de componentes web. Nossas recomendações incluem: desenvolvimento, verificação de código, testes, ferramentas, demonstrações, publicação e automação.

Ao começar com o Open-WC, todos os membros de uma equipe podem ter o mesmo ponto de partida para criar componentes web. Como em muitas coisas, a consistência é um fator de sucesso.

Como o Open-WC tem uma abordagem bastante definida sobre como os Web Components e os projetos devem ser criados, ele oferece uma ferramenta CLI bastante completa para gerá-los. Vamos configurar tudo.

No seu terminal, acesse o diretório onde o projeto do Componente Web ficará armazenado.

Em seguida, digite npm init @open-wc. Isso iniciará o processo de configuração do Open-WC.

Aqui estão as opções que utilizei para o projeto desta postagem do blog:

  • O que você gostaria de fazer hoje?: Montar a estrutura de um novo projeto

  • O que você gostaria de desenvolver?: Componente da Web

  • O que você gostaria de acrescentar?: Verificação de código (eslint e prettier)

  • Você gostaria de usar o TypeScript? Não

  • Qual é o nome da tag do seu aplicativo/componente web? whatever-you-like-keypad (Você pode nomear o componente web como quiser, desde que o nome tenha pelo menos duas palavras separadas por um ‘-’)

  • Deseja gravar essa estrutura de arquivos no disco? Sim

  • Deseja instalar as dependências? Sim, com o npm (se preferir o yarn, pode escolher essa opção)

Open-WC cli tool setup processOpen-WC cli tool setup process

Para instalar o botão e o campo de texto do Material Design, acesse a nova pasta criada durante o processo de configuração do Open-WC e digite o seguinte:

npm i @material/mwc-button

npm i @material/mwc-textfield

Installing Material Design button and text fieldInstalling Material Design button and text field

O código do componente

O código do Componente Web pode ser encontrado neste repositório do GitHub. Vamos examinar o código no único arquivo da src pasta.

Primeiro, as importações. O Open-WC recomenda o uso de lit-html e o lit-element para construir e renderizar o Web Component. Também importamos o botão e o campo de texto do Material Design para usar no Web Component.

import { html, css, LitElement } from 'lit-element';
import '@material/mwc-button/mwc-button';
import '@material/mwc-textfield/mwc-textfield';

Baseamos nosso novo componente da Web no LitElement.

export class WhateverYouLikeKeypad extends LitElement {

Estilização do componente da Web

static get styles() {
    return css`
      :host {
        display: block;
        padding: 25px;
        color: var(--vwc-dialer-text-color, #000);
      }

      #container {
        width: 75vw;
        max-width: 300px;
      }

      .button-row {
        display: flex;
        justify-content: space-evenly;
      }

      .full-width {
        width: 100%;
      }

      mwc-button {
          margin: 10px;
      }

      mwc-textfield {
        --mdc-notched-outline-leading-width: 28px;
        --mdc-notched-outline-leading-border-radius: 28px 0 0 28px;
        --mdc-notched-outline-trailing-border-radius: 0 28px 28px 0;
        width: 100%;
      }
    `;
  }

Aqui, os atributos e propriedades que o Web Component aceita são definidos juntamente com seus tipos. Dessa forma, o lit-html sabe como lidar com os valores passados.

static get properties() {
    return {
      noAsterisk: { attribute: 'no-asterisk', type: Boolean },
      noHash: { attribute: 'no-hash', type: Boolean },
      noDisplay: { attribute: 'no-display', type: Boolean },
      actionText: { type: String },
      cancelText: { type: String },
      actionStarted: { type: Boolean },
      digits: { type: String }
    };
  }

O Web Component herda todos os “superpoderes” do LitElement e define os valores padrão.

constructor() {
    super();
    this.noAsterisk = false;
    this.noHash = false;
    this.noDisplay = false;
    this.digits = "";
    this.actionText = "Enter";
    this.cancelText = "Cancel"
    this.actionStarted = false;
  }

A seguir, abordaremos os diversos métodos do Componente Web. Coisas como disparar eventos personalizados ao adicionar ou enviar dígitos e encerrar uma ação. Há também o método que pode ser chamado no Componente Web para informá-lo de que uma ação foi iniciada.

__addDigit(digit){
    this.digits += digit;
    const digitAdded = new CustomEvent('digit-added', {
      detail: { digit },
      bubbles: true,
      composed: true });
    this.dispatchEvent(digitAdded);
  }

  __sendDigits(){
    const digitsSent = new CustomEvent('digits-sent', {
      detail: { digits: this.digits },
      bubbles: true,
      composed: true });
    this.dispatchEvent(digitsSent);
  }

  createAction(){
    this.actionStarted = true;
  }

  __endAction(){
    const actionEnded = new CustomEvent('action-ended', {
      detail: { },
      bubbles: true,
      composed: true });
    this.dispatchEvent(actionEnded);
    this.digits = "";
    this.actionStarted = false;
  }

Você deve ter notado que a __addDigit função simplesmente adiciona o dígito ao final. Se um usuário mover o cursor para o meio dos dígitos, novos dígitos serão adicionados apenas ao final.

addDigit function only adding digits to the endaddDigit function only adding digits to the end

Agora, como exercício, vamos permitir que novos dígitos sejam adicionados onde quer que o cursor esteja. Aqui está uma dica sobre onde start.

A marcação para exibir o Componente da Web. Dependendo do estado e dos atributos/propriedades definidos, o Componente da Web exibirá ou ocultará diferentes elementos.

  render() {
    return html`
        <div id="container">
            ${this.noDisplay ? "" : html`<mwc-textfield outlined label="" .value=${this.digits}></mwc-textfield>`}
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('1')}>1</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('2')}>2</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('3')}>3</mwc-button>
            </div>
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('4')}>4</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('5')}>5</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('6')}>6</mwc-button>
            </div>
            <div class="button-row">
                  <mwc-button unelevated @click=${()=>this.__addDigit('7')}>7</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('8')}>8</mwc-button>
                  <mwc-button unelevated @click=${()=>this.__addDigit('9')}>9</mwc-button>
            </div>
            <div class="button-row">
                  ${this.noAsterisk ?
      ""
      : html`<mwc-button unelevated @click=${()=>this.__addDigit('*')}>*</mwc-button>`
    }
                  <mwc-button unelevated @click=${()=>this.__addDigit('0')}>0</mwc-button>
                  ${this.noHash ?
      ""
      :html`<mwc-button unelevated @click=${()=>this.__addDigit('#')}>#</mwc-button>`
    }
            </div>
            <div class="button-row">
                ${this.actionStarted ?
      html`<mwc-button unelevated fullwidth @click=${this.__endAction}>${this.cancelText}</mwc-button>`
      :html`<mwc-button unelevated fullwidth @click=${this.__sendDigits}>${this.actionText}</mwc-button>`
    }
            </div>
        </div>
    `;
  }

Publicando seu novo componente da Web

Agora que o Web Component está pronto, vamos publicá-lo para que nós e outras pessoas possamos usá-lo em um projeto.

Para isso, vamos usar um repositório como o npm. Se você ainda não tiver uma, crie um Account. Aqui estão algumas informações. Isso não só mostrará como criar um Account, mas também como fazer login nele usando o terminal, para que você possa publicar o Web Component.

Depois que isso estiver configurado, o Componente Web será publicado como um pacote de escopo público. Isso ajudará a evitar conflitos, caso exista um Componente Web ou pacote com o mesmo nome que você escolheu. Mais informações sobre escopos podem ser encontradas aqui.

No terminal, no diretório do projeto, digite (substituindo “seu-nome-de-usuário-npm” pelo seu nome de usuário do npm):

npm init --scope=@your-npm-username

Aceite todas as opções padrão ou altere-as como achar melhor em cada etapa.

Using the command line to set the scope of the projectUsing the command line to set the scope of the project

Como seu Web Component agora está dentro de um escopo, vamos modificar o Readme que foi gerado pelo Open-WC para refletir isso. Mais uma vez, substitua os placeholders (your-npm-username e whatever-you-like-keypad) pelos seus próprios.

O comando para instalar será:

npm i @your-npm-username/whatever-you-like-keypad

Para utilizá-lo em um projeto, você utilizará a import sintaxe mostrada abaixo:

import '@your-npm-username/whatever-you-like-keypad/whatever-you-like-keypad.js';

Salve suas alterações.

Agora, vamos publicar o Web Component. Digite no terminal:

npm publish --access public

Publishing the project to npmPublishing the project to npm

Se tudo der certo, você poderá encontrar o Web Component no site do npm em https://www.npmjs.com/package/@your-npm-username/whatever-you-like-keypad.

É claro que substituir your-npm-username e whatever-you-like-keypad pelos seus valores.

Parabéns, sua publicação foi aprovada! Agora você tem um Componente Web disponível ao público que você e outras pessoas podem usar em um projeto.

Como usar o componente da Web

Para instalar uma cópia localmente, digite no terminal o diretório de um projeto, substituindo novamente pelos seus valores:

npm i @your-npm-username/whatever-you-like-keypad

Mas e se você não quiser instalar o pacote? Talvez você queira garantir que sempre carregue a versão mais recente ou queira ver o Web Component em um ambiente que não permita a instalação, como CodePen.

É aí que entra uma Rede de Entrega de Conteúdo (CDN). Ela hospeda seu pacote e você pode criar um link direto para seus arquivos. Para este post, vamos usar unpkg.com. Eles copiam automaticamente seus arquivos, então você não precisa fazer nada.

Aqui está um exemplo no CodePen que você pode usar para testar seu Web Component:

Mais uma vez, substitua os espaços reservados para o nome de usuário e o nome do componente pelos seus próprios, tanto no HTML e JS guias.

Veja a Pen teclado-como-você-quiser por conshus do OUR show (@conshus) no CodePen.

Tente adicionar alguns dos atributos e propriedades do Componente Web que criamos (no-asterisk, no-hash, no-display) e defina os valores para o texto do botão (actionText="Algo" cancelText="Outra coisa").

Observação: Ao usar a opção “no-display”, para visualizar os dígitos, será necessário um elemento HTML do tipo “input” ou “textarea”. Como neste exemplo:

Veja a Pen teclado-como-você-quiser (todas as opções) por conshus do OUR show (@conshus) no CodePen.

E agora?

Agora que você tem um componente da Web novinho em folha, o que mais você pode adicionar a ele? Talvez um botão de retrocesso que apague um caractere ou que permita ao usuário definir seus próprios botões. Ou talvez simplesmente criar algo totalmente novo.

Deixe aqui os links para o seu Web Component, suas dúvidas e/ou comentários em nosso canal da Comunidade no Slack. Estou ansioso para ver o que vocês vão criar.

Compartilhar:

https://a.storyblok.com/f/270183/384x384/1a06993970/dwanehemmings.png
Dwane HemmingsPromotor de Desenvolvedores de JavaScript