react ~5 KB 0 deps v0.1.0 โ†— GitHub โ†—

@mshafiqyajid/react-pagination

Headless pagination hook and styled component. Ellipsis algorithm, page size selector, controlled and uncontrolled state, multiple variants and sizes, full keyboard and ARIA support.

Playground #

Page 1 of 10 โ€” showing items 1โ€“10 of 100

Props
TSX
import { PaginationStyled } from "@mshafiqyajid/react-pagination/styled";
import "@mshafiqyajid/react-pagination/styles.css";

<PaginationStyled />

Install #

npm install @mshafiqyajid/react-pagination

Quick start #

import { useState } from "react";
import { PaginationStyled } from "@mshafiqyajid/react-pagination/styled";
import "@mshafiqyajid/react-pagination/styles.css";

function App() {
  const [page, setPage] = useState(1);
  return (
    <PaginationStyled
      page={page}
      onChange={setPage}
      total={200}
      pageSize={10}
    />
  );
}

Variants #

Three visual variants: "default" (filled active page), "outline" (bordered buttons), and "ghost" (no borders, bold active).

<PaginationStyled total={100} variant="default" />
<PaginationStyled total={100} variant="outline" />
<PaginationStyled total={100} variant="ghost" />

Tones #

Use tone="primary" to apply a branded color to the active page button.

<PaginationStyled total={100} tone="neutral" />
<PaginationStyled total={100} tone="primary" />

Sizes #

<PaginationStyled total={100} size="sm" />
<PaginationStyled total={100} size="md" />
<PaginationStyled total={100} size="lg" />

Page size selector #

Enable a native <select> for rows-per-page with showPageSize.

const [pageSize, setPageSize] = useState(10);

<PaginationStyled
  total={500}
  pageSize={pageSize}
  onPageSizeChange={setPageSize}
  pageSizeOptions={[10, 25, 50, 100]}
  showPageSize
/>

Ellipsis algorithm #

The siblings prop controls how many page buttons appear on each side of the current page before an ellipsis is shown. boundaries controls how many pages are always shown at the start and end.

{/* Show 2 siblings on each side of current page */}
<PaginationStyled total={500} siblings={2} />

{/* Always show 2 boundary pages at each end */}
<PaginationStyled total={500} boundaries={2} />

Headless #

import { usePagination } from "@mshafiqyajid/react-pagination";

function MyPagination() {
  const {
    page,
    pages,
    totalPages,
    hasPrev,
    hasNext,
    prev,
    next,
    getPageProps,
    prevProps,
    nextProps,
    firstProps,
    lastProps,
  } = usePagination({ total: 200, pageSize: 10 });

  return (
    <nav role="navigation" aria-label="Pagination">
      <button {...firstProps}>ยซ</button>
      <button {...prevProps}>โ€น</button>
      {pages.map((p, i) =>
        p === "..." ? (
          <span key={`e-${i}`}>โ€ฆ</span>
        ) : (
          <button key={p} {...getPageProps(p)}>{p}</button>
        )
      )}
      <button {...nextProps}>โ€บ</button>
      <button {...lastProps}>ยป</button>
    </nav>
  );
}

API โ€” PaginationStyled #

PropTypeDefaultDescription
totalnumberโ€”Total number of items (required)
pagenumberโ€”Controlled current page (1-based)
defaultPagenumber1Uncontrolled initial page
onChange(page: number) => voidโ€”Fires when the page changes
pageSizenumber10Items per page
onPageSizeChange(size: number) => voidโ€”Fires when the page size selector changes
pageSizeOptionsnumber[][10, 20, 50, 100]Options for the page size selector
showPageSizebooleanfalseShow the rows-per-page selector
siblingsnumber1Page buttons on each side of current before ellipsis
boundariesnumber1Always-visible pages at each end
showFirstLastbooleantrueShow first/last buttons
showPrevNextbooleantrueShow previous/next buttons
size"sm" | "md" | "lg""md"Button size
variant"default" | "outline" | "ghost""default"Visual style
tone"neutral" | "primary""neutral"Color tone for the active page
labels{ prev?, next?, first?, last? }โ€”Override the navigation button labels
classNamestringโ€”Extra class on the root element
styleCSSPropertiesโ€”Inline style override

API โ€” usePagination #

KeyTypeDescription
pagenumberCurrent page (1-based)
setPage(page: number) => voidNavigate to a specific page
pages(number | "...")[]Ordered array of page numbers and ellipsis markers
totalPagesnumberTotal number of pages
hasPrevbooleanWhether a previous page exists
hasNextbooleanWhether a next page exists
prev() => voidNavigate to the previous page
next() => voidNavigate to the next page
getPageProps(p: number) => ButtonPropsARIA props for a numbered page button
prevPropsButtonPropsARIA props for the previous button
nextPropsButtonPropsARIA props for the next button
firstPropsButtonPropsARIA props for the first button
lastPropsButtonPropsARIA props for the last button
Edit this page on GitHub