Getting Started
Components
- Accordion
- Alert
- Alert Dialog
- Avatar
- Badge
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Collapsible
- Compare Slider
- Dialog
- Dropdown Menu
- Gauge
- Input
- Label
- Marquee
- Navigation Menu
- Number Field
- Pagination
- Popover
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Tooltip
Demos
Pagination with previous and next links and an ellipsis.
"use client"
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@workspace/ui/components/pagination"
export function 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>
)
}
Usage
Use pagination for long lists split across pages, such as past reports or invoices. It renders links, so each page can have its own URL.
Import it from @workspace/ui/components/pagination.
Anatomy
- Pagination — The
navlandmark, centred. - PaginationContent — The list of items.
- PaginationItem — One list item.
- PaginationLink — A page number. The active page gets an outline.
- PaginationPrevious and PaginationNext — Arrow links. Their text hides on small screens.
- PaginationEllipsis — Marks skipped pages.
Notes
- The active link has
aria-current="page". - Show the first and last pages and the ones around the current page. Replace the rest with an ellipsis.
- The links have no disabled state. On the first or last page, hide the arrow or style it with
aria-disabled, as in the controlled example.
Examples
Controlled
Keep the page in state and stop the links from navigating.
"use client"
import * as React from "react"
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "@workspace/ui/components/pagination"
const totalPages = 5
export function PaginationControlled() {
const [page, setPage] = React.useState(1)
const goTo = (next: number) => (event: React.MouseEvent) => {
event.preventDefault()
setPage(Math.min(Math.max(next, 1), totalPages))
}
return (
<div className="grid w-full gap-3">
<p className="text-center text-xs text-muted-foreground">
Reports {page * 10 - 9}–{page * 10} of {totalPages * 10}
</p>
<Pagination>
<PaginationContent>
<PaginationItem>
<PaginationPrevious
href="#"
onClick={goTo(page - 1)}
aria-disabled={page === 1}
className="aria-disabled:pointer-events-none aria-disabled:opacity-50"
/>
</PaginationItem>
{Array.from({ length: totalPages }, (_, i) => i + 1).map((n) => (
<PaginationItem key={n}>
<PaginationLink href="#" isActive={n === page} onClick={goTo(n)}>
{n}
</PaginationLink>
</PaginationItem>
))}
<PaginationItem>
<PaginationNext
href="#"
onClick={goTo(page + 1)}
aria-disabled={page === totalPages}
className="aria-disabled:pointer-events-none aria-disabled:opacity-50"
/>
</PaginationItem>
</PaginationContent>
</Pagination>
</div>
)
}
Props
Unlisted props pass through to the underlying element.
PaginationLink
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | — | Page URL. |
isActive | boolean | false | Marks the current page. |
size | Button size | icon | Size of the link. |
PaginationPrevious and PaginationNext
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | — | URL of the previous or next page. |
text | string | Previous or Next | Visible text. |