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