Pagination
Page navigation where the current page is a latched, pressed-in key with tabular numerals.
@emboss/pagination
Installation
pnpm dlx shadcn@latest add @emboss/paginationUsage
import {
Pagination,
PaginationContent,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
export function Example() {
return (
<Pagination>
<PaginationContent>
<PaginationPrevious href="#previous" />
<PaginationLink href="#1" isActive>
1
</PaginationLink>
<PaginationLink href="#2">2</PaginationLink>
<PaginationNext href="#next" />
</PaginationContent>
</Pagination>
);
}API reference
Pagination / PaginationContent / PaginationLink / PaginationPrevious / PaginationNext / PaginationEllipsis
A labelled nav of page links rendered as anchors — wire href (or compose with your router's Link via the className).
| Prop | Type | Default | Description |
|---|---|---|---|
| isActive | boolean | false | Marks the current page: latched depth plus aria-current (PaginationLink). |
Source
View source — pagination.tsxHide source — pagination.tsx
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import { cn } from "@/lib/utils";
/**
* Page navigation where the current page is a latched, pressed-in key.
*
* @example
* <Pagination>
* <PaginationContent>
* <PaginationPrevious href="#" />
* <PaginationLink href="#" isActive>1</PaginationLink>
* <PaginationLink href="#">2</PaginationLink>
* <PaginationNext href="#" />
* </PaginationContent>
* </Pagination>
*/
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
return (
<nav
data-slot="pagination"
aria-label="Pagination"
className={cn("mx-auto flex w-full justify-center", className)}
{...props}
/>
);
}
function PaginationContent({
className,
...props
}: React.ComponentProps<"ul">) {
return (
<ul
data-slot="pagination-content"
className={cn("flex items-center gap-1.5", className)}
{...props}
/>
);
}
const linkClassName =
"focus-ring inline-flex h-(--control-sm) min-w-(--control-sm) cursor-pointer items-center justify-center gap-1 rounded-sm px-2 text-sm font-medium transition-[box-shadow,background-color,color] duration-(--duration-press) ease-(--ease-press) select-none";
function PaginationLink({
className,
isActive = false,
children,
...props
}: React.ComponentProps<"a"> & {
/** Marks the current page: latched into the surface with aria-current. */
isActive?: boolean;
}) {
return (
<li data-slot="pagination-item">
<a
data-slot="pagination-link"
aria-current={isActive ? "page" : undefined}
className={cn(
linkClassName,
isActive
? "bg-well font-mono text-ink tabular-nums shadow-deboss-1"
: "font-mono text-ink-muted tabular-nums hover:bg-surface-2 hover:text-ink hover:shadow-emboss-1",
className,
)}
{...props}
>
{children}
</a>
</li>
);
}
function PaginationPrevious({
className,
...props
}: React.ComponentProps<"a">) {
return (
<li data-slot="pagination-item">
<a
data-slot="pagination-previous"
className={cn(
linkClassName,
"px-2.5 text-ink-muted hover:bg-surface-2 hover:text-ink hover:shadow-emboss-1",
className,
)}
{...props}
>
<ChevronLeft className="size-4" aria-hidden />
<span className="hidden sm:inline">Previous</span>
</a>
</li>
);
}
function PaginationNext({ className, ...props }: React.ComponentProps<"a">) {
return (
<li data-slot="pagination-item">
<a
data-slot="pagination-next"
className={cn(
linkClassName,
"px-2.5 text-ink-muted hover:bg-surface-2 hover:text-ink hover:shadow-emboss-1",
className,
)}
{...props}
>
<span className="hidden sm:inline">Next</span>
<ChevronRight className="size-4" aria-hidden />
</a>
</li>
);
}
function PaginationEllipsis({
className,
...props
}: React.ComponentProps<"span">) {
return (
<li data-slot="pagination-item">
<span
data-slot="pagination-ellipsis"
aria-hidden
className={cn(
"flex size-(--control-sm) items-center justify-center text-ink-faint",
className,
)}
{...props}
>
<MoreHorizontal className="size-4" />
<span className="sr-only">More pages</span>
</span>
</li>
);
}
export {
Pagination,
PaginationContent,
PaginationLink,
PaginationPrevious,
PaginationNext,
PaginationEllipsis,
};