Ir para o conteúdo principal
WBC - GovBR-DS
Copiar página como Markdown para IA

Slots

Slots são pontos de entrada para conteúdo dentro de um Web Component. Eles permitem que você componha a interface com textos, ícones, imagens, links e outros elementos sem depender de uma propriedade específica para cada variação de conteúdo.

Na prática, o componente controla a estrutura, acessibilidade e comportamento. A aplicação fornece o conteúdo que entra nos espaços definidos pelo componente.

Quando usar​

Use slots quando o conteúdo precisa ser flexível, sem alterar o contrato principal do componente.

Exemplos comuns:

  • Texto ou ícone dentro de um botão.
  • Mensagem de erro, sucesso ou ajuda dentro de um campo.
  • Itens de navegação dentro de breadcrumb, menu, footer ou tabela.
  • Conteúdo complementar, como imagem institucional em br-sign-in.

Slot padrão​

O slot padrão recebe o conteúdo que não possui o atributo slot.

<br-button emphasis="primary"> Enviar solicitação </br-button>

Nesse exemplo, o texto Enviar solicitação entra no slot padrão do br-button.

Slots nomeados​

Slots nomeados recebem conteúdo marcado com slot="nome-do-slot". Eles são usados quando o componente expõe mais de uma área de composição.

<br-input label="CPF" placeholder="000.000.000-00">
<br-message slot="feedback" state="danger"> Informe um CPF válido. </br-message>
</br-input>

No exemplo acima, o br-message ocupa o slot feedback do br-input. Isso mantém a mensagem conectada visualmente ao campo, sem exigir que a aplicação conheça a estrutura interna do componente.

Compondo componentes e encadeamento de slots​

Slots também podem receber outros Web Components. Esse padrão é a base dos componentes compostos, como tabela, menu, footer e breadcrumb.

<br-table>
<br-table-header slot="header">
<br-table-header-cell>Serviço</br-table-header-cell>
<br-table-header-cell>Situação</br-table-header-cell>
</br-table-header>

<br-table-body slot="body">
<br-table-row>
<br-table-cell>Agendamento</br-table-cell>
<br-table-cell>Disponível</br-table-cell>
</br-table-row>
</br-table-body>
</br-table>

Repasse de slots (Slot forwarding)​

Quando componentes orquestradores delegam partes de sua UI para subcomponentes internos, pode ocorrer o encadeamento de slots (slot forwarding): o componente pai expõe um slot e o repassa diretamente para o slot de um componente filho no seu template:

<!-- No template do componente orquestrador -->
<div class="container">
<slot name="header" slot="header"></slot>
<slot></slot>
</div>

Esse encadeamento preserva a semântica e permite que a aplicação consumidora customize níveis mais profundos sem quebrar o encapsulamento.

Fallback e conteúdo alternativo​

O conteúdo colocado dentro da tag <slot> no template do Web Component funciona como valor padrão (fallback). Ele só é exibido se o consumidor não passar nenhum nó para aquele slot:

<!-- Definição interna no componente -->
<slot name="title">
<span>Título Padrão do Componente</span>
</slot>

Se o consumidor usar o componente sem fornecer nó para o slot title:

<!-- O fallback interno será renderizado -->
<meu-card>
<p>Conteúdo do slot padrão</p>
</meu-card>

Por outro lado, quando o consumidor fornece um nó com slot="title", o fallback é descartado e o conteúdo da aplicação assume a posição.

Exemplo real em br-sign-in:

<br-sign-in shape="pill" aria-label="Entrar com conta gov.br">
<br-icon
slot="icon"
svg='<svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm0 2c-4.42 0-8 2.24-8 5v1h16v-1c0-2.76-3.58-5-8-5Z"/></svg>'
></br-icon>
Entrar com gov.br
<img slot="image" src="/img/logo-positive.svg" alt="GovBR-DS" />
</br-sign-in>

Contrato de composição: Light DOM vs Shadow DOM​

Um aspecto crucial dos Web Components é a separação de escopos entre o que entra pelo slot e o que é desenhado internamente:

Contrato entre a biblioteca e a aplicação

Como um Web Component não pode (e não deve) restringir à força tudo o que a aplicação injeta em seus slots, a biblioteca define um contrato de composição: estabelecemos quais elementos são esperados (ex: ícones, tags de texto, botões de ação), orientando o desenvolvedor a manter a coerência visual e a acessibilidade.

Escopo de CSS e fontes​

  1. Conteúdo projetado (Light DOM): Os nós que você passa via slot pertencem ao Light DOM da aplicação consumidora. Eles continuam recebendo os estilos globais, folhas de estilo e fontes externas (como Font Awesome ou classes de utilitário) carregadas pela sua aplicação.
  2. Conteúdo de Fallback (Shadow DOM): O fallback mora dentro do Shadow DOM do Web Component. Caso seu fallback dependa de classes ou fontes externas que não estejam disponíveis globalmente ou encapsuladas, elas não alcançarão o mesmo resultado. Por isso, a biblioteca prioriza SVG embutido ou estilos próprios para fallbacks.

O evento slotchange​

Em componentes avançados que precisam inspecionar ou reagir ao conteúdo que foi injetado (por exemplo, para contar itens, ajustar densidade ou sincronizar acessibilidade), o navegador dispara o evento nativo slotchange no elemento <slot> sempre que seus nós atribuídos mudam:

// Dentro da implementação de um Web Component (ex: Stencil ou Vanilla JS)
const slot = this.el.shadowRoot.querySelector('slot[name="actions"]');

slot.addEventListener('slotchange', () => {
// Retorna nós diretos atribuídos (incluindo texto)
const nodes = slot.assignedNodes({ flatten: true });

// Retorna apenas elementos HTML atribuídos
const elements = slot.assignedElements({ flatten: true });

console.log(`Quantidade de elementos no slot: ${elements.length}`);
});
Importante

O evento slotchange só é acionado quando os próprios nós imediatos atribuídos ao slot mudam (adição ou remoção). Modificações internas nos nós filhos dos elementos atribuídos não disparam slotchange automaticamente.

Nomenclatura semântica e lógica direcional​

Ao escolher ou documentar nomes de slots, o Design System adota convenções consistentes:

  • Nomes com propósito semântico: header, footer, feedback, actions, trigger.
  • Direção lógica em vez de física: Dê preferência a nomes como start e end em vez de left e right. Nomes lógicos respeitam a internacionalização e fluxos de texto bidirecionais (LTR e RTL), mantendo o código agnóstico à direção de leitura.

Boas práticas​

  • Consulte a seção Slots da página de cada componente para saber quais nomes estão disponíveis.
  • Use o slot padrão para conteúdo principal e slots nomeados para áreas específicas.
  • Evite inserir elementos interativos dentro de outro elemento interativo, como um botão dentro de br-button.
  • Preserve nomes de slots exatamente como documentados, incluindo o caractere -.
  • Em frameworks (Angular, React, Vue), defina o atributo slot no elemento de nível superior que deve ser projetado.

Diferença entre slots e propriedades​

  • Use propriedades para configurar comportamento, densidade e estado do componente.
  • Use slots para fornecer conteúdo e composição estrutural.
<br-button emphasis="primary" density="small"> Salvar </br-button>

Nesse exemplo, emphasis e density configuram o componente. O texto Salvar é conteúdo projetado no slot padrão.

Comece aquiComponentesQuickstartsSobre o projetoRepositório GitLabVersõesDiscordGovBR-DSFAQWikiRedefinir cookies