-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpagination.ts
More file actions
114 lines (97 loc) · 3.3 KB
/
Copy pathpagination.ts
File metadata and controls
114 lines (97 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { Component, ChangeDetectionStrategy, input, output, computed } from '@angular/core';
import { AppIconComponent } from '../icon/app-icon';
export interface PageItem {
type: 'page' | 'ellipsis';
page?: number;
}
@Component({
selector: 'app-pagination',
standalone: true,
imports: [AppIconComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './pagination.html',
styleUrl: './pagination.css',
})
export class PaginationComponent {
readonly currentPage = input<number>(1);
readonly pageSize = input<number>(10);
readonly totalItems = input<number>(0);
readonly pageSizeOptions = input<number[]>([10, 25, 50, 100]);
readonly showPageSize = input<boolean>(true);
readonly showItemRange = input<boolean>(true);
readonly pageChange = output<number>();
readonly pageSizeChange = output<number>();
readonly totalPages = computed(() => {
return Math.max(1, Math.ceil(this.totalItems() / this.pageSize()));
});
readonly startItem = computed(() => {
if (this.totalItems() === 0) return 0;
return (this.currentPage() - 1) * this.pageSize() + 1;
});
readonly endItem = computed(() => {
return Math.min(this.currentPage() * this.pageSize(), this.totalItems());
});
readonly startItemFormatted = computed(() => {
return this.startItem().toLocaleString('pt-BR');
});
readonly endItemFormatted = computed(() => {
return this.endItem().toLocaleString('pt-BR');
});
readonly totalItemsFormatted = computed(() => {
return this.totalItems().toLocaleString('pt-BR');
});
readonly visiblePages = computed<PageItem[]>(() => {
const total = this.totalPages();
const current = this.currentPage();
if (total <= 7) {
const items: PageItem[] = [];
for (let i = 1; i <= total; i++) {
items.push({ type: 'page', page: i });
}
return items;
}
const pages: PageItem[] = [];
if (current <= 4) {
for (let i = 1; i <= 5; i++) {
pages.push({ type: 'page', page: i });
}
pages.push({ type: 'ellipsis' });
pages.push({ type: 'page', page: total });
} else if (current >= total - 3) {
pages.push({ type: 'page', page: 1 });
pages.push({ type: 'ellipsis' });
for (let i = total - 4; i <= total; i++) {
pages.push({ type: 'page', page: i });
}
} else {
pages.push({ type: 'page', page: 1 });
pages.push({ type: 'ellipsis' });
pages.push({ type: 'page', page: current - 1 });
pages.push({ type: 'page', page: current });
pages.push({ type: 'page', page: current + 1 });
pages.push({ type: 'ellipsis' });
pages.push({ type: 'page', page: total });
}
return pages;
});
goToPage(page: number): void {
if (page >= 1 && page <= this.totalPages() && page !== this.currentPage()) {
this.pageChange.emit(page);
}
}
onPageSizeChange(event: Event): void {
const size = parseInt((event.target as HTMLSelectElement).value, 10);
if (!isNaN(size)) {
this.pageSizeChange.emit(size);
}
}
onDirectJump(event: Event): void {
const inputEl = event.target as HTMLInputElement;
const val = parseInt(inputEl.value, 10);
if (!isNaN(val) && val >= 1 && val <= this.totalPages()) {
this.goToPage(val);
} else {
inputEl.value = this.currentPage().toString();
}
}
}