A pagination component in neobrutalism style.
1import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
2
3import * as React from "react"
4
5import { buttonVariants } from "@/components/ui/button"
6
7import { cn } from "@/lib/utils"
8
9function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
10 return (
11 <nav
12 data-slot="pagination"
13 role="navigation"
14 aria-label="pagination"
15 className={cn("mx-auto flex w-full justify-center", className)}
16 {...props}
17 />
18 )
19}
20
21function PaginationContent({
22 className,
23 ...props
24}: React.ComponentProps<"ul">) {
25 return (
26 <ul
27 data-slot="pagination-content"
28 className={cn("flex flex-row items-center gap-1", className)}
29 {...props}
30 />
31 )
32}
33
34function PaginationItem({ className, ...props }: React.ComponentProps<"li">) {
35 return (
36 <li data-slot="pagination-item" className={cn("", className)} {...props} />
37 )
38}
39
40function PaginationLink({
41 className,
42 isActive,
43 size = "icon",
44 ...props
45}: React.ComponentProps<"a"> & {
46 isActive?: boolean
47 size?: "default" | "sm" | "lg" | "icon"
48}) {
49 return (
50 <a
51 data-slot="pagination-link"
52 aria-current={isActive ? "page" : undefined}
53 className={cn(
54 buttonVariants({
55 variant: "noShadow",
56 size,
57 }),
58 className,
59 isActive && "bg-black text-white",
60 )}
61 {...props}
62 />
63 )
64}
65
66function PaginationPrevious({
67 className,
68 ...props
69}: React.ComponentProps<typeof PaginationLink>) {
70 return (
71 <PaginationLink
72 data-slot="pagination-previous"
73 aria-label="Go to previous page"
74 size="default"
75 className={cn("gap-1 pl-2.5", className)}
76 {...props}
77 >
78 <ChevronLeft className="size-4" />
79 <span>Previous</span>
80 </PaginationLink>
81 )
82}
83
84function PaginationNext({
85 className,
86 ...props
87}: React.ComponentProps<typeof PaginationLink>) {
88 return (
89 <PaginationLink
90 data-slot="pagination-next"
91 aria-label="Go to next page"
92 size="default"
93 className={cn("gap-1 pr-2.5", className)}
94 {...props}
95 >
96 <span>Next</span>
97 <ChevronRight className="size-4" />
98 </PaginationLink>
99 )
100}
101
102function PaginationEllipsis({
103 className,
104 ...props
105}: React.ComponentProps<"span">) {
106 return (
107 <span
108 data-slot="pagination-ellipsis"
109 aria-hidden
110 className={cn("flex size-9 items-center justify-center", className)}
111 {...props}
112 >
113 <MoreHorizontal className="size-4" />
114 <span className="sr-only">More pages</span>
115 </span>
116 )
117}
118
119export {
120 Pagination,
121 PaginationContent,
122 PaginationEllipsis,
123 PaginationItem,
124 PaginationLink,
125 PaginationNext,
126 PaginationPrevious,
127}
128