import * as React from "react";
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
const total = 12;
function pageList(current: number) {
const pages = [...new Set([1, current - 1, current, current + 1, total])]
.filter((page) => page >= 1 && page <= total)
.sort((a, b) => a - b);
const items: (number | "ellipsis")[] = [];
let previous = 0;
for (const page of pages) {
if (page - previous > 1) items.push("ellipsis");
items.push(page);
previous = page;
}
return items;
}
export default function PaginationInteractive() {
const [page, setPage] = React.useState(5);
const go = (next: number) => (event: React.MouseEvent) => {
event.preventDefault();
setPage(Math.min(total, Math.max(1, next)));
};
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" onClick={go(page - 1)} disabled={page === 1} />
</PaginationItem>
{pageList(page).map((item, index) =>
item === "ellipsis" ? (
<PaginationItem key={`ellipsis-${index}`}>
<PaginationEllipsis />
</PaginationItem>
) : (
<PaginationItem key={item}>
<PaginationLink href="#" isActive={item === page} onClick={go(item)}>
{item}
</PaginationLink>
</PaginationItem>
),
)}
<PaginationItem>
<PaginationNext href="#" onClick={go(page + 1)} disabled={page === total} />
</PaginationItem>
</PaginationContent>
</Pagination>
);
}- Add the registryOnce per project
pnpm dlx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json - Add pagination
pnpm dlx shadcn@latest add @jarvis/pagination
Usage
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
export function InvoicePagination() {
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="?page=1" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=1">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=2" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=12">12</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="?page=3" />
</PaginationItem>
</PaginationContent>
</Pagination>
);
}Mark the current page with isActive. On the first or last page, set disabled on
PaginationPrevious or PaginationNext.
Composition
Examples
Compact
Leave out the page numbers when you only need previous and next. text changes their labels.
Showing 41–50 of 118 invoices
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
import { preventNavigation } from "@/examples/data";
export default function PaginationCompact() {
return (
<div className="flex w-full max-w-lg flex-wrap items-center justify-between gap-3">
<span className="text-sm text-muted-foreground tabular-nums">
Showing 41–50 of 118 invoices
</span>
<Pagination className="mx-0 w-auto">
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" onClick={preventNavigation} text="Prev" />
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" onClick={preventNavigation} />
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
);
}Props
| Part | Extends |
|---|---|
| Pagination | <nav> |
| PaginationContent | <ul> |
| PaginationItem | <li> |
| PaginationLink | <a> |
| PaginationPrevious | PaginationLink |
| PaginationNext | PaginationLink |
| PaginationEllipsis | <span> |
PaginationLink
| Prop | Type | Default |
|---|---|---|
isActive | boolean | — |
disabledDims the link and stops it navigating, for the ends of the range. | boolean | — |
size | "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | "icon" |
PaginationPrevious
| Prop | Type | Default |
|---|---|---|
isActive | boolean | — |
disabledDims the link and stops it navigating, for the ends of the range. | boolean | — |
size | "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | "default" |
text | string | "Previous" |
PaginationNext
| Prop | Type | Default |
|---|---|---|
isActive | boolean | — |
disabledDims the link and stops it navigating, for the ends of the range. | boolean | — |
size | "default" | "icon" | "icon-lg" | "icon-sm" | "icon-xs" | "lg" | "sm" | "xs" | "default" |
text | string | "Next" |