Pagination
Page numbers with previous and next, from a page count or composed from parts.
Composed
Built from parts: links, the current page outlined, an ellipsis.
Code
<Pagination>
<PaginationContent>
<PaginationItem><PaginationPrevious href="?page=1" /></PaginationItem>
<PaginationItem><PaginationLink href="?page=1">1</PaginationLink></PaginationItem>
<PaginationItem><PaginationLink href="?page=2" active>2</PaginationLink></PaginationItem>
<PaginationItem><PaginationLink href="?page=3">3</PaginationLink></PaginationItem>
<PaginationItem><PaginationEllipsis /></PaginationItem>
<PaginationItem><PaginationNext href="?page=3" /></PaginationItem>
</PaginationContent>
</Pagination>Usage
import { Pagination } from "@elements/ui/pagination";
<Pagination page={state.page} total={20} />
<Pagination page={current} total={20} href={(p) => `/orders?page=${p}`} />Examples
Simple
Page numbers only.
Code
<Pagination>
<PaginationContent>
<PaginationItem><PaginationLink href="?page=1">1</PaginationLink></PaginationItem>
<PaginationItem><PaginationLink href="?page=2" active>2</PaginationLink></PaginationItem>
...
</PaginationContent>
</Pagination>From a page count
total renders the range: the ends, siblings around the current page, ellipses for the gaps. Bind page to control it.
Code
<Pagination page={state.page} total={20} onPageChange={(p) => load(p)} />Links
href turns each page into a link, so the page works without script and can be opened in a new tab.
Code
<Pagination page={current} total={12} href={(p) => `/orders?page=${p}`} />Edges and more siblings
edges adds First and Last; siblings=2 shows two pages either side.
Code
<Pagination page={state.page} total={50} siblings={2} edges />Ranges
siblings=0 keeps only the current page between the ellipses; boundaries=2 keeps two pages at each end.
Code
<Pagination page={state.page} total={20} siblings={0} boundaries={2} />First and last only
controls=false with edges keeps First and Last and drops Previous and Next.
Code
<Pagination page={state.page} total={10} controls={false} edges />Paged content
The bound page picks which slice of a list to show.
- Apple
- Banana
- Cherry
- Date
- Elderberry
Code
<ul>
<li e:for={item of items.slice((state.page - 1) * 5, state.page * 5)}>{item}</li>
</ul>
<Pagination page={state.page} total={Math.ceil(items.length / 5)} />Disabled
disabled turns off every page and control at once, while a list loads.
Code
<Pagination page={state.page} total={10} disabled={state.loading} />Translated parts
Translated text with no label names the control by its text, so the name matches what is on screen. label sets a longer one.
Code
<Pagination>
<PaginationContent>
<PaginationItem><PaginationPrevious href="?page=1" text="Précédent" /></PaginationItem>
...
<PaginationItem><PaginationNext href="?page=3" text="Suivant" label="Aller à la page suivante" /></PaginationItem>
</PaginationContent>
</Pagination>In a table footer
numbers=false keeps only Previous and Next with a page count, beside a rows-per-page select.
Code
<div class="table-footer">
<label>Rows per page <select value={state.rows}>...</select></label>
<Pagination page={state.page} total={8} numbers={false} />
</div>Custom status
statusText formats the text between Previous and Next, here the rows on screen. The status keeps the width of its longest text, so Next never moves.
Code
<Pagination page={state.page} total={15} numbers={false}
statusText={(p) => `Showing ${(p - 1) * 10 + 1} to ${Math.min(p * 10, 145)} of 145`} />Small
size=sm for dense layouts.
Code
<Pagination size="sm" page={state.page} total={5} />Many pages
Every page slot keeps the width of the widest page number, so moving from page 1 to page 600 moves nothing.
Code
<Pagination page={state.page} total={1200} />Large
size=lg for touch screens and roomy layouts.
Code
<Pagination size="lg" page={state.page} total={10} />Outlined
variant=outlined draws a border on every page and control; the current page takes the accent border.
Code
<Pagination variant="outlined" page={state.page} total={10} />Color
color=primary fills the current page with the primary button color, color=secondary with the secondary one.
Code
<Pagination color="primary" page={state.page} total={10} />
<Pagination color="secondary" page={state.page} total={10} />Circular
shape=circular makes every page and control round.
Code
<Pagination shape="circular" page={state.page} total={10} />Custom icons
The first-icon, previous-icon, next-icon, last-icon and dots-icon slots replace the chevrons and the ellipsis.
Code
<Pagination page={state.page} total={20} edges>
<Icon slot="first-icon" name="arrow-left-to-line" />
<Icon slot="previous-icon" name="arrow-left" />
<Icon slot="next-icon" name="arrow-right" />
<Icon slot="last-icon" name="arrow-right-to-line" />
<Icon slot="dots-icon" name="dot" />
</Pagination>Start value
startValue numbers the pages from it: here 5 to 15.
Code
<Pagination startValue={5} page={state.page} total={15} />Icons only
Empty previousText and nextText leave square chevrons, named for screen readers.
Code
<Pagination page={state.page} total={10} previousText="" nextText="" />Hide with one page
hideWithOnePage renders nothing while there is only one page of results.
Code
<Pagination page={state.page} total={results.pages} hideWithOnePage />No results
total=0, an empty result: Previous and Next stay in place, disabled, so the pager keeps its height when results arrive.
Code
<Pagination page={1} total={results.pages} /> <!-- 0 while there are no results -->Responsive layout
layout=responsive shows every page in a wide container and Page X of Y between the chevrons in a narrow one, such as a sidebar. Drag the box's corner to resize it.
Code
<aside class="sidebar">
<Pagination page={state.page} total={20} layout="responsive" />
</aside>Right to left
Controls and chevrons mirror; previousText, nextText and getItemLabel translate the text and the labels.
Code
<div dir="rtl">
<Pagination page={state.page} total={10}
previousText="السابق" nextText="التالي" label="ترقيم الصفحات"
getItemLabel={arabicLabel} />
</div>
function arabicLabel(kind: PaginationItemKind, page: number): string {
switch (kind) {
case "previous":
return "السابق، الصفحة " + page;
case "next":
return "التالي، الصفحة " + page;
case "first":
return "الصفحة الأولى";
case "last":
return "الصفحة الأخيرة";
default:
return "الصفحة " + page;
}
}