From 5b7ccf0b671e2999b62befc729a3e517a0433728 Mon Sep 17 00:00:00 2001
From: Bertrand Yuan <bert.yuan@outlook.com>
Date: Mon, 15 Dec 2025 23:48:10 +0800
Subject: initial commit -- the front-end prototype

The initial code is base on Anirudh's work.

More to see at:

    https://github.com/techwithanirudh/shadcn-blog

Therefore, the code in this commit is under MIT license.
---
 src/components/ui/pagination.tsx | 126 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)
 create mode 100644 src/components/ui/pagination.tsx

(limited to 'src/components/ui/pagination.tsx')

diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx
new file mode 100644
index 0000000..e1bee31
--- /dev/null
+++ b/src/components/ui/pagination.tsx
@@ -0,0 +1,126 @@
+import {
+  ChevronLeftIcon,
+  ChevronRightIcon,
+  MoreHorizontalIcon,
+} from 'lucide-react';
+import type * as React from 'react';
+
+import { type Button, buttonVariants } from '@/components/ui/button';
+import { cn } from '@/lib/utils';
+
+function Pagination({ className, ...props }: React.ComponentProps<'nav'>) {
+  return (
+    <nav
+      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',
+  ...props
+}: PaginationLinkProps) {
+  return (
+    <a
+      aria-current={isActive ? 'page' : undefined}
+      data-slot='pagination-link'
+      data-active={isActive}
+      className={cn(
+        buttonVariants({
+          variant: isActive ? 'outline' : 'ghost',
+          size,
+        }),
+        className,
+      )}
+      {...props}
+    />
+  );
+}
+
+function PaginationPrevious({
+  className,
+  ...props
+}: React.ComponentProps<typeof PaginationLink>) {
+  return (
+    <PaginationLink
+      aria-label='Go to previous page'
+      size='default'
+      className={cn('gap-1 px-2.5 sm:pl-2.5', className)}
+      {...props}
+    >
+      <ChevronLeftIcon />
+      <span className='hidden sm:block'>Previous</span>
+    </PaginationLink>
+  );
+}
+
+function PaginationNext({
+  className,
+  ...props
+}: React.ComponentProps<typeof PaginationLink>) {
+  return (
+    <PaginationLink
+      aria-label='Go to next page'
+      size='default'
+      className={cn('gap-1 px-2.5 sm:pr-2.5', 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-9 items-center justify-center', className)}
+      {...props}
+    >
+      <MoreHorizontalIcon className='size-4' />
+      <span className='sr-only'>More pages</span>
+    </span>
+  );
+}
+
+export {
+  Pagination,
+  PaginationContent,
+  PaginationLink,
+  PaginationItem,
+  PaginationPrevious,
+  PaginationNext,
+  PaginationEllipsis,
+};
-- 
cgit v1.2.3

