Docs/Components/Pagination

Pagination

Pagination with page navigation, previous and next controls.

Installation

Install the component Pagination in your project using the CLI.

Pagination.tsx

pnpm dlx behsseui@latest add Pagination

Install the component manually.

Create a ui folder at the root of the project, then a component folder inside it, and finally a Pagination.tsx file in that folder.

Copy and paste the following code into your project.

ui/components/Pagination.tsx

1import type { ReactNode, HTMLAttributes, AnchorHTMLAttributes } from "react"
2import { cn } from "@/lib/utils"
3import ChevronLeft from "@/ui/icons/ChevronLeft"
4import ChevronRight from "@/ui/icons/ChevronRight"
5
6// Pagination Root
7type PaginationProps = {
8 className?: string
9} & HTMLAttributes<HTMLElement>
10
11export function Pagination({ className, ...props }: PaginationProps) {
12 return (
13 <nav
14 role="navigation"
15 aria-label="pagination"
16 className={cn("mx-auto flex w-full justify-center", className)}
17 {...props}
18 />
19 )
20}
21
22// Content
23type PaginationContentProps = {
24 children: ReactNode
25 className?: string
26} & HTMLAttributes<HTMLUListElement>
27
28export function PaginationContent({ children, className, ...props }: PaginationContentProps) {
29 return (
30 <ul className={cn("flex flex-row items-center gap-1", className)} {...props}>
31 {children}
32 </ul>
33 )
34}
35
36// Item
37type PaginationItemProps = {
38 children: ReactNode
39 className?: string
40} & HTMLAttributes<HTMLLIElement>
41
42export function PaginationItem({ children, className, ...props }: PaginationItemProps) {
43 return (
44 <li className={cn("", className)} {...props}>
45 {children}
46 </li>
47 )
48}
49
50// Link
51type PaginationLinkProps = {
52 children: ReactNode
53 className?: string
54 isActive?: boolean
55 size?: "default" | "icon"
56} & AnchorHTMLAttributes<HTMLAnchorElement>
57
58export function PaginationLink({
59 children,
60 className,
61 isActive = false,
62 size = "default",
63 ...props
64}: PaginationLinkProps) {
65 return (
66 <a
67 aria-current={isActive ? "page" : undefined}
68 className={cn(
69 "inline-flex items-center justify-center gap-1 rounded-md text-sm font-medium transition-colors whitespace-nowrap",
70 "hover:bg-accent hover:text-accent-foreground",
71 "focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
72 size === "default" && "h-9 min-w-9 px-3",
73 size === "icon" && "h-9 w-9",
74 isActive
75 ? "border border-input bg-background shadow-sm"
76 : "border border-transparent",
77 className
78 )}
79 {...props}
80 >
81 {children}
82 </a>
83 )
84}
85
86// Previous
87type PaginationPreviousProps = {
88 className?: string
89} & AnchorHTMLAttributes<HTMLAnchorElement>
90
91export function PaginationPrevious({ className, ...props }: PaginationPreviousProps) {
92 return (
93 <PaginationLink
94 aria-label="Go to previous page"
95 className={cn("gap-1 pl-2.5", className)}
96 {...props}
97 >
98 <ChevronLeft className="h-4 w-4" />
99 <span>Previous</span>
100 </PaginationLink>
101 )
102}
103
104// Next
105type PaginationNextProps = {
106 className?: string
107} & AnchorHTMLAttributes<HTMLAnchorElement>
108
109export function PaginationNext({ className, ...props }: PaginationNextProps) {
110 return (
111 <PaginationLink
112 aria-label="Go to next page"
113 className={cn("gap-1 pr-2.5", className)}
114 {...props}
115 >
116 <span>Next</span>
117 <ChevronRight className="h-4 w-4" />
118 </PaginationLink>
119 )
120}
121
122// Ellipsis
123type PaginationEllipsisProps = {
124 className?: string
125} & HTMLAttributes<HTMLSpanElement>
126
127export function PaginationEllipsis({ className, ...props }: PaginationEllipsisProps) {
128 return (
129 <span
130 aria-hidden="true"
131 className={cn("flex h-9 w-9 items-center justify-center", className)}
132 {...props}
133 >
134 <svg
135 xmlns="http://www.w3.org/2000/svg"
136 viewBox="0 0 24 24"
137 fill="currentColor"
138 className="h-4 w-4"
139 >
140 <circle cx="12" cy="12" r="1" />
141 <circle cx="19" cy="12" r="1" />
142 <circle cx="5" cy="12" r="1" />
143 </svg>
144 <span className="sr-only">More pages</span>
145 </span>
146 )
147}
148

Usages

Different variants and use cases for the Pagination component.

Default

Basic pagination with previous, page numbers, ellipsis, and next.

Default.tsx

<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>
      <PaginationNext href="#" />
    </PaginationItem>
  </PaginationContent>
</Pagination>

With More Pages

Pagination with ellipsis on both sides for large page sets.

With More Pages.tsx

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationPrevious href="#" />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">1</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationEllipsis />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">4</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#" isActive>5</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">6</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationEllipsis />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">10</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationNext href="#" />
    </PaginationItem>
  </PaginationContent>
</Pagination>

First & Last

Include dedicated first and last page buttons.

First & Last.tsx

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationLink href="#">« First</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationPrevious href="#" />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">3</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#" isActive>4</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">5</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationNext href="#" />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">Last »</PaginationLink>
    </PaginationItem>
  </PaginationContent>
</Pagination>

Simple

Only previous and next buttons without page numbers.

Simple.tsx

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationPrevious href="#" />
    </PaginationItem>
    <PaginationItem>
      <PaginationNext href="#" />
    </PaginationItem>
  </PaginationContent>
</Pagination>

With Icons Only

Previous and next as icon-only buttons.

With Icons Only.tsx

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationLink href="#" size="icon" aria-label="Previous page">
        <ChevronLeft className="h-4 w-4" />
      </PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">1</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#" isActive>2</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">3</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#" size="icon" aria-label="Next page">
        <ChevronRight className="h-4 w-4" />
      </PaginationLink>
    </PaginationItem>
  </PaginationContent>
</Pagination>

Active States

Different active page positions.

Active States.tsx

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationPrevious href="#" />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#" isActive>1</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">2</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">3</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">4</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="#">5</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationNext href="#" />
    </PaginationItem>
  </PaginationContent>
</Pagination>