Pagination
Page navigation for tables and lists. Previous/next arrows, numbered pages that collapse to "…" around the current page, and an optional "1–20 of 482" summary. It's controlled — you track the page and update it on change.
bash
jlds add paginationUsage
html
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/jarooda/jlds@main/registry/css/pagination.css">
<nav class="jl-pagination" aria-label="Pagination">
<div class="jl-pagination__list">
<button class="jl-page jl-page--arrow" aria-label="Previous page">‹</button>
<button class="jl-page" aria-label="Page 1">1</button>
<button class="jl-page" aria-current="page" aria-label="Page 2">2</button>
<button class="jl-page" aria-label="Page 3">3</button>
<button class="jl-page jl-page--arrow" aria-label="Next page">›</button>
</div>
</nav>vue
<script setup lang="ts">
import { ref } from "vue"
import { Pagination } from "@/components/ui/pagination"
const page = ref(2)
</script>
<template>
<Pagination v-model:page="page" :page-count="10" />
</template>tsx
import { useState } from "react"
import { Pagination } from "@/components/ui/pagination"
const [page, setPage] = useState(2)
<Pagination page={page} pageCount={10} onChange={setPage} />Collapsed (many pages)
With many pages, the middle collapses to "…" — siblingCount controls how many neighbors stay visible around the current page.
html
<nav class="jl-pagination" aria-label="Pagination">
<div class="jl-pagination__list">
<button class="jl-page jl-page--arrow" aria-label="Previous page">‹</button>
<button class="jl-page" aria-label="Page 1">1</button>
<span class="jl-page jl-page--ellipsis" aria-hidden="true">…</span>
<button class="jl-page" aria-label="Page 5">5</button>
<button class="jl-page" aria-current="page" aria-label="Page 6">6</button>
<button class="jl-page" aria-label="Page 7">7</button>
<span class="jl-page jl-page--ellipsis" aria-hidden="true">…</span>
<button class="jl-page" aria-label="Page 20">20</button>
<button class="jl-page jl-page--arrow" aria-label="Next page">›</button>
</div>
</nav>vue
<template>
<Pagination v-model:page="page" :page-count="20" :sibling-count="1" />
</template>tsx
<Pagination page={page} pageCount={20} siblingCount={1} onChange={setPage} />With summary
Pass total, pageSize, and showSummary for the "1–20 of 482" readout on the left.
html
<nav class="jl-pagination" aria-label="Pagination">
<div class="jl-pagination__summary"><b>1–20</b> of <b>482</b></div>
<div class="jl-pagination__spacer"></div>
<div class="jl-pagination__list"><!-- page buttons --></div>
</nav>vue
<template>
<Pagination
v-model:page="page"
:page-count="25"
:total="482"
:page-size="20"
show-summary
/>
</template>tsx
<Pagination
page={page}
pageCount={25}
total={482}
pageSize={20}
showSummary
onChange={setPage}
/>Props
React
Pagination extends React.HTMLAttributes<HTMLElement> (minus onChange).
| Prop | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Current page (1-based) |
pageCount | number | — | Total number of pages (required) |
total | number | — | Record count — for the summary |
pageSize | number | — | Records per page — for the summary |
siblingCount | number | 1 | Pages shown each side of current before "…" |
showSummary | boolean | false | Show the "1–20 of 482" summary |
onChange | (page: number) => void | — | Fires with the next page |
Vue
Same props. Supports v-model:page, and also emits a change event with the next page.
CSS classes (HTML)
| Class | Purpose |
|---|---|
.jl-pagination | Wrapper (nav) |
.jl-pagination__summary | The "1–20 of 482" readout |
.jl-pagination__spacer | Pushes the page list to the right |
.jl-pagination__list | The control group |
.jl-page | A page button (use aria-current="page" for the active one) |
.jl-page--arrow | Previous/next arrow buttons |
.jl-page--ellipsis | The "…" gap |