@schenkerjon/ng-govbr-tw 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,81 @@
1
1
  # @schenkerjon/ng-govbr-tw
2
2
 
3
- Biblioteca Angular de componentes baseados no **Design System do Governo Federal (GovBR DS)**, estilizados com **Tailwind CSS 3**. Componentes standalone, acessíveis e prontos para produção.
3
+ <p align="center">
4
+ <a href="https://jordaobass.github.io/ng-govbr-tw/">
5
+ <img src="https://img.shields.io/badge/🚀_SHOWCASE-Ver_Demo_Online-1351b4?style=for-the-badge&labelColor=071D41" alt="Ver Demo Online" />
6
+ </a>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <img src="https://www.gov.br/++theme++padrao_govbr/img/govbr-logo-large.png" alt="Gov.br" height="60" />
11
+ </p>
12
+
13
+ <p align="center">
14
+ Biblioteca Angular <strong>open-source</strong> que implementa componentes visuais baseados no <strong>Gov.br Design System</strong>, utilizando <strong>Tailwind CSS 3</strong> para estilização.
15
+ </p>
16
+
17
+ <p align="center">
18
+ <a href="https://www.npmjs.com/package/@schenkerjon/ng-govbr-tw"><img src="https://img.shields.io/npm/v/@schenkerjon/ng-govbr-tw.svg" alt="npm version" /></a>
19
+ <a href="https://www.npmjs.com/package/@schenkerjon/ng-govbr-tw"><img src="https://img.shields.io/npm/dm/@schenkerjon/ng-govbr-tw.svg" alt="npm downloads" /></a>
20
+ <img src="https://img.shields.io/badge/Angular-17%2B-dd0031.svg" alt="Angular 17+" />
21
+ <img src="https://img.shields.io/badge/Tailwind-3.x-38bdf8.svg" alt="Tailwind CSS 3" />
22
+ <img src="https://img.shields.io/badge/license-MIT-green.svg" alt="MIT License" />
23
+ </p>
24
+
25
+ ---
26
+
27
+ ## Índice
28
+
29
+ - [Visão Geral](#visão-geral)
30
+ - [Instalação](#instalação)
31
+ - [Configuração](#configuração)
32
+ - [Tailwind CSS](#1-tailwind-css)
33
+ - [CSS Base](#2-css-base)
34
+ - [Font Awesome](#3-font-awesome-opcional)
35
+ - [Uso Básico](#uso-básico)
36
+ - [Componentes](#componentes)
37
+ - [Formulários](#formulários)
38
+ - [Feedback](#feedback)
39
+ - [Navegação](#navegação)
40
+ - [Conteúdo](#conteúdo)
41
+ - [Avançados](#avançados)
42
+ - [Animações](#animações)
43
+ - [Configuração de Animações](#configuração-de-animações)
44
+ - [Componentes Animados](#componentes-animados)
45
+ - [Acessibilidade](#acessibilidade)
46
+ - [Tokens Gov.br](#tokens-govbr)
47
+ - [Exemplos Detalhados](#exemplos-detalhados)
48
+ - [Formulário Completo](#formulário-completo)
49
+ - [Select com Busca](#select-com-busca)
50
+ - [Modal](#modal)
51
+ - [Tabs](#tabs)
52
+ - [Accordion](#accordion)
53
+ - [Sidebar com Menu](#sidebar-com-menu)
54
+ - [Wizard Multi-etapas](#wizard-multi-etapas)
55
+ - [Upload de Arquivos](#upload-de-arquivos)
56
+ - [Toast Notifications](#toast-notifications)
57
+ - [Inputs Especializados](#inputs-especializados)
58
+ - [Demo](#demo)
59
+ - [Contribuição](#contribuição)
60
+ - [Licença](#licença)
61
+
62
+ ---
63
+
64
+ ## Visão Geral
65
+
66
+ O objetivo deste projeto é oferecer uma alternativa leve e moderna para construir interfaces de sistemas governamentais brasileiros com Angular, seguindo os padrões visuais definidos pelo Gov.br.
67
+
68
+ ### Características
69
+
70
+ - **Standalone Components** — Compatível com Angular 17+
71
+ - **Tailwind CSS 3** — Classes utilitárias para fácil customização
72
+ - **Acessibilidade** — ARIA labels, navegação por teclado, suporte a reduced-motion
73
+ - **Formulários Reativos** — ControlValueAccessor em todos os inputs
74
+ - **Animações Suaves** — Transições respeitando preferências do usuário
75
+ - **LGPD Ready** — Componente de cookies integrado
76
+ - **Sem dependências pesadas** — Não depende do Web Components oficial
4
77
 
5
- Compatível com Angular 17, 18 e 19.
78
+ ---
6
79
 
7
80
  ## Instalação
8
81
 
@@ -10,1120 +83,735 @@ Compatível com Angular 17, 18 e 19.
10
83
  npm install @schenkerjon/ng-govbr-tw
11
84
  ```
12
85
 
13
- ### Configuração automática (recomendado)
14
-
15
- ```bash
16
- ng add @schenkerjon/ng-govbr-tw
17
- ```
86
+ ---
18
87
 
19
- O schematic configura automaticamente:
20
- - Preset Tailwind no `tailwind.config.js`
21
- - Fontes Rawline e Font Awesome no `index.html`
22
- - Import do CSS no `styles.css`
88
+ ## Configuração
23
89
 
24
- ### Configuração manual
90
+ ### 1. Tailwind CSS
25
91
 
26
- 1. Adicione o preset ao `tailwind.config.js`:
92
+ Adicione o preset da biblioteca no seu `tailwind.config.js`:
27
93
 
28
94
  ```js
29
- const govbrPreset = require('@schenkerjon/ng-govbr-tw/tailwind.preset');
30
-
31
95
  module.exports = {
32
- presets: [govbrPreset],
96
+ presets: [require('@schenkerjon/ng-govbr-tw/tailwind.preset')],
33
97
  content: [
34
98
  "./src/**/*.{html,ts}",
35
- "./node_modules/@schenkerjon/ng-govbr-tw/**/*.{mjs,js}"
99
+ "./node_modules/@schenkerjon/ng-govbr-tw/**/*.{html,ts,mjs}"
36
100
  ],
101
+ // ...
37
102
  };
38
103
  ```
39
104
 
40
- 2. Adicione as fontes no `index.html`:
41
-
42
- ```html
43
- <link href="https://fonts.googleapis.com/css2?family=Raleway:wght@100;300;400;500;600;700;900&display=swap" rel="stylesheet" />
44
- <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" rel="stylesheet" />
45
- ```
105
+ ### 2. CSS Base
46
106
 
47
- 3. Importe o CSS base:
107
+ Importe o CSS base no seu `styles.css`:
48
108
 
49
109
  ```css
50
- /* styles.css */
51
- @import '@schenkerjon/ng-govbr-tw/src/lib/styles/govbr-tw.css';
52
- ```
53
-
54
- ---
55
-
56
- ## Uso
57
-
58
- Todos os componentes são **standalone** — importe diretamente:
59
-
60
- ```typescript
61
- import { BrButtonComponent, BrInputComponent } from '@schenkerjon/ng-govbr-tw';
62
-
63
- @Component({
64
- standalone: true,
65
- imports: [BrButtonComponent, BrInputComponent],
66
- })
67
- ```
68
-
69
- ---
70
-
71
- ## Sumário de Componentes
72
-
73
- | Categoria | Componentes |
74
- |-----------|-------------|
75
- | **Layout** | `br-layout`, `br-header`, `br-footer`, `br-menu`, `br-menu-item`, `br-sidebar` |
76
- | **Navegação** | `br-menu-bar`, `br-mega-menu`, `br-breadcrumb`, `br-tab`, `br-pagination` |
77
- | **Formulários** | `br-input`, `br-select`, `br-checkbox`, `br-radio-group`, `br-textarea`, `br-datepicker`, `br-timepicker`, `br-datetimepicker` |
78
- | **Botões** | `br-button`, `br-magic-button` |
79
- | **Dados** | `br-table`, `br-card`, `br-item`, `br-list`, `br-badge` |
80
- | **Feedback** | `br-message`, `br-modal`, `br-loading`, `br-tooltip` |
81
- | **Utilitários** | `br-accordion`, `br-wizard`, `br-cookiebar` |
82
-
83
- ---
84
-
85
- ## Layout
86
-
87
- ### br-layout
88
-
89
- Estrutura principal da aplicação. Organiza header, menu lateral (push), conteúdo e footer.
90
-
91
- ```html
92
- <br-layout>
93
- <br-header
94
- systemTitle="Meu Sistema"
95
- logoSrc="assets/logo.png"
96
- (menuToggle)="menuOpen = $event"
97
- ></br-header>
98
-
99
- <br-menu [open]="menuOpen" (openChange)="menuOpen = $event">
100
- <br-menu-item label="Início" icon="house" route="/"></br-menu-item>
101
- <br-menu-item label="Documentos" icon="file" route="/docs"></br-menu-item>
102
- </br-menu>
103
-
104
- <div>Conteúdo da página</div>
105
-
106
- <br-footer logoSrc="assets/logo.png"></br-footer>
107
- </br-layout>
108
- ```
109
-
110
- ---
111
-
112
- ### br-header
110
+ @import 'tailwindcss/base';
111
+ @import 'tailwindcss/components';
112
+ @import 'tailwindcss/utilities';
113
113
 
114
- Header GovBR DS com duas linhas: logo/ações (topo) e título/busca (inferior).
115
-
116
- ```html
117
- <br-header
118
- systemTitle="Nome do Sistema"
119
- systemSubtitle="Órgão responsável"
120
- logoSrc="assets/gov-logo.png"
121
- logoHref="/"
122
- signature="gov.br"
123
- variant="primary"
124
- density="medium"
125
- [sticky]="true"
126
- menuMode="sidebar"
127
- [showSearch]="true"
128
- [showLogin]="true"
129
- [hasLinks]="true"
130
- [hasFunctions]="true"
131
- userName="João Silva"
132
- userRole="Administrador"
133
- avatarSrc="assets/avatar.jpg"
134
- (menuToggle)="menuOpen = $event"
135
- (searchSubmit)="onSearch($event)"
136
- (signIn)="onLogin()"
137
- (logout)="onLogout()"
138
- >
139
- <!-- Links de acesso rápido (dropdown ⋮) -->
140
- <a header-links href="/acessibilidade" class="block px-4 py-2 text-sm hover:bg-gray-50">
141
- Acessibilidade
142
- </a>
143
- <a header-links href="/mapa-do-site" class="block px-4 py-2 text-sm hover:bg-gray-50">
144
- Mapa do site
145
- </a>
146
-
147
- <!-- Funcionalidades do sistema (dropdown ⊞) -->
148
- <a header-functions href="/notificacoes" class="block px-4 py-2 text-sm hover:bg-gray-50">
149
- Notificações
150
- </a>
151
-
152
- <!-- Menu do avatar -->
153
- <a avatar-menu href="/perfil" class="block px-4 py-2 text-sm hover:bg-gray-50">
154
- Meu perfil
155
- </a>
156
- </br-header>
114
+ @import '@schenkerjon/ng-govbr-tw/styles/govbr-tw.css';
157
115
  ```
158
116
 
159
- | Input | Tipo | Padrão | Descrição |
160
- |-------|------|--------|-----------|
161
- | `systemTitle` | `string` | `''` | Título do sistema |
162
- | `systemSubtitle` | `string` | — | Subtítulo (órgão, departamento) |
163
- | `logoSrc` | `string` | `''` | URL do logo |
164
- | `logoHref` | `string` | — | Link do logo |
165
- | `signature` | `string` | — | Assinatura (ex: "gov.br") |
166
- | `variant` | `'primary' \| 'white'` | `'primary'` | Tema de cores |
167
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` | Tamanho do header |
168
- | `sticky` | `boolean` | `false` | Header fixo no topo |
169
- | `menuMode` | `'sidebar' \| 'mega' \| 'none'` | `'sidebar'` | Tipo de menu |
170
- | `showSearch` | `boolean` | `true` | Exibir busca |
171
- | `showContrast` | `boolean` | `false` | Exibir botão de alto contraste |
172
- | `contrastActive` | `boolean` | `false` | Alto contraste ativo |
173
- | `showLogin` | `boolean` | `true` | Exibir botão entrar |
174
- | `hasLinks` | `boolean` | `false` | Exibir dropdown de links rápidos |
175
- | `hasFunctions` | `boolean` | `false` | Exibir dropdown de funcionalidades |
176
- | `userName` | `string` | — | Nome do usuário logado |
177
- | `userRole` | `string` | — | Cargo/papel do usuário |
178
- | `avatarSrc` | `string` | — | URL da foto do avatar |
179
-
180
- | Output | Tipo | Descrição |
181
- |--------|------|-----------|
182
- | `menuToggle` | `boolean` | Menu abriu/fechou |
183
- | `searchSubmit` | `string` | Texto pesquisado |
184
- | `signIn` | `void` | Clicou em "Entrar" |
185
- | `logout` | `void` | Clicou em "Sair" |
186
- | `contrastChange` | `boolean` | Alto contraste alterado |
187
-
188
- **Slots de conteúdo:** `[header-links]`, `[header-functions]`, `[avatar-menu]`
117
+ ### 3. Font Awesome (Opcional)
189
118
 
190
- ---
191
-
192
- ### br-menu
193
-
194
- Menu lateral push — quando aberto, empurra o conteúdo para o lado.
119
+ Os ícones utilizam Font Awesome. Adicione no `index.html`:
195
120
 
196
121
  ```html
197
- <br-menu [open]="menuOpen" (openChange)="menuOpen = $event" variant="white" width="default">
198
- <br-menu-item label="Início" icon="house" route="/" [exact]="true"></br-menu-item>
199
- <br-menu-item label="Usuários" icon="users" route="/usuarios"></br-menu-item>
200
-
201
- <!-- Item com submenu -->
202
- <br-menu-item label="Configurações" icon="gear" [hasChildren]="true" [expanded]="configExpanded" (expandedChange)="configExpanded = $event">
203
- <br-menu-item label="Geral" route="/config/geral"></br-menu-item>
204
- <br-menu-item label="Segurança" route="/config/seguranca"></br-menu-item>
205
- </br-menu-item>
206
-
207
- <!-- Footer do menu -->
208
- <div menu-footer>
209
- <span class="text-xs text-gray-500">v1.0.0</span>
210
- </div>
211
- </br-menu>
122
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" />
212
123
  ```
213
124
 
214
- | Input | Tipo | Padrão | Descrição |
215
- |-------|------|--------|-----------|
216
- | `open` | `boolean` | `true` | Menu aberto/fechado |
217
- | `variant` | `'white' \| 'light'` | `'white'` | Cor de fundo |
218
- | `width` | `'narrow' \| 'default' \| 'wide'` | `'default'` | Largura (60/64/72) |
219
- | `hasFooter` | `boolean` | `false` | Exibir área de footer |
220
- | `ariaLabel` | `string` | `'Menu principal'` | Label de acessibilidade |
221
-
222
- ### br-menu-item
223
-
224
- | Input | Tipo | Padrão | Descrição |
225
- |-------|------|--------|-----------|
226
- | `route` | `string \| unknown[]` | — | Rota Angular (routerLink) |
227
- | `label` | `string` | `''` | Texto do item |
228
- | `icon` | `string` | — | Nome Font Awesome (sem `fa-`) |
229
- | `badge` | `string \| number` | — | Badge/contador vermelho |
230
- | `exact` | `boolean` | `false` | routerLinkActive exato |
231
- | `hasChildren` | `boolean` | `false` | Tem submenu |
232
- | `expanded` | `boolean` | `false` | Submenu expandido |
233
-
234
- ---
235
-
236
- ### br-footer
237
-
238
- ```html
239
- <br-footer logoSrc="assets/logo-footer.png">
240
- <div class="text-sm text-gray-600">© 2024 Governo Federal</div>
241
- </br-footer>
242
- ```
125
+ Ou instale via npm:
243
126
 
244
- ---
245
-
246
- ## Navegação
247
-
248
- ### br-menu-bar
249
-
250
- Barra de navegação horizontal abaixo do header.
251
-
252
- ```html
253
- <br-menu-bar variant="primary">
254
- <br-menu-bar-item label="Início" icon="house" route="/"></br-menu-bar-item>
255
- <br-menu-bar-item label="Serviços" icon="grid" [hasSubmenu]="true">
256
- <br-menu-bar-sub-item label="Consulta" route="/servicos/consulta"></br-menu-bar-sub-item>
257
- <br-menu-bar-sub-item label="Solicitação" route="/servicos/solicitacao"></br-menu-bar-sub-item>
258
- </br-menu-bar-item>
259
- </br-menu-bar>
260
- ```
261
-
262
- | Input | Tipo | Padrão |
263
- |-------|------|--------|
264
- | `variant` | `'primary' \| 'dark' \| 'white'` | `'primary'` |
265
-
266
- ---
267
-
268
- ### br-mega-menu
269
-
270
- Menu mega com colunas e categorias.
271
-
272
- ```html
273
- <br-mega-menu variant="primary" [activePanel]="activePanel" (activePanelChange)="activePanel = $event">
274
- <br-mega-menu-trigger label="Serviços" panelId="servicos" icon="grid"></br-mega-menu-trigger>
275
- <br-mega-menu-trigger label="Institucional" panelId="institucional"></br-mega-menu-trigger>
276
-
277
- <br-mega-menu-panel panelId="servicos" [isActive]="activePanel === 'servicos'">
278
- <br-mega-menu-column title="Cidadão">
279
- <br-mega-menu-link label="CPF" route="/servicos/cpf" icon="id-card"></br-mega-menu-link>
280
- <br-mega-menu-link label="Passaporte" route="/servicos/passaporte"></br-mega-menu-link>
281
- </br-mega-menu-column>
282
- </br-mega-menu-panel>
283
- </br-mega-menu>
127
+ ```bash
128
+ npm install @fortawesome/fontawesome-free
284
129
  ```
285
130
 
286
131
  ---
287
132
 
288
- ### br-breadcrumb
289
-
290
- ```html
291
- <br-breadcrumb [items]="breadcrumbs" [showHome]="true" homeRoute="/"></br-breadcrumb>
292
- ```
133
+ ## Uso Básico
293
134
 
294
135
  ```typescript
295
- import { BrBreadcrumbItem } from '@schenkerjon/ng-govbr-tw';
136
+ import { BrButtonComponent } from '@schenkerjon/ng-govbr-tw';
296
137
 
297
- breadcrumbs: BrBreadcrumbItem[] = [
298
- { label: 'Serviços', route: '/servicos' },
299
- { label: 'Consulta', route: '/servicos/consulta' },
300
- { label: 'Resultado' },
301
- ];
302
- ```
303
-
304
- ---
305
-
306
- ### br-tab
307
-
308
- ```html
309
- <br-tab density="medium" [activeIndex]="0" (activeIndexChange)="onTabChange($event)">
310
- <br-tab-panel label="Dados" icon="file">
311
- Conteúdo da aba Dados
312
- </br-tab-panel>
313
- <br-tab-panel label="Histórico" icon="clock" [counter]="5">
314
- Conteúdo da aba Histórico
315
- </br-tab-panel>
316
- <br-tab-panel label="Desativada" [disabled]="true">
317
- ...
318
- </br-tab-panel>
319
- </br-tab>
320
- ```
321
-
322
- | Input (br-tab) | Tipo | Padrão |
323
- |-------|------|--------|
324
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` |
325
- | `activeIndex` | `number` | `0` |
326
- | `inverted` | `boolean` | `false` |
327
-
328
- | Input (br-tab-panel) | Tipo | Padrão |
329
- |-------|------|--------|
330
- | `label` | `string` | `''` |
331
- | `icon` | `string` | |
332
- | `counter` | `number` | |
333
- | `disabled` | `boolean` | `false` |
334
-
335
- ---
336
-
337
- ### br-pagination
338
-
339
- ```html
340
- <br-pagination
341
- [page]="currentPage"
342
- [totalPages]="20"
343
- [maxVisible]="5"
344
- [showFirstLast]="true"
345
- density="medium"
346
- (pageChange)="currentPage = $event"
347
- ></br-pagination>
348
- ```
349
-
350
- | Input | Tipo | Padrão |
351
- |-------|------|--------|
352
- | `page` | `number` | `1` |
353
- | `totalPages` | `number` | `1` |
354
- | `maxVisible` | `number` | `5` |
355
- | `showFirstLast` | `boolean` | `false` |
356
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` |
357
-
358
- ---
359
-
360
- ## Formulários
361
-
362
- Todos os componentes de formulário implementam `ControlValueAccessor` — funcionam com `[(ngModel)]` e `formControl`.
363
-
364
- ### br-input
365
-
366
- ```html
367
- <br-input
368
- label="Nome completo"
369
- placeholder="Digite seu nome"
370
- [(ngModel)]="nome"
371
- [required]="true"
372
- icon="user"
373
- density="medium"
374
- helperText="Informe seu nome completo"
375
- ></br-input>
376
-
377
- <!-- Com validação -->
378
- <br-input label="E-mail" type="email" [(ngModel)]="email" error="E-mail inválido"></br-input>
379
-
380
- <!-- Busca -->
381
- <br-input type="search" placeholder="Pesquisar..." [(ngModel)]="busca" (searchSubmit)="pesquisar($event)"></br-input>
382
-
383
- <!-- Arquivo -->
384
- <br-input label="Documento" type="file" (fileSelected)="onFile($event)"></br-input>
385
- ```
386
-
387
- | Input | Tipo | Padrão | Descrição |
388
- |-------|------|--------|-----------|
389
- | `label` | `string` | — | Rótulo do campo |
390
- | `type` | `string` | `'text'` | text, email, password, number, search, file, select, textarea |
391
- | `placeholder` | `string` | `''` | Placeholder |
392
- | `required` | `boolean` | `false` | Obrigatório |
393
- | `error` | `string` | — | Mensagem de erro |
394
- | `successMessage` | `string` | — | Mensagem de sucesso |
395
- | `warningMessage` | `string` | — | Mensagem de aviso |
396
- | `helperText` | `string` | — | Texto auxiliar |
397
- | `icon` | `string` | — | Ícone Font Awesome |
398
- | `iconRight` | `boolean` | `false` | Ícone à direita |
399
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` | Tamanho |
400
- | `highlight` | `boolean` | `false` | Destaque visual |
401
- | `maxLength` | `number` | — | Máximo de caracteres |
402
-
403
- ---
404
-
405
- ### br-select
406
-
407
- ```html
408
- <br-select
409
- label="Estado"
410
- placeholder="Selecione o estado"
411
- [(ngModel)]="estado"
412
- [options]="estados"
413
- [searchable]="true"
414
- [required]="true"
415
- ></br-select>
416
-
417
- <!-- Seleção múltipla -->
418
- <br-select label="Categorias" [(ngModel)]="categorias" [options]="categoriasOpts" [multiple]="true"></br-select>
419
- ```
138
+ @Component({
139
+ standalone: true,
140
+ imports: [BrButtonComponent],
141
+ template: `<br-button variant="primary">Entrar</br-button>`
142
+ })
143
+ export class MyComponent {}
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Componentes
149
+
150
+ ### Formulários
151
+
152
+ | Componente | Seletor | Descrição |
153
+ |---|---|---|
154
+ | `BrButtonComponent` | `<br-button>` | Botão com variantes primary, secondary, danger, outline |
155
+ | `BrInputComponent` | `<br-input>` | Campo de entrada com validação e máscara |
156
+ | `BrSelectComponent` | `<br-select>` | Select com busca e multi-seleção |
157
+ | `BrTextareaComponent` | `<br-textarea>` | Área de texto com contagem de caracteres |
158
+ | `BrCheckboxComponent` | `<br-checkbox>` | Checkbox com estados valid/invalid/indeterminate |
159
+ | `BrRadioGroupComponent` | `<br-radio-group>` | Grupo de radio buttons |
160
+ | `BrSwitchComponent` | `<br-switch>` | Toggle switch on/off |
161
+ | `BrDatepickerComponent` | `<br-datepicker>` | Seletor de data com calendário |
162
+ | `BrTimepickerComponent` | `<br-timepicker>` | Seletor de horário |
163
+ | `BrDatetimepickerComponent` | `<br-datetimepicker>` | Seletor de data e hora combinado |
164
+ | `BrUploadComponent` | `<br-upload>` | Upload de arquivos com drag & drop |
165
+
166
+ ### Feedback
167
+
168
+ | Componente | Seletor | Descrição |
169
+ |---|---|---|
170
+ | `BrBadgeComponent` | `<br-badge>` | Badge/tag de status |
171
+ | `BrChipComponent` | `<br-chip>` | Chip selecionável/removível |
172
+ | `BrMessageComponent` | `<br-message>` | Mensagem de feedback (success, danger, warning, info) |
173
+ | `BrTooltipComponent` | `<br-tooltip>` | Tooltip posicionável com variantes |
174
+ | `BrLoadingComponent` | `<br-loading>` | Spinner e barra de progresso |
175
+ | `BrSkeletonComponent` | `<br-skeleton>` | Placeholder de carregamento |
176
+ | `BrModalComponent` | `<br-modal>` | Dialog/modal com footer configurável |
177
+ | `BrNotificationComponent` | `<br-notification>` | Badge de notificação com contador |
178
+ | `BrToastComponent` | `<br-toast>` | Toast notifications |
179
+
180
+ ### Navegação
181
+
182
+ | Componente | Seletor | Descrição |
183
+ |---|---|---|
184
+ | `BrHeaderComponent` | `<br-header>` | Cabeçalho do sistema Gov.br |
185
+ | `BrFooterComponent` | `<br-footer>` | Rodapé do sistema |
186
+ | `BrMenuComponent` | `<br-menu>` | Menu lateral push |
187
+ | `BrMenuItemComponent` | `<br-menu-item>` | Item do menu |
188
+ | `BrMenuBarComponent` | `<br-menu-bar>` | Barra de menu horizontal |
189
+ | `BrMegaMenuComponent` | `<br-mega-menu>` | Mega menu com painéis |
190
+ | `BrSidebarComponent` | `<br-sidebar>` | Sidebar colapsável com mobile drawer |
191
+ | `BrBreadcrumbComponent` | `<br-breadcrumb>` | Navegação breadcrumb |
192
+ | `BrTabComponent` | `<br-tab>` | Navegação por abas |
193
+ | `BrPaginationComponent` | `<br-pagination>` | Paginação com itens por página |
194
+
195
+ ### Conteúdo
196
+
197
+ | Componente | Seletor | Descrição |
198
+ |---|---|---|
199
+ | `BrCardComponent` | `<br-card>` | Card informativo com ícone e link |
200
+ | `BrTableComponent` | `<br-table>` | Tabela com ordenação e paginação |
201
+ | `BrListComponent` | `<br-list>` | Lista estruturada |
202
+ | `BrItemComponent` | `<br-item>` | Item de lista com avatar/ícone/tag |
203
+ | `BrAccordionComponent` | `<br-accordion>` | Accordion com modo single/multiple |
204
+ | `BrDividerComponent` | `<br-divider>` | Divisor horizontal/vertical |
205
+ | `BrAvatarComponent` | `<br-avatar>` | Avatar com imagem ou iniciais |
206
+ | `BrTimelineComponent` | `<br-timeline>` | Timeline de eventos |
207
+ | `BrLayoutComponent` | `<br-layout>` | Layout principal (header + menu + content + footer) |
208
+
209
+ ### Avançados
210
+
211
+ | Componente | Seletor | Descrição |
212
+ |---|---|---|
213
+ | `BrWizardComponent` | `<br-wizard>` | Stepper para fluxos multi-etapas |
214
+ | `BrStepperComponent` | `<br-stepper>` | Indicador de progresso em etapas |
215
+ | `BrCookiebarComponent` | `<br-cookiebar>` | Barra de consentimento de cookies (LGPD) |
216
+ | `BrMagicButtonComponent` | `<br-magic-button>` | Botão flutuante (FAB) com speed dial |
217
+ | `BrSigninComponent` | `<br-signin>` | Botão de login Gov.br |
218
+
219
+ ---
220
+
221
+ ## Animações
222
+
223
+ A biblioteca inclui animações suaves em vários componentes, todas respeitando a preferência do usuário por movimento reduzido (`prefers-reduced-motion`).
224
+
225
+ ### Configuração de Animações
420
226
 
421
227
  ```typescript
422
- import { BrSelectOption } from '@schenkerjon/ng-govbr-tw';
423
-
424
- estados: BrSelectOption[] = [
425
- { label: 'São Paulo', value: 'SP' },
426
- { label: 'Rio de Janeiro', value: 'RJ' },
427
- { label: 'Minas Gerais', value: 'MG' },
428
- ];
429
- ```
430
-
431
- | Input | Tipo | Padrão |
432
- |-------|------|--------|
433
- | `label` | `string` | — |
434
- | `placeholder` | `string` | `'Selecione'` |
435
- | `options` | `BrSelectOption[]` | `[]` |
436
- | `required` | `boolean` | `false` |
437
- | `error` | `string` | — |
438
- | `multiple` | `boolean` | `false` |
439
- | `searchable` | `boolean` | `false` |
440
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` |
228
+ import { BrAnimationService } from '@schenkerjon/ng-govbr-tw';
441
229
 
442
- ---
443
-
444
- ### br-checkbox
445
-
446
- ```html
447
- <br-checkbox label="Aceito os termos de uso" [(ngModel)]="aceitoTermos"></br-checkbox>
448
-
449
- <br-checkbox label="Selecionar todos" [indeterminate]="algumSelecionado" [(ngModel)]="todosSelecionados"></br-checkbox>
450
- ```
451
-
452
- | Input | Tipo | Padrão |
453
- |-------|------|--------|
454
- | `label` | `string` | — |
455
- | `indeterminate` | `boolean` | `false` |
456
- | `error` | `string` | — |
457
- | `size` | `'default' \| 'small'` | `'default'` |
458
- | `state` | `'default' \| 'valid' \| 'invalid'` | `'default'` |
459
-
460
- ---
230
+ @Component({...})
231
+ export class AppComponent {
232
+ private animationService = inject(BrAnimationService);
461
233
 
462
- ### br-radio-group
234
+ // Desabilitar animações globalmente
235
+ disableAnimations() {
236
+ this.animationService.setEnabled(false);
237
+ }
463
238
 
464
- ```html
465
- <br-radio-group
466
- legend="Tipo de pessoa"
467
- [(ngModel)]="tipoPessoa"
468
- [options]="tipoPessoaOpts"
469
- [inline]="true"
470
- ></br-radio-group>
239
+ // Verificar status
240
+ isEnabled() {
241
+ return this.animationService.isEnabled();
242
+ }
243
+ }
471
244
  ```
472
245
 
473
- ```typescript
474
- import { BrRadioOption } from '@schenkerjon/ng-govbr-tw';
246
+ ### Componentes Animados
475
247
 
476
- tipoPessoaOpts: BrRadioOption[] = [
477
- { label: 'Pessoa Física', value: 'PF' },
478
- { label: 'Pessoa Jurídica', value: 'PJ' },
479
- ];
480
- ```
481
-
482
- | Input | Tipo | Padrão |
483
- |-------|------|--------|
484
- | `legend` | `string` | |
485
- | `options` | `BrRadioOption[]` | `[]` |
486
- | `required` | `boolean` | `false` |
487
- | `error` | `string` | |
488
- | `inline` | `boolean` | `false` |
489
- | `size` | `'default' \| 'small'` | `'default'` |
248
+ | Componente | Tipo de Animação | Descrição |
249
+ |---|---|---|
250
+ | `br-message` | Slide-in | Mensagens deslizam ao aparecer |
251
+ | `br-select` | Dropdown | Menu abre com fade + slide |
252
+ | `br-notification` | Bounce | Badge pulsa ao aparecer |
253
+ | `br-sidebar` | Slide + Fade | Drawer mobile desliza, overlay faz fade |
254
+ | `br-tab` | Fade-in | Conteúdo das abas faz fade suave |
255
+ | `br-datepicker` | Dropdown | Calendário abre com animação |
256
+ | `br-timepicker` | Dropdown | Painel de horário abre com animação |
257
+ | `br-cookiebar` | Slide-up | Barra sobe da parte inferior |
258
+ | `br-menu` | Slide-in | Menu desliza da esquerda |
259
+ | `br-mega-menu` | Dropdown | Painel mega menu abre com animação |
260
+ | `br-wizard` | Fade-slide | Steps deslizam horizontalmente |
261
+ | `br-upload` | Enter | Arquivos aparecem com animação |
262
+ | `br-modal` | Scale + Fade | Modal escala ao abrir |
263
+ | `br-accordion` | Collapse | Conteúdo expande/colapsa suavemente |
264
+ | `br-tooltip` | Fade | Tooltip aparece com fade |
265
+ | `br-loading` | Spin/Pulse | Animação contínua de loading |
490
266
 
491
267
  ---
492
268
 
493
- ### br-textarea
494
-
495
- ```html
496
- <br-textarea
497
- label="Observações"
498
- placeholder="Digite suas observações..."
499
- [(ngModel)]="observacoes"
500
- [rows]="5"
501
- [maxLength]="500"
502
- helperText="Máximo de 500 caracteres"
503
- resizable="vertical"
504
- ></br-textarea>
505
- ```
506
-
507
- | Input | Tipo | Padrão |
508
- |-------|------|--------|
509
- | `label` | `string` | — |
510
- | `placeholder` | `string` | `''` |
511
- | `rows` | `number` | `4` |
512
- | `maxLength` | `number` | — |
513
- | `helperText` | `string` | — |
514
- | `error` | `string` | — |
515
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` |
516
- | `resizable` | `'none' \| 'vertical' \| 'both'` | `'vertical'` |
517
-
518
- ---
269
+ ## Acessibilidade
519
270
 
520
- ### br-datepicker
271
+ Todos os componentes seguem as diretrizes WCAG 2.1:
521
272
 
522
- Seletor de data com calendário dropdown. Valor no formato `"dd/mm/aaaa"`.
273
+ - **ARIA Labels** Atributos aria-label, aria-describedby, role
274
+ - **Navegação por Teclado** — Tab, Enter, Escape, Arrow keys
275
+ - **Focus Visible** — Indicadores de foco visíveis
276
+ - **Reduced Motion** — Respeita `prefers-reduced-motion`
277
+ - **Contraste** — Cores seguem o padrão Gov.br (AA/AAA)
278
+ - **Screen Readers** — Textos alternativos e live regions
523
279
 
524
280
  ```html
525
- <br-datepicker
526
- label="Data de nascimento"
527
- [(ngModel)]="dataNascimento"
528
- [required]="true"
529
- hint="Formato: dd/mm/aaaa"
530
- ></br-datepicker>
281
+ <!-- Exemplo de acessibilidade -->
282
+ <br-button
283
+ variant="primary"
284
+ ariaLabel="Enviar formulário de contato"
285
+ [loading]="true"
286
+ loadingText="Enviando..."
287
+ >
288
+ Enviar
289
+ </br-button>
531
290
  ```
532
291
 
533
- | Input | Tipo | Padrão |
534
- |-------|------|--------|
535
- | `label` | `string` | — |
536
- | `placeholder` | `string` | `'dd/mm/aaaa'` |
537
- | `hint` | `string` | — |
538
- | `error` | `string` | — |
539
- | `required` | `boolean` | `false` |
540
- | `block` | `boolean` | `true` |
541
-
542
292
  ---
543
293
 
544
- ### br-timepicker
545
-
546
- Seletor de hora com painel de horas e minutos. Valor no formato `"HH:MM"`.
547
-
548
- ```html
549
- <br-timepicker label="Horário" [(ngModel)]="horario" [step]="15"></br-timepicker>
550
- ```
294
+ ## Tokens Gov.br
551
295
 
552
- | Input | Tipo | Padrão |
553
- |-------|------|--------|
554
- | `label` | `string` | — |
555
- | `placeholder` | `string` | `'HH:MM'` |
556
- | `step` | `number` | `5` |
557
- | `hint` | `string` | — |
558
- | `error` | `string` | — |
559
- | `required` | `boolean` | `false` |
296
+ O preset Tailwind mapeia os tokens oficiais do Design System:
560
297
 
561
- ---
298
+ ### Cores
562
299
 
563
- ### br-datetimepicker
300
+ | Token | Valor | Uso |
301
+ |---|---|---|
302
+ | `govbr-primary` | #1351b4 | Cor principal (blue-warm-vivid-70) |
303
+ | `govbr-primary-dark` | #0c326f | Hover/active |
304
+ | `govbr-primary-lightest` | #d4e5ff | Backgrounds suaves |
305
+ | `govbr-success` | #168821 | Sucesso, confirmação |
306
+ | `govbr-danger` | #e52207 | Erro, alerta crítico |
307
+ | `govbr-warning` | #ffcd07 | Atenção |
308
+ | `govbr-info` | #155bcb | Informação |
309
+ | `govbr-gray-80` | #333333 | Texto principal |
310
+ | `govbr-gray-60` | #636363 | Texto secundário |
311
+ | `govbr-gray-20` | #cccccc | Bordas |
564
312
 
565
- Composição de `br-datepicker` + `br-timepicker`. Valor no formato `"dd/mm/aaaa HH:MM"`.
313
+ ### Tipografia
566
314
 
567
- ```html
568
- <br-datetimepicker
569
- label="Agendamento"
570
- [(ngModel)]="agendamento"
571
- [minuteStep]="15"
572
- layout="horizontal"
573
- ></br-datetimepicker>
315
+ ```css
316
+ font-rawline /* Rawline, Raleway, sans-serif */
317
+ text-govbr-xs /* 11px */
318
+ text-govbr-sm /* 13px */
319
+ text-govbr-base /* 14px */
320
+ text-govbr-lg /* 16px */
321
+ text-govbr-xl /* 20px */
574
322
  ```
575
323
 
576
- | Input | Tipo | Padrão |
577
- |-------|------|--------|
578
- | `label` | `string` | — |
579
- | `dateLabel` | `string` | `'Data'` |
580
- | `timeLabel` | `string` | `'Hora'` |
581
- | `minuteStep` | `number` | `5` |
582
- | `layout` | `'horizontal' \| 'vertical'` | `'horizontal'` |
583
- | `hint` | `string` | — |
584
- | `dateError` | `string` | — |
585
- | `timeError` | `string` | — |
586
-
587
- ---
588
-
589
- ## Botões
590
-
591
- ### br-button
592
-
593
- Botão seguindo o padrão GovBR DS com suporte a emphasis, density, modo escuro e mais.
324
+ ### Bordas e Espaçamentos
594
325
 
595
- ```html
596
- <!-- Emphasis (ênfase) -->
597
- <br-button emphasis="primary" (clicked)="salvar()">Salvar</br-button>
598
- <br-button emphasis="secondary" icon="download">Download</br-button>
599
- <br-button emphasis="tertiary" icon="trash">Excluir</br-button>
600
- <br-button emphasis="danger" icon="warning">Remover</br-button>
601
-
602
- <!-- Density (densidade) -->
603
- <br-button emphasis="primary" density="small">Pequeno</br-button>
604
- <br-button emphasis="primary" density="medium">Médio</br-button>
605
- <br-button emphasis="primary" density="large">Grande</br-button>
606
-
607
- <!-- Circular (icon-only) -->
608
- <br-button emphasis="primary" [circle]="true" icon="plus" density="large"></br-button>
609
-
610
- <!-- Block (largura total) -->
611
- <br-button emphasis="primary" [block]="true">Largura total</br-button>
612
-
613
- <!-- Loading -->
614
- <br-button emphasis="primary" [loading]="salvando">Salvando...</br-button>
615
-
616
- <!-- Modo escuro (para fundos escuros) -->
617
- <br-button emphasis="primary" [dark]="true">Modo escuro</br-button>
618
- <br-button emphasis="secondary" [dark]="true">Outlined escuro</br-button>
619
-
620
- <!-- Ícone à direita -->
621
- <br-button emphasis="primary" icon="arrow-right" iconPosition="right">Próximo</br-button>
622
-
623
- <!-- Estado ativo -->
624
- <br-button emphasis="primary" [active]="true">Ativo</br-button>
326
+ ```css
327
+ rounded-govbr-sm /* 4px */
328
+ rounded-govbr-md /* 8px */
329
+ rounded-govbr-pill /* 100em */
625
330
  ```
626
331
 
627
- | Input | Tipo | Padrão | Descrição |
628
- |-------|------|--------|-----------|
629
- | `emphasis` | `'primary' \| 'secondary' \| 'tertiary' \| 'danger'` | `'primary'` | Nível de ênfase: primary (preenchido), secondary (outlined), tertiary (somente texto), danger |
630
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` | Densidade/tamanho |
631
- | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | Tipo do botão HTML |
632
- | `icon` | `string` | — | Ícone Font Awesome (sem `fa-`) |
633
- | `iconPosition` | `'left' \| 'right'` | `'left'` | Posição do ícone |
634
- | `circle` | `boolean` | `false` | Botão circular (icon-only) |
635
- | `block` | `boolean` | `false` | Largura total |
636
- | `loading` | `boolean` | `false` | Estado de carregamento com spinner |
637
- | `disabled` | `boolean` | `false` | Desabilitado |
638
- | `active` | `boolean` | `false` | Estado ativo/pressionado |
639
- | `dark` | `boolean` | `false` | Modo escuro (cores invertidas para fundos escuros) |
640
-
641
- > **Backward compatibility:** `variant` e `size` ainda funcionam como aliases para `emphasis` e `density`.
642
-
643
332
  ---
644
333
 
645
- ### br-magic-button
334
+ ## Exemplos Detalhados
646
335
 
647
- Botão flutuante (FAB) com speed dial de ações rápidas.
648
-
649
- ```html
650
- <!-- FAB simples -->
651
- <br-magic-button icon="plus" (fabClick)="criarNovo()"></br-magic-button>
652
-
653
- <!-- FAB com ações -->
654
- <br-magic-button icon="plus" [actions]="acoes" position="bottom-right" (actionClick)="onAction($event)"></br-magic-button>
655
- ```
336
+ ### Formulário Completo
656
337
 
657
338
  ```typescript
658
- import { BrMagicAction } from '@schenkerjon/ng-govbr-tw';
339
+ import {
340
+ BrInputComponent,
341
+ BrSelectComponent,
342
+ BrCheckboxComponent,
343
+ BrButtonComponent
344
+ } from '@schenkerjon/ng-govbr-tw';
345
+ import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
659
346
 
660
- acoes: BrMagicAction[] = [
661
- { id: 'doc', label: 'Novo documento', icon: 'file' },
662
- { id: 'foto', label: 'Tirar foto', icon: 'camera' },
663
- { id: 'msg', label: 'Nova mensagem', icon: 'envelope' },
664
- ];
347
+ @Component({
348
+ standalone: true,
349
+ imports: [ReactiveFormsModule, BrInputComponent, BrSelectComponent, BrCheckboxComponent, BrButtonComponent],
350
+ template: `
351
+ <form [formGroup]="form" (ngSubmit)="onSubmit()">
352
+ <br-input
353
+ label="Nome completo"
354
+ formControlName="nome"
355
+ [required]="true"
356
+ placeholder="Digite seu nome"
357
+ ></br-input>
358
+
359
+ <br-input
360
+ label="E-mail"
361
+ type="email"
362
+ formControlName="email"
363
+ [required]="true"
364
+ hint="Usaremos para contato"
365
+ ></br-input>
366
+
367
+ <br-select
368
+ label="Estado"
369
+ formControlName="estado"
370
+ [options]="estados"
371
+ [searchable]="true"
372
+ placeholder="Selecione"
373
+ ></br-select>
374
+
375
+ <br-checkbox
376
+ label="Aceito os termos de uso"
377
+ formControlName="termos"
378
+ ></br-checkbox>
379
+
380
+ <br-button
381
+ type="submit"
382
+ variant="primary"
383
+ [disabled]="form.invalid"
384
+ [loading]="submitting"
385
+ >
386
+ Enviar
387
+ </br-button>
388
+ </form>
389
+ `
390
+ })
391
+ export class FormularioComponent {
392
+ submitting = false;
393
+
394
+ form = new FormGroup({
395
+ nome: new FormControl('', Validators.required),
396
+ email: new FormControl('', [Validators.required, Validators.email]),
397
+ estado: new FormControl(''),
398
+ termos: new FormControl(false, Validators.requiredTrue)
399
+ });
400
+
401
+ estados = [
402
+ { label: 'São Paulo', value: 'SP' },
403
+ { label: 'Rio de Janeiro', value: 'RJ' },
404
+ { label: 'Minas Gerais', value: 'MG' },
405
+ ];
406
+
407
+ onSubmit() {
408
+ this.submitting = true;
409
+ // ...
410
+ }
411
+ }
665
412
  ```
666
413
 
667
- | Input | Tipo | Padrão |
668
- |-------|------|--------|
669
- | `icon` | `string` | `'plus'` |
670
- | `actions` | `BrMagicAction[]` | `[]` |
671
- | `variant` | `'primary' \| 'secondary' \| 'danger'` | `'primary'` |
672
- | `size` | `'medium' \| 'large'` | `'large'` |
673
- | `position` | `'bottom-right' \| 'bottom-left' \| 'bottom-center'` | `'bottom-right'` |
674
- | `showLabels` | `boolean` | `true` |
675
-
676
- ---
677
-
678
- ## Dados
414
+ ### Select com Busca
679
415
 
680
- ### br-card
416
+ ```typescript
417
+ import { BrSelectComponent, BrSelectOption } from '@schenkerjon/ng-govbr-tw';
681
418
 
682
- ```html
683
- <!-- Card com imagem -->
684
- <br-card
685
- cardTitle="Título"
686
- subtitle="Descrição breve"
687
- imageSrc="assets/imagem.jpg"
688
- imageRatio="16:9"
689
- tag="Novo"
690
- linkText="Ver mais"
691
- linkRoute="/detalhes"
692
- ></br-card>
693
-
694
- <!-- Card horizontal -->
695
- <br-card layout="horizontal" cardTitle="Documento" imageSrc="assets/thumb.jpg"></br-card>
696
-
697
- <!-- Card com ícone e footer customizado -->
698
- <br-card cardTitle="Estatísticas" icon="chart-bar">
699
- <p class="text-2xl font-bold">1.234</p>
700
- <div card-footer>
701
- <a href="#">Ver relatório</a>
702
- </div>
703
- </br-card>
419
+ @Component({
420
+ standalone: true,
421
+ imports: [BrSelectComponent],
422
+ template: `
423
+ <br-select
424
+ label="Município"
425
+ [options]="municipios"
426
+ [searchable]="true"
427
+ [multiple]="true"
428
+ searchPlaceholder="Digite para buscar..."
429
+ [(ngModel)]="selecionados"
430
+ ></br-select>
431
+ `
432
+ })
433
+ export class SelectComponent {
434
+ selecionados: string[] = [];
435
+ municipios: BrSelectOption[] = [
436
+ { label: 'São Paulo', value: 'sao-paulo' },
437
+ { label: 'Campinas', value: 'campinas' },
438
+ { label: 'Santos', value: 'santos' },
439
+ ];
440
+ }
704
441
  ```
705
442
 
706
- | Input | Tipo | Padrão |
707
- |-------|------|--------|
708
- | `cardTitle` | `string` | — |
709
- | `subtitle` | `string` | — |
710
- | `icon` | `string` | — |
711
- | `tag` | `string` | — |
712
- | `imageSrc` | `string` | — |
713
- | `imageAlt` | `string` | — |
714
- | `imageRatio` | `'16:9' \| '4:3' \| '1:1'` | `'16:9'` |
715
- | `layout` | `'vertical' \| 'horizontal'` | `'vertical'` |
716
- | `linkText` | `string` | — |
717
- | `linkRoute` | `string \| unknown[]` | — |
718
- | `clickable` | `boolean` | `false` |
719
-
720
- **Slots:** `[card-footer]`
443
+ ### Modal
721
444
 
722
- ---
445
+ ```typescript
446
+ import { BrModalComponent, BrButtonComponent } from '@schenkerjon/ng-govbr-tw';
723
447
 
724
- ### br-table
448
+ @Component({
449
+ standalone: true,
450
+ imports: [BrModalComponent, BrButtonComponent],
451
+ template: `
452
+ <br-button (click)="modalOpen = true">Abrir Modal</br-button>
453
+
454
+ <br-modal
455
+ [isOpen]="modalOpen"
456
+ title="Confirmar ação"
457
+ size="medium"
458
+ [showCloseButton]="true"
459
+ (closed)="modalOpen = false"
460
+ (confirmed)="onConfirm()"
461
+ >
462
+ <p>Você tem certeza que deseja continuar com esta ação?</p>
463
+ <p class="text-sm text-govbr-gray-60 mt-2">Esta ação não pode ser desfeita.</p>
464
+ </br-modal>
465
+ `
466
+ })
467
+ export class ModalComponent {
468
+ modalOpen = false;
725
469
 
726
- ```html
727
- <br-table headerVariant="blue" [page]="page" [totalPages]="10" (pageChange)="page = $event">
728
- <thead>
729
- <tr><th>Nome</th><th>E-mail</th><th>Status</th></tr>
730
- </thead>
731
- <tbody>
732
- @for (u of users; track u) {
733
- <tr>
734
- <td>{{ u.nome }}</td>
735
- <td>{{ u.email }}</td>
736
- <td><br-badge [variant]="u.ativo ? 'success' : 'danger'">{{ u.ativo ? 'Ativo' : 'Inativo' }}</br-badge></td>
737
- </tr>
738
- }
739
- </tbody>
740
- </br-table>
470
+ onConfirm() {
471
+ console.log('Confirmado!');
472
+ this.modalOpen = false;
473
+ }
474
+ }
741
475
  ```
742
476
 
743
- | Input | Tipo | Padrão |
744
- |-------|------|--------|
745
- | `headerVariant` | `'blue' \| 'light'` | `'blue'` |
746
- | `page` | `number` | `1` |
747
- | `totalPages` | `number` | `1` |
477
+ ### Tabs
748
478
 
749
- ---
750
-
751
- ### br-badge
479
+ ```typescript
480
+ import { BrTabComponent, BrTabItem } from '@schenkerjon/ng-govbr-tw';
752
481
 
753
- ```html
754
- <br-badge variant="success">Ativo</br-badge>
755
- <br-badge variant="danger">Inativo</br-badge>
756
- <br-badge variant="warning">Pendente</br-badge>
757
- <br-badge variant="neutral">Rascunho</br-badge>
482
+ @Component({
483
+ standalone: true,
484
+ imports: [BrTabComponent],
485
+ template: `
486
+ <br-tab
487
+ [tabs]="tabs"
488
+ [(activeIndex)]="activeTab"
489
+ density="medium"
490
+ >
491
+ @switch (activeTab) {
492
+ @case (0) {
493
+ <div class="p-4">
494
+ <h3>Dados Pessoais</h3>
495
+ <p>Conteúdo da primeira aba...</p>
496
+ </div>
497
+ }
498
+ @case (1) {
499
+ <div class="p-4">
500
+ <h3>Endereço</h3>
501
+ <p>Conteúdo da segunda aba...</p>
502
+ </div>
503
+ }
504
+ @case (2) {
505
+ <div class="p-4">
506
+ <h3>Documentos</h3>
507
+ <p>Conteúdo da terceira aba...</p>
508
+ </div>
509
+ }
510
+ }
511
+ </br-tab>
512
+ `
513
+ })
514
+ export class TabsComponent {
515
+ activeTab = 0;
516
+ tabs: BrTabItem[] = [
517
+ { label: 'Dados Pessoais', icon: 'user' },
518
+ { label: 'Endereço', icon: 'location-dot' },
519
+ { label: 'Documentos', icon: 'file', counter: 3 },
520
+ ];
521
+ }
758
522
  ```
759
523
 
760
- | Input | Tipo | Padrão |
761
- |-------|------|--------|
762
- | `variant` | `'primary' \| 'success' \| 'danger' \| 'warning' \| 'neutral'` | `'primary'` |
763
-
764
- ---
765
-
766
- ### br-item / br-list
524
+ ### Accordion
767
525
 
768
- Lista estruturada de itens.
526
+ ```typescript
527
+ import { BrAccordionComponent, BrAccordionItemComponent } from '@schenkerjon/ng-govbr-tw';
769
528
 
770
- ```html
771
- <br-list title="Documentos recentes" variant="card">
772
- <br-item
773
- title="Relatório Anual 2024"
774
- subtitle="Atualizado em 15/01/2024"
775
- icon="file-pdf"
776
- tag="PDF"
777
- [clickable]="true"
778
- [showArrow]="true"
779
- (itemClick)="abrirDoc('relatorio')"
780
- >
781
- <span item-meta class="text-xs text-gray-500">2.4 MB</span>
782
- </br-item>
783
-
784
- <br-item
785
- title="João da Silva"
786
- subtitle="Analista de Sistemas"
787
- avatarSrc="assets/avatar.jpg"
788
- [clickable]="true"
789
- >
790
- <div item-actions>
791
- <br-button density="small" emphasis="secondary" icon="envelope" [circle]="true"></br-button>
792
- </div>
793
- </br-item>
794
- </br-list>
529
+ @Component({
530
+ standalone: true,
531
+ imports: [BrAccordionComponent, BrAccordionItemComponent],
532
+ template: `
533
+ <br-accordion mode="single" [negative]="false">
534
+ <br-accordion-item title="O que é o Gov.br?" [open]="true">
535
+ <p>O Gov.br é a plataforma de relacionamento digital única entre cidadão e Governo.</p>
536
+ </br-accordion-item>
537
+
538
+ <br-accordion-item title="Como criar uma conta?">
539
+ <p>Acesse gov.br/conta e siga as instruções para criar sua conta.</p>
540
+ </br-accordion-item>
541
+
542
+ <br-accordion-item title="Esqueci minha senha" [disabled]="true">
543
+ <p>Conteúdo indisponível.</p>
544
+ </br-accordion-item>
545
+ </br-accordion>
546
+ `
547
+ })
548
+ export class AccordionComponent {}
795
549
  ```
796
550
 
797
- **br-list:**
798
-
799
- | Input | Tipo | Padrão |
800
- |-------|------|--------|
801
- | `title` | `string` | — |
802
- | `subtitle` | `string` | — |
803
- | `variant` | `'default' \| 'bordered' \| 'card'` | `'default'` |
804
- | `role` | `'list' \| 'listbox' \| 'menu'` | `'list'` |
805
-
806
- **br-item:**
807
-
808
- | Input | Tipo | Padrão |
809
- |-------|------|--------|
810
- | `title` | `string` | `''` |
811
- | `subtitle` | `string` | — |
812
- | `icon` | `string` | — |
813
- | `avatarSrc` | `string` | — |
814
- | `tag` | `string` | — |
815
- | `clickable` | `boolean` | `false` |
816
- | `showArrow` | `boolean` | `false` |
817
- | `selected` | `boolean` | `false` |
818
- | `disabled` | `boolean` | `false` |
819
- | `variant` | `'default' \| 'compact'` | `'default'` |
551
+ ### Sidebar com Menu
820
552
 
821
- **Slots:** `[item-meta]`, `[item-actions]`
822
-
823
- ---
824
-
825
- ## Feedback
553
+ ```typescript
554
+ import {
555
+ BrSidebarComponent,
556
+ BrSidebarGroupComponent,
557
+ BrSidebarGroupLabelComponent,
558
+ BrSidebarItemComponent,
559
+ BrSidebarSubComponent
560
+ } from '@schenkerjon/ng-govbr-tw';
826
561
 
827
- ### br-message
562
+ @Component({
563
+ standalone: true,
564
+ imports: [
565
+ BrSidebarComponent,
566
+ BrSidebarGroupComponent,
567
+ BrSidebarGroupLabelComponent,
568
+ BrSidebarItemComponent,
569
+ BrSidebarSubComponent
570
+ ],
571
+ template: `
572
+ <br-sidebar
573
+ [(collapsed)]="collapsed"
574
+ [collapsible]="true"
575
+ [hasHeader]="true"
576
+ [hasFooter]="true"
577
+ >
578
+ <div sidebar-header>
579
+ <img src="logo.png" alt="Logo" class="h-8" />
580
+ </div>
828
581
 
829
- ```html
830
- <br-message type="info" title="Informação">Sua solicitação foi recebida.</br-message>
831
- <br-message type="success" [dismissible]="true">Cadastro realizado!</br-message>
832
- <br-message type="warning" [autoDismiss]="5000" title="Atenção">Sessão expira em breve.</br-message>
833
- <br-message type="danger" title="Erro">Falha ao processar.</br-message>
582
+ <br-sidebar-group>
583
+ <br-sidebar-group-label>Principal</br-sidebar-group-label>
584
+ <br-sidebar-item
585
+ route="/dashboard"
586
+ label="Dashboard"
587
+ icon="home"
588
+ [collapsed]="collapsed"
589
+ ></br-sidebar-item>
590
+ <br-sidebar-item
591
+ route="/usuarios"
592
+ label="Usuários"
593
+ icon="users"
594
+ badge="5"
595
+ [collapsed]="collapsed"
596
+ ></br-sidebar-item>
597
+ </br-sidebar-group>
598
+
599
+ <br-sidebar-group>
600
+ <br-sidebar-group-label>Configurações</br-sidebar-group-label>
601
+ <br-sidebar-sub
602
+ label="Sistema"
603
+ icon="gear"
604
+ [collapsed]="collapsed"
605
+ >
606
+ <br-sidebar-item route="/config/geral" label="Geral"></br-sidebar-item>
607
+ <br-sidebar-item route="/config/seguranca" label="Segurança"></br-sidebar-item>
608
+ </br-sidebar-sub>
609
+ </br-sidebar-group>
610
+
611
+ <div sidebar-footer>
612
+ <span class="text-xs text-govbr-gray-40">v1.0.0</span>
613
+ </div>
614
+ </br-sidebar>
615
+ `
616
+ })
617
+ export class SidebarComponent {
618
+ collapsed = false;
619
+ }
834
620
  ```
835
621
 
836
- | Input | Tipo | Padrão |
837
- |-------|------|--------|
838
- | `type` | `'success' \| 'danger' \| 'warning' \| 'info'` | `'info'` |
839
- | `title` | `string` | — |
840
- | `dismissible` | `boolean` | `false` |
841
- | `autoDismiss` | `number` | — |
622
+ ### Wizard Multi-etapas
842
623
 
843
- **Método público:** `show()` — reexibe a mensagem após dismiss.
844
-
845
- ---
624
+ ```typescript
625
+ import { BrWizardComponent, BrWizardStepComponent } from '@schenkerjon/ng-govbr-tw';
846
626
 
847
- ### br-modal
627
+ @Component({
628
+ standalone: true,
629
+ imports: [BrWizardComponent, BrWizardStepComponent],
630
+ template: `
631
+ <br-wizard
632
+ [(currentStep)]="step"
633
+ [showNavigation]="true"
634
+ (complete)="onComplete()"
635
+ >
636
+ <br-wizard-step label="Dados Pessoais" icon="user">
637
+ <h3 class="text-lg font-semibold mb-4">Informações Pessoais</h3>
638
+ <p>Preencha seus dados pessoais...</p>
639
+ </br-wizard-step>
640
+
641
+ <br-wizard-step label="Endereço" icon="location-dot">
642
+ <h3 class="text-lg font-semibold mb-4">Endereço</h3>
643
+ <p>Informe seu endereço...</p>
644
+ </br-wizard-step>
645
+
646
+ <br-wizard-step label="Confirmação" icon="check">
647
+ <h3 class="text-lg font-semibold mb-4">Revisar dados</h3>
648
+ <p>Confira as informações antes de enviar...</p>
649
+ </br-wizard-step>
650
+ </br-wizard>
651
+ `
652
+ })
653
+ export class WizardComponent {
654
+ step = 0;
848
655
 
849
- ```html
850
- <br-modal
851
- [isOpen]="modalAberto"
852
- title="Confirmar exclusão"
853
- size="small"
854
- primaryText="Excluir"
855
- (confirmed)="excluir()"
856
- (canceled)="modalAberto = false"
857
- (closed)="modalAberto = false"
858
- >
859
- <p>Tem certeza que deseja excluir?</p>
860
- </br-modal>
656
+ onComplete() {
657
+ console.log('Wizard finalizado!');
658
+ }
659
+ }
861
660
  ```
862
661
 
863
- | Input | Tipo | Padrão |
864
- |-------|------|--------|
865
- | `isOpen` | `boolean` | `false` |
866
- | `title` | `string` | `''` |
867
- | `size` | `'xsmall' \| 'small' \| 'medium' \| 'large' \| 'auto'` | `'medium'` |
868
- | `showCloseButton` | `boolean` | `true` |
869
- | `primaryText` | `string` | `'Confirmar'` |
870
- | `cancelText` | `string` | `'Cancelar'` |
871
- | `primaryDisabled` | `boolean` | `false` |
872
- | `loading` | `boolean` | `false` |
873
- | `closeOnScrim` | `boolean` | `true` |
874
- | `closeOnEscape` | `boolean` | `true` |
875
- | `hasCustomFooter` | `boolean` | `false` |
876
-
877
- **Slot:** `[modal-footer]` — footer customizado (com `[hasCustomFooter]="true"`)
878
-
879
- ---
662
+ ### Upload de Arquivos
880
663
 
881
- ### br-loading
664
+ ```typescript
665
+ import { BrUploadComponent, BrUploadFile } from '@schenkerjon/ng-govbr-tw';
882
666
 
883
- ```html
884
- <br-loading size="medium"></br-loading>
885
- <br-loading [progress]="75" [showPercentage]="true" label="Carregando..."></br-loading>
667
+ @Component({
668
+ standalone: true,
669
+ imports: [BrUploadComponent],
670
+ template: `
671
+ <br-upload
672
+ label="Documentos"
673
+ accept=".pdf,.doc,.docx"
674
+ [multiple]="true"
675
+ [maxSizeMB]="5"
676
+ [maxFiles]="3"
677
+ helperText="Arquivos PDF ou Word, máximo 5MB cada"
678
+ (filesChange)="onFilesChange($event)"
679
+ (fileAdded)="onFileAdded($event)"
680
+ (fileRemoved)="onFileRemoved($event)"
681
+ ></br-upload>
682
+ `
683
+ })
684
+ export class UploadComponent {
685
+ onFilesChange(files: BrUploadFile[]) {
686
+ console.log('Arquivos:', files);
687
+ }
688
+
689
+ onFileAdded(file: BrUploadFile) {
690
+ console.log('Adicionado:', file.name);
691
+ }
692
+
693
+ onFileRemoved(file: BrUploadFile) {
694
+ console.log('Removido:', file.name);
695
+ }
696
+ }
886
697
  ```
887
698
 
888
- | Input | Tipo | Padrão |
889
- |-------|------|--------|
890
- | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
891
- | `progress` | `number` | — |
892
- | `showPercentage` | `boolean` | `true` |
893
- | `label` | `string` | — |
894
-
895
- ---
699
+ ### Toast Notifications
896
700
 
897
- ### br-tooltip
898
-
899
- ```html
900
- <br-tooltip text="Informação adicional" place="top">
901
- <i class="fa-solid fa-circle-info"></i>
902
- </br-tooltip>
701
+ ```typescript
702
+ import { BrToastService } from '@schenkerjon/ng-govbr-tw';
703
+
704
+ @Component({...})
705
+ export class ToastComponent {
706
+ private toastService = inject(BrToastService);
707
+
708
+ showSuccess() {
709
+ this.toastService.success('Operação realizada com sucesso!');
710
+ }
711
+
712
+ showError() {
713
+ this.toastService.danger('Erro ao processar solicitação.');
714
+ }
715
+
716
+ showWarning() {
717
+ this.toastService.warning('Atenção: verifique os dados.');
718
+ }
719
+
720
+ showInfo() {
721
+ this.toastService.info('Nova atualização disponível.', {
722
+ duration: 5000,
723
+ position: 'top-right'
724
+ });
725
+ }
726
+ }
903
727
  ```
904
728
 
905
- | Input | Tipo | Padrão |
906
- |-------|------|--------|
907
- | `text` | `string` | `''` |
908
- | `place` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` |
909
- | `variant` | `'info' \| 'success' \| 'danger' \| 'warning'` | `'info'` |
910
- | `timer` | `number` | — |
911
-
912
729
  ---
913
730
 
914
- ## Utilitários
731
+ ## Inputs Especializados
915
732
 
916
- ### br-accordion
733
+ A biblioteca inclui inputs com máscaras brasileiras:
917
734
 
918
- ```html
919
- <br-accordion mode="single" [bordered]="true">
920
- <br-accordion-item title="Seção 1" icon="file" [open]="true">
921
- Conteúdo da seção 1.
922
- </br-accordion-item>
923
- <br-accordion-item title="Seção 2" badge="3">
924
- Conteúdo da seção 2.
925
- </br-accordion-item>
926
- </br-accordion>
927
- ```
735
+ | Componente | Seletor | Formato |
736
+ |---|---|---|
737
+ | `BrInputCpfComponent` | `<br-input-cpf>` | 000.000.000-00 |
738
+ | `BrInputCnpjComponent` | `<br-input-cnpj>` | 00.000.000/0000-00 |
739
+ | `BrInputCepComponent` | `<br-input-cep>` | 00000-000 |
740
+ | `BrInputTelefoneComponent` | `<br-input-telefone>` | (00) 00000-0000 |
741
+ | `BrInputMoneyComponent` | `<br-input-money>` | R$ 1.234,56 |
928
742
 
929
- | Input (accordion) | Tipo | Padrão |
930
- |-------|------|--------|
931
- | `mode` | `'single' \| 'multiple'` | `'multiple'` |
932
- | `variant` | `'default' \| 'negative'` | `'default'` |
933
- | `bordered` | `boolean` | `true` |
934
-
935
- | Input (item) | Tipo | Padrão |
936
- |-------|------|--------|
937
- | `title` | `string` | `''` |
938
- | `icon` | `string` | — |
939
- | `badge` | `string \| number` | — |
940
- | `open` | `boolean` | `false` |
941
- | `disabled` | `boolean` | `false` |
942
- | `density` | `'small' \| 'medium' \| 'large'` | `'medium'` |
943
-
944
- ---
945
-
946
- ### br-wizard
743
+ ```typescript
744
+ import { BrInputCpfComponent, BrInputCepComponent } from '@schenkerjon/ng-govbr-tw';
947
745
 
948
- Stepper para fluxos multi-etapas.
746
+ @Component({
747
+ standalone: true,
748
+ imports: [BrInputCpfComponent, BrInputCepComponent],
749
+ template: `
750
+ <br-input-cpf
751
+ label="CPF"
752
+ [(ngModel)]="cpf"
753
+ [required]="true"
754
+ ></br-input-cpf>
755
+
756
+ <br-input-cep
757
+ label="CEP"
758
+ [(ngModel)]="cep"
759
+ (cepChange)="onCepChange($event)"
760
+ ></br-input-cep>
761
+ `
762
+ })
763
+ export class InputsComponent {
764
+ cpf = '';
765
+ cep = '';
949
766
 
950
- ```html
951
- <br-wizard [currentStep]="step" (stepChange)="step = $event" (complete)="onComplete()">
952
- <br-wizard-step label="Dados Pessoais" icon="user">
953
- <br-input label="Nome" [(ngModel)]="nome"></br-input>
954
- <br-input label="CPF" [(ngModel)]="cpf"></br-input>
955
- </br-wizard-step>
956
-
957
- <br-wizard-step label="Endereço" icon="location-dot">
958
- <br-input label="CEP" [(ngModel)]="cep"></br-input>
959
- </br-wizard-step>
960
-
961
- <br-wizard-step label="Confirmação" icon="check">
962
- <p>Revise seus dados antes de enviar.</p>
963
- </br-wizard-step>
964
- </br-wizard>
767
+ onCepChange(cep: string) {
768
+ // Buscar endereço por CEP...
769
+ }
770
+ }
965
771
  ```
966
772
 
967
- | Input | Tipo | Padrão |
968
- |-------|------|--------|
969
- | `currentStep` | `number` | `0` |
970
- | `variant` | `'simple' \| 'numbered'` | `'numbered'` |
971
- | `showNavigation` | `boolean` | `true` |
972
- | `allowJump` | `boolean` | `false` |
973
-
974
- | Output | Tipo |
975
- |--------|------|
976
- | `stepChange` | `number` |
977
- | `complete` | `void` |
978
-
979
- **Métodos públicos:** `next()`, `previous()`, `goToStep(index)`
980
-
981
773
  ---
982
774
 
983
- ### br-cookiebar
775
+ ## Demo
984
776
 
985
- Barra de consentimento de cookies (LGPD).
986
-
987
- ```html
988
- <br-cookiebar
989
- [(visible)]="showCookies"
990
- [cookieGroups]="cookieGroups"
991
- (acceptAll)="onAcceptAll()"
992
- (acceptSelected)="onAcceptSelected($event)"
993
- (reject)="onReject()"
994
- >
995
- <p>
996
- Este site utiliza cookies para melhorar sua experiência.
997
- <a href="/politica" class="underline font-semibold">Política de Privacidade</a>.
998
- </p>
999
- </br-cookiebar>
1000
- ```
777
+ **[🔗 Ver Demo Online](https://jordaobass.github.io/ng-govbr-tw/)** Showcase interativo com todos os componentes.
1001
778
 
1002
- ```typescript
1003
- import { BrCookieGroup } from '@schenkerjon/ng-govbr-tw';
779
+ Para rodar localmente:
1004
780
 
1005
- cookieGroups: BrCookieGroup[] = [
1006
- { id: 'essential', label: 'Essenciais', description: 'Necessários para o site funcionar.', required: true, enabled: true },
1007
- { id: 'analytics', label: 'Analíticos', description: 'Nos ajudam a entender o uso do site.', enabled: false },
1008
- { id: 'marketing', label: 'Marketing', description: 'Exibir anúncios relevantes.', enabled: false },
1009
- ];
781
+ ```bash
782
+ git clone https://github.com/jordaobass/ng-govbr-tw.git
783
+ cd ng-govbr-tw
784
+ npm install
785
+ npm run build
786
+ ng serve demo
1010
787
  ```
1011
788
 
1012
- | Input | Tipo | Padrão |
1013
- |-------|------|--------|
1014
- | `visible` | `boolean` | `false` |
1015
- | `cookieGroups` | `BrCookieGroup[]` | `[]` |
1016
-
1017
- | Output | Tipo |
1018
- |--------|------|
1019
- | `acceptAll` | `void` |
1020
- | `acceptSelected` | `BrCookieGroup[]` |
1021
- | `reject` | `void` |
1022
- | `visibleChange` | `boolean` |
789
+ Acesse `http://localhost:4200` para ver o showcase completo.
1023
790
 
1024
791
  ---
1025
792
 
1026
- ## Sidebar (alternativa ao br-menu)
793
+ ## Contribuição
1027
794
 
1028
- Para layouts com sidebar colapsável estilo shadcn:
795
+ Contribuições são bem-vindas!
1029
796
 
1030
- ```html
1031
- <br-sidebar [collapsed]="collapsed" (collapsedChange)="collapsed = $event" [collapsible]="true" [hasHeader]="true">
1032
- <div sidebar-header>Logo</div>
1033
-
1034
- <br-sidebar-group>
1035
- <br-sidebar-group-label>Menu</br-sidebar-group-label>
1036
- <br-sidebar-item label="Dashboard" icon="gauge" route="/dashboard"></br-sidebar-item>
1037
- <br-sidebar-item label="Relatórios" icon="chart-bar" route="/relatorios" badge="5"></br-sidebar-item>
1038
- <br-sidebar-sub label="Configurações" icon="gear" [open]="true">
1039
- <br-sidebar-item label="Geral" route="/config/geral"></br-sidebar-item>
1040
- </br-sidebar-sub>
1041
- </br-sidebar-group>
1042
-
1043
- <div sidebar-footer>Footer</div>
1044
- </br-sidebar>
1045
- ```
797
+ 1. Fork o repositório
798
+ 2. Crie uma branch (`git checkout -b feature/nova-feature`)
799
+ 3. Commit suas mudanças (`git commit -m 'Adiciona nova feature'`)
800
+ 4. Push para a branch (`git push origin feature/nova-feature`)
801
+ 5. Abra um Pull Request
1046
802
 
1047
- | Input | Tipo | Padrão |
1048
- |-------|------|--------|
1049
- | `collapsed` | `boolean` | `false` |
1050
- | `collapsible` | `boolean` | `true` |
1051
- | `variant` | `'sidebar' \| 'floating' \| 'inset'` | `'sidebar'` |
1052
- | `hasHeader` | `boolean` | `false` |
1053
- | `hasFooter` | `boolean` | `false` |
1054
- | `mobileOpen` | `boolean` | `false` |
1055
-
1056
- ---
803
+ ### Reportar Bugs
1057
804
 
1058
- ## Tokens de Cor
1059
-
1060
- | Token | Cor |
1061
- |-------|-----|
1062
- | `govbr-primary` | `#1351b4` |
1063
- | `govbr-primary-dark` | `#0c326f` |
1064
- | `govbr-primary-darkest` | `#071d41` |
1065
- | `govbr-primary-light` | `#c5d4eb` |
1066
- | `govbr-primary-lightest` | `#dbe8fb` |
1067
- | `govbr-success` | `#168821` |
1068
- | `govbr-danger` | `#e52207` |
1069
- | `govbr-warning` | `#ffcd07` |
1070
- | `govbr-info` | `#155bcb` |
1071
- | `govbr-focus` | `#c2850c` |
805
+ Abra uma issue em [github.com/jordaobass/ng-govbr-tw/issues](https://github.com/jordaobass/ng-govbr-tw/issues)
1072
806
 
1073
807
  ---
1074
808
 
1075
- ## Exemplo Completo
1076
-
1077
- ```typescript
1078
- import { Component } from '@angular/core';
1079
- import {
1080
- BrLayoutComponent, BrHeaderComponent, BrMenuComponent,
1081
- BrMenuItemComponent, BrFooterComponent, BrCardComponent,
1082
- } from '@schenkerjon/ng-govbr-tw';
1083
-
1084
- @Component({
1085
- selector: 'app-root',
1086
- standalone: true,
1087
- imports: [
1088
- BrLayoutComponent, BrHeaderComponent, BrMenuComponent,
1089
- BrMenuItemComponent, BrFooterComponent, BrCardComponent,
1090
- ],
1091
- template: `
1092
- <br-layout>
1093
- <br-header
1094
- systemTitle="Portal de Serviços"
1095
- systemSubtitle="Ministério da Economia"
1096
- logoSrc="assets/gov-logo.png"
1097
- (menuToggle)="menuOpen = $event"
1098
- (searchSubmit)="onSearch($event)"
1099
- ></br-header>
1100
-
1101
- <br-menu [open]="menuOpen" (openChange)="menuOpen = $event">
1102
- <br-menu-item label="Início" icon="house" route="/" [exact]="true"></br-menu-item>
1103
- <br-menu-item label="Serviços" icon="grid" route="/servicos"></br-menu-item>
1104
- <br-menu-item label="Documentos" icon="file" route="/docs" badge="3"></br-menu-item>
1105
- </br-menu>
1106
-
1107
- <div class="max-w-4xl mx-auto">
1108
- <h2 class="text-xl font-bold mb-4">Bem-vindo</h2>
1109
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
1110
- <br-card cardTitle="Consultar CPF" icon="id-card" linkText="Acessar" linkRoute="/cpf"></br-card>
1111
- <br-card cardTitle="Emitir certidão" icon="file-certificate" linkText="Acessar" linkRoute="/certidao"></br-card>
1112
- </div>
1113
- </div>
809
+ ## Licença
1114
810
 
1115
- <br-footer logoSrc="assets/gov-logo.png"></br-footer>
1116
- </br-layout>
1117
- `,
1118
- })
1119
- export class AppComponent {
1120
- menuOpen = true;
1121
- onSearch(query: string) { console.log('Busca:', query); }
1122
- }
1123
- ```
811
+ MIT © [Jordan Bass](https://github.com/jordaobass)
1124
812
 
1125
813
  ---
1126
814
 
1127
- ## Licença
1128
-
1129
- MIT
815
+ <p align="center">
816
+ Feito com ❤️ para a comunidade brasileira de desenvolvedores Angular
817
+ </p>