Skip to content

Commit

Permalink
Merge pull request #941 from tszhong0411/pack-14-add-pagination
Browse files Browse the repository at this point in the history
Add pagination
  • Loading branch information
tszhong0411 authored Jan 9, 2025
2 parents d2bd5e0 + c7cbc8f commit a8502dc
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-spies-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tszhong0411/ui': patch
---

add pagination component
39 changes: 39 additions & 0 deletions apps/docs/src/app/ui/components/pagination.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
title: Pagination
description: Pagination with page navigation, next and previous links.
---

<ComponentPreview name='pagination/pagination' />

## Usage

```tsx
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious
} from '@/components/ui/pagination'
```

```tsx
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious href='#' />
</PaginationItem>
<PaginationItem>
<PaginationLink href='#'>1</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href='#' />
</PaginationItem>
</PaginationContent>
</Pagination>
```
40 changes: 40 additions & 0 deletions apps/docs/src/components/demos/pagination/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious
} from '@tszhong0411/ui'

const PaginationDemo = () => {
return (
<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>
)
}

export default PaginationDemo
4 changes: 4 additions & 0 deletions apps/docs/src/config/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ export const SIDEBAR_LINKS: SidebarLinks = [
href: '/ui/components/navigation-menu',
text: 'Navigation Menu'
},
{
href: '/ui/components/pagination',
text: 'Pagination'
},
{
href: '/ui/components/popover',
text: 'Popover'
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export * from './link'
export * from './logo'
export * from './marquee'
export * from './navigation-menu'
export * from './pagination'
export * from './popover'
export * from './resizable'
export * from './scroll-area'
Expand Down
113 changes: 113 additions & 0 deletions packages/ui/src/pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { cn } from '@tszhong0411/utils'
import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react'
import Link from 'next/link'

import { type ButtonProps, buttonVariants } from './button'

type PaginationProps = React.ComponentProps<'nav'>

export const Pagination = (props: PaginationProps) => {
const { className, ...rest } = props

return (
<nav
role='navigation'
aria-label='pagination'
className={cn('mx-auto flex w-full justify-center', className)}
{...rest}
/>
)
}

type PaginationContentProps = React.ComponentProps<'ul'>

export const PaginationContent = (props: PaginationContentProps) => {
const { className, ...rest } = props

return <ul className={cn('flex flex-row items-center gap-1', className)} {...rest} />
}

type PaginationItemProps = React.ComponentProps<'li'>

export const PaginationItem = (props: PaginationItemProps) => {
const { className, ...rest } = props

return <li className={cn(className)} {...rest} />
}

type PaginationLinkProps = {
isActive?: boolean
} & Pick<ButtonProps, 'size'> &
React.ComponentProps<typeof Link>

export const PaginationLink = (props: PaginationLinkProps) => {
const { className, isActive, size = 'icon', ...rest } = props

return (
// eslint-disable-next-line jsx-a11y/anchor-has-content -- it's a component
<Link
aria-current={isActive ? 'page' : undefined}
className={cn(
buttonVariants({
variant: isActive ? 'outline' : 'ghost',
size
}),
className
)}
{...rest}
/>
)
}

type PaginationPreviousProps = React.ComponentProps<typeof PaginationLink>

export const PaginationPrevious = (props: PaginationPreviousProps) => {
const { className, ...rest } = props

return (
<PaginationLink
aria-label='Go to previous page'
size='default'
className={cn('gap-1 pl-2.5', className)}
{...rest}
>
<ChevronLeftIcon className='size-4' />
<span>Previous</span>
</PaginationLink>
)
}

type PaginationNextProps = React.ComponentProps<typeof PaginationLink>

export const PaginationNext = (props: PaginationNextProps) => {
const { className, ...rest } = props

return (
<PaginationLink
aria-label='Go to next page'
size='default'
className={cn('gap-1 pr-2.5', className)}
{...rest}
>
<span>Next</span>
<ChevronRightIcon className='size-4' />
</PaginationLink>
)
}

type PaginationEllipsisProps = React.ComponentProps<'span'>

export const PaginationEllipsis = (props: PaginationEllipsisProps) => {
const { className, ...rest } = props

return (
<span
aria-hidden
className={cn('flex size-9 items-center justify-center', className)}
{...rest}
>
<MoreHorizontalIcon className='size-4' />
<span className='sr-only'>More pages</span>
</span>
)
}

0 comments on commit a8502dc

Please sign in to comment.