Pagination

A navigation control for paged data. It lives beside a table or list — never inside it. Controlled by attributes but self-updating: moving the page updates page and fires nana-page-change, so the same component drives client-side slicing and server-side fetching.

Anatomy (recommended default)

pagination.html
html
1 <nana-pagination
2 page="7"
3 page-size="20"
4 total-items="2845"
5 show-first-last
6 show-result-count
7 show-page-size
8 show-jump
9 ></nana-pagination>

Layouts

layout="numbered" — scales to thousands of pages with ellipsis

layout="compact" — tiny footprint for mobile / side panels

layout="simple" — prev / next for docs & articles

layouts.html
html
1 <nana-pagination layout="numbered" show-first-last></nana-pagination>
2 <nana-pagination layout="compact"></nana-pagination>
3 <nana-pagination layout="simple"></nana-pagination>

Variants

default
ghost
filled
soft
pill
variants.html
html
1 <nana-pagination variant="default"></nana-pagination>
2 <nana-pagination variant="ghost"></nana-pagination>
3 <nana-pagination variant="filled"></nana-pagination>
4 <nana-pagination variant="soft"></nana-pagination>
5 <nana-pagination variant="pill"></nana-pagination>

Sizes

sm
md
lg

Live (client-side)

The control emits events; you own the data. Here it slices a 47-item array.

wire-up.ts
ts
1 const pager = document.querySelector('nana-pagination');
2
3 // Client-side: slice the array
4 pager.addEventListener('nana-page-change', (e) => {
5 const { page } = e.detail;
6 render(data.slice((page - 1) * pageSize, page * pageSize));
7 });
8
9 // Server-side: refetch
10 pager.addEventListener('nana-page-change', (e) => {
11 fetchUsers({ page: e.detail.page, limit: pager.pageSize }).then(render);
12 });
13
14 pager.addEventListener('nana-page-size-change', (e) => {
15 pageSize = e.detail.pageSize; // page resets to 1 automatically
16 });

Import

main.ts
ts
1 import "@nana-tec/ui-components/pagination";

Events

Event Detail
nana-page-change { page: number }
nana-page-size-change { pageSize: number }

Customization

Pick a variant and size; to brand the current page, set the accent variables.

pagination.css
css
1 /* Match the current-page accent to your brand (filled / pill variants) */
2 nana-pagination.brand {
3 --nana-pagination-active-bg: #2563eb;
4 --nana-pagination-active-color: #fff;
5 --nana-pagination-radius: 9999px;
6 }
CSS Variable Description
--nana-pagination-radiusCorner radius of the page controls
--nana-pagination-active-bgActive page background (filled / pill)
--nana-pagination-active-colorActive page text colour (filled / pill)
Part Description
navThe controls container
ellipsisThe truncation gap (…)

Props

Attribute Type Default Description
page number 1 Current page (1-based)
page-size number 10 Rows per page
total-items number Total items — derives pages + result count
total-pages number Explicit page count (when total is unknown)
variant default | ghost | filled | soft | pill default Visual style
layout numbered | compact | simple numbered Structural layout
size sm | md | lg md Control size (32 / 40 / 48px)
sibling-count number 1 Page numbers either side of current
boundary-count number 1 Page numbers pinned at each end
show-first-last boolean false Show « First / Last » buttons
show-result-count boolean false Show "Showing X–Y of Z"
show-page-size boolean false Show the rows-per-page selector
show-jump boolean false Show the jump-to-page input
page-size-options string "10,25,50,100" Comma-separated page sizes
disabled boolean false Disable the whole control

Accessibility

  • Rendered as a nav labelled "Pagination"; the current page carries aria-current="page".
  • Each page button has a descriptive label ("Go to page 5"); arrows are labelled "Previous/Next/First/Last page".
  • Keyboard: Tab to focus, Enter/Space to activate, and / to step pages.