UnflowUI
Components

Pagination

A generic pagination control — reusable for tables, slideshows, or any other paged content — with four visual styles.

Overview

Pagination renders first/previous/next/last arrows (each with a hover tooltip) plus a center section that varies by variant:

  • value — arrows + a "N of Total" display, optionally editable.
  • counter — arrows + one dot (or bar) per page, each clickable — the slideshow use case.
  • buttonOnly — just the four arrows, no center content.
  • table — an items-count label, numbered pages (or the value display) in the center, and a rows-per-page selector.

It's fully controlled/uncontrolled for both page and rowsPerPage — own the state yourself and decide what happens on change (e.g. refetch data), or let the component manage itself.

Import

import { Pagination } from '@unflow.io/ui/components/Pagination';

Props

PropTypeDefaultDescription
variant'value' | 'counter' | 'buttonOnly' | 'table''value'
pagenumberControlled current page, 1-based
defaultPagenumber1Seeds the uncontrolled page state. Ignored when page is provided
onPageChange(page: number) => void
pageCountnumberRequired. Total number of pages
disabledboolean
editablePagebooleanLets the page number be typed directly. Applies to value, and to table when centerVariant="value"
hideFirstLastbooleanHides the first/last (double-chevron) buttons
disableArrowKeysbooleanDisables the built-in ArrowLeft/ArrowRight handling — turn this on if more than one Pagination is mounted at once
counterShape'dot' | 'bar''dot'counter variant only
centerVariant'numbered' | 'value''numbered'table variant only — what renders between the arrows
itemCountnumbertable variant — total items, drives the "Showing N items from Total" label
hideItemsLabelbooleantable variant
rowsPerPagenumbertable variant, controlled
defaultRowsPerPagenumberfirst of rowsPerPageOptionstable variant, uncontrolled seed
onRowsPerPageChange(rows: number) => voidtable variant
rowsPerPageOptionsnumber[][10, 25, 50, 100]table variant
hideRowsPerPagebooleantable variant
siblingCountnumber1Numbered-page windowing, table variant with centerVariant="numbered"
boundaryCountnumber1Numbered-page windowing, table variant with centerVariant="numbered"

Value

<Pagination page={page} onPageChange={setPage} pageCount={100} />

Editable

Set editablePage to let the page number be typed directly instead of only stepped via the arrows — committing (Enter or blur) clamps it to [1, pageCount].

<Pagination editablePage page={page} onPageChange={setPage} pageCount={100} />

Counter

Arrows plus one indicator per page — pick this for a small pageCount (e.g. a slideshow), since every page gets its own indicator with no windowing.

<Pagination variant="counter" page={page} onPageChange={setPage} pageCount={5} />

Bar shape

<Pagination variant="counter" counterShape="bar" page={page} onPageChange={setPage} pageCount={5} />

Button only

Just the four arrows, no center content.

<Pagination variant="buttonOnly" page={page} onPageChange={setPage} pageCount={100} />

Table

A three-part row: an items-count label on the left, numbered pages (with ellipsis windowing) in the center, and a rows-per-page selector on the right.

<Pagination
  variant="table"
  page={page}
  onPageChange={setPage}
  pageCount={100}
  itemCount={1000}
  rowsPerPage={rowsPerPage}
  onRowsPerPageChange={(next) => {
    setRowsPerPage(next);
    setPage(1);
  }}
/>

Value center

For very large pageCounts where a numbered-button list isn't practical, set centerVariant="value" to swap the numbered pages for the same "N of Total" display the standalone value variant uses — editablePage applies here too.

<Pagination
  variant="table"
  centerVariant="value"
  editablePage
  page={page}
  onPageChange={setPage}
  pageCount={100}
  itemCount={1000}
  rowsPerPage={10}
/>

Customization (slots & slotProps)

SlotTypeDescription
firstIcon / previousIcon / nextIcon / lastIconReactNodeOverrides the corresponding arrow's icon
Slot PropPropsDescription
firstButton / previousButton / nextButton / lastButtonOmit<IIconButton, 'onClick' | 'icon'>The corresponding arrow's IconButton
tooltip.first / .previous / .next / .lastOmit<ITooltip, 'content' | 'anchorEl'>The corresponding arrow's Tooltip
valueRootBaseHTMLProps<HTMLDivElement>Wrapper around the value variant's "{page} of {pageCount}" pair
pageValue / totalValueBaseHTMLProps<HTMLParagraphElement>The two text pieces of the value display
pageInputOmit<IInput, 'value' | 'onChange' | 'type'>The editable page number field (editablePage)
counterRoot / counterButtonBaseHTMLProps<HTMLDivElement> / BaseButtonProps<HTMLButtonElement>The counter variant's row and each dot/bar
pagesRoot / pageButton / ellipsisThe table variant's numbered-page row, each page button, and the ellipsis span
itemsLabelBaseHTMLProps<HTMLParagraphElement>The "Showing N items from Total" label
rowsPerPageRoot / rowsPerPageLabel / rowsPerPageSelectThe rows-per-page group, its label, and the underlying Select

Accessibility

  • The root renders as <nav aria-label="Pagination">, following the WAI-ARIA pagination pattern.
  • Every arrow button carries its own aria-label ("First page" / "Previous page" / "Next page" / "Last page") independent of the Tooltip that shows the same text on hover/focus — assistive tech gets the label either way.
  • First/previous disable on the first page; next/last disable on the last page, rather than silently no-op-ing.
  • The current page (numbered button, counter dot/bar) carries aria-current="page".
  • ArrowLeft/ArrowRight step the page while focus isn't in an editable field, mirroring ItemNav's ArrowUp/ArrowDown handling — set disableArrowKeys if more than one Pagination is mounted on the same page.