Pagination

Page navigation control. Numbered, prev/next-only, and compact variants.

Overview

The Pagination component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.

Why this exists

Pagination enables navigation through large datasets. It communicates the total volume of data and the user's current position within it.

Mental model

Pagination splits a large list into manageable pages. It shows page numbers, prev/next, and optionally total count and per-page selector.

When to use

• Data tables with 20+ rows per page • Search results • Product listings • Any list too large for infinite scroll

When not to use

• Do not use for small lists (< 20 items) — show all • Avoid for feed-style content — use infinite scroll • Do not use when the user needs to compare across pages — use a single view

Basic example

The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.

Variants

Each variant communicates a different meaning. Choose based on priority, not aesthetics.

Single default variant.

Sizes

Size should match the importance and context of the component.

  • md — md size.

States

This component reacts seamlessly to the following interaction and data states:

  • default — Resting appearance before interaction.
  • active — Currently selected or in use.
  • disabled — Non-interactive — grayed out, cursor not-allowed.
  • hover — Pointer is over the element — visual feedback via color or shadow.
  • focus — Keyboard or tab focus — shows ring indicator for accessibility.

Anatomy

• Page numbers — clickable buttons • Prev/Next — arrow buttons • Ellipsis — indicates skipped pages • Per-page selector — optional dropdown • Total count —"Showing 1-20 of 342"

Usage guidelines

  • Show 5-7 page numbers at most.
  • Always show prev/next.
  • Include a per-page selector for large datasets.

Do and Don't

Do

  • Show prev/next always.
  • Limit visible page numbers.
  • Include total count.

Don't

  • Do not show all page numbers for large datasets.
  • Do not disable prev/next when other pages exist.
  • Do not omit the per-page selector for 100+ items.

Accessibility

Uses <nav aria-label="Pagination">. Current page has aria-current="page". Prev/Next have descriptive labels.

Role:navigation

Customization

Active page color follows --primary.

Compose with React cva()

Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.

import { cva, cn, type VariantProps } from '@byteion/react';

const myPagination = cva('base classes…', {
 variants: {
  accent: { soft:'border-primary-200', loud:'border-primary-500' },
 },
 defaultVariants: { accent:'soft' },
});

type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof myPagination>;

Compose with Vue cva()

Use the exportedcva() +cn() utilities inside standard Vue setup blocks.

<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';

interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();

const myPagination = cva('base classes…', {
  variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});

const cls = computed(() => myPagination({ accent: props.accent, class: attrs.class as string | undefined }));
</script>

Runtime events

Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.

HTML / JS events

No HTML runtime events are declared by this adapter.

React callbacks

  • onPageChange(page: number) => void

Vue emits

  • pageChange[page: number]

Remote / AJAX

This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.

API Reference

Static HTML. Page changes trigger navigation or API call.

HTML Data Attributes

No custom data attributes required.

React Props · PaginationProps

Extracted directly fromreact/src/components/Pagination.tsx.

export interface PaginationProps extends Omit<HTMLAttributes<HTMLElement>, 'onChange'> {
  /** Current 1-based page number. */
  page: number;
  /** Total number of pages. */
  totalPages: number;
  /** Called with the new page number. */
  onPageChange: (page: number) => void;
  /** Visual layout. */
  variant?: 'numbered' | 'prev-next' | 'compact';
  /** Max number of page buttons shown in the numbered variant. Default 5. */
  siblings?: number;
  /** Accessible label for the nav element. */
  'aria-label'?: string;
}

Vue Props · PaginationProps

Extracted directly fromvue/src/components/Pagination.vue.

export interface PaginationProps {
  /** Current 1-based page number. */
  page: number;
  /** Total number of pages. */
  totalPages: number;
  /** Visual layout. */
  variant?: 'numbered' | 'prev-next' | 'compact';
  /** Max number of page buttons shown in the numbered variant. Default 5. */
  siblings?: number;
  /** Accessible label for the nav element. */
  ariaLabel?: string;
}

Developer tips

• Best practice: preserve scroll position after page change — jump to top of the table, not the top of the page.

Common mistakes

  • Showing too many page buttons — use the siblings prop to limit the range.
  • Losing filter/search/sort query when the page changes — preserve state in the parent component or URL.
  • Using <button> for server-side links that should be crawlable or deep-linkable — use <a> tags instead.
  • Using <a> for purely client-side state without preventing default navigation.
  • Forgetting disabled states on the first and last page — the component handles this automatically.
  • Not resetting to page 1 after changing filters or search terms.
  • Not announcing the current page to assistive technology — aria-current="page" is built in.
  • Using v-model with the Vue Pagination — use page + @page-change instead.

Production usage tips

  • For Laravel/server-rendered apps, use anchor links with query params (?page=2) instead of client-side state.
  • For React/Vue SPAs, keep page in component state or router query (useSearchParams / vue-router query).
  • For data tables, coordinate pagination with sorting, filtering, loading, empty, and error states — a single query state object helps.
  • Test with page 1, a middle page, the last page, totalPages=1, and very large totals (100+ pages).
  • Test dark mode and branded themes — token-based colors adapt automatically.
  • Test disabled state on Previous when on page 1 and Next when on the last page.

Premium examples

Advanced patterns available in Byteion Pro:

• Pagination with result count and per-page selector — "Showing 1–20 of 940" with a dropdown for 10/20/50/100. • Server-side paginated data table — pagination, sorting, and filtering coordinated in a single query state. • Cursor-based pagination for activity logs — "Load more" style with a page indicator. • Jump-to-page input — a small input field between page numbers for direct navigation. • Go-to-page dropdown — a select/dropdown for quickly jumping to a specific page in large datasets.

Unlock Premium Patterns

Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.

Explore Pro Components