import { ChangeDetectionStrategy, Component, computed, input, model, numberAttribute, ViewEncapsulation, } from "@angular/core"; import { SdAnchor } from "../button/sd-anchor"; import { NgIcon } from "@ng-icons/core"; import { tablerChevronLeft, tablerChevronRight, tablerChevronsLeft, tablerChevronsRight, } from "@ng-icons/tabler-icons"; @Component({ selector: "sd-pagination", changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, imports: [SdAnchor, NgIcon], template: ` @for (page of displayPages(); track page) { {{ page }} } `, styles: [ /* language=SCSS */ ` sd-pagination { > sd-anchor { display: inline-block; padding: var(--gap-xs); } } `, ], host: { class: "flex-row gap-xs", }, }) export class SdPagination { icons = { tablerChevronsLeft, tablerChevronLeft, tablerChevronRight, tablerChevronsRight }; currentPage = model(0); totalPageCount = input(0, { transform: numberAttribute }); visiblePageCount = input(10, { transform: numberAttribute }); private readonly _groupIndex = computed(() => { return Math.floor(this.currentPage() / Math.max(this.visiblePageCount(), 1)); }); hasPrev = computed(() => { if (this.totalPageCount() === 0) { return false; } return this._groupIndex() > 0; }); hasNext = computed(() => { const totalPageCount = this.totalPageCount(); if (totalPageCount === 0) { return false; } const lastGroupIndex = Math.floor((totalPageCount - 1) / Math.max(this.visiblePageCount(), 1)); return this._groupIndex() < lastGroupIndex; }); displayPages = computed(() => { const totalPageCount = this.totalPageCount(); if (totalPageCount === 0) { return [] as number[]; } const visiblePageCount = this.visiblePageCount(); const startPage = this._groupIndex() * visiblePageCount + 1; const endPage = Math.min(startPage + visiblePageCount - 1, totalPageCount); const pages: number[] = []; for (let i = startPage; i <= endPage; i++) { pages.push(i); } return pages; }); goToPage(page: number): void { this.currentPage.set(page); } goToNextGroup(): void { this.currentPage.set((this._groupIndex() + 1) * Math.max(this.visiblePageCount(), 1)); } goToPrevGroup(): void { if (!this.hasPrev()) return; this.currentPage.set((this._groupIndex() - 1) * Math.max(this.visiblePageCount(), 1)); } goToFirst(): void { this.currentPage.set(0); } goToLast(): void { if (this.totalPageCount() === 0) return; this.currentPage.set(this.totalPageCount() - 1); } }