Navigation
Pagination.
Page links with previous and next controls. The current page gets an orange outline.
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";
export default function PaginationDemo() {
return (
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="#" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">3</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationLink href="#">12</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href="#" />
</PaginationItem>
</PaginationContent>
</Pagination>
);
}Installation#
With the CLI
$npx lanterncn add paginationThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/pagination. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install lucide-reactCopy the source into your project
components/ui/pagination.tsximport * as React from "react"; import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"; import { cn } from "@/lib/utils"; import { buttonVariants, type Button } from "@/components/ui/button"; function Pagination({ className, ...props }: React.ComponentProps<"nav">) { return ( <nav role="navigation" aria-label="pagination" data-slot="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 flex-row items-center gap-1", className)} {...props} />; } function PaginationItem({ ...props }: React.ComponentProps<"li">) { return <li data-slot="pagination-item" {...props} />; } type PaginationLinkProps = { isActive?: boolean; } & Pick<React.ComponentProps<typeof Button>, "size"> & React.ComponentProps<"a">; function PaginationLink({ className, isActive, size = "icon-sm", ...props }: PaginationLinkProps) { return ( <a aria-current={isActive ? "page" : undefined} data-slot="pagination-link" data-active={isActive} className={cn( buttonVariants({ variant: isActive ? "outline" : "ghost", size }), "font-mono text-xs font-medium tabular-nums active:translate-y-0", isActive && "border-primary text-primary hover:bg-primary/10", className, )} {...props} /> ); } function PaginationPrevious({ className, ...props }: React.ComponentProps<typeof PaginationLink>) { return ( <PaginationLink aria-label="Go to previous page" size="sm" className={cn("gap-1.5 px-2.5 text-[11px] tracking-[0.14em] uppercase sm:pl-2", className)} {...props} > <ChevronLeftIcon /> <span className="hidden sm:block">Prev</span> </PaginationLink> ); } function PaginationNext({ className, ...props }: React.ComponentProps<typeof PaginationLink>) { return ( <PaginationLink aria-label="Go to next page" size="sm" className={cn("gap-1.5 px-2.5 text-[11px] tracking-[0.14em] uppercase sm:pr-2", className)} {...props} > <span className="hidden sm:block">Next</span> <ChevronRightIcon /> </PaginationLink> ); } function PaginationEllipsis({ className, ...props }: React.ComponentProps<"span">) { return ( <span aria-hidden data-slot="pagination-ellipsis" className={cn("flex size-8 items-center justify-center text-muted-foreground", className)} {...props} > <MoreHorizontalIcon className="size-4" /> <span className="sr-only">More pages</span> </span> ); } export { Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, };Update the import paths to match your project
The source imports
cnfrom@/lib/utilsand uses button.
Usage#
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@/components/ui/pagination";<Pagination>
<PaginationContent>
<PaginationItem><PaginationPrevious href="#" /></PaginationItem>
<PaginationItem><PaginationLink href="#" isActive>2</PaginationLink></PaginationItem>
<PaginationItem><PaginationNext href="#" /></PaginationItem>
</PaginationContent>
</Pagination>The Prev and Next words hide on phones to leave room for the page numbers.