Skip to content

Pagination

Page navigation controls for paginated content.

Source Code

Areia's Pagination renders page information, navigation controls, optional page-size selectors, and emits page-change events when used as an Ilha island with Pagination.

Showing 1-25 of 100
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination page={1} perPage={25} totalCount={100} />
));

Import

import { Pagination } from "areia";

Usage

Call Pagination(...) when you want interactive controls. It dispatches pagination:page-change and calls setPage / onPageChange when controls are used.

Showing 26-50 of 250
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination page={2} perPage={25} totalCount={250} />
));

Use Pagination.Static(...) for static markup or when you want to wire events yourself. For most application usage, call Pagination(...).

Examples

Full Controls

The default pagination includes first, previous, page input, next, and last buttons.

Showing 1-25 of 100
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination page={1} perPage={25} totalCount={100} />
));

Simple Controls

Use controls: "simple" for previous and next buttons only.

Showing 101-125 of 250
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination
    controls="simple"
    page={5}
    perPage={25}
    totalCount={250}
  />
));

Mid-Page State

Pagination in the middle of a dataset with all navigation buttons enabled.

Showing 101-125 of 250
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination page={5} perPage={25} totalCount={250} />
));

Large Dataset

Pagination handles large datasets. Use the input page selector for large page counts to avoid rendering many options.

Showing 1-25 of 10000
import ilha from "ilha";
import { Pagination } from "areia";

export default ilha.render(() => (
  <Pagination page={1} perPage={25} totalCount={10000} />
));

Custom Info Text

Use Pagination.Info with explicit children to customize the visible text.

import ilha from "ilha";
import { Pagination } from "areia";

const page = 3;
const perPage = 25;
const totalCount = 100;
const maxPage = Math.ceil(totalCount / perPage);

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
  >
    <Pagination.Info>
      Page {page} of {maxPage}
    </Pagination.Info>
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
  </Pagination>
));

Compound Components

Use the compound helpers when you need custom layout or page-size controls.

Page Size Selector

Pagination.PageSize renders a native select for choosing page size. In island mode, changing it emits pagination:page-size-change and calls onPageSizeChange on Pagination when provided.

import ilha from "ilha";
import { Pagination } from "areia";

const page = 1;
const perPage = 25;
const totalCount = 500;

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
  >
    <Pagination.Info
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
    <Pagination.Separator />
    <Pagination.PageSize value={perPage} />
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
  </Pagination>
));

Custom Page Size Options

Customize page-size options with the options prop. Defaults to [25, 50, 100, 250].

import ilha from "ilha";
import { Pagination } from "areia";

const page = 1;
const perPage = 10;
const totalCount = 100;

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
  >
    <Pagination.Info
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
    <Pagination.PageSize
      value={perPage}
      options={[10, 20, 50]}
    />
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
  </Pagination>
));

Custom Layout

Arrange the helpers in any order.

import ilha from "ilha";
import { Pagination } from "areia";

const page = 2;
const perPage = 50;
const totalCount = 400;

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
  >
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
    <div class="grow"></div>
    <Pagination.PageSize value={perPage} />
    <Pagination.Info
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
  </Pagination>
));

Use pageSelector: "dropdown" to render a select with one option per page. This is best for small page counts.

import ilha from "ilha";
import { Pagination } from "areia";

const page = 2;
const perPage = 25;
const totalCount = 100;

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
  >
    <Pagination.Info
      page={page}
      perPage={perPage}
      totalCount={totalCount}
    />
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
      pageSelector="dropdown"
    />
  </Pagination>
));

Internationalization

Use labels to customize ARIA labels. Visible text can be customized with Pagination.Info children and the label prop on Pagination.PageSize.

import ilha from "ilha";
import { Pagination } from "areia";

const page = 1;
const perPage = 25;
const totalCount = 100;
const labels = {
  navigation: "Pagination",
  firstPage: "Première page",
  previousPage: "Page précédente",
  nextPage: "Page suivante",
  lastPage: "Dernière page",
  pageNumber: "Numéro de page",
  pageSize: "Taille de page",
};

export default ilha.render(() => (
  <Pagination
    page={page}
    perPage={perPage}
    totalCount={totalCount}
    labels={labels}
  >
    <Pagination.Info>
      Affichage de <span class="tabular-nums">1-25</span> sur{" "}
      <span class="tabular-nums">100</span>
    </Pagination.Info>
    <Pagination.PageSize
      value={perPage}
      label="Par page :"
      labels={labels}
    />
    <Pagination.Controls
      page={page}
      perPage={perPage}
      totalCount={totalCount}
      labels={labels}
    />
  </Pagination>
));

Listening for Changes

Pagination dispatches DOM events when controls are used. Use these when you are not passing callback functions.

const root = document.querySelector('[data-slot="pagination"]');

root?.addEventListener("pagination:page-change", (event) => {
  const { page } = (event as CustomEvent<{ page: number }>)
    .detail;
  console.log(page);
});

root?.addEventListener(
  "pagination:page-size-change",
  (event) => {
    const { pageSize } = (
      event as CustomEvent<{ pageSize: number }>
    ).detail;
    console.log(pageSize);
  },
);

API Reference

Pagination

Pagination is an Ilha island. It accepts standard HTML div attributes plus the following props.

PropTypeDefaultDescription
pagenumber1Current page number, 1-indexed.
setPage(page: number) => void-Callback fired when page changes.
onPageChange(page: number) => void-Alias callback fired when page changes.
perPagenumber-Number of items displayed per page.
onPageSizeChange(size: number) => void-Callback fired when page size changes.
totalCountnumber-Total number of items across all pages.
controls"full" | "simple""full"Control layout for the default renderer.
pageSelector"input" | "dropdown""input"Page selector style.
childrenunknown-Compound children for custom layouts.
labelsPaginationLabelsEnglishLabels for aria-labels.
classstring-Additional CSS classes.
classNamestring-Alias for class.

Pagination.Info

PropTypeDefaultDescription
pagenumber1Current page.
perPagenumber-Page size.
totalCountnumber-Total item count.
childrenunknown-Custom content. Defaults to Showing X-Y of Z.
classstring-Additional CSS classes.
classNamestring-Alias for class.

Pagination.PageSize

PropTypeDefaultDescription
valuenumber-Current page-size value.
optionsnumber[][25, 50, 100, 250]Available page-size options.
labelunknown"Per page:"Visible label before the select.
labelsPaginationLabelsEnglishAria labels.
namestring-Native select name.
classstring-Additional CSS classes.
classNamestring-Alias for class.

Pagination.Controls

PropTypeDefaultDescription
pagenumber1Current page.
perPagenumber-Page size.
totalCountnumber-Total item count.
controls"full" | "simple""full"Control layout.
pageSelector"input" | "dropdown""input"Page selector style.
labelsPaginationLabelsEnglishAria labels.
buttonSize"xs" | "sm" | "base" | "lg""base"Button size.
classstring-Additional CSS classes.
classNamestring-Alias for class.

Pagination.Separator

Renders a vertical separator for compound layouts. Accepts standard div attributes plus class and className.

Accessibility

  • Pagination controls are wrapped in a nav with an accessible label.
  • Control buttons have aria-labels for first, previous, next, and last page.
  • Default info text is wrapped in an aria-live region so page range updates can be announced.
  • Page input uses aria-label and commits on blur or Enter.