Front End

7 dez, 2018

Bem-vindo ao Polymer 3 – Parte 02: adicionando filhos com <slot>

Publicidade

Fala, galera! Beleza?

No primeiro artigo desta série nós vimos como criar um web component de Hello World onde, ao utilizarmos a nossa tag <hello-world>, já era renderizado um h1 com a nossa saudação.

Tudo muito lindo, muito maravilho, mas vocês devem ter se perguntado: “Ok, e se eu não quiser que meu elemento renderize algo pré-definido? E se eu quiser definir o conteúdo que vai dentro do meu componente de acordo com o lugar onde vou utilizá-lo?

E se eu quisesse utilizar um componente dentro do outro?”. É por isso que o segundo artigo dessa série vai abordar exatamente esses pontos. Lhes apresento a tag <slot>!

O <slot> é um espaço reservado dentro de um web component, onde você pode preencher com sua própria marcação HTML.

Criando nosso elemento com <slot>

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

class MyElement extends PolymerElement {
  static get template() {
    return html`
    <button>
      <slot></slot>
    </button>
    `;
  }
};

customElements.define('my-element', MyElement);

Acima, temos um arquivo chamado “slot.js”. Nele, estamos criando o nosso web component <my-element>. Perceba que nosso componente é composto apenas de um <button>, e que dentro desse button declaramos o <slot>.

Utilizando nosso elemento

<!doctype html>
<html>
  <head>
    <script type="module" src="slot.js"></script>
  </head>
  <body>
    <my-element>
      <span>Entendi</span>
    </my-element>
  </body>
</html>

Com o nosso elemento criado, podemos usá-lo na nossa página, conforme o exemplo acima, onde estamos inserindo um <span> dentro do nosso componente com o texto “Entendi”.

Agora, ao renderizar a nossa página HTML, teremos o seguinte resultado:

Página renderizada no browser com um botão que tem o texto “Entendi”

Legal, né? Mas dessa forma só podemos utilizar um <slot> dentro de cada componente. Para mais de um, somente com slots nomeados!

Slot nomeado

Um slot nomeado serve para quando queremos mais de um slot dentro de um mesmo componente, como no exemplo abaixo:

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

class MyElement extends PolymerElement {
  static get template() {
    return html`
    <h1>
      <slot name="header"></slot>
    </h1>
    <p>
      <slot name="paragraph"></slot>
    </p>
    `;
  }
};

customElements.define('my-element', MyElement);

Aqui temos um slot chamado “header”, que coloquei dentro de uma tag <h1>, e um slot chamado “paragraph”, que coloquei dentro de uma tag <p>.

<!doctype html>
<html>
  <head>
    <script type="module" src="slot-named.js"></script>
  </head>
  <body>
    <my-element>
      <span slot="header">Aqui é o título</span>
      <span slot="paragraph">Aqui é o paragrafo</span>
    </my-element>
  </body>
</html>

Na nossa página HTML conseguimos dizer qual <span> pertence a qual slot. Dessa forma, podemos ter vários slots no nosso componente.

Você consegue atribuir várias tags HTML ao mesmo slot. Por exemplo: se eu quiser colocar outro <span> na minha página e dizer que ele pertence ao slot “paragraph”, eu posso.

Agora a nossa página renderizada está assim:

Página renderizada com os conteúdos dos slots nomeados. Há um header escrito “Aqui é o título” e um paragrafo escrito “Aqui é o paragrafo”

Fallback

Sabendo o que é um slot nomeado, você deve saber também que pode ter um slot nomeado que contém um fallback, ou seja, um valor default. Isso pode ser muito útil quando você precisa, por exemplo, que algo seja renderizado no seu web component independente se algum elemento foi atrelado àquele slot ou não.

Calma, não fique desesperado. Olha só o componente que eu tenho aqui:

import {html, PolymerElement} from '@polymer/polymer/polymer-element.js';

class MyElement extends PolymerElement {
  static get template() {
    return html`
    <h1>
      <slot name="header">Aqui é o titulo</slot>
    </h1>
    <button>
      <slot></slot>
    </button>
    `;
  }
};

customElements.define('my-element', MyElement);

Nesse componente eu tenho um slot “normal” (utilizei o mesmo slot do primeiro exemplo para ficar mais simples) e um slot nomeado (o meu “header”). Coloquei a frase “Aqui é o titulo” como valor default do meu slot nomeado.

Com meu componente criado dessa forma eu posso ter uma página HTML assim:

<!doctype html>
<html>
  <head>
    <script type="module" src="slot-fallback.js"></script>
  </head>
  <body>
    <my-element>
      <span>Entendi</span>
    </my-element>
  </body>
</html>

Ao renderizar minha página eu vou encontrar o seguinte resultado:

Página com um valor default do slot renderizada contendo um

Perceberam que mesmo eu não declarando o slot nomeado ele apareceu ali onde deveria? Isso por causa do fallback que atribuí a ele lá no meu componente.

Se eu passasse na minha página HTML um conteúdo para o slot “header”, esse conteúdo substituiria o meu valor de fallback.

Só é possível passar um valor de fallback para slots nomeados! Lembre-se sempre disso.

Conclusão

No artigo de hoje pudemos ver como inserir marcações HTML dentro do nosso web component, seja com um simples slot, com um slot nomeado ou com um fallback de slot nomeado.

Agora podemos brincar um pouco mais com nossos componentes, e fiquem ligados que no próximo artigo falarei sobre como criar propriedades para seus componentes nativos!

Ah, e não se esqueçam de me seguir nas minhas redes sociais para continuar por dentro dos conteúdos que estou preparando pra vocês.