main
tsx 81 lines 2.62 KB
Raw
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<HTMLUListElement, React.ComponentProps<"ul">>(
18 ({ className, ...props }, ref) => (
19 <ul ref={ref} className={cn("flex flex-row items-center gap-1", className)} {...props} />
20 ),
21 );
22 PaginationContent.displayName = "PaginationContent";
23
24 const PaginationItem = React.forwardRef<HTMLLIElement, React.ComponentProps<"li">>(({ className, ...props }, ref) => (
25 <li ref={ref} className={cn("", className)} {...props} />
26 ));
27 PaginationItem.displayName = "PaginationItem";
28
29 type PaginationLinkProps = {
30 isActive?: boolean;
31 } & Pick<ButtonProps, "size"> &
32 React.ComponentProps<"a">;
33
34 const PaginationLink = ({ className, isActive, size = "icon", ...props }: PaginationLinkProps) => (
35 <a
36 aria-current={isActive ? "page" : undefined}
37 className={cn(
38 buttonVariants({
39 variant: isActive ? "outline" : "ghost",
40 size,
41 }),
42 className,
43 )}
44 {...props}
45 />
46 );
47 PaginationLink.displayName = "PaginationLink";
48
49 const PaginationPrevious = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
50 <PaginationLink aria-label="Go to previous page" size="default" className={cn("gap-1 pl-2.5", className)} {...props}>
51 <ChevronLeft className="h-4 w-4" />
52 <span>Previous</span>
53 </PaginationLink>
54 );
55 PaginationPrevious.displayName = "PaginationPrevious";
56
57 const PaginationNext = ({ className, ...props }: React.ComponentProps<typeof PaginationLink>) => (
58 <PaginationLink aria-label="Go to next page" size="default" className={cn("gap-1 pr-2.5", className)} {...props}>
59 <span>Next</span>
60 <ChevronRight className="h-4 w-4" />
61 </PaginationLink>
62 );
63 PaginationNext.displayName = "PaginationNext";
64
65 const PaginationEllipsis = ({ className, ...props }: React.ComponentProps<"span">) => (
66 <span aria-hidden className={cn("flex h-9 w-9 items-center justify-center", className)} {...props}>
67 <MoreHorizontal className="h-4 w-4" />
68 <span className="sr-only">More pages</span>
69 </span>
70 );
71 PaginationEllipsis.displayName = "PaginationEllipsis";
72
73 export {
74 Pagination,
75 PaginationContent,
76 PaginationEllipsis,
77 PaginationItem,
78 PaginationLink,
79 PaginationNext,
80 PaginationPrevious,
81 };