@govbr-ds/webcomponents-angular
v2.1.1
Published
Wrapper Angular para a biblioteca de Web Components do GovBR-DS.
Readme
Angular – @govbr-ds/webcomponents-angular
Este é um wrapper Angular que encapsula os Web Components GovBR-DS, habilita NG_VALUE_ACCESSORS e permite a vinculação de eventos de entrada diretamente a um value accessor, proporcionando uma integração perfeita no fluxo de dados bidirecional do Angular.
Compatibilidade
- Angular
>=14.0.0, incluindo@angular/common,@angular/coree@angular/forms. @govbr-ds/webcomponents2.0.0.- Navegadores: a mesma política Baseline Widely Available dos Web Components. Internet Explorer não é suportado.
O subpath standalone exige Angular 14 ou superior; a entrada principal com NgModule usa o mesmo contrato publicado. Consulte o guia de eventos nativos.
Por que usar este wrapper? 🤔
- Desacoplamento da detecção de mudanças dos elementos Web.
- Conversão de eventos para observáveis RxJS, alinhado ao
@Output(). - Control Value Accessors para integração com Reactive Forms e
ngModel.
[!TIP] Para mais detalhes, consulte a documentação oficial do Stencil.
Instalação 📦
Instale o wrapper e suas dependências:
npm install @govbr-ds/webcomponents-angular
# ou
pnpm add @govbr-ds/webcomponents-angular
# ou
yarn add @govbr-ds/webcomponents-angularpeerDependencies
peerDependencies são pacotes que este wrapper não instala automaticamente — o seu projeto precisa tê-los instalados.
Observe que algumas peerDependencies podem ter suas próprias peerDependencies que também precisam ser atendidas. Consulte a documentação de cada pacote para garantir que todas as dependências necessárias estejam presentes.
Por que existem: Garantem que o Angular CLI e o wrapper compartilhem a mesma instância do Angular e dos Web Components. Versões duplicadas podem causar falhas na compilação ou erros em tempo de execução.
O que isso implica: Se as peers não estiverem instaladas ou forem de versão incompatível, o npm emitirá avisos e o pacote pode não funcionar corretamente.
As peers declaradas neste pacote são:
| Pacote | Versão mínima |
| ------------------------- | ------------- |
| @angular/core | >=14.0.0 |
| @angular/common | >=14.0.0 |
| @angular/forms | >=14.0.0 |
| @govbr-ds/webcomponents | ^2 |
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:
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.
Quickstart Angular
Use o quickstart Angular como referência para configuração de projeto:
- Repositório: govbr-ds-wbc-quickstart-angular
- Servidor local:
pnpm start - Porta padrão:
http://localhost:4200/
Uso 📚
Angular com módulos
// app.module.ts
import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormsModule } from '@angular/forms'
import { WebcomponentsAngularModule } from '@govbr-ds/webcomponents-angular'
import { AppComponent } from './app.component'
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, FormsModule, WebcomponentsAngularModule.forRoot()],
bootstrap: [AppComponent],
})
export class AppModule {}Angular standalone
// app.component.ts
import { Component } from '@angular/core'
import { BrButton } from '@govbr-ds/webcomponents-angular/standalone'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
standalone: true,
imports: [BrButton],
})
export class AppComponent {}<!-- app.component.html -->
<br-button>Lorem ipsum</br-button>Uso com NgModel e binding
Para habilitar ngModel e 2-way binding, adicione FormsModule. Os value accessors são fornecidos pelo próprio wrapper; não é necessário criar directives no projeto consumidor nem usar ngDefaultControl.
[!CAUTION] Em algumas versões pode ser necessário desativar
aot. Veja: issue #317
<br-checkbox
name="userTermsConditions"
[(ngModel)]="termsConditions"
(change)="onTermsConditionsChange($event)"
>
Concordo com os Termos e Condições
</br-checkbox>// app.component.ts
import { Component } from '@angular/core'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
termsConditions = true
onTermsConditionsChange() {
console.log('O valor mudou!', this.termsConditions)
}
}Validação e Acessibilidade (Reactive Forms)
Ao utilizar o ReactiveFormsModule, você pode aproveitar a infraestrutura nativa do Angular para validação em conjunto com os estados do GovBR-DS. Quando um componente é inválido, o wrapper se certifica de aplicar a estilização de erro e enviar os atributos ARIA corretos.
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<br-input
label="Usuário"
formControlName="username"
[state]="loginForm.get('username').invalid && loginForm.get('username').touched ? 'danger' : 'info'">
</br-input>
<br-message
*ngIf="loginForm.get('username').invalid && loginForm.get('username').touched"
state="danger" show-icon>
O nome de usuário é obrigatório.
</br-message>
<br-button type="submit" [disabled]="loginForm.invalid">Entrar</br-button>
</form>Dependências de Build 🛠️
Este pacote é um wrapper gerado automaticamente e depende dos artefatos produzidos pelo núcleo de Web Components.
| Pacote | Dependência de Build | Motivo |
| :--- | :--- | :--- |
| @govbr-ds/webcomponents-angular | webcomponents:build | Necessita dos proxies gerados em src/stencil-generated e standalone/src/stencil-generated. |
Desenvolvimento 👨💻
Estrutura do projeto
├── 📁 src
│ ├── 📁 stencil-generated
│ ├── 📄 angular-webcomponents.module.ts
│ └── 📄 index.ts
├── 📁 standalone
│ └── 📁 src
│ ├── 📁 stencil-generated
│ └── 📄 index.ts
└── 📁 scripts[!WARNING] Tudo dentro de
stencil-generatedé sobrescrito ao gerar o build de Web Components.
Scripts/Build
Gere os Web Components antes de compilar o wrapper:
nx build webcomponents
nx build angularFormatos do build 📦
A tarefa nx build angular compila o wrapper com ng-packagr e gera a saída em dist/angular/. Abaixo estão os artefatos produzidos e quando utilizá-los.
Estrutura do dist/angular/
dist/angular/
├── esm2022/ ← Módulos ESM (Angular Ivy)
│ ├── index.js
│ └── stencil-generated/
├── fesm2022/ ← Flat ESM bundle (otimizado para bundlers)
│ └── govbr-ds-webcomponents-angular.mjs
├── standalone/ ← Componentes standalone (sem NgModule)
│ ├── esm2022/
│ └── fesm2022/
├── index.d.ts ← Tipos TypeScript (entrada principal)
├── package.json ← Campos exports/main/module para resolução
└── README.mdQuando usar cada formato
| Artefato | Quando usar | Observações |
| ------------- | ------------------------------------------------ | -------------------------------------------------------------- |
| fesm2022/ | Aplicações Angular 14+ (padrão) | Resolvido automaticamente pelo Angular CLI via campo exports |
| esm2022/ | Toolchains que necessitam de módulos individuais | Permite tree-shaking granular por arquivo |
| standalone/ | Aplicações Angular standalone (sem NgModule) | Importação via @govbr-ds/webcomponents-angular/standalone |
| index.d.ts | Autocomplete e tipagem TypeScript | Tipos para diretivas, value accessors e módulo |
NgModule vs Standalone
O pacote disponibiliza duas variantes de uso:
- NgModule (entrada principal): use
WebcomponentsAngularModule.forRoot()noimportsdo módulo. - Standalone (subpath
/standalone): importe componentes individuais diretamente.
// NgModule
import { WebcomponentsAngularModule } from '@govbr-ds/webcomponents-angular'
@NgModule({
imports: [WebcomponentsAngularModule.forRoot()],
})
export class AppModule {}
// Standalone
import { BrButton } from '@govbr-ds/webcomponents-angular/standalone'
@Component({
standalone: true,
imports: [BrButton],
})
export class AppComponent {}[!NOTE] Ambas as variantes dependem de
@govbr-ds/webcomponentse@govbr-ds/coreinstalados.
Documentações Complementares 📖
SSR (Server-Side Rendering)
Web Components dependem de APIs do navegador (DOM, window, customElements). Para projetos Angular Universal / SSR:
- Proteja imports com verificação
isPlatformBrowser:
import { isPlatformBrowser, PLATFORM_ID } from '@angular/common'
import { inject } from '@angular/core'
const isBrowser = isPlatformBrowser(inject(PLATFORM_ID))- Use
afterNextRender()(Angular 16+) para lógica que depende do DOM:
afterNextRender(() => {
// Código que acessa o DOM
})- Em
angular.json, importe os estilos CSS condicionalmente para evitar warnings no servidor.
Referências Complementares📖
- Wiki: gov.br/ds/wiki/desenvolvimento/web-components
- MDN Web Components: developer.mozilla.org/Web_Components
Contribuindo 🤝
- Siga os padrões descritos na nossa wiki.
- Guia: como contribuir.
Reportar Bugs/Problemas 🐛
Abra uma issue: gitlab.com/.../issues/new
Commits 📝
Padrões de branches e commits: gov.br/ds/wiki
Precisa de ajuda? 🆘
- Site: gov.br/ds
- Web Components: gov.br/ds/webcomponents
- Discord: discord.gg/U5GwPfqhUP
Créditos 🎉
Desenvolvido pelo SERPRO com a comunidade.
