# Web Components – @govbr-ds/webcomponents

A biblioteca de Web Components do [GovBR-DS](https://gov.br/ds) é desenvolvida utilizando o [Stencil](https://stenciljs.com/), um compilador que cria Web Components (Custom Elements). O Stencil combina os melhores conceitos dos frameworks mais populares em uma ferramenta simples e eficiente. Para mais informações, visite o [site oficial do Stencil](https://stenciljs.com/).

## Demonstração 🚀

Confira nossos componentes em ação:

- [Versão 2.x](https://www.gov.br/ds/webcomponents)

## Tecnologias 💻

Este projeto utiliza as seguintes tecnologias:

1. [GovBR-DS](https://gov.br/ds/ 'GovBR-DS')
1. [Stencil](https://stenciljs.com/ 'Stencil')
1. [NX Monorepo](https://nx.dev/ 'NX Monorepo')

## O que são Web Components? ❓

Web Components são um conjunto de tecnologias que permitem criar novos elementos HTML personalizados, reutilizáveis e encapsulados para uso em páginas e aplicativos web. Baseados em padrões da web, são suportados por todos os navegadores modernos.

O diagrama abaixo ilustra os três principais componentes dos Web Components:

- **Elementos HTML personalizados**: Tags HTML definidas com JavaScript, usadas como qualquer outro elemento HTML.
- **Shadow DOM**: Um espaço de nome encapsulado para cada elemento HTML personalizado, garantindo que estilos e scripts não interfiram no restante da página.
- **Templates**: Fragmentos de HTML reutilizáveis em vários elementos.
- **Slots**: Áreas em um elemento HTML personalizado onde templates podem ser inseridos.

### Ciclo de Vida

Para entender melhor o ciclo de vida dos componentes, acesse a página [https://stenciljs.com/docs/component-lifecycle](https://stenciljs.com/docs/component-lifecycle).

## Integração com frameworks 🔗

Integrar Web Components com frameworks pode ser desafiador em algumas situações. Para facilitar, criamos bibliotecas de integração (wrappers oficiais para Angular, React e Vue), que encapsulam os Web Components em bibliotecas nativas de cada framework.

O Web Component é a **fonte única da API, comportamento e acessibilidade** de todo o ecossistema. Os wrappers consomem os artefatos gerados pelo output target `dist-custom-elements` do Stencil. SSR, transporte de dados, autenticação, cache e cancelamento continuam sendo responsabilidades da aplicação consumidora.

Para mais detalhes, consulte a [documentação do Stencil sobre integrações](https://stenciljs.com/docs/overview).

## Compatibilidade e Ambiente 🌐

- **Ambiente de desenvolvimento e CI:** Node.js e pnpm nas versões declaradas no `package.json` da raiz do monorepo.
- **Target de publicação:** JavaScript compatível com ECMAScript 2020 (`es2020`).
- **Política de navegadores:** [Baseline Widely Available](https://web.dev/baseline), configurada em [`.browserslistrc`](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/.browserslistrc) e revisada a cada release.
- **Validação de plataforma:** Contratos críticos validados em execuções headless de Chromium, Firefox e WebKit.

> [!NOTE]
> Internet Explorer não é suportado. O runtime requer Custom Elements, Shadow DOM e APIs DOM modernas. A aplicação consumidora continua responsável por eventuais polyfills fora do Baseline.

O runtime também precisa expor Web Crypto (`crypto.randomUUID` ou `crypto.getRandomValues`) para os IDs automáticos; em SSR, carregue um polyfill antes de importar os componentes quando essa API não for nativa.

## Instalação 📦

Instale o pacote e os estilos base do Design System como dependências de produção:

```bash
npm install @govbr-ds/core @govbr-ds/webcomponents
# ou
yarn add @govbr-ds/core @govbr-ds/webcomponents
# ou
pnpm add @govbr-ds/core @govbr-ds/webcomponents
```

### peerDependencies

`peerDependencies` são pacotes que este pacote **não instala automaticamente** — o seu projeto precisa tê-los instalados.

**Por que existem:** O pacote depende de bibliotecas externas para posicionamento de elementos flutuantes, estilos e datas. Declará-las como peers garante que o seu app e o pacote usem a **mesma versão** dessas bibliotecas, evitando conflitos.

**O que isso implica:** Se as peers não estiverem instaladas ou forem incompatíveis, componentes como `br-datetime-picker` e `br-tooltip` podem não funcionar.

As peers declaradas neste pacote são:

- `@govbr-ds/core`
- `@floating-ui/dom`
- `date-fns`
- `iconify-icon`

As faixas aceitas estão em `peerDependencies` no `package.json` publicado deste pacote (também exibidas na página do npm).

```bash
npm install @floating-ui/dom date-fns iconify-icon
# ou
pnpm add @floating-ui/dom date-fns iconify-icon
```

## Nota importante: pnpm e tree-shaking

Se ao consumir estes pacotes você notar que o bundler não está removendo código não utilizado (tree‑shaking), pode haver uma incompatibilidade com o layout padrão do pnpm.

Solução rápida (opcional, somente se precisar): crie um arquivo `.npmrc` na raiz do seu projeto com:

```properties
node-linker=hoisted
```

Por que isso ajuda: por padrão, o pnpm organiza as dependências em pastas isoladas com symlinks. Alguns bundlers/otimizadores se baseiam na estrutura de `node_modules` e no campo `sideEffects` para decidir o que pode ser eliminado. O layout hoisted aproxima o formato “achatado” (similar ao npm/yarn), facilitando essa análise e, em muitos casos, restaurando o tree‑shaking.

Observações:

- Use apenas se o tree‑shaking realmente não estiver funcionando.
- Pode aumentar o uso de disco e alterar a resolução de dependências do seu projeto.

## Uso 📚

### Passo-a-passo

Os Web Components GOVBR são elementos HTML regulares ou personalizados (Web Components). Em uma página HTML simples, podem ser usados como qualquer outro elemento.

```html
<html>
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.esm.js"
    ></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@govbr-ds/core/dist/core-tokens.min.css" />
  </head>
  <body>
    <br-button>Clique aqui</br-button>
  </body>
</html>
```

Você pode escutar eventos padrão, como clique e mouseover, da mesma forma que faria com elementos HTML normais. Muitos componentes também emitem eventos personalizados, que recomendamos fortemente utilizar. Esses eventos funcionam como os eventos padrão, mas possuem nomes específicos. Consulte a documentação de cada componente para obter detalhes sobre os nomes e dados dos eventos.

```html
<br-button>Label</br-button>

<script>
  const button = document.querySelector('br-button');
  button.addEventListener('click', (event) => {
    console.log('Botão foi clicado', event);
  });
</script>
```

### Exemplos de uso

Disponibilizamos exemplos de como usar este projeto com diferentes tecnologias. Consulte o [nosso grupo no GitLab](https://gitlab.com/govbr-ds/bibliotecas/wbc 'GovBR-DS/WBC') e procure pelos projetos de 'Quickstart' para mais detalhes.

### Formato do `presets.json`

Cada pasta em `src/pages/components/<nome>` pode ter um `presets.json`, lido pelo
playground de desenvolvimento e pelo Playground do site:

```json
{
  "schemaVersion": 2,
  "presets": [
    {
      "id": "remote",
      "label": "Busca remota",
      "source": "remote.html",
      "description": "Opções carregadas sob demanda a partir do termo digitado.",
      "details": "Primeiro parágrafo da explicação.\n\nSegundo parágrafo."
    }
  ],
  "examples": [{ "id": "remote", "label": "Busca remota", "presets": ["remote"], "defaultPreset": "remote" }]
}
```

| Campo                      | Obrigatório | Descrição                                                                                                                                                                                                                                 |
| -------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `presets[].id`             | sim         | Identificador em minúsculas com hífens, único no arquivo.                                                                                                                                                                                 |
| `presets[].label`          | sim         | Nome exibido no seletor de presets.                                                                                                                                                                                                       |
| `presets[].source`         | sim         | Arquivo HTML do preset, relativo à pasta.                                                                                                                                                                                                 |
| `presets[].hidden`         | não         | `true` oculta o preset no site; o playground de desenvolvimento continua exibindo-o.                                                                                                                                                      |
| `presets[].description`    | não         | Frase curta sobre o que o preset demonstra, sem repetir o `label`. Aparece numa linha entre a barra do playground e o preview.                                                                                                            |
| `presets[].details`        | não         | Explicação mais longa (motivação, acessibilidade, tokens, limites, quando usar). Só é válida junto com `description`; linhas em branco (`\n\n`) separam parágrafos. Aparece num `<details>` "Explicação detalhada", recolhido por padrão. |
| `examples[].id`            | sim         | Nome do exemplo usado pela documentação (`examples/<id>.html`).                                                                                                                                                                           |
| `examples[].presets`       | sim         | Presets disponíveis no exemplo.                                                                                                                                                                                                           |
| `examples[].defaultPreset` | não         | Preset aberto inicialmente.                                                                                                                                                                                                               |
| `examples[].hidden`        | não         | `true` oculta o exemplo no site.                                                                                                                                                                                                          |

`description` e `details` precisam ser textos não vazios. `details` sem
`description` é erro, informado pelo gerador do menu, pelo build do site e pelo
teste de contrato. Explique o preset nesses campos, e não em comentários no
HTML; nos arquivos `.js`/`.css`, mantenha só comentários sobre decisões do
próprio código.

### JavaScript e CSS dos presets do playground

O HTML do preset não deve conter `<script>` nem `<style>`. Coloque o
comportamento e os estilos do exemplo em arquivos com o mesmo nome do HTML, na
pasta do componente:

```text
src/pages/components/select/remote.html
src/pages/components/select/remote.js
src/pages/components/select/remote.css
```

Para JavaScript ou CSS compartilhado por todos os presets do componente, crie
`index.js` ou `index.css` na mesma pasta. O conteúdo compartilhado vem antes do
arquivo do preset.

O playground de desenvolvimento e o Playground do site exibem esse conteúdo nas
abas `index.js` e `index.css`, e o preview executa o que estiver nelas. O
JavaScript roda como módulo depois do bundle dos componentes. Ao trocar de
preset, as abas passam a mostrar os arquivos do novo preset. Os arquivos são
opcionais.

Mantenha `style` inline somente quando o conteúdo for copiado para o Shadow DOM
de um componente. É o caso do conteúdo de `br-select-option` em
`select/complex-option.html`, que CSS do documento não alcança.

Para ocultar um preset ou exemplo no site Docusaurus, defina `"hidden": true`
no item correspondente de `presets.json`. O Playground do site ignora esse item;
o playground de desenvolvimento continua exibindo-o para teste. Um exemplo cujos
presets estejam todos ocultos também deixa de aparecer no site.

Para mais detalhes sobre a arquitetura e utilitários do playground (`pageLoader.js`, controles de propriedades, editor de código e console de eventos), consulte o [README dos scripts das páginas](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/src/pages/scripts/README.md).

## Desenvolvimento

### Figma Code Connect

Os templates de Code Connect ficam co-localizados em `src/components/**/*.figma.ts`
e geram snippets HTML para as instâncias Figma dos Web Components. A configuração
de URLs é centralizada na raiz em
[`figma.config.json`](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/figma.config.json).

Para conferir a cobertura e o parse local sem publicar mappings, execute:

```bash
pnpm figma:status
pnpm figma:validate:structure
pnpm figma:parse
```

O [guia técnico de Figma Code Connect](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/apps/site/docs/guias-tecnicos/figma-code-connect.mdx)
documenta o token `FIGMA_ACCESS_TOKEN`, o fluxo de preview/publicação, os
labels de prerelease e as exceções de aliases.

### Scripts Disponíveis

No arquivo `package.json` e `project.json`, você encontrará diversos scripts úteis para o desenvolvimento e manutenção dos Web Components.

#### Tarefas de Build

O pacote possui diferentes níveis de build gerenciados pelo Nx. Abaixo estão os detalhes de cada tarefa:

| Tarefa          | Descrição                                                      | O que gera                                                                           |
| :-------------- | :------------------------------------------------------------- | :----------------------------------------------------------------------------------- |
| `build`         | Tarefa principal de build para distribuição completa.          | Core (`dist`), Wrappers (Angular/React/Vue), SSR (`hydrate`) e metadados (`cem`).    |
| `build:dist`    | Build focado na distribuição "vanilla" (puro Custom Elements). | Core (`dist`) e metadados (`cem`). Não inclui SSR/Hydrate.                           |
| `build:all`     | Build completo de todo o ecossistema do pacote.                | Tudo da tarefa `build` + Site/Playground (`www`) + Documentação técnica auto-gerada. |
| `build:hydrate` | Build específico para suporte a Server-Side Rendering (SSR).   | App de hidratação em `dist/webcomponents/dist/hydrate`.                              |
| `build:www`     | Build do playground/site de testes interno.                    | Pasta `www` com os componentes carregados para visualização local.                   |
| `build:docs`    | Build de documentação técnica automática.                      | Gera/atualiza os arquivos `README.md` dentro da pasta de cada componente.            |

#### Outros Scripts

- **`nx start webcomponents`**: Inicia o site localmente para desenvolvimento.
- **`nx run webcomponents:tests`**: Executa os testes E2E em browser mode.
- **`nx run webcomponents:lint:biome`**: Realiza a análise estática com Biome.
- **`nx run webcomponents:lint:md`**: Realiza a análise estática nos arquivos Markdown.
- **`nx run webcomponents:lint:md:fix`**: Corrige a formatação dos arquivos Markdown.
- **`nx run webcomponents:lint:styles:fix`**: Corrige a formatação dos arquivos CSS/SCSS.
- **`pnpm --dir packages/webcomponents exec vitest run --project e2e <arquivo>`**: Executa somente um teste E2E.

IDs automáticos de componentes são gerados por `src/shared/utils/id.ts` usando
Web Crypto. Isso evita dependência de relógio, `Math.random` ou contadores
mantidos por componentes individuais e mantém os prefixos públicos (por
exemplo, `br-select-*`).

O utilitário `getRandomFromArray` também usa Web Crypto para sortear amostras sem
reposição, sem repetir o mesmo instante do relógio em um loop.

### Build e Documentação Autogerada

Ao gerar o `build` (ou `build:docs`) deste projeto Stencil, são automaticamente criados ou atualizados:

- O arquivo `readme.md` dentro da pasta de cada componente (contendo especificações de props, eventos, slots, etc).
- Documentações dos componentes na pasta `apps/site/docs/stencil-generated-docs`, que são consumidas pelo site oficial.

```bash
nx build webcomponents
```

## Tipagem e contratos públicos

Os tipos usados na API dos componentes são gerados a partir dos componentes Stencil e reexportados pelos wrappers Angular, React e Vue. O consumidor deve importar o tipo pelo pacote público correspondente; imports de arquivos internos não fazem parte do contrato.

### Quando um tipo fica global

`components/global.types.ts` contém apenas tipos reutilizados por dois ou mais componentes, como `BrDensity`, `BrFeedbackState`, `BrLinkTarget`, `BrNavigationMode`, `BrOrientation` e `BrProgressionType`. Eles representam vocabulário compartilhado do Design System.

Tipos específicos permanecem no diretório do componente. Por exemplo: opções e validação de `br-select`, valores e validação de `br-slider`, datas de `br-datetime-picker` e arquivos de `br-upload`. Essa organização evita transformar detalhes de implementação em API global.

Tipos de implementação, como referências de DOM e controladores internos, também ficam locais e não devem ser adicionados a `global.types.ts`. Um tipo só deve ser promovido quando for referenciado por uma propriedade, evento ou método público de mais de um componente.

`BrValidationState` permanece exportado por compatibilidade, embora não seja usado atualmente por uma API de componente. Ele não deve receber novos usos sem uma decisão de API; uma remoção fica reservada para uma versão major.

### Wrappers e geração

Os arquivos em `packages/*/stencil-generated` são artefatos gerados. Alterações de API devem começar no componente Web Component e ser refletidas pela geração dos wrappers. Para o inventário dos scripts e seus pontos de execução, consulte o [README de scripts](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/scripts/README.md).

Nos value accessors Angular, valores externos são tratados como `unknown` até serem validados ou convertidos pelo componente. Isso evita propagar `any` para o contrato do wrapper.

### Testes

Nossa estratégia de testes utiliza testes end-to-end (E2E) executados em navegador.

### Testes E2E (\*.e2e.tsx)

Os testes E2E rodam em browser mode com Vitest e `@stencil/vitest`, usando
`render()`, `userEvent` e helpers de estabilidade. Cenários de viewport,
regressão visual ou consultas profundas em Shadow DOM usam `queryPiercing` ou o
fixture local já adotado pelo componente; não há um fixture compartilhado para
essa composição.

Esse tipo de teste é fundamental para validar:

- Eventos do componente: clique, blur, change, entre outros.
- Interações do usuário: drag-drop, digitação, atalhos.
- Integrações DOM: forms, validação nativa, atributos aria-\*.
- Estilos visuais: dimensões, cores, transições.
- Shadow DOM: slots, parts, estilos encapsulados.

```typescript
import { h } from '@stencil/core'
import { describe, expect, it, render } from '@stencil/vitest'

describe('br-component', () => {
  it('deve renderizar', async () => {
    const { root } = await render(<br-component></br-component>)

    expect(root).not.toBeNull()
  })

  it('deve ter shadow root', async () => {
    const { root } = await render(<br-component></br-component>)

    expect(root).toHaveShadowRoot()
  })
})
```

Para mais informações sobre testes no Stencil, consulte a [documentação oficial](https://stenciljs.com/docs/testing-overview).

## Formatos do build 📦

A tarefa `nx build webcomponents` lê as definições de saída em [stencil.config.ts](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/stencil.config.ts) e gera múltiplos formatos dentro de `dist/webcomponents/dist`. Cada pasta/arquivo atende um cenário específico de consumo da biblioteca. O resumo abaixo ajuda a identificar qual artefato utilizar em cada contexto.

### Visão rápida

| Pasta/arquivo                                                  | Origem no build                                                   | Quando usar                                                                             | Observações                                                                                            |
| -------------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `cjs/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers ou runtimes que ainda resolvem CommonJS (`require`)                            | Referenciado pelo campo `main` do [package.json](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/package.json) e inclui `loader.cjs.js`                |
| `esm/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers modernos/ESBuild/Vite/Rollup com suporte a ESM e tree-shaking                  | Referenciado pelo campo `module` do `package.json`                                                     |
| `components/`                                                  | `outputTargets: { type: 'dist-custom-elements' }`                 | Importações diretas de componentes individuais, geração de _wrappers_ Angular/React/Vue | Gera `.js` + `.d.ts` por componente                                                                    |
| `collection/`                                                  | `outputTargets: { type: 'dist' }` (manifest Stencil)              | Projetos Stencil que desejam consumir os componentes como dependência                   | Descrito pelos campos `collection` e `collection:main` do `package.json`                               |
| `hydrate/`                                                     | `outputTargets: { type: 'dist-hydrate-script' }`                  | SSR/pré-renderização em Node, integrações como React SSR target                         | Exporta scripts CommonJS/ESM para `@govbr-ds/webcomponents/dist/hydrate`                               |
| `loader/`                                                      | `outputTargets: { type: 'dist' }`                                 | Registro manual dos componentes em apps vanilla, integrações legadas                    | Disponibiliza `defineCustomElements()` em múltiplos formatos                                           |
| `webcomponents/`                                               | `outputTargets: { type: 'dist' }`                                 | Consumo via CDN (ex.: `<script type="module" ...>`)                                     | Contém `webcomponents.esm.js` e os chunks dinâmicos `p-*.entry.js`; os estilos vêm de `@govbr-ds/core` |
| `types/`                                                       | `generateTypeDeclarations: true` (custom elements + d.ts globais) | Autocomplete/TypeScript/IDE hints                                                       | Referenciado por `types` em `package.json`                                                             |
| `custom-elements.json` e `webcomponents.html-custom-data.json` | Derivados do compilador                                           | IntelliSense e validação em IDEs/editores                                               | VS Code utiliza via `html.customData`                                                                  |
| `index.js` / `index.cjs.js`                                    | Entradas principais do pacote                                     | Re-exportam os módulos `esm`/`cjs` e definem side-effects                               | Apontados por `module`/`main`                                                                          |

### `cjs/` – bundles CommonJS

- Contém `index.cjs.js`, `webcomponents.cjs.js` e um arquivo `*.entry.js` por componente, acompanhados dos _source maps_ (`.map`).
- É resolvido sempre que o consumidor faz `require('@govbr-ds/webcomponents')` ou quando o bundler privilegia o campo `main` definido em [package.json](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/package.json).
- Use este formato em toolchains legadas (Node 14/16, Webpack < 4, Jest sem suporte a ESM) ou quando precisar depurar módulos CommonJS. Inclui também `loader.cjs.js`, permitindo registrar os elementos manualmente com `require('@govbr-ds/webcomponents/dist/loader')`.

### `esm/` – bundles ES Modules

- Equivalente modular do `cjs/`, com chunks otimizados (`p-*.entry.js`) e `webcomponents.esm.js`.
- É o alvo do campo `module` do pacote e atende bundlers modernos (Vite, Webpack 5+, Rollup, ESBuild) que fazem tree-shaking. Como os chunks mantêm _imports_ explícitos, apenas o necessário é incluído no bundle final.
- Prefira esta saída quando o projeto já executa em módulos nativos ou quando precisa de melhor performance em builds SPA/MPA modernos.

### `components/` – `dist-custom-elements`

- Resultado do `outputTargets: { type: 'dist-custom-elements', customElementsExportBehavior: 'single-export-module' }` definido em [stencil.config.ts](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/stencil.config.ts).
- Cada componente possui um arquivo isolado (`br-button.js`) e o respectivo `.d.ts`. Para registrar somente um componente, importe sua função `defineCustomElement` diretamente:

  ```ts
  import { defineCustomElement as defineBrButton } from '@govbr-ds/webcomponents/dist/components/br-button.js';

  defineBrButton();
  ```

  Esse formato evita incluir o loader completo quando a aplicação usa poucos componentes.

- Esta pasta também alimenta os geradores Angular/React/Vue configurados no mesmo arquivo (`customElementsDir` aponta para `dist/components` dentro do pacote publicado). Use-a para criar _wrappers_ customizados ou testar componentes isoladamente.

### `collection/` – manifest Stencil

- Inclui `collection-manifest.json`, cópias de assets/páginas e os _proxies_ de acesso (`index.js`).
- Necessário apenas para quem desenvolve outra biblioteca Stencil e deseja usar `@govbr-ds/webcomponents` como dependência, preservando metadados como slots, eventos e estilos.
- Os campos `collection` e `collection:main` no [package.json](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/packages/webcomponents/package.json) apontam para esses arquivos para que o compilador Stencil dos consumidores encontre as definições.

### `hydrate/` – script para SSR/pré-render

- Produzido pelo target `dist-hydrate-script` e exportado como módulo CommonJS/ESM (`index.js`, `index.mjs`).
- Permite renderizar componentes em ambientes sem DOM (Node.js) e hidratar o HTML no cliente. O React SSR output target e a configuração de Vue (`hydrateModule: '@govbr-ds/webcomponents/dist/hydrate'`) dependem desta pasta.
- Utilize quando precisar pré-renderizar páginas (Next.js, Astro, custom SSR) ou ao gerar imagens/relatórios estáticos com os componentes já resolvidos.

### `loader/` – helpers para registro manual

- Disponibiliza `defineCustomElements()` e `applyPolyfills()` em diferentes formatos (`index.js`, `index.cjs.js`, `index.es2017.js`, `cdn.js`).
- Ideal para projetos vanilla ou quando o bundle principal não deve executar automaticamente o `defineCustomElements`. Você importa apenas o loader, registra os componentes no momento oportuno e mantém controle fino sobre o Custom Elements Registry.
- Use `cdn.js` em páginas HTML estáticas (por exemplo, `<script src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/loader/cdn.js"></script>`) quando precisa apenas do registro.

### `webcomponents/` – pacote pronto para CDN

- É a forma mais simples de consumo: `webcomponents.esm.js` + chunks `p-*.entry.js`, prontos para serem servidos via CDN.
- Recomendada para páginas estáticas, protótipos, documentações ou integrações que não passam por bundlers. Lembre-se de importar os estilos de `@govbr-ds/core` (tokens) separadamente.
- Inclui _chunks_ nomeados resolvidos dinamicamente pelo loader gerado pelo Stencil, permitindo _lazy loading_ automático.

### `types/` – declarações TypeScript

- Resultado da opção `generateTypeDeclarations: true` da saída `dist-custom-elements`.
- Contém `components.d.ts` com todas as interfaces de propriedades/eventos e uma pasta `components/` com os tipos específicos. O campo `types` do `package.json` aponta para `dist/types/index.d.ts`.
- Necessário para projetos TypeScript, IDEs e também para os wrappers Angular/React/Vue, que reexportam esses tipos.

### Metadados auxiliares

- `custom-elements.json`: arquivo padrão da especificação [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest). Importante para ferramentas de documentação e IDEs.
- `webcomponents.html-custom-data.json`: arquivo usado pelo VS Code via `html.customData` para habilitar autocomplete e validação nos editores.
- `index.js` / `index.cjs.js`: reexportam os bundles ESM/CJS e expõem `defineCustomElements()` / `setNonce()` gerados pelo Stencil; raramente precisam ser importados diretamente.
- Documentação Markdown: gerada automaticamente em `apps/site/docs/stencil-generated-docs` via `outputTargets.docs-custom`, mas não é distribuída dentro de `dist/webcomponents`.

### Como escolher o formato correto

1. **Aplicações modernas com bundler**: instale o pacote e deixe seu bundler resolver o campo `module` → carregará `esm/` automaticamente.
2. **SSR ou pré-render**: combine `esm/` no cliente com `hydrate/` no servidor para renderização isomórfica.
3. **Integrações framework-nativas**: use os pacotes `@govbr-ds/angular|react|vue`, gerados a partir de `components/` e com tipos em `types/`.
4. **Páginas estáticas/CDN**: carregue diretamente os arquivos em `webcomponents/` e use o `loader/` se precisar controlar o registro manualmente.
5. **Toolchains legadas**: force o campo `main` e consuma `cjs/` para manter compatibilidade com CommonJS.

Manter estes contextos claros evita duplicidade de código, falta de tree-shaking ou registros repetidos de Custom Elements.

## VS Code IntelliSense

Durante o desenvolvimento de nossos Web Components, utilizamos custom elements. O VS Code, por padrão, não reconhece esses componentes, o que impede sugestões inteligentes no autocomplete. Para resolver isso, geramos um arquivo com as definições dos componentes, disponibilizado junto ao pacote npm.

Para importar no seu VS Code, adicione o seguinte campo, ajustando o caminho para o local onde o `node_modules` está armazenado no seu projeto:

```json
{
  "html.customData": ["./node_modules/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.html-custom-data.json"]
}
```

## Documentações Complementares 📖

Consulte a seção sobre Web Components na nossa [Wiki](https://gov.br/ds/wiki/desenvolvimento/web-components) para obter mais informações sobre este projeto.

Para mais detalhes sobre a especificação de Web Components, recomendamos a consulta ao [MDN](https://developer.mozilla.org/pt-BR/docs/Web/API/Web_components 'Web Components | MDN').

## Contribuindo 🤝

Antes de abrir um Merge Request, considere as seguintes orientações:

- Este é um projeto open-source, e contribuições são sempre bem-vindas.
- Para facilitar a aprovação da sua contribuição, utilize um título claro e explicativo no MR e siga os padrões descritos em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki').
- Deseja contribuir? Consulte o nosso guia [como contribuir](https://gov.br/ds/wiki/comunidade/contribuindo-com-o-ds/ 'Como contribuir?').

## Reportar Bugs/Problemas ou Sugestões 🐛

Caso encontre problemas ou tenha sugestões de melhorias, abra uma [issue](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/issues/new). Utilize o modelo apropriado e forneça o máximo de detalhes possível.

Nos comprometemos a responder a todas as issues.

## Commits 📝

Este projeto segue um padrão específico para branches e commits. Consulte a documentação em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki') para entender mais sobre esses padrões.

## Precisa de ajuda? 🆘

Por favor, **não** crie issues para dúvidas gerais.

Utilize os canais abaixo para esclarecer suas dúvidas:

- Site do GovBR-DS [http://gov.br/ds](http://gov.br/ds)
- Web Components [https://gov.br/ds/webcomponents](https://gov.br/ds/webcomponents)
- Canal no Discord [https://discord.gg/U5GwPfqhUP](https://discord.gg/U5GwPfqhUP)

## Créditos 🎉

Os Web Components do [GovBR-DS](https://gov.br/ds/ 'GovBR-DS') foram desenvolvidos pelo [SERPRO](https://www.serpro.gov.br/ 'SERPRO | Serviço Federal de Processamento de Dados') em parceria com a comunidade.
