@dev-tcloud/tcloud-ui 6.14.3 → 6.17.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.
Files changed (92) hide show
  1. package/docs/tcloud-ui-accordion.md +345 -0
  2. package/docs/tcloud-ui-actions.md +88 -0
  3. package/docs/tcloud-ui-alert-banner.md +104 -0
  4. package/docs/tcloud-ui-array-to-text.md +361 -0
  5. package/docs/tcloud-ui-breadcrumb.md +103 -0
  6. package/docs/tcloud-ui-bytes.md +109 -0
  7. package/docs/tcloud-ui-calendar.md +387 -0
  8. package/docs/tcloud-ui-card-accordion.md +266 -0
  9. package/docs/tcloud-ui-card-title.md +47 -0
  10. package/docs/tcloud-ui-card.md +40 -0
  11. package/docs/tcloud-ui-choice-issues.md +59 -0
  12. package/docs/tcloud-ui-cnpj.md +102 -0
  13. package/docs/tcloud-ui-container.md +171 -0
  14. package/docs/tcloud-ui-cpf.md +102 -0
  15. package/docs/tcloud-ui-currency.md +271 -0
  16. package/docs/tcloud-ui-data-list.md +91 -0
  17. package/docs/tcloud-ui-datebr.md +139 -0
  18. package/docs/tcloud-ui-datepicker-time.md +191 -0
  19. package/docs/tcloud-ui-datepicker.md +186 -0
  20. package/docs/tcloud-ui-dropdown-multi.md +444 -0
  21. package/docs/tcloud-ui-dropdown.md +369 -0
  22. package/docs/tcloud-ui-el-copy.md +113 -0
  23. package/docs/tcloud-ui-empty-content.md +412 -0
  24. package/docs/tcloud-ui-faq.md +496 -0
  25. package/docs/tcloud-ui-filter-bar.md +86 -0
  26. package/docs/tcloud-ui-filters.md +337 -0
  27. package/docs/tcloud-ui-hover-parent.md +467 -0
  28. package/docs/tcloud-ui-icon-button.md +104 -0
  29. package/docs/tcloud-ui-input-container.md +520 -0
  30. package/docs/tcloud-ui-input-password.md +258 -0
  31. package/docs/tcloud-ui-input-search.md +314 -0
  32. package/docs/tcloud-ui-label-token.md +286 -0
  33. package/docs/tcloud-ui-legend.md +72 -0
  34. package/docs/tcloud-ui-line-step-circle.md +98 -0
  35. package/docs/tcloud-ui-line-step-title.md +194 -0
  36. package/docs/tcloud-ui-linha-logo.md +550 -0
  37. package/docs/tcloud-ui-loading.md +88 -0
  38. package/docs/tcloud-ui-message.md +539 -0
  39. package/docs/tcloud-ui-modal.md +196 -0
  40. package/docs/tcloud-ui-monthname.md +123 -0
  41. package/docs/tcloud-ui-multi-input.md +290 -0
  42. package/docs/tcloud-ui-multi-select.md +311 -0
  43. package/docs/tcloud-ui-multiples-values.md +157 -0
  44. package/docs/tcloud-ui-not-found.md +88 -0
  45. package/docs/tcloud-ui-number-step.md +134 -0
  46. package/docs/tcloud-ui-pagination.md +579 -0
  47. package/docs/tcloud-ui-progress-bar.md +65 -0
  48. package/docs/tcloud-ui-radio.md +83 -0
  49. package/docs/tcloud-ui-reorder-items.md +418 -0
  50. package/docs/tcloud-ui-respective.md +167 -0
  51. package/docs/tcloud-ui-scroll-box.md +109 -0
  52. package/docs/tcloud-ui-search-bar.md +88 -0
  53. package/docs/tcloud-ui-search-in-object.md +143 -0
  54. package/docs/tcloud-ui-search-input.md +74 -0
  55. package/docs/tcloud-ui-skeleton-loading.md +394 -0
  56. package/docs/tcloud-ui-slide-toggle.md +210 -0
  57. package/docs/tcloud-ui-statusinfo.md +138 -0
  58. package/docs/tcloud-ui-tab-group.md +376 -0
  59. package/docs/tcloud-ui-tab-menu.md +109 -0
  60. package/docs/tcloud-ui-table.md +96 -0
  61. package/docs/tcloud-ui-tag.md +379 -0
  62. package/docs/tcloud-ui-tc-badge.md +168 -0
  63. package/docs/tcloud-ui-tc-btn.md +189 -0
  64. package/docs/tcloud-ui-tc-colors.md +204 -0
  65. package/docs/tcloud-ui-tc-form-control.md +200 -0
  66. package/docs/tcloud-ui-tc-text.md +139 -0
  67. package/docs/tcloud-ui-tc-title.md +118 -0
  68. package/docs/tcloud-ui-tcloud-form.md +55 -0
  69. package/docs/tcloud-ui-toast.md +83 -0
  70. package/docs/tcloud-ui-tooltip.md +88 -0
  71. package/docs/tcloud-ui-topology.md +232 -0
  72. package/docs/tcloud-ui-upload-area.md +195 -0
  73. package/docs/tcloud-ui-welcome.md +112 -0
  74. package/docs/tcloud-ui-wizard-steps.md +103 -0
  75. package/js/tcloud-ui-app.js +11 -0
  76. package/package.json +1 -1
  77. package/scss/tcloud-ui/styles/_claus-badge.scss +117 -0
  78. package/scss/tcloud-ui/styles/_claus-btn.scss +207 -0
  79. package/scss/tcloud-ui/styles/_claus-card.scss +12 -0
  80. package/scss/tcloud-ui/styles/_claus-colors.scss +192 -0
  81. package/scss/tcloud-ui/styles/_claus-form.scss +88 -0
  82. package/scss/tcloud-ui/styles/_claus-sizes.scss +28 -0
  83. package/scss/tcloud-ui/styles/_claus-spacers.scss +49 -0
  84. package/scss/tcloud-ui/styles/_claus-themes.scss +36 -0
  85. package/scss/tcloud-ui/styles/_claus-title.scss +24 -0
  86. package/scss/tcloud-ui/styles/_claus-typography.scss +70 -0
  87. package/scss/tcloud-ui/styles/_claus-variables.scss +131 -0
  88. package/scss/tcloud-ui/styles/_colors.scss +123 -0
  89. package/scss/tcloud-ui/styles/_tc-btn.scss +210 -0
  90. package/scss/tcloud-ui/styles/_tc-card.scss +7 -0
  91. package/scss/tcloud-ui/styles/_tc-title.scss +49 -0
  92. package/scss/tcloud-ui/styles.scss +35 -0
@@ -0,0 +1,579 @@
1
+ # TCloud UI Pagination
2
+
3
+ Componente Angular standalone para paginação com suporte a múltiplas instâncias independentes e detecção automática de mudanças de dados.
4
+
5
+ ## Características
6
+
7
+ - ✅ **Múltiplas instâncias independentes** - Cada paginação funciona isoladamente
8
+ - ✅ **Detecção automática de filtros** - Reseta para página 1 quando dados mudam
9
+ - ✅ **ChangeDetection OnPush** - Otimizado para performance
10
+ - ✅ **Pipe para fatiar dados** - `TCloudUiPagination` pipe integrado
11
+ - ✅ **Serviço reativo** - Baseado em RxJS Subjects
12
+
13
+ ## Instalação
14
+
15
+ O componente já está disponível no módulo `TCloudUiModule`:
16
+
17
+ ```typescript
18
+ import { TCloudUiModule } from 'projects/tcloud-ui/src/public-api';
19
+
20
+ @NgModule({
21
+ imports: [TCloudUiModule]
22
+ })
23
+ export class MyModule { }
24
+ ```
25
+
26
+ Ou importar direto o componente (standalone):
27
+
28
+ ```typescript
29
+ import { TCloudUiPaginationComponent } from 'projects/tcloud-ui/src/lib/_modules/tcloud-ui-pagination/tcloud-ui-pagination.component';
30
+ import { TCloudUiPaginationPipe } from 'projects/tcloud-ui/src/lib/_modules/tcloud-ui-pagination/pipes/tcloud-ui-pagination.pipe';
31
+
32
+ @Component({
33
+ imports: [TCloudUiPaginationComponent, TCloudUiPaginationPipe]
34
+ })
35
+ ```
36
+
37
+ ## Uso Básico
38
+
39
+ ### 1. Exemplo Simple - Uma Paginação
40
+
41
+ ```typescript
42
+ // Componente TypeScript
43
+ export class MyComponent {
44
+ items = [
45
+ { name: "Item 1", value: 100 },
46
+ { name: "Item 2", value: 200 },
47
+ // ...
48
+ ];
49
+
50
+ currentPage: number = 1;
51
+ itemsPerPage: number = 5;
52
+
53
+ onPageChange(newPage: number) {
54
+ this.currentPage = newPage;
55
+ }
56
+ }
57
+ ```
58
+
59
+ ```html
60
+ <!-- Template HTML -->
61
+ <table>
62
+ <tr *ngFor="let item of items | TCloudUiPagination: {
63
+ currentPage: currentPage,
64
+ itemsPerPage: itemsPerPage,
65
+ id: 'my-pagination'
66
+ }">
67
+ <td>{{ item.name }}</td>
68
+ <td>{{ item.value }}</td>
69
+ </tr>
70
+ </table>
71
+
72
+ <tcloud-ui-pagination
73
+ [id]="'my-pagination'"
74
+ [currentPage]="currentPage"
75
+ (pageChange)="onPageChange($event)">
76
+ </tcloud-ui-pagination>
77
+ ```
78
+
79
+ ### 2. Exemplo Avançado - Múltiplas Paginações Independentes
80
+
81
+ ```typescript
82
+ export class MyComponent {
83
+ // Primeira tabela
84
+ items: any[] = [/* dados */];
85
+ currentPage: number = 1;
86
+ itemsPerPage: number = 4;
87
+
88
+ // Segunda tabela (com filtro)
89
+ resultItems: any[] = [];
90
+ currentPage2: number = 1;
91
+ itemsPerPage2: number = 3;
92
+
93
+ onPageChange(newPage: number) {
94
+ this.currentPage = newPage;
95
+ }
96
+
97
+ onPageChange2(newPage: number) {
98
+ this.currentPage2 = newPage;
99
+ }
100
+
101
+ searchInItems(event: any) {
102
+ const search = event?.target?.value;
103
+ // Filtrar dados
104
+ this.resultItems = this.items.filter(item =>
105
+ item.name.toLowerCase().includes(search.toLowerCase())
106
+ );
107
+ // currentPage2 será resetado automaticamente pelo pipe
108
+ }
109
+ }
110
+ ```
111
+
112
+ ```html
113
+ <!-- Primeira Tabela -->
114
+ <table>
115
+ <tr *ngFor="let item of items | TCloudUiPagination: {
116
+ currentPage: currentPage,
117
+ itemsPerPage: itemsPerPage,
118
+ id: 'pagination-1'
119
+ }">
120
+ <td>{{ item.name }}</td>
121
+ </tr>
122
+ </table>
123
+
124
+ <tcloud-ui-pagination
125
+ [id]="'pagination-1'"
126
+ [currentPage]="currentPage"
127
+ (pageChange)="onPageChange($event)">
128
+ </tcloud-ui-pagination>
129
+
130
+ <hr>
131
+
132
+ <!-- Filtro -->
133
+ <input type="text" placeholder="Buscar..." (input)="searchInItems($event)">
134
+
135
+ <!-- Segunda Tabela (com Filtro) -->
136
+ <table>
137
+ <tr *ngFor="let item of resultItems | TCloudUiPagination: {
138
+ currentPage: currentPage2,
139
+ itemsPerPage: itemsPerPage2,
140
+ id: 'result-pagination'
141
+ }">
142
+ <td>{{ item.name }}</td>
143
+ </tr>
144
+ </table>
145
+
146
+ <tcloud-ui-pagination
147
+ [id]="'result-pagination'"
148
+ [currentPage]="currentPage2"
149
+ (pageChange)="onPageChange2($event)">
150
+ </tcloud-ui-pagination>
151
+ ```
152
+
153
+ ## API
154
+
155
+ ### Componente: `tcloud-ui-pagination`
156
+
157
+ #### Inputs
158
+
159
+ | Propriedade | Tipo | Padrão | Descrição | Obrigatório |
160
+ |-----------|------|--------|-----------|---|
161
+ | `id` | `string` | Auto-gerado se não fornecido | ID único para sincronização entre pipe e componente | ❌ |
162
+ | `currentPage` | `number` | `1` | Página atual (1-based index: 1, 2, 3...) | ❌ |
163
+
164
+ #### Outputs
165
+
166
+ | Propriedade | Tipo | Descrição |
167
+ |-----------|------|-----------|
168
+ | `pageChange` | `EventEmitter<number>` | Emitido quando a página muda |
169
+
170
+ #### Propriedades Públicas (Getters)
171
+
172
+ | Propriedade | Tipo | Descrição | Writable |
173
+ |-----------|------|-----------|---|
174
+ | `totalPages` | `number` | Total de páginas calculado pelo serviço | ❌ |
175
+ | `pageInputError` | `boolean` | Indica erro na entrada do campo 'ir para página' | ❌ |
176
+
177
+ #### Métodos
178
+
179
+ | Método | Descrição |
180
+ |--------|-----------|
181
+ | `previous(): void` | Navega para a página anterior (se não estiver na página 1) |
182
+ | `next(): void` | Navega para a próxima página (se não estiver na última) |
183
+ | `goToPage(event: Event): void` | Extrai page do input e navega; valida limites (1 até totalPages) |
184
+ | `formatPage(page: number): string` | Formata com zero à esquerda (ex: 05, 10, 25) |
185
+ | `getTotal(): IPagination` | Retorna objeto com dados de paginação desta instância do serviço |
186
+
187
+ ### Pipe: `TCloudUiPagination`
188
+
189
+ Fatia um array baseado na paginação.
190
+
191
+ #### Parâmetro
192
+
193
+ ```typescript
194
+ TCloudUiPagination: {
195
+ currentPage: number; // Página atual
196
+ itemsPerPage: number; // Itens por página
197
+ id?: string; // ID único (opcional, padrão: '1')
198
+ }
199
+ ```
200
+
201
+ #### Retorno
202
+
203
+ Array com os itens paginados.
204
+
205
+ ### Serviço: `TCloudUiPaginationService`
206
+
207
+ Gerencia o estado de paginação de múltiplas instâncias de forma centralizada usando Map(id → estado).
208
+
209
+ #### Propriedades Públicas
210
+
211
+ | Propriedade | Tipo | Descrição | Uso |
212
+ |-----------|------|-----------|---|
213
+ | `stateTotal$` | `BehaviorSubject<IPagination[]>` | Emite array de estados de paginação sempre que houver mudanças; subscribers recebem histórico | Pipe e componente escutam |
214
+ | `collectionChanged$` | `Subject<string>` | Emite ID da coleção que mudou (detectado pelo pipe) | Notificação de mudança de dados |
215
+
216
+ #### Métodos
217
+
218
+ | Método | Descrição |
219
+ |--------|-----------|
220
+ | `set_total(args: {id?, currentPage, itemsPerPage}, total: number): void` | Cria ou atualiza entrada no Map de paginações; emite via `stateTotal$` |
221
+ | `get_total(): IPagination[]` | Retorna array de todas as paginações armazenadas |
222
+ | `resetToFirstPage(id: string): void` | Reseta página específica para 1 e emite |
223
+ | `notifyCollectionChange(id: string): void` | Emite via `collectionChanged$` para notificar mudança de tamanho |
224
+
225
+ ## Comportamento Detalhado
226
+
227
+ ### 1. Fluxo de Detecção Automática (Quando Filtro é Aplicado)
228
+
229
+ ```
230
+ Filtro: this.resultItems = items.filter(...)
231
+
232
+ Pipe detecta: array.length diferente
233
+
234
+ Pipe reseta: args.currentPage = 1
235
+
236
+ Pipe chama: service.notifyCollectionChange(id)
237
+
238
+ Serviço emite: collectionChanged$ → {id}
239
+
240
+ Componente escuta: markForCheck() ativado
241
+
242
+ Template renderiza: página 1 dos novos dados
243
+ ```
244
+
245
+ **Função do Map no Pipe:**
246
+ ```typescript
247
+ private _previousLengths: Map<string, number> = new Map();
248
+
249
+ // Detecta se tamanho mudou:
250
+ if (previousLength !== currentLength && previousLength > 0) {
251
+ args.currentPage = 1; // Reset automático
252
+ service.notifyCollectionChange(args.id); // Notifica
253
+ }
254
+ ```
255
+
256
+ ### 2. Sincronização de Múltiplas Instâncias
257
+
258
+ Cada instância precisa de um `id` único, que é o mesmo tanto no pipe quanto no componente:
259
+
260
+ ```typescript
261
+ // Primeira instância
262
+ items | TCloudUiPagination: { currentPage: currentPage, itemsPerPage: 4, id: 'pagination-1' }
263
+ <tcloud-ui-pagination [id]="'pagination-1'" ...></tcloud-ui-pagination>
264
+
265
+ // Segunda instância (independente)
266
+ resultItems | TCloudUiPagination: { currentPage: currentPage2, itemsPerPage: 3, id: 'result-pagination' }
267
+ <tcloud-ui-pagination [id]="'result-pagination'" ...></tcloud-ui-pagination>
268
+ ```
269
+
270
+ **Armazenamento no Serviço:**
271
+ ```
272
+ TCloudUiPaginationService
273
+ ├─ Map<'pagination-1', {total: 3, current: 1, ...}>
274
+ └─ Map<'result-pagination', {total: 2, current: 1, ...}>
275
+ ```
276
+
277
+ **Resultado:**
278
+ - ✅ Navegação independente em cada tabela
279
+ - ✅ Filtro de uma não afeta a outra
280
+ - ✅ Cada instance pode ter itemsPerPage diferente
281
+ - ✅ Resets automáticos funcionam isoladamente
282
+
283
+ ## Performance e ChangeDetection
284
+
285
+ ### OnPush Strategy
286
+
287
+ O componente usa `ChangeDetectionStrategy.OnPush` para otimização:
288
+
289
+ ```typescript
290
+ @Component({
291
+ selector: 'tcloud-ui-pagination',
292
+ changeDetection: ChangeDetectionStrategy.OnPush, // ← Apenas detecta quando @Input muda
293
+ standalone: true,
294
+ })
295
+ export class TCloudUiPaginationComponent { }
296
+ ```
297
+
298
+ **Comportamento:**
299
+ - Só detecta mudanças quando `@Input` é alterado
300
+ - Quando serviço emite, componente chama `markForCheck()` manualmente
301
+ - Promove performance em listas grandes
302
+ - Requer cuidado ao emitir eventos (use `Promise.resolve().then()`)
303
+
304
+ **Emissão de Eventos com Segurança:**
305
+ ```typescript
306
+ // ❌ Causa ExpressionChangedAfterItHasBeenCheckedError
307
+ this.pageChange.emit(1);
308
+
309
+ // ✅ Seguro - Deferred to next microtask
310
+ Promise.resolve().then(() => {
311
+ this.pageChange.emit(1);
312
+ });
313
+ ```
314
+
315
+ ## Exemplo Completo com Tipos
316
+
317
+ ```typescript
318
+ import { Component, OnInit } from '@angular/core';
319
+ import { CommonModule } from '@angular/common';
320
+ import { TCloudUiPaginationComponent, TCloudUiPaginationPipe } from 'projects/tcloud-ui/src/public-api';
321
+
322
+ interface Item {
323
+ id: number;
324
+ name: string;
325
+ value: number;
326
+ }
327
+
328
+ @Component({
329
+ selector: 'app-pagination-demo',
330
+ standalone: true,
331
+ imports: [CommonModule, TCloudUiPaginationComponent, TCloudUiPaginationPipe],
332
+ template: `
333
+ <div class="container">
334
+ <h2>Tabela Principal</h2>
335
+ <table>
336
+ <thead>
337
+ <tr>
338
+ <th>#</th>
339
+ <th>Nome</th>
340
+ <th>Valor</th>
341
+ </tr>
342
+ </thead>
343
+ <tbody>
344
+ <tr *ngFor="let item of items | TCloudUiPagination: paginationConfig1; let i = index">
345
+ <td>{{ (currentPage - 1) * paginationConfig1.itemsPerPage + i + 1 }}</td>
346
+ <td>{{ item.name }}</td>
347
+ <td>{{ item.value }}</td>
348
+ </tr>
349
+ </tbody>
350
+ </table>
351
+
352
+ <tcloud-ui-pagination
353
+ [id]="'table-1'"
354
+ [currentPage]="currentPage"
355
+ (pageChange)="onPageChange1($event)">
356
+ </tcloud-ui-pagination>
357
+
358
+ <hr>
359
+
360
+ <h2>Tabela com Filtro</h2>
361
+ <input
362
+ type="text"
363
+ placeholder="Filtrar..."
364
+ (input)="onFilter($event)">
365
+
366
+ <table>
367
+ <thead>
368
+ <tr>
369
+ <th>#</th>
370
+ <th>Nome</th>
371
+ <th>Valor</th>
372
+ </tr>
373
+ </thead>
374
+ <tbody>
375
+ <tr *ngFor="let item of filteredItems | TCloudUiPagination: paginationConfig2; let i = index">
376
+ <td>{{ (currentPage2 - 1) * paginationConfig2.itemsPerPage + i + 1 }}</td>
377
+ <td>{{ item.name }}</td>
378
+ <td>{{ item.value }}</td>
379
+ </tr>
380
+ </tbody>
381
+ </table>
382
+
383
+ <tcloud-ui-pagination
384
+ [id]="'table-2'"
385
+ [currentPage]="currentPage2"
386
+ (pageChange)="onPageChange2($event)">
387
+ </tcloud-ui-pagination>
388
+ </div>
389
+ `
390
+ })
391
+ export class PaginationDemoComponent implements OnInit {
392
+ items: Item[] = [
393
+ { id: 1, name: 'Protheus', value: 154 },
394
+ { id: 2, name: 'RM', value: 33 },
395
+ // ... mais itens
396
+ ];
397
+
398
+ filteredItems: Item[] = [];
399
+ currentPage: number = 1;
400
+ currentPage2: number = 1;
401
+
402
+ paginationConfig1 = {
403
+ currentPage: this.currentPage,
404
+ itemsPerPage: 4,
405
+ id: 'table-1'
406
+ };
407
+
408
+ paginationConfig2 = {
409
+ currentPage: this.currentPage2,
410
+ itemsPerPage: 3,
411
+ id: 'table-2'
412
+ };
413
+
414
+ ngOnInit() {
415
+ this.filteredItems = [...this.items]; // Cópia inicial
416
+ }
417
+
418
+ onPageChange1(newPage: number) {
419
+ this.currentPage = newPage;
420
+ this.paginationConfig1 = { ...this.paginationConfig1, currentPage: newPage };
421
+ }
422
+
423
+ onPageChange2(newPage: number) {
424
+ this.currentPage2 = newPage;
425
+ this.paginationConfig2 = { ...this.paginationConfig2, currentPage: newPage };
426
+ }
427
+
428
+ onFilter(event: any) {
429
+ const searchTerm = event.target.value.toLowerCase();
430
+ this.filteredItems = this.items.filter(item =>
431
+ item.name.toLowerCase().includes(searchTerm)
432
+ );
433
+ // Pipe detectará mudança de tamanho e resetará automaticamente para página 1
434
+ }
435
+ }
436
+ ```
437
+
438
+ ## Boas Práticas
439
+
440
+ 1. **Sempre use IDs únicos** quando houver múltiplas paginações
441
+ ```typescript
442
+ [id]="'pagination-1'" // ✅ Especificado
443
+ // Sem [id] → ❌ Auto-gerado aleatorily, pode causar conflitos
444
+ ```
445
+
446
+ 2. **Use o mesmo ID no pipe e no componente**
447
+ ```html
448
+ <!-- ✅ Correto -->
449
+ *ngFor="let item of items | TCloudUiPagination: { ..., id: 'list-1' }"
450
+ <tcloud-ui-pagination [id]="'list-1'" ...></tcloud-ui-pagination>
451
+
452
+ <!-- ❌ Errado -->
453
+ *ngFor="let item of items | TCloudUiPagination: { ..., id: 'list-1' }"
454
+ <tcloud-ui-pagination [id]="'list-2'" ...></tcloud-ui-pagination>
455
+ ```
456
+
457
+ 3. **Não manipule `currentPage` diretamente**
458
+ ```typescript
459
+ // ❌ Evitar
460
+ this.currentPage = 2; // Pode causar dessincronização
461
+
462
+ // ✅ Preferir
463
+ onPageChange(newPage: number) {
464
+ this.currentPage = newPage;
465
+ }
466
+ ```
467
+
468
+ 4. **Mantenha dados imutáveis** para melhor performance com OnPush
469
+ ```typescript
470
+ // ❌ Modificação in-place
471
+ this.items.pop();
472
+
473
+ // ✅ Novo array
474
+ this.items = this.items.filter(...);
475
+ this.items = [...this.items];
476
+ ```
477
+
478
+ 5. **Use `trackBy` em `*ngFor`** para grandes listas
479
+ ```typescript
480
+ trackByFn(index: number, item: any) {
481
+ return item.id; // Usa propriedade única
482
+ }
483
+
484
+ *ngFor="let item of items; trackBy: trackByFn"
485
+ ```
486
+
487
+ ## Troubleshooting
488
+
489
+ ### ❌ Total não aparece no início do componente
490
+
491
+ **Cause:** Timing do binding antes do serviço emitir
492
+
493
+ **Solução:**
494
+ ```typescript
495
+ // ✅ Agora tem binding direto no template
496
+ get totalPages(): number {
497
+ return this.getTotal().total; // Getter sempre sincronizado
498
+ }
499
+ ```
500
+
501
+ ### ❌ Paginação 2 afeta Paginação 1
502
+
503
+ **Verify:**
504
+ - Confirme que os `id` são realmente diferentes no HTML
505
+ - Certifique-se de passar `id` tanto no **pipe** quanto no **componente**
506
+
507
+ ```html
508
+ <!-- ✅ Correto -->
509
+ <ng-container *ngFor="let item of items | TCloudUiPagination: { ..., id: 'p1' }"> ... </ng-container>
510
+ <tcloud-ui-pagination [id]="'p1'" ...></tcloud-ui-pagination>
511
+
512
+ <ng-container *ngFor="let item of items | TCloudUiPagination: { ..., id: 'p2' }"> ... </ng-container>
513
+ <tcloud-ui-pagination [id]="'p2'" ...></tcloud-ui-pagination>
514
+ ```
515
+
516
+ ### ❌ Página não reseta ao filtrar
517
+
518
+ **Cause:** O pipe detecta mudanças apenas se o tamanho do array muda
519
+
520
+ **Verificar:**
521
+ 1. Array está realmente mudando? Verifique `console.log(items.length)`
522
+ 2. Se modificar inline:
523
+ ```typescript
524
+ // ❌ Não cria novo array, pipe não detecta
525
+ this.items.splice(0, 5);
526
+
527
+ // ✅ Cria novo array, pipe detecta
528
+ this.items = this.items.filter(...);
529
+ this.items = this.items.slice();
530
+ this.items = [...this.items];
531
+ ```
532
+
533
+ ### ❌ ExpressionChangedAfterItHasBeenCheckedError
534
+
535
+ **Cause:** Emit durante change detection cycle
536
+
537
+ **Solução:** Use Promise deferred:
538
+ ```typescript
539
+ // ✅ Resolvido internamente no componente
540
+ Promise.resolve().then(() => {
541
+ this.pageChange.emit(1);
542
+ });
543
+ ```
544
+
545
+ ## Integração com Serviços Customizados
546
+
547
+ Você pode integrar o serviço em seus próprios serviços:
548
+
549
+ ```typescript
550
+ @Injectable({ providedIn: 'root' })
551
+ export class MyDataService {
552
+ constructor(private pagination: TCloudUiPaginationService) {}
553
+
554
+ filterData(term: string, allItems: any[]): any[] {
555
+ const filtered = allItems.filter(item =>
556
+ item.name.toLowerCase().includes(term.toLowerCase())
557
+ );
558
+
559
+ // Notifique o serviço de paginação
560
+ this.pagination.notifyCollectionChange('my-list-id');
561
+
562
+ // Resete para página 1
563
+ this.pagination.resetToFirstPage('my-list-id');
564
+
565
+ return filtered;
566
+ }
567
+ }
568
+ ```
569
+
570
+ ## Versionamento
571
+
572
+ | Versão | Data | Mudanças |
573
+ |--------|------|----------|
574
+ | 1.0.0 | 2026-02-11 | Versão inicial com múltiplas instâncias independentes |
575
+ | 1.0.1 | 2026-02-12 | ✅ Documentação atualizada com detalhes de implementação, Change Detection OnPush, troubleshooting expandido |
576
+
577
+ ## Licença
578
+
579
+ Parte do TCloud UI Component Library
@@ -0,0 +1,65 @@
1
+ # Progress Bar
2
+
3
+ ## Características
4
+ - Barra de progresso standalone com modos de cor (primário, danger, warning, info, success, gray e gradientes).
5
+ - Suporte a diferentes alturas (`normal`, `slim`, `fat`, `very-fat`) e exibição opcional do valor (`showValue`).
6
+ - Aceita limite customizado (`limit`) para escalar percentuais acima de 100% (exibe marcador de 100%).
7
+ - Pode usar ou não o background padrão (`useDefaultBackground`).
8
+
9
+ ## Instalação
10
+ ```ts
11
+ import { TCloudUiProgressBarComponent } from 'projects/tcloud-ui/src/public-api';
12
+
13
+ @Component({
14
+ selector: 'app-example',
15
+ standalone: true,
16
+ imports: [TCloudUiProgressBarComponent],
17
+ template: `<tcloud-ui-progress-bar status="50"></tcloud-ui-progress-bar>`
18
+ })
19
+ export class ExampleComponent {}
20
+ ```
21
+
22
+ ## Propriedades (API)
23
+ ### Inputs
24
+ | Nome | Tipo | Descrição | Valor Default |
25
+ | --- | --- | --- | --- |
26
+ | status | string \| number | Valor percentual exibido (0-100 ou maior quando usado com `limit`). | '0' |
27
+ | limit | string \| number | Limite superior para reescalar o `status` (ex.: 200 escala 200 para 100%). | undefined |
28
+ | mode | string | Tema de cor: `primary`, `danger`, `warning`, `info`, `success`, `gray`, `gradient-success`, `gradient-danger`, `gradient-warning`, `gradient-info`. | 'primary' |
29
+ | height | string | Altura: `normal`, `slim`, `fat`, `very-fat`. | 'normal' |
30
+ | useDefaultBackground | boolean | Aplica fundo padrão da barra. | true |
31
+ | showValue | boolean | Exibe o valor percentual como label quando altura permite. | false |
32
+
33
+ ### Outputs
34
+ | Nome | Tipo de Evento | Descrição |
35
+ | --- | --- | --- |
36
+ | (não possui) | - | Componente não emite eventos. |
37
+
38
+ ## Exemplos de Uso
39
+ ### Uso Básico
40
+ ```html
41
+ <tcloud-ui-progress-bar status="70"></tcloud-ui-progress-bar>
42
+ ```
43
+
44
+ ### Modos e alturas
45
+ ```html
46
+ <tcloud-ui-progress-bar status="50" mode="warning" height="fat"></tcloud-ui-progress-bar>
47
+ <tcloud-ui-progress-bar status="30" mode="danger"></tcloud-ui-progress-bar>
48
+ <tcloud-ui-progress-bar status="45" mode="gradient-success" height="very-fat"></tcloud-ui-progress-bar>
49
+ ```
50
+
51
+ ### Exibir valor
52
+ ```html
53
+ <tcloud-ui-progress-bar status="50" mode="gray" [showValue]="true"></tcloud-ui-progress-bar>
54
+ ```
55
+
56
+ ### Usando limite para valores > 100%
57
+ ```html
58
+ <!-- Se limit=130 e status=24, o componente recalcula percentuais -->
59
+ <tcloud-ui-progress-bar [status]="24" limit="130" mode="gradient-danger" height="slim"></tcloud-ui-progress-bar>
60
+ ```
61
+
62
+ ### Sem background padrão
63
+ ```html
64
+ <tcloud-ui-progress-bar [status]="60" [useDefaultBackground]="false" mode="success" height="slim"></tcloud-ui-progress-bar>
65
+ ```