@govbr-ds/webcomponents
v2.1.2
Published
Biblioteca de Web Components baseado no GovBR-DS
Downloads
9,586
Readme
Web Components – @govbr-ds/webcomponents
A biblioteca de Web Components do GovBR-DS é desenvolvida utilizando o Stencil, 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.
Demonstração 🚀
Confira nossos componentes em ação:
Tecnologias 💻
Este projeto utiliza as seguintes tecnologias:
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.
Integração com frameworks 🔗
Integrar Web Components com frameworks pode ser desafiador em algumas situações. Para facilitar, criamos bibliotecas de integração (wrappers), que encapsulam os Web Components em bibliotecas nativas de frameworks, simplificando a integração com funcionalidades como binding.
Para mais detalhes, consulte a documentação do Stencil sobre integrações.
Vale lembrar que, em alguns casos, a integração pode não ser possível, dependendo da evolução da especificação de Web Components e do suporte dos frameworks.
Compatibilidade de Navegadores 🌐
Esta documentação corresponde à release >=2.0.0 do pacote @govbr-ds/webcomponents.
O suporte segue a política Baseline Widely Available, configurada no arquivo .browserslistrc e revisada a cada release. Essa política é dinâmica: não há uma versão mínima fixa válida para toda a vida do pacote. Como referência para a release atual, o alvo resolve para Chrome/Edge 121+, Firefox 122+ e Safari 17.2+; confirme a lista da release com npx browserslist "baseline widely available".
Os contratos críticos são validados nos projetos automatizados de Chromium, Firefox e WebKit. Isso não equivale a declarar suporte a versões ou engines que não tenham validação automatizada.
[!NOTE] Internet Explorer não é suportado. O target de compilação TypeScript é
es2020, e o runtime requer Custom Elements, Shadow DOM e APIs DOM modernas. A aplicação consumidora continua responsável por eventuais polyfills fora do Baseline.
Instalação 📦
Instale o pacote e os estilos base do Design System como dependências de produção:
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/webcomponentspeerDependencies
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:
| Pacote | Versão compatível |
| ------------------ | ----------------- |
| @govbr-ds/core | >=3.6.0 <4.0.0 |
| @floating-ui/dom | >=1.7.6 |
| date-fns | >=4.1.0 |
| iconify-icon | 3.0.2 |
npm install @floating-ui/dom date-fns iconify-icon
# ou
pnpm add @floating-ui/dom date-fns iconify-iconNota 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:
node-linker=hoistedPor 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>
<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.
<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 e procure pelos projetos de 'Quickstart' para mais detalhes.
Desenvolvimento 👨💻
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.
Gerenciar baseline de tamanho:
# Da raiz do monorepo:
pnpm baseline:update
pnpm baseline:compare
# Depois de um build, detalha cada JS/CSS em bruto, gzip e Brotli:
pnpm size:reportBuild e Documentação Autogerada
Ao gerar o build (ou build:docs) deste projeto Stencil, são automaticamente criados ou atualizados:
- O arquivo
readme.mddentro 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.
nx build webcomponentsTipagem 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. O job contract_tests do CI executa node scripts/check-wrapper-contract.mjs e detecta nomes antigos do br-select nos wrappers. Para o inventário dos scripts e seus pontos de execução, consulte o README de scripts.
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 @stencil/vitest, usando render() e
userEvent. Cenários de viewport, regressão visual ou consultas profundas em
Shadow DOM usam a fachada tipada createBrowserTestFixture().
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.
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.
Formatos do build 📦
A tarefa nx build webcomponents lê as definições de saída em 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 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.jse um arquivo*.entry.jspor componente, acompanhados dos source maps (.map). - É resolvido sempre que o consumidor faz
require('@govbr-ds/webcomponents')ou quando o bundler privilegia o campomaindefinido em 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 comrequire('@govbr-ds/webcomponents/dist/loader').
esm/ – bundles ES Modules
- Equivalente modular do
cjs/, com chunks otimizados (p-*.entry.js) ewebcomponents.esm.js. - É o alvo do campo
moduledo 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.Cada componente possui um arquivo isolado (
br-button.js) e o respectivo.d.ts. Para registrar somente um componente, importe sua funçãodefineCustomElementdiretamente: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 (
customElementsDiraponta paradist/componentsdentro do pacote publicado). Use-a para criar wrappers customizados ou testar componentes isoladamente em Storybook.
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/webcomponentscomo dependência, preservando metadados como slots, eventos e estilos. - Os campos
collectionecollection:mainno 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-scripte 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()eapplyPolyfills()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.jsem 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+ chunksp-*.entry.js, prontos para serem servidos via CDN. - Recomendada para páginas estáticas, protótipos, Storybook do Design System 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: trueda saídadist-custom-elements. - Contém
components.d.tscom todas as interfaces de propriedades/eventos e uma pastacomponents/com os tipos específicos. O campotypesdopackage.jsonaponta paradist/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. Importante para ferramentas de documentação e IDEs.webcomponents.html-custom-data.json: arquivo usado pelo VS Code viahtml.customDatapara habilitar autocomplete e validação nos editores.index.js/index.cjs.js: reexportam os bundles ESM/CJS e expõemdefineCustomElements()/setNonce()gerados pelo Stencil; raramente precisam ser importados diretamente.- Documentação Markdown: gerada automaticamente em
apps/site/docs/stencil-generated-docsviaoutputTargets.docs-custom, mas não é distribuída dentro dedist/webcomponents.
Como escolher o formato correto
- Aplicações modernas com bundler: instale o pacote e deixe seu bundler resolver o campo
module→ carregaráesm/automaticamente. - SSR ou pré-render: combine
esm/no cliente comhydrate/no servidor para renderização isomórfica. - Integrações framework-nativas: use os pacotes
@govbr-ds/angular|react|vue, gerados a partir decomponents/e com tipos emtypes/. - Páginas estáticas/CDN: carregue diretamente os arquivos em
webcomponents/e use oloader/se precisar controlar o registro manualmente. - Toolchains legadas: force o campo
maine consumacjs/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:
{
"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 para obter mais informações sobre este projeto.
Para mais detalhes sobre a especificação de Web Components, recomendamos a consulta ao 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.
- Deseja contribuir? Consulte o nosso guia como contribuir.
Reportar Bugs/Problemas ou Sugestões 🐛
Caso encontre problemas ou tenha sugestões de melhorias, abra uma issue. 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 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
- Web Components https://gov.br/ds/webcomponents
- Canal no Discord https://discord.gg/U5GwPfqhUP
Créditos 🎉
Os Web Components do GovBR-DS foram desenvolvidos pelo SERPRO em parceria com a comunidade.
