# Angular – @govbr-ds/webcomponents-angular

[![npm (next)](https://img.shields.io/npm/v/@govbr-ds/webcomponents-angular/next.svg)](https://www.npmjs.com/package/@govbr-ds/webcomponents-angular)

Este é um wrapper Angular que encapsula os [Web Components GovBR-DS](https://gov.br/ds/webcomponents), 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.

## 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](https://stenciljs.com/docs/angular).

## Instalação 📦

Instale os pacotes necessários como dependências de produção:

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

> [!NOTE]
> Certifique-se de incluir os estilos do `@govbr-ds/core`.

## 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 📚

### Fontes e ícones

Inclua os estilos-base no Angular (via `angular.json` ou CSS global):

```json
// angular.json (trecho)
{
  "projects": {
    "app": {
      "architect": {
        "build": {
          "options": {
            "styles": ["node_modules/@govbr-ds/core/dist/core-tokens.min.css"]
          }
        }
      }
    }
  }
}
```

Ou importe no seu stylesheet global:

```css
@import '~@govbr-ds/core/dist/core-tokens.min.css';
```

### Angular com módulos

```ts
// 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

```ts
// 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 {}
```

```html
<!-- app.component.html -->
<br-button emphasis="primary">Lorem ipsum</br-button>
```

### Uso com NgModel e binding

Para habilitar `ngModel` e 2-way binding, adicione `FormsModule` e o atributo `ngDefaultControl` no componente de formulário.

> [!CAUTION]
> Em algumas versões pode ser necessário desativar `aot`. Veja: [issue #317](https://github.com/ionic-team/stencil-ds-output-targets/issues/317)

```html
<br-checkbox
  name="userTermsConditions"
  [(ngModel)]="termsConditions"
  (checkedChange)="onTermsConditionsChange()"
  ngDefaultControl
>
  Concordo com os Termos e Condições
</br-checkbox>
```

```ts
// 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)
  }
}
```

## Desenvolvimento 👨‍💻

### Estrutura do projeto

```plaintext
├── 📁 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:

```bash
nx build webcomponents
nx build angular
```

## Documentações Complementares 📖

- Wiki: [gov.br/ds/wiki/desenvolvimento/web-components](https://gov.br/ds/wiki/desenvolvimento/web-components)
- MDN Web Components: [developer.mozilla.org/Web_Components](https://developer.mozilla.org/pt-BR/docs/Web/Web_Components)

## Contribuindo 🤝

- Siga os padrões descritos na nossa [wiki](https://gov.br/ds/wiki/).
- Guia: [como contribuir](https://gov.br/ds/wiki/comunidade/contribuindo-com-o-ds/).

## Reportar Bugs/Problemas 🐛

Abra uma issue: [gitlab.com/.../issues/new](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/issues/new)

## Commits 📝

Padrões de branches e commits: [gov.br/ds/wiki](https://gov.br/ds/wiki/)

## Precisa de ajuda? 🆘

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

## Créditos 🎉

Desenvolvido pelo [SERPRO](https://www.serpro.gov.br/) com a comunidade.
