Components
Pagination
Moves between pages of a long list or table: Previous, the page numbers around the current one, Next. Pages are real links when they have a URL (getHref), or buttons that call onPageChange. They look like small Buttons: ghost, and secondary for the current page.
Preview
import { Pagination } from "@/components/ui/pagination"
<Pagination page={4} pageCount={12} onPageChange={goToPage} />Usage
When to use
- Move between pages of a long list or table, with the total number of pages known.
- Lists whose pages have a URL, so a page can be shared and reloaded.
When not to use
- A short list. Show it whole.
- The steps of a flow.
- Sections of one page. Use Tabs.
Examples
Links
Each page has a URL, so the pages are real links.
import { Pagination } from "@/components/ui/pagination"
<Pagination page={4} pageCount={12} getHref={pageHref} />Buttons
No URLs: the pages call onPageChange.
import { Pagination } from "@/components/ui/pagination"
<Pagination page={1} pageCount={5} onPageChange={goToPage} />Do and don't
Do
- Give pages a URL with getHref when the list has one, so a page can be shared and reloaded.
- Keep it under the list it pages, and move focus to the top of the list after a page change.
- Say how many results there are near the list, not only the page count.
- When the next page loads from the server, change page in a transition (useTransition) and keep the current rows on screen with Table pending, instead of blanking the list.
Don't
- Don't use it for the steps of a flow.
- Don't page a short list; show it whole.
- Don't change siblingCount between pages of one list; the links would jump.
Props
| Name | Type | Values | Default | Description |
|---|---|---|---|---|
| page | number | - | - | Set on Pagination. The current page, from 1. |
| pageCount | number | - | - | Set on Pagination. How many pages there are. |
| onPageChange | function | - | - | Set on Pagination. Called with the page to go to, when the pages are buttons. |
| siblingCount | number | - | 1 | Set on Pagination. Pages shown on each side of the current one. The first and last page always show. |
| getHref | function | - | - | Set on Pagination. Returns the URL of a page: (page) => `?page=${page}`. With it the pages are real links, so they open in a new tab and work without JavaScript. |
| isActive | boolean | - | false | Set on PaginationLink in your own layout. Marks the current page. |
Anatomy
| Part | Description |
|---|---|
| root | Pagination: a nav named Pagination. With page and pageCount it draws everything below; with children it holds your own PaginationContent. |
| content | PaginationContent: the row of items, gap-xs, that wraps. |
| item | PaginationItem: one slot in the row. |
| link | PaginationLink: a page, an sm ghost Button at least as wide as it is tall, with tabular figures. The current page is secondary. |
| step | PaginationPrevious and PaginationNext: sm ghost Buttons with a 16px caret and the words Previous and Next. |
| ellipsis | PaginationEllipsis: Tabler DotsThree, 16px, in place of the pages left out. |
| hitArea | Transparent ::before on every link, never smaller than size-target-min. |
Accessibility
Role: navigation
| Keys | Action |
|---|---|
| Tab | Moves through Previous, the pages and Next. |
| Enter, Space | Goes to that page (Space only on buttons). |
- The nav is named Pagination. Each page is named Page 3, and the current one carries aria-current="page".
- The current page stands out by its border and fill, not only by color.
- Previous on the first page and Next on the last are disabled: a button gets disabled, a link loses its href and gets aria-disabled.
- The ellipsis is decorative; the page numbers around it say where the gap is.
- Each page link keeps a size-target-min hit area.
Install
npx shadcn add https://werewolf-ui.vercel.app/r/pagination.jsonThis also adds styles/werewolf.css, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after @import "tailwindcss", with a path relative to that CSS file (from app/globals.css it is @import "../styles/werewolf.css").