PixelPagination

Windowed page-number navigator with Prev/Next, ellipses, and first/last anchors for navigating long paginated collections.

  • Windowed page list with ellipses to handle large totals without overflow.
  • Configurable siblings to widen or tighten the visible window around the current page.
  • Prev/Next buttons auto-disable at the edges (page 1 and last page).
  • Localised prevLabel, nextLabel, and ariaLabel for i18n.
  • Pixel and linear surfaces follow the nearest PxlKitSurfaceProvider.
Status
stable
Category
navigation
Since
v1.0.0

API

import { PixelPagination } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
page (required)number—Current page (1-indexed).
total (required)number—Total number of pages.
onChange (required)(next: number) => void—Fires when the user picks a new page.
siblingsnumber1Sibling pages to show around the current. Defaults to 1.
surface'pixel' | 'linear'—Visual surface treatment override.
ariaLabelstring'Pagination'Accessible label for the nav region.
prevLabelstring'Prev'Localised label for the Prev button.
nextLabelstring'Next'Localised label for the Next button.

ref points to its element (HTMLElement).

Accessibility

WCAG target: 2.1 AA

  • navigation

Rendered as a <nav> landmark with a configurable aria-label. The current page button carries aria-current="page"; ellipses are aria-hidden so screen readers skip decorative gaps. Prev/Next buttons disable at the edges instead of being removed, preserving layout and predictable tab order.

Keyboard

KeyActionWhen
TabMoves focus through Prev, page buttons, and Next.—
EnterActivates the focused page or Prev/Next button.—
SpaceActivates the focused page or Prev/Next button.—

Usage

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function Default() {
  const [page, setPage] = useState(1);
  return <PixelPagination page={page} total={10} onChange={setPage} />;
}

Examples

Default

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function Default() {
  const [page, setPage] = useState(1);
  return <PixelPagination page={page} total={10} onChange={setPage} />;
}

Many Pages

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function ManyPages() {
  const [page, setPage] = useState(5);
  return <PixelPagination page={page} total={50} onChange={setPage} />;
}

Mid Window

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function MidWindow() {
  const [page, setPage] = useState(10);
  return <PixelPagination page={page} total={20} onChange={setPage} />;
}

More Siblings

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function MoreSiblings() {
  const [page, setPage] = useState(8);
  return <PixelPagination page={page} total={20} onChange={setPage} siblings={2} />;
}

Pixel Surface

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function PixelSurface() {
  const [page, setPage] = useState(3);
  return <PixelPagination page={page} total={12} onChange={setPage} surface="pixel" />;
}

Linear Surface

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function LinearSurface() {
  const [page, setPage] = useState(3);
  return <PixelPagination page={page} total={12} onChange={setPage} surface="linear" />;
}

Localised Labels

import { useState } from 'react';
import { PixelPagination } from '@pxlkit/ui-kit';

export function LocalisedLabels() {
  const [page, setPage] = useState(2);
  return (
    <PixelPagination
      page={page}
      total={8}
      onChange={setPage}
      prevLabel="Anterior"
      nextLabel="Siguiente"
      ariaLabel="Paginación"
    />
  );
}

First Page

import { PixelPagination } from '@pxlkit/ui-kit';

export function FirstPage() {
  return <PixelPagination page={1} total={10} onChange={() => {}} />;
}

Last Page

import { PixelPagination } from '@pxlkit/ui-kit';

export function LastPage() {
  return <PixelPagination page={10} total={10} onChange={() => {}} />;
}

Single Page

import { PixelPagination } from '@pxlkit/ui-kit';

export function SinglePage() {
  return <PixelPagination page={1} total={1} onChange={() => {}} />;
}

Related