SPB Git forge

spb/fetcha

Public
11commits 1branches 0releases
1.5 MBsize
maindefault branch
16 days agolast push
TypeScript 97.5% SQL 1.4% Python 0.8%
1.7 KB · 46 lines tsx
Raw Blame History
1import Link from "next/link";2import { ChevronLeft, ChevronRight } from "lucide-react";3import { Button } from "@/components/ui/button";4import { formatNumber } from "@/lib/format";56/** Offset pagination with URL-preserving links. */7export function Pagination({ page, pageCount, total, pageSize, hrefFor }: { page: number; pageCount: number; total: number; pageSize: number; hrefFor: (page: number) => string }) {8  if (total === 0) return null;9  const start = (page - 1) * pageSize + 1;10  const end = Math.min(total, page * pageSize);11  return (12    <nav className="flex flex-wrap items-center justify-between gap-3 text-[12.5px] text-fg-muted" aria-label="Pagination">13      <span className="font-mono tabular">14        {formatNumber(start)}–{formatNumber(end)} of {formatNumber(total)}15      </span>16      <div className="flex items-center gap-1">17        <Button asChild={page > 1} variant="outline" size="sm" disabled={page <= 1} aria-label="Previous page">18          {page > 1 ? (19            <Link href={hrefFor(page - 1)} rel="prev">20              <ChevronLeft /> Previous21            </Link>22          ) : (23            <span>24              <ChevronLeft /> Previous25            </span>26          )}27        </Button>28        <span className="px-2 font-mono tabular">29          {page} / {pageCount}30        </span>31        <Button asChild={page < pageCount} variant="outline" size="sm" disabled={page >= pageCount} aria-label="Next page">32          {page < pageCount ? (33            <Link href={hrefFor(page + 1)} rel="next">34              Next <ChevronRight />35            </Link>36          ) : (37            <span>38              Next <ChevronRight />39            </span>40          )}41        </Button>42      </div>43    </nav>44  );45}46