@vipsolucoes/dynamic-form 1.0.2

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 ADDED
@@ -0,0 +1,405 @@
1
+ # @vipsolucoes/dynamic-form
2
+
3
+ Biblioteca Angular para criação de formulários dinâmicos baseados em configuração, construída com PrimeNG e Reactive Forms.
4
+
5
+ ## 📦 Instalação
6
+
7
+ ```bash
8
+ npm install @vipsolucoes/dynamic-form
9
+ ```
10
+
11
+ ### Dependências
12
+
13
+ Esta biblioteca requer as seguintes dependências peer:
14
+
15
+ - `@angular/core`: ^19.0.0 || ^20.0.0 || ^21.0.0
16
+ - `@angular/common`: ^19.0.0 || ^20.0.0 || ^21.0.0
17
+ - `@angular/forms`: ^19.0.0 || ^20.0.0 || ^21.0.0
18
+ - `primeng`: ^19.0.0 || ^20.0.0 || ^21.0.0
19
+
20
+ ## 🚀 Uso Básico
21
+
22
+ ### 1. Importe o módulo no seu componente
23
+
24
+ ```typescript
25
+ import { Component } from '@angular/core';
26
+ import { FormGroup } from '@angular/forms';
27
+ import { DynamicFormComponent, iFormConfig } from '@vipsolucoes/dynamic-form';
28
+ import { Validators } from '@angular/forms';
29
+
30
+ @Component({
31
+ selector: 'app-example',
32
+ standalone: true,
33
+ imports: [DynamicFormComponent],
34
+ template: `
35
+ <vp-dynamic-form [config]="formConfig" (formReady)="onFormReady($event)"> </vp-dynamic-form>
36
+ `,
37
+ })
38
+ export class ExampleComponent {
39
+ formConfig: iFormConfig[] = [
40
+ {
41
+ key: 'nome',
42
+ controlType: 'text',
43
+ label: 'Nome',
44
+ placeholder: 'Digite seu nome',
45
+ validators: [Validators.required, Validators.minLength(3)],
46
+ },
47
+ {
48
+ key: 'email',
49
+ controlType: 'email',
50
+ label: 'E-mail',
51
+ placeholder: 'Digite seu e-mail',
52
+ validators: [Validators.required, Validators.email],
53
+ },
54
+ {
55
+ key: 'idade',
56
+ controlType: 'number',
57
+ label: 'Idade',
58
+ validators: [Validators.required, Validators.min(18)],
59
+ },
60
+ ];
61
+
62
+ onFormReady(form: FormGroup): void {
63
+ console.log('Formulário pronto:', form);
64
+ // Acesse o formulário e seus valores
65
+ form.valueChanges.subscribe((values) => {
66
+ console.log('Valores do formulário:', values);
67
+ });
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### 2. Controle de Submissão
73
+
74
+ O componente **não possui botão de submit interno**. O controle de submissão deve ser feito pelo componente pai usando `@ViewChild`:
75
+
76
+ ```typescript
77
+ import { Component, ViewChild } from '@angular/core';
78
+ import { DynamicFormComponent } from '@vipsolucoes/dynamic-form';
79
+ import { FormGroup } from '@angular/forms';
80
+
81
+ @Component({
82
+ selector: 'app-example',
83
+ standalone: true,
84
+ imports: [DynamicFormComponent],
85
+ template: `
86
+ <vp-dynamic-form #myForm [config]="formConfig" />
87
+ <button (click)="onSubmit()">Enviar</button>
88
+ `,
89
+ })
90
+ export class ExampleComponent {
91
+ @ViewChild('myForm') myForm!: DynamicFormComponent;
92
+
93
+ formConfig: iFormConfig[] = [
94
+ // ... sua configuração
95
+ ];
96
+
97
+ onSubmit(): void {
98
+ if (this.myForm.form.valid) {
99
+ console.log('Dados:', this.myForm.form.value);
100
+ // Enviar dados ao backend
101
+ } else {
102
+ this.myForm.form.markAllAsTouched();
103
+ }
104
+ }
105
+ }
106
+ ```
107
+
108
+ ## 📝 Tipos de Campos Suportados
109
+
110
+ A biblioteca suporta os seguintes tipos de campos:
111
+
112
+ - `text` - Campo de texto
113
+ - `email` - Campo de e-mail
114
+ - `password` - Campo de senha
115
+ - `number` - Campo numérico
116
+ - `select` - Dropdown/Select
117
+ - `datepicker` - Seletor de data
118
+ - `textarea` - Área de texto
119
+ - `toggleswitch` - Switch/Toggle
120
+
121
+ ## 🎯 Exemplos de Configuração
122
+
123
+ ### Campo de Texto
124
+
125
+ ```typescript
126
+ {
127
+ key: 'nome',
128
+ controlType: 'text',
129
+ label: 'Nome Completo',
130
+ placeholder: 'Digite seu nome',
131
+ value: '', // Valor inicial
132
+ hint: 'Este campo é obrigatório',
133
+ validators: [Validators.required]
134
+ }
135
+ ```
136
+
137
+ ### Campo Select
138
+
139
+ ```typescript
140
+ {
141
+ key: 'pais',
142
+ controlType: 'select',
143
+ label: 'País',
144
+ placeholder: 'Selecione um país',
145
+ options: [
146
+ { label: 'Brasil', value: 'BR' },
147
+ { label: 'Estados Unidos', value: 'US' },
148
+ { label: 'Portugal', value: 'PT' }
149
+ ],
150
+ validators: [Validators.required]
151
+ }
152
+ ```
153
+
154
+ ### Campo DatePicker
155
+
156
+ ```typescript
157
+ {
158
+ key: 'dataNascimento',
159
+ controlType: 'datepicker',
160
+ label: 'Data de Nascimento',
161
+ dateFormat: 'dd/mm/yy',
162
+ dateViewType: 'date', // 'date' | 'month' | 'year'
163
+ validators: [Validators.required]
164
+ }
165
+ ```
166
+
167
+ ### Campo Textarea
168
+
169
+ ```typescript
170
+ {
171
+ key: 'observacoes',
172
+ controlType: 'textarea',
173
+ label: 'Observações',
174
+ placeholder: 'Digite suas observações',
175
+ textareaAutoResize: true,
176
+ textareaRows: 5,
177
+ validators: [Validators.maxLength(500)]
178
+ }
179
+ ```
180
+
181
+ ### Campo ToggleSwitch
182
+
183
+ ```typescript
184
+ {
185
+ key: 'aceitaTermos',
186
+ controlType: 'toggleswitch',
187
+ label: 'Aceito os termos e condições',
188
+ value: false,
189
+ toggleTrueValue: true,
190
+ toggleFalseValue: false
191
+ }
192
+ ```
193
+
194
+ ### Campos Condicionais
195
+
196
+ Você pode fazer campos serem habilitados/desabilitados baseado no valor de um toggle switch:
197
+
198
+ ```typescript
199
+ {
200
+ key: 'notificacoes',
201
+ controlType: 'toggleswitch',
202
+ label: 'Receber notificações'
203
+ },
204
+ {
205
+ key: 'emailNotificacao',
206
+ controlType: 'email',
207
+ label: 'E-mail para notificações',
208
+ placeholder: 'Digite seu e-mail',
209
+ enabledWhen: 'notificacoes', // Campo será habilitado quando 'notificacoes' for true
210
+ validators: [Validators.required, Validators.email]
211
+ }
212
+ ```
213
+
214
+ ### Layout Customizado com styleClass
215
+
216
+ Use a propriedade `styleClass` para criar layouts customizados em grid:
217
+
218
+ ```typescript
219
+ const layoutConfig: iFormConfig[] = [
220
+ {
221
+ key: 'firstName',
222
+ controlType: 'text',
223
+ label: 'Primeiro Nome',
224
+ validators: [Validators.required],
225
+ styleClass: 'grid-col-6', // Ocupa 6 colunas (50%)
226
+ },
227
+ {
228
+ key: 'lastName',
229
+ controlType: 'text',
230
+ label: 'Sobrenome',
231
+ validators: [Validators.required],
232
+ styleClass: 'grid-col-6', // Ocupa 6 colunas (50%)
233
+ },
234
+ {
235
+ key: 'email',
236
+ controlType: 'email',
237
+ label: 'E-mail',
238
+ validators: [Validators.required, Validators.email],
239
+ styleClass: 'grid-col-12', // Ocupa 12 colunas (100%)
240
+ },
241
+ ];
242
+ ```
243
+
244
+ Você precisará definir as classes CSS no seu componente ou globalmente:
245
+
246
+ ```css
247
+ .form-grid-layout {
248
+ display: grid;
249
+ grid-template-columns: repeat(12, 1fr);
250
+ gap: 1rem;
251
+ }
252
+
253
+ .grid-col-12 {
254
+ grid-column: span 12;
255
+ }
256
+ .grid-col-6 {
257
+ grid-column: span 6;
258
+ }
259
+ .grid-col-4 {
260
+ grid-column: span 4;
261
+ }
262
+ .grid-col-3 {
263
+ grid-column: span 3;
264
+ }
265
+ ```
266
+
267
+ ## 🔧 API
268
+
269
+ ### DynamicFormComponent
270
+
271
+ #### Inputs
272
+
273
+ - `config: iFormConfig[]` (obrigatório) - Array com a configuração dos campos do formulário
274
+
275
+ #### Outputs
276
+
277
+ - `formReady: FormGroup` - Emite o FormGroup quando o formulário está pronto
278
+
279
+ #### Métodos Públicos
280
+
281
+ - `getControl(key: string): AbstractControl` - Obtém um controle do formulário pela chave
282
+
283
+ ### Interface iFormConfig
284
+
285
+ ```typescript
286
+ interface iFormConfig {
287
+ key: string; // Identificador único do campo
288
+ controlType:
289
+ | 'text'
290
+ | 'password'
291
+ | 'email'
292
+ | 'number'
293
+ | 'select'
294
+ | 'datepicker'
295
+ | 'textarea'
296
+ | 'toggleswitch';
297
+ label: string; // Texto do label
298
+ value?: any; // Valor inicial
299
+ placeholder?: string; // Texto de placeholder
300
+ hint?: string; // Texto de ajuda
301
+ disabled?: boolean; // Campo desabilitado
302
+ enabledWhen?: string; // Chave do toggle que controla este campo
303
+ styleClass?: string; // Classes CSS customizadas
304
+ options?: iFieldOption[]; // Opções para select (obrigatório se controlType for 'select')
305
+ validators?: ValidatorFn[]; // Validadores Angular
306
+ dateFormat?: string; // Formato da data (default: 'dd/mm/yy')
307
+ dateViewType?: 'date' | 'month' | 'year'; // Tipo de visualização da data (default: 'date')
308
+ textareaAutoResize?: boolean; // Auto-resize do textarea (default: false)
309
+ textareaRows?: number; // Número de linhas do textarea
310
+ textareaCols?: number; // Número de colunas do textarea
311
+ toggleTrueValue?: any; // Valor quando toggle está ativo (default: true)
312
+ toggleFalseValue?: any; // Valor quando toggle está inativo (default: false)
313
+ }
314
+ ```
315
+
316
+ ## 🎨 Customização de Campos
317
+
318
+ Você pode registrar campos customizados usando o `FieldRegistryService`:
319
+
320
+ ```typescript
321
+ import { FieldRegistryService } from '@vipsolucoes/dynamic-form';
322
+ import { CustomFieldComponent } from './custom-field.component';
323
+
324
+ export class AppComponent {
325
+ constructor(private fieldRegistry: FieldRegistryService) {
326
+ // Registra um campo customizado
327
+ this.fieldRegistry.registerField('custom', CustomFieldComponent);
328
+ }
329
+ }
330
+ ```
331
+
332
+ Depois, use o tipo customizado na configuração:
333
+
334
+ ```typescript
335
+ {
336
+ key: 'campoCustom',
337
+ controlType: 'custom',
338
+ label: 'Campo Customizado'
339
+ }
340
+ ```
341
+
342
+ ## 🌐 Customização de Mensagens de Erro
343
+
344
+ Você pode personalizar as mensagens de erro através do provider:
345
+
346
+ ```typescript
347
+ import { provideDynamicFormConfig } from '@vipsolucoes/dynamic-form';
348
+ import { ApplicationConfig } from '@angular/core';
349
+
350
+ export const appConfig: ApplicationConfig = {
351
+ providers: [
352
+ provideDynamicFormConfig({
353
+ required: 'Este campo é obrigatório',
354
+ email: 'E-mail inválido',
355
+ minlength: (requiredLength: number) => `Mínimo de ${requiredLength} caracteres necessários`,
356
+ maxlength: (requiredLength: number) => `Máximo de ${requiredLength} caracteres permitidos`,
357
+ custom: (error: any) => error.message || 'Erro de validação',
358
+ }),
359
+ ],
360
+ };
361
+ ```
362
+
363
+ **Nota:** As mensagens `minlength` e `maxlength` são funções que recebem o comprimento requerido como parâmetro. A função `custom` permite tratar erros de validação personalizados.
364
+
365
+ ## 🌐 Internacionalização (PT-BR)
366
+
367
+ A biblioteca já disponibiliza uma tradução completa para português do Brasil das mensagens padrão do PrimeNG, garantindo consistência de idioma em todos os componentes (DatePicker, Table, Dialog, FileUpload, etc.).
368
+
369
+ Para habilitar a tradução globalmente na aplicação, basta utilizar o provider do PrimeNG conforme o exemplo abaixo:
370
+
371
+ ```typescript
372
+ import { PRIMENG_PTBR } from '@vipsolucoes/dynamic-form';
373
+
374
+ providePrimeNG({
375
+ translation: PRIMENG_PTBR,
376
+ });
377
+ ```
378
+
379
+ **Nota:** a tradução é aplicada de forma global e deve ser configurada durante o bootstrap da aplicação.
380
+
381
+ ## 🛠️ Desenvolvimento
382
+
383
+ ### Build da biblioteca
384
+
385
+ ```bash
386
+ ng build dynamic-form
387
+ ```
388
+
389
+ ### Publicação no npm
390
+
391
+ Após o build:
392
+
393
+ ```bash
394
+ cd dist/dynamic-form
395
+ npm publish
396
+ ```
397
+
398
+ ## 📄 Licença
399
+
400
+ MIT
401
+
402
+ ## 🔗 Links
403
+
404
+ - [Repositório](https://github.com/vipsolucoes/dynamic-form)
405
+ - [Issues](https://github.com/vipsolucoes/dynamic-form/issues)