@dev-tcloud/tcloud-ui 6.19.0 → 6.19.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.
@@ -4,6 +4,8 @@
4
4
 
5
5
  O componente `tcloud-ui-dropdown` é um componente de seleção versátil com suporte a opções customizáveis, two-way binding, detecção automática de viewport (desktop/mobile) e tooltip para textos elipsados. Implementa comportamento responsivo com menu dropdown em desktop e fullscreen em dispositivos móveis.
6
6
 
7
+ Implementa a interface `ControlValueAccessor` do Angular, sendo compatível com **formulários reativos** (`formControl`, `formControlName`) e **template-driven** (`[(ngModel)]`), incluindo suporte a validadores e ao ciclo `touched`/`dirty`.
8
+
7
9
  ## Instalação
8
10
 
9
11
  Para utilizar o componente Dropdown, importe o módulo `TCloudUiModule`:
@@ -148,6 +150,110 @@ export class AdvancedDropdownComponent {
148
150
  }
149
151
  ```
150
152
 
153
+ ### Uso com Formulários Reativos (formControl / formControlName)
154
+
155
+ ```typescript
156
+ import { Component } from '@angular/core';
157
+ import { TCloudUiModule } from '@tcloud-ui/lib';
158
+ import { CommonModule } from '@angular/common';
159
+ import { ReactiveFormsModule, FormBuilder, FormGroup, Validators } from '@angular/forms';
160
+
161
+ @Component({
162
+ selector: 'app-reactive-dropdown',
163
+ standalone: true,
164
+ imports: [CommonModule, TCloudUiModule, ReactiveFormsModule],
165
+ template: `
166
+ <form [formGroup]="form" (ngSubmit)="onSubmit()">
167
+ <tcloud-ui-dropdown
168
+ formControlName="status"
169
+ [options]="options"
170
+ label="Status"
171
+ ></tcloud-ui-dropdown>
172
+
173
+ <span *ngIf="form.get('status')?.invalid && form.get('status')?.touched">
174
+ Campo obrigatório
175
+ </span>
176
+
177
+ <button type="submit" [disabled]="form.invalid">Enviar</button>
178
+ <button type="button" (click)="form.disable()">Desabilitar formulário</button>
179
+ <button type="button" (click)="form.enable()">Habilitar formulário</button>
180
+ </form>
181
+ `
182
+ })
183
+ export class ReactiveDropdownComponent {
184
+ form: FormGroup;
185
+
186
+ options = [
187
+ { value: 'active', displayValue: 'Ativo' },
188
+ { value: 'inactive', displayValue: 'Inativo' },
189
+ { value: 'pending', displayValue: 'Pendente' },
190
+ ];
191
+
192
+ constructor(private fb: FormBuilder) {
193
+ this.form = this.fb.group({
194
+ status: [null, Validators.required],
195
+ });
196
+ }
197
+
198
+ onSubmit(): void {
199
+ if (this.form.valid) {
200
+ console.log(this.form.value); // { status: 'active' }
201
+ }
202
+ }
203
+ }
204
+ ```
205
+
206
+ > **Nota:** `form.disable()` / `form.enable()` propagam o estado para o componente via `setDisabledState`, sem interferir no input `[disabled]` externo.
207
+
208
+ ### Uso com Template-Driven Forms (ngModel)
209
+
210
+ ```typescript
211
+ import { Component } from '@angular/core';
212
+ import { TCloudUiModule } from '@tcloud-ui/lib';
213
+ import { CommonModule } from '@angular/common';
214
+ import { FormsModule } from '@angular/forms';
215
+
216
+ @Component({
217
+ selector: 'app-ngmodel-dropdown',
218
+ standalone: true,
219
+ imports: [CommonModule, TCloudUiModule, FormsModule],
220
+ template: `
221
+ <form #f="ngForm" (ngSubmit)="onSubmit(f)">
222
+ <tcloud-ui-dropdown
223
+ name="category"
224
+ [(ngModel)]="selectedCategory"
225
+ required
226
+ [options]="options"
227
+ label="Categoria"
228
+ ></tcloud-ui-dropdown>
229
+
230
+ <span *ngIf="f.controls['category']?.invalid && f.controls['category']?.touched">
231
+ Campo obrigatório
232
+ </span>
233
+
234
+ <button type="submit">Enviar</button>
235
+ </form>
236
+
237
+ <p>Valor atual: {{ selectedCategory }}</p>
238
+ `
239
+ })
240
+ export class NgModelDropdownComponent {
241
+ selectedCategory: any = null;
242
+
243
+ options = [
244
+ { value: 'tech', displayValue: 'Tecnologia' },
245
+ { value: 'finance', displayValue: 'Finanças' },
246
+ { value: 'health', displayValue: 'Saúde' },
247
+ ];
248
+
249
+ onSubmit(form: any): void {
250
+ if (form.valid) {
251
+ console.log(this.selectedCategory);
252
+ }
253
+ }
254
+ }
255
+ ```
256
+
151
257
  ### Diferentes Tamanhos
152
258
 
153
259
  ```typescript
@@ -357,13 +463,18 @@ Quando um texto de opção é muito longo e sofre truncamento, o componente auto
357
463
  - **Hover**: Indica que o dropdown pode ser clicado
358
464
  - **Aberto (Desktop)**: Menu dropdown expandido
359
465
  - **Aberto (Mobile)**: Menu fullscreen exibido
360
- - **Desabilitado**: Dropdown indisponível para interação
466
+ - **Desabilitado**: Dropdown indisponível para interação — ativado por `[disabled]="true"` ou por `form.disable()`
361
467
  - **Selecionado**: Opção com fundo destacado e ícone de check
468
+ - **Touched**: Marcado como `touched` ao fechar o dropdown (compatível com validadores)
469
+ - **Dirty**: Marcado como `dirty` ao selecionar uma opção via interação do usuário
362
470
 
363
471
  ## Notas de Implementação
364
472
 
365
- - O componente implementa OnInit e OnChanges para sincronização de valores
473
+ - O componente implementa `OnInit` e `OnChanges` para sincronização de valores
366
474
  - Utiliza signals do Angular 16+ para reatividade
367
- - Suporta tanto `initialValue` (deprecated) quanto `value` (dois-way binding)
475
+ - Suporta tanto `initialValue` (deprecated) quanto `value` (two-way binding)
368
476
  - O seletor CSS é sensível a eventos de clique no documento para fechar o dropdown
369
477
  - A largura padrão é 100% do elemento pai, podendo ser customizada
478
+ - Implementa `ControlValueAccessor` — compatível com `formControl`, `formControlName` e `[(ngModel)]`
479
+ - O estado `disabled` do formulário (`setDisabledState`) é gerenciado por um signal interno, sem sobrescrever o input `[disabled]` externo; ambos coexistem
480
+ - `writeValue` não dispara `onChangeCallback`, evitando que o formulário seja marcado como `dirty` em atualizações programáticas (`patchValue`, `setValue`, `reset`)