pjc-fields 0.0.44 → 0.0.46

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,64 +1,613 @@
1
- # PjcFields
1
+ # pjc-fields
2
2
 
3
- This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 21.2.0.
3
+ Biblioteca Angular de campos de formulário para dados tipicamente brasileiros — CPF, CNPJ, telefone, placa, data, hora, CEP, CNH, RENAVAM, chassi, IMEI, cartão, moeda e muito mais. Construída sobre [PrimeNG](https://primeng.org/) com suporte completo a Reactive Forms via `ControlValueAccessor` e `Validator`.
4
4
 
5
- ## Code scaffolding
5
+ - **Demo:** https://pjcfields.alvarocda.dev/
6
+ - **NPM:** https://www.npmjs.com/package/pjc-fields
6
7
 
7
- Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
8
+
9
+ ---
10
+
11
+ ## Instalação
8
12
 
9
13
  ```bash
10
- ng generate component component-name
14
+ npm install pjc-fields
11
15
  ```
12
16
 
13
- For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
17
+ ### Dependências necessárias (peer dependencies)
14
18
 
15
- ```bash
16
- ng generate --help
19
+ | Pacote | Versão |
20
+ |---|---|
21
+ | `@angular/common` | `^21.2.0` |
22
+ | `@angular/core` | `^21.2.0` |
23
+ | `@angular/forms` | `^21.2.0` |
24
+ | `primeng` | `^21.1.3` |
25
+ | `@primeuix/themes` | `^2.0.3` |
26
+ | `primeicons` | `^7.0.0` |
27
+
28
+ ---
29
+
30
+ ## Uso básico
31
+
32
+ Todos os componentes são **standalone** — importe diretamente no array `imports` do seu componente Angular:
33
+
34
+ ```typescript
35
+ import { PjcCpfFieldComponent } from 'pjc-fields';
36
+
37
+ @Component({
38
+ imports: [ReactiveFormsModule, PjcCpfFieldComponent],
39
+ })
40
+ export class MeuComponent {
41
+ form = new FormGroup({
42
+ cpf: new FormControl(''),
43
+ });
44
+ }
45
+ ```
46
+
47
+ ```html
48
+ <form [formGroup]="form">
49
+ <pjc-cpf-field formControlName="cpf" label="CPF" />
50
+ </form>
17
51
  ```
18
52
 
19
- ## Building
53
+ ---
20
54
 
21
- To build the library, run:
55
+ ## Componentes
22
56
 
23
- ```bash
24
- ng build pjc-fields
57
+ ### `pjc-cpf-field`
58
+
59
+ Campo de CPF com máscara `000.000.000-00` e validação pelo algoritmo Módulo 11.
60
+
61
+ ```html
62
+ <pjc-cpf-field
63
+ formControlName="cpf"
64
+ label="CPF"
65
+ placeholder="000.000.000-00"
66
+ labelVariant="over"
67
+ />
25
68
  ```
26
69
 
27
- This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
70
+ | Input | Tipo | Padrão | Descrição |
71
+ |---|---|---|---|
72
+ | `label` | `string` | `''` | Rótulo do campo |
73
+ | `hint` | `string` | `''` | Texto de dica abaixo do campo |
74
+ | `placeholder` | `string` | `000.000.000-00` | Placeholder |
75
+ | `id` | `string` | gerado automaticamente | ID do elemento |
76
+ | `labelVariant` | `'over' \| 'in' \| 'on'` | `'over'` | Variante do FloatLabel do PrimeNG |
77
+ | `readonly` | `boolean` | `false` | Impede edição sem desabilitar o controle |
78
+ | `erros` | `Record<string, string>` | `{}` | Mapa de chave de erro → mensagem |
28
79
 
29
- ### Publishing the Library
80
+ Erro de validação: `cpfInvalido`
30
81
 
31
- Once the project is built, you can publish your library by following these steps:
82
+ ---
32
83
 
33
- 1. Navigate to the `dist` directory:
84
+ ### `pjc-cnpj-field`
34
85
 
35
- ```bash
36
- cd dist/pjc-fields
37
- ```
86
+ Campo de CNPJ com máscara `00.000.000/0000-00` e validação pelo algoritmo Módulo 11.
38
87
 
39
- 2. Run the `npm publish` command to publish your library to the npm registry:
40
- ```bash
41
- npm publish
42
- ```
88
+ ```html
89
+ <pjc-cnpj-field
90
+ formControlName="cnpj"
91
+ label="CNPJ"
92
+ />
93
+ ```
43
94
 
44
- ## Running unit tests
95
+ Mesmos inputs de `pjc-cpf-field`. Erro de validação: `cnpjInvalido`
45
96
 
46
- To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
97
+ ---
47
98
 
48
- ```bash
49
- ng test
99
+ ### `pjc-cpf-cnpj-field`
100
+
101
+ Campo que aceita CPF **ou** CNPJ com máscara dinâmica — alterna automaticamente conforme o tamanho digitado.
102
+
103
+ ```html
104
+ <pjc-cpf-cnpj-field
105
+ formControlName="documento"
106
+ label="CPF / CNPJ"
107
+ />
108
+ ```
109
+
110
+ Erros de validação: `cpfInvalido` ou `cnpjInvalido`
111
+
112
+ ---
113
+
114
+ ### `pjc-telefone-field`
115
+
116
+ Campo de telefone com suporte a fixo (10 dígitos) e celular (11 dígitos, com 9 após o DDD).
117
+
118
+ ```html
119
+ <pjc-telefone-field
120
+ formControlName="telefone"
121
+ label="Telefone"
122
+ />
123
+ ```
124
+
125
+ Erro de validação: `telefoneInvalido`
126
+
127
+ ---
128
+
129
+ ### `pjc-placa-field`
130
+
131
+ Campo de placa de veículo com suporte ao padrão antigo (`AAA9999`) e Mercosul (`AAA9A99`).
132
+
133
+ ```html
134
+ <pjc-placa-field
135
+ formControlName="placa"
136
+ label="Placa do Veículo"
137
+ />
138
+ ```
139
+
140
+ Erro de validação: `placaInvalida`
141
+
142
+ ---
143
+
144
+ ### `pjc-data-field`
145
+
146
+ Campo de data com PrimeNG DatePicker. O valor do controle é `Date | null`. Suporta `minDate` e `maxDate`.
147
+
148
+ ```html
149
+ <pjc-data-field
150
+ formControlName="dataNascimento"
151
+ label="Data de Nascimento"
152
+ [minDate]="minDate"
153
+ [maxDate]="maxDate"
154
+ />
155
+ ```
156
+
157
+ | Input | Tipo | Padrão | Descrição |
158
+ |---|---|---|---|
159
+ | `label` | `string` | `'Data'` | Rótulo do campo |
160
+ | `id` | `string` | gerado automaticamente | ID do elemento |
161
+ | `minDate` | `Date \| undefined` | `undefined` | Data mínima selecionável |
162
+ | `maxDate` | `Date \| undefined` | `undefined` | Data máxima selecionável |
163
+ | `labelVariant` | `'over' \| 'in' \| 'on'` | `'on'` | Variante do FloatLabel |
164
+ | `readonly` | `boolean` | `false` | Impede edição sem desabilitar o controle |
165
+ | `erros` | `Record<string, string>` | `{}` | Mapa de chave de erro → mensagem |
166
+
167
+ Erros de validação: `dataMinima`, `dataMaxima`
168
+
169
+ ---
170
+
171
+ ### `pjc-data-hora-field`
172
+
173
+ Campo de data **e hora** com PrimeNG DatePicker (`showTime`). O valor do controle é `Date | null`.
174
+
175
+ ```html
176
+ <pjc-data-hora-field
177
+ formControlName="dataHora"
178
+ label="Data e Hora"
179
+ [minDate]="minDate"
180
+ [maxDate]="maxDate"
181
+ />
182
+ ```
183
+
184
+ Mesmos inputs de `pjc-data-field`. Erros de validação: `dataMinima`, `dataMaxima`
185
+
186
+ ---
187
+
188
+ ### `pjc-hora-field`
189
+
190
+ Campo de hora com máscara `HH:MM` e validação de intervalo (00:00–23:59).
191
+
192
+ ```html
193
+ <pjc-hora-field
194
+ formControlName="horario"
195
+ label="Horário"
196
+ />
197
+ ```
198
+
199
+ Erro de validação: `horaInvalida`
200
+
201
+ ---
202
+
203
+ ### `pjc-cep-field`
204
+
205
+ Campo de CEP com máscara `99999-999`. O valor do controle são os 8 dígitos sem formatação. Inclui botão de busca opcional e evento `busca` para disparar consulta de endereço.
206
+
207
+ ```html
208
+ <pjc-cep-field
209
+ formControlName="cep"
210
+ label="CEP"
211
+ (busca)="onBusca($event)"
212
+ [erros]="{ required: 'CEP obrigatório.', cepInvalido: 'CEP inválido.' }"
213
+ />
214
+ ```
215
+
216
+ | Input | Tipo | Padrão | Descrição |
217
+ |---|---|---|---|
218
+ | `label` | `string` | `''` | Rótulo do campo |
219
+ | `hint` | `string` | `''` | Texto de dica abaixo do campo |
220
+ | `placeholder` | `string` | `'00000-000'` | Placeholder |
221
+ | `id` | `string` | gerado automaticamente | ID do elemento |
222
+ | `labelVariant` | `'over' \| 'in' \| 'on'` | `'on'` | Variante do FloatLabel |
223
+ | `readonly` | `boolean` | `false` | Impede edição sem desabilitar o controle |
224
+ | `showSearchButton` | `boolean` | `true` | Exibe botão de busca ao lado do campo |
225
+ | `erros` | `Record<string, string>` | `{}` | Mapa de chave de erro → mensagem |
226
+
227
+ | Output | Tipo | Descrição |
228
+ |---|---|---|
229
+ | `busca` | `string` | Emite os 8 dígitos brutos ao completar a máscara ou clicar no botão de busca |
230
+
231
+ Erro de validação: `cepInvalido`
232
+
233
+ ---
234
+
235
+ ### `pjc-cnh-field`
236
+
237
+ Campo de CNH com validação Módulo 11.
238
+
239
+ ```html
240
+ <pjc-cnh-field
241
+ formControlName="cnh"
242
+ label="CNH"
243
+ />
244
+ ```
245
+
246
+ Erro de validação: `cnhInvalida`
247
+
248
+ ---
249
+
250
+ ### `pjc-renavam-field`
251
+
252
+ Campo de RENAVAM com validação Módulo 11.
253
+
254
+ ```html
255
+ <pjc-renavam-field
256
+ formControlName="renavam"
257
+ label="RENAVAM"
258
+ />
50
259
  ```
51
260
 
52
- ## Running end-to-end tests
261
+ Erro de validação: `renavamInvalido`
53
262
 
54
- For end-to-end (e2e) testing, run:
263
+ ---
264
+
265
+ ### `pjc-chassi-field`
266
+
267
+ Campo de chassi/VIN (17 caracteres, alfabeto VIN).
268
+
269
+ ```html
270
+ <pjc-chassi-field
271
+ formControlName="chassi"
272
+ label="Chassi"
273
+ />
274
+ ```
275
+
276
+ Erro de validação: `chassiInvalido`
277
+
278
+ ---
279
+
280
+ ### `pjc-imei-field`
281
+
282
+ Campo de IMEI com validação Luhn (15 dígitos).
283
+
284
+ ```html
285
+ <pjc-imei-field
286
+ formControlName="imei"
287
+ label="IMEI"
288
+ />
289
+ ```
290
+
291
+ Erro de validação: `imeiInvalido`
292
+
293
+ ---
294
+
295
+ ### `pjc-numero-cartao-field`
296
+
297
+ Campo de número de cartão com validação Luhn (13–19 dígitos).
298
+
299
+ ```html
300
+ <pjc-numero-cartao-field
301
+ formControlName="numeroCartao"
302
+ label="Número do Cartão"
303
+ />
304
+ ```
305
+
306
+ Erro de validação: `numeroCartaoInvalido`
307
+
308
+ ---
309
+
310
+ ### `pjc-email-field`
311
+
312
+ Campo de e-mail que converte automaticamente a entrada para minúsculas.
313
+
314
+ ```html
315
+ <pjc-email-field
316
+ formControlName="email"
317
+ label="E-mail"
318
+ />
319
+ ```
320
+
321
+ Erro de validação: `emailInvalido`
322
+
323
+ ---
324
+
325
+ ### `pjc-uppercase-field`
326
+
327
+ Campo de texto com conversão automática para maiúsculas. Ideal para nomes e razão social.
328
+
329
+ ```html
330
+ <pjc-uppercase-field
331
+ formControlName="nome"
332
+ label="Nome Completo"
333
+ placeholder="Digite o nome"
334
+ />
335
+ ```
336
+
337
+ Sem validação própria — sem erro de validação.
338
+
339
+ ---
340
+
341
+ ### `pjc-password-field`
342
+
343
+ Campo de senha com botão de mostrar/ocultar.
344
+
345
+ ```html
346
+ <pjc-password-field
347
+ formControlName="senha"
348
+ label="Senha"
349
+ />
350
+ ```
351
+
352
+ Sem validação própria — use `Validators.minLength` etc. no `FormControl`.
353
+
354
+ ---
355
+
356
+ ### `pjc-moeda-field`
357
+
358
+ Campo de moeda/decimal com acumulação de centavos por teclado (estilo caixa registradora). O valor do controle é `number | null` (`null` quando zero).
359
+
360
+ ```html
361
+ <pjc-moeda-field
362
+ formControlName="valor"
363
+ label="Valor"
364
+ mode="currency"
365
+ currency="BRL"
366
+ />
367
+ ```
368
+
369
+ | Input | Tipo | Padrão | Descrição |
370
+ |---|---|---|---|
371
+ | `label` | `string` | `''` | Rótulo do campo |
372
+ | `hint` | `string` | `''` | Texto de dica |
373
+ | `id` | `string` | gerado automaticamente | ID do elemento |
374
+ | `labelVariant` | `'over' \| 'in' \| 'on'` | `'on'` | Variante do FloatLabel |
375
+ | `mode` | `'currency' \| 'decimal'` | `'currency'` | Modo de exibição |
376
+ | `currency` | `string` | `'BRL'` | Código ISO 4217 da moeda |
377
+ | `locale` | `string` | `'pt-BR'` | Locale para `Intl.NumberFormat` |
378
+ | `minFractionDigits` | `number` | `2` | Casas decimais mínimas |
379
+ | `maxFractionDigits` | `number` | `2` | Casas decimais máximas |
380
+ | `readonly` | `boolean` | `false` | Impede entrada sem desabilitar o controle |
381
+ | `erros` | `Record<string, string>` | `{}` | Mapa de chave de erro → mensagem |
382
+
383
+ Sem validação própria — use `PjcValidators.decimalMaiorZero()` no `FormControl`.
384
+
385
+ ---
386
+
387
+ ### `pjc-integer-field`
388
+
389
+ Campo numérico inteiro (PrimeNG InputNumber com `maxFractionDigits=0`).
390
+
391
+ ```html
392
+ <pjc-integer-field
393
+ formControlName="quantidade"
394
+ label="Quantidade"
395
+ />
396
+ ```
397
+
398
+ Sem validação própria — use `PjcValidators.inteiroMaiorZero()` no `FormControl`.
399
+
400
+ ---
401
+
402
+ ### `pjc-tipo-pessoa-field`
403
+
404
+ Dropdown para tipo de pessoa: `FISICA` ou `JURIDICA`.
405
+
406
+ ```html
407
+ <pjc-tipo-pessoa-field
408
+ formControlName="tipoPessoa"
409
+ label="Tipo de Pessoa"
410
+ />
411
+ ```
412
+
413
+ Sem validação própria.
414
+
415
+ ---
416
+
417
+ ### `pjc-uf-field`
418
+
419
+ Dropdown com todas as 27 UFs brasileiras.
420
+
421
+ ```html
422
+ <pjc-uf-field
423
+ formControlName="uf"
424
+ label="Estado"
425
+ />
426
+ ```
427
+
428
+ Sem validação própria.
429
+
430
+ ---
431
+
432
+ ### `pjc-cidade-field`
433
+
434
+ Autocomplete de município via API do IBGE, filtrável pela UF selecionada.
435
+
436
+ ```html
437
+ <pjc-cidade-field
438
+ formControlName="cidade"
439
+ label="Município"
440
+ [uf]="form.get('uf')?.value"
441
+ />
442
+ ```
443
+
444
+ Sem validação própria.
445
+
446
+ ---
447
+
448
+ ### `pjc-erro-validacao`
449
+
450
+ Componente utilitário que exibe mensagens de erro de validação para um `FormControl` pelo nome dentro de um `FormGroup`. **Não é um campo de formulário** — não implementa `ControlValueAccessor`.
451
+
452
+ ```html
453
+ <form [formGroup]="form">
454
+ <pjc-cpf-field formControlName="cpf" label="CPF" />
455
+ <pjc-erro-validacao
456
+ controlName="cpf"
457
+ [erros]="{ required: 'CPF obrigatório.', cpfInvalido: 'CPF inválido.' }"
458
+ />
459
+ </form>
460
+ ```
461
+
462
+ | Input | Tipo | Obrigatório | Descrição |
463
+ |---|---|---|---|
464
+ | `controlName` | `string` | Sim | Nome do controle no `FormGroup` |
465
+ | `erros` | `Record<string, string>` | Sim | Mapa de chave de erro → mensagem |
466
+
467
+ > **Nota:** não use `[erros]` no próprio campo **e** `pjc-erro-validacao` ao mesmo tempo para o mesmo controle — as mensagens serão duplicadas.
468
+
469
+ ---
470
+
471
+ ## Validadores standalone (`PjcValidators`)
472
+
473
+ Use os validadores de forma independente, sem os componentes, em qualquer `FormControl`.
474
+
475
+ > **Atenção:** os componentes `pjc-*-field` que validam já se registram como `NG_VALIDATORS`. **Não adicione** o `PjcValidators` correspondente ao mesmo `FormControl` — os erros serão duplicados.
476
+
477
+ ```typescript
478
+ import { PjcValidators } from 'pjc-fields';
479
+
480
+ form = new FormGroup({
481
+ cpf: new FormControl('', [PjcValidators.cpf()]),
482
+ cnpj: new FormControl('', [PjcValidators.cnpj()]),
483
+ doc: new FormControl('', [PjcValidators.cpfCnpj()]),
484
+ telefone: new FormControl('', [PjcValidators.telefone()]),
485
+ hora: new FormControl('', [PjcValidators.hora()]),
486
+ placa: new FormControl('', [PjcValidators.placaVeiculo()]),
487
+ email: new FormControl('', [PjcValidators.email()]),
488
+ imei: new FormControl('', [PjcValidators.imei()]),
489
+ cartao: new FormControl('', [PjcValidators.numeroCartao()]),
490
+ renavam: new FormControl('', [PjcValidators.renavam()]),
491
+ chassi: new FormControl('', [PjcValidators.chassi()]),
492
+ cnh: new FormControl('', [PjcValidators.cnh()]),
493
+ cep: new FormControl('', [PjcValidators.cep()]),
494
+ });
495
+ ```
496
+
497
+ ### Validadores de domínio
498
+
499
+ | Método | Erro retornado |
500
+ |---|---|
501
+ | `PjcValidators.cpf()` | `{ cpfInvalido: true }` |
502
+ | `PjcValidators.cnpj()` | `{ cnpjInvalido: true }` |
503
+ | `PjcValidators.cpfCnpj()` | `{ cpfInvalido: true }` ou `{ cnpjInvalido: true }` |
504
+ | `PjcValidators.telefone()` | `{ telefoneInvalido: true }` |
505
+ | `PjcValidators.hora()` | `{ horaInvalida: true }` |
506
+ | `PjcValidators.placaVeiculo()` | `{ placaInvalida: true }` |
507
+ | `PjcValidators.email()` | `{ emailInvalido: true }` |
508
+ | `PjcValidators.imei()` | `{ imeiInvalido: true }` |
509
+ | `PjcValidators.numeroCartao()` | `{ numeroCartaoInvalido: true }` |
510
+ | `PjcValidators.renavam()` | `{ renavamInvalido: true }` |
511
+ | `PjcValidators.chassi()` | `{ chassiInvalido: true }` |
512
+ | `PjcValidators.cnh()` | `{ cnhInvalida: true }` |
513
+ | `PjcValidators.cep()` | `{ cepInvalido: true }` |
514
+
515
+ ### Validadores numéricos
516
+
517
+ Use com `pjc-integer-field`, `pjc-moeda-field` ou `<input type="number">`.
518
+
519
+ #### Inteiros
520
+
521
+ | Método | Erro retornado | Condição |
522
+ |---|---|---|
523
+ | `PjcValidators.inteiroMaiorZero()` | `{ inteiroMaiorZero: true }` | `value ≤ 0` |
524
+ | `PjcValidators.inteiroMaiorIgualZero()` | `{ inteiroMaiorIgualZero: true }` | `value < 0` |
525
+ | `PjcValidators.inteiroMenorZero()` | `{ inteiroMenorZero: true }` | `value ≥ 0` |
526
+ | `PjcValidators.inteiroMenorIgualZero()` | `{ inteiroMenorIgualZero: true }` | `value > 0` |
527
+ | `PjcValidators.inteiroNuloOuMaiorZero()` | `{ inteiroNuloOuMaiorZero: true }` | `value ≤ 0` (null permitido) |
528
+ | `PjcValidators.inteiroNuloOuMaiorIgualZero()` | `{ inteiroNuloOuMaiorIgualZero: true }` | `value < 0` (null permitido) |
529
+ | `PjcValidators.inteiroNuloOuMenorZero()` | `{ inteiroNuloOuMenorZero: true }` | `value ≥ 0` (null permitido) |
530
+ | `PjcValidators.inteiroNuloOuMenorIgualZero()` | `{ inteiroNuloOuMenorIgualZero: true }` | `value > 0` (null permitido) |
531
+
532
+ #### Decimais
533
+
534
+ | Método | Erro retornado | Condição |
535
+ |---|---|---|
536
+ | `PjcValidators.decimalMaiorZero()` | `{ decimalMaiorZero: true }` | `value ≤ 0` |
537
+ | `PjcValidators.decimalMaiorIgualZero()` | `{ decimalMaiorIgualZero: true }` | `value < 0` |
538
+ | `PjcValidators.decimalMenorZero()` | `{ decimalMenorZero: true }` | `value ≥ 0` |
539
+ | `PjcValidators.decimalMenorIgualZero()` | `{ decimalMenorIgualZero: true }` | `value > 0` |
540
+
541
+ ---
542
+
543
+ ## Exibindo erros de validação
544
+
545
+ ### Via input `erros` no próprio campo
546
+
547
+ ```html
548
+ <pjc-cpf-field
549
+ formControlName="cpf"
550
+ label="CPF"
551
+ [erros]="{ required: 'CPF obrigatório.', cpfInvalido: 'CPF inválido.' }"
552
+ />
553
+ ```
554
+
555
+ ### Via `pjc-erro-validacao`
556
+
557
+ ```html
558
+ <pjc-cpf-field formControlName="cpf" label="CPF" />
559
+ <pjc-erro-validacao
560
+ controlName="cpf"
561
+ [erros]="{ required: 'CPF obrigatório.', cpfInvalido: 'CPF inválido.' }"
562
+ />
563
+ ```
564
+
565
+ ### Via template manual
566
+
567
+ ```html
568
+ <pjc-cpf-field formControlName="cpf" label="CPF" />
569
+ @if (form.get('cpf')?.hasError('cpfInvalido') && form.get('cpf')?.touched) {
570
+ <small class="p-error">CPF inválido.</small>
571
+ }
572
+ ```
573
+
574
+ ---
575
+
576
+ ## Documentação para IA (llms.txt)
577
+
578
+ Este repositório inclui documentação no formato AI-ready:
579
+
580
+ - **[llms.txt](llms.txt)** — índice de todos os arquivos de documentação da biblioteca, seguindo o padrão [llms.txt](https://llmstxt.org/).
581
+ - **[docs/kb/](docs/kb/)** — documentação detalhada de cada componente e validador em Markdown, pronta para uso com Claude Projects, Cursor, GitHub Copilot e similares.
582
+
583
+ Para usar com seu assistente de IA:
584
+
585
+ 1. Aponte seu assistente para o arquivo `llms.txt` do repositório, ou
586
+ 2. Cole o conteúdo de `docs/kb/index.md` no contexto do seu projeto.
587
+
588
+ ---
589
+
590
+ ## Desenvolvimento local
55
591
 
56
592
  ```bash
57
- ng e2e
593
+ # Instalar dependências
594
+ npm install
595
+
596
+ # Servidor de desenvolvimento (porta 4200)
597
+ npm start
598
+
599
+ # Executar todos os testes
600
+ npm test
601
+
602
+ # Executar testes apenas da biblioteca
603
+ ng test pjc-fields
604
+
605
+ # Reconstruir a biblioteca e iniciar o demo
606
+ ng build pjc-fields && npm start
58
607
  ```
59
608
 
60
- Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
609
+ ---
61
610
 
62
- ## Additional Resources
611
+ ## Licença
63
612
 
64
- For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
613
+ MIT