Files
bizmatch-project/bizmatch/src/app/components/paginator/paginator.component.ts

99 lines
4.2 KiB
TypeScript

import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';
@Component({
selector: 'app-paginator',
standalone: true,
imports: [CommonModule],
template: `
<nav class="my-2" aria-label="Page navigation">
<ul class="flex justify-center items-center -space-x-px h-8 text-sm">
<li>
<a
(click)="onPageChange(currentPage - 1)"
[class.pointer-events-none]="currentPage === 1"
class="flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
>
<span class="sr-only">Previous</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4" />
</svg>
</a>
</li>
<ng-container *ngFor="let page of visiblePages">
<li *ngIf="page !== '...'">
<a
(click)="onPageChange(page)"
[ngClass]="
page === currentPage
? 'z-10 flex items-center justify-center px-3 h-8 leading-tight text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700 dark:border-gray-700 dark:bg-gray-700 dark:text-white'
: 'flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white'
"
>
{{ page }}
</a>
</li>
<li *ngIf="page === '...'">
<span class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400">...</span>
</li>
</ng-container>
<li>
<a
(click)="onPageChange(currentPage + 1)"
[class.pointer-events-none]="currentPage === pageCount"
class="flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white"
>
<span class="sr-only">Next</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4" />
</svg>
</a>
</li>
</ul>
</nav>
`,
})
export class PaginatorComponent implements OnChanges {
@Input() page = 1;
@Input() pageCount = 1;
@Output() pageChange = new EventEmitter<number>();
currentPage = 1;
visiblePages: (number | string)[] = [];
ngOnChanges(changes: SimpleChanges): void {
if (changes['page'] || changes['pageCount']) {
this.currentPage = this.page;
this.updateVisiblePages();
}
}
updateVisiblePages(): void {
const totalPages = this.pageCount;
const current = this.currentPage;
if (totalPages <= 6) {
this.visiblePages = Array.from({ length: totalPages }, (_, i) => i + 1);
} else {
if (current <= 3) {
this.visiblePages = [1, 2, 3, 4, '...', totalPages];
} else if (current >= totalPages - 2) {
this.visiblePages = [1, '...', totalPages - 3, totalPages - 2, totalPages - 1, totalPages];
} else {
this.visiblePages = [1, '...', current - 1, current, current + 1, '...', totalPages];
}
}
}
onPageChange(page: number | string): void {
if (typeof page === 'string') {
return;
}
if (page >= 1 && page <= this.pageCount && page !== this.currentPage) {
this.currentPage = page;
this.pageChange.emit(page);
this.updateVisiblePages();
}
}
}