@dev-tcloud/tcloud-ui 6.15.0 → 6.18.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/docs/tcloud-ui-accordion.md +345 -0
- package/docs/tcloud-ui-actions.md +88 -0
- package/docs/tcloud-ui-alert-banner.md +104 -0
- package/docs/tcloud-ui-array-to-text.md +361 -0
- package/docs/tcloud-ui-breadcrumb.md +103 -0
- package/docs/tcloud-ui-bytes.md +109 -0
- package/docs/tcloud-ui-calendar.md +387 -0
- package/docs/tcloud-ui-card-accordion.md +266 -0
- package/docs/tcloud-ui-card-title.md +47 -0
- package/docs/tcloud-ui-card.md +40 -0
- package/docs/tcloud-ui-choice-issues.md +59 -0
- package/docs/tcloud-ui-cnpj.md +102 -0
- package/docs/tcloud-ui-container.md +171 -0
- package/docs/tcloud-ui-cpf.md +102 -0
- package/docs/tcloud-ui-currency.md +271 -0
- package/docs/tcloud-ui-data-list.md +91 -0
- package/docs/tcloud-ui-datebr.md +139 -0
- package/docs/tcloud-ui-datepicker-time.md +191 -0
- package/docs/tcloud-ui-datepicker.md +186 -0
- package/docs/tcloud-ui-dropdown-multi.md +444 -0
- package/docs/tcloud-ui-dropdown.md +369 -0
- package/docs/tcloud-ui-el-copy.md +113 -0
- package/docs/tcloud-ui-empty-content.md +412 -0
- package/docs/tcloud-ui-faq.md +496 -0
- package/docs/tcloud-ui-filter-bar.md +86 -0
- package/docs/tcloud-ui-filters.md +337 -0
- package/docs/tcloud-ui-hover-parent.md +467 -0
- package/docs/tcloud-ui-icon-button.md +104 -0
- package/docs/tcloud-ui-input-container.md +520 -0
- package/docs/tcloud-ui-input-password.md +258 -0
- package/docs/tcloud-ui-input-search.md +314 -0
- package/docs/tcloud-ui-label-token.md +286 -0
- package/docs/tcloud-ui-legend.md +72 -0
- package/docs/tcloud-ui-line-step-circle.md +98 -0
- package/docs/tcloud-ui-line-step-title.md +194 -0
- package/docs/tcloud-ui-linha-logo.md +550 -0
- package/docs/tcloud-ui-loading.md +88 -0
- package/docs/tcloud-ui-message.md +539 -0
- package/docs/tcloud-ui-modal.md +196 -0
- package/docs/tcloud-ui-monthname.md +123 -0
- package/docs/tcloud-ui-multi-input.md +290 -0
- package/docs/tcloud-ui-multi-select.md +311 -0
- package/docs/tcloud-ui-multiples-values.md +157 -0
- package/docs/tcloud-ui-not-found.md +88 -0
- package/docs/tcloud-ui-number-step.md +134 -0
- package/docs/tcloud-ui-pagination.md +579 -0
- package/docs/tcloud-ui-progress-bar.md +65 -0
- package/docs/tcloud-ui-radio.md +83 -0
- package/docs/tcloud-ui-reorder-items.md +418 -0
- package/docs/tcloud-ui-respective.md +167 -0
- package/docs/tcloud-ui-scroll-box.md +109 -0
- package/docs/tcloud-ui-search-bar.md +88 -0
- package/docs/tcloud-ui-search-in-object.md +143 -0
- package/docs/tcloud-ui-search-input.md +74 -0
- package/docs/tcloud-ui-skeleton-loading.md +394 -0
- package/docs/tcloud-ui-slide-toggle.md +210 -0
- package/docs/tcloud-ui-statusinfo.md +138 -0
- package/docs/tcloud-ui-tab-group.md +376 -0
- package/docs/tcloud-ui-tab-menu.md +109 -0
- package/docs/tcloud-ui-table.md +96 -0
- package/docs/tcloud-ui-tag.md +379 -0
- package/docs/tcloud-ui-tc-badge.md +168 -0
- package/docs/tcloud-ui-tc-btn.md +189 -0
- package/docs/tcloud-ui-tc-colors.md +204 -0
- package/docs/tcloud-ui-tc-form-control.md +200 -0
- package/docs/tcloud-ui-tc-text.md +139 -0
- package/docs/tcloud-ui-tc-title.md +118 -0
- package/docs/tcloud-ui-tcloud-form.md +55 -0
- package/docs/tcloud-ui-toast.md +83 -0
- package/docs/tcloud-ui-tooltip.md +88 -0
- package/docs/tcloud-ui-topology.md +232 -0
- package/docs/tcloud-ui-upload-area.md +195 -0
- package/docs/tcloud-ui-welcome.md +112 -0
- package/docs/tcloud-ui-wizard-steps.md +103 -0
- package/js/tcloud-ui-app.js +11 -0
- package/package.json +1 -1
- package/scss/tcloud-revitalizacao/components/_tcloud-ui-table.scss +95 -0
- package/scss/tcloud-revitalizacao/tc-rev-styles.scss +1 -1
- package/scss/tcloud-revitalizacao/components/_tc-rev-table.scss +0 -57
|
@@ -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
|
+
```
|