Skip to content
DesignOSby h4rithd
Components/Pagination
ui / navigation

Pagination

Compact controlled pagination with clear current-page semantics.

PREVIEW READY
LIVE PREVIEWDARK / LIGHT COMPATIBLE
PAGINATION

Designed as a complete stateful module

Responsive, keyboard-ready, theme-aware, and owned by your project after installation.

INSTALL / SOURCE REGISTRY

Add Pagination to your project

The command adds the component source and its DesignOS base dependency.

$pnpm dlx shadcn@latest add https://designos.h4rithd.com/r/pagination.json
registry/default/ui/pagination.tsx
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import "@/components/designos/designos.css"

export function Pagination({ page, pageCount, onPageChange, label = "Pagination" }: { page: number; pageCount: number; onPageChange: (page: number) => void; label?: string }) {
  const start = Math.max(1, Math.min(page - 2, pageCount - 4))
  const pages = Array.from({ length: Math.min(5, pageCount) }, (_, index) => Math.max(1, start) + index).filter((value) => value <= pageCount)
  return <nav aria-label={label} className="dos-pagination"><button type="button" aria-label="Previous page" disabled={page <= 1} onClick={() => onPageChange(page - 1)}><ChevronLeft aria-hidden="true" size={15} /></button>{pages.map((value) => <button key={value} type="button" aria-current={value === page ? "page" : undefined} aria-label={`Page ${value}`} onClick={() => onPageChange(value)}>{value}</button>)}<button type="button" aria-label="Next page" disabled={page >= pageCount} onClick={() => onPageChange(page + 1)}><ChevronRight aria-hidden="true" size={15} /></button></nav>
}

Component contract

  • Source-owned after installation
  • Dark and light theme variables
  • Keyboard and visible-focus behavior
  • Reduced-motion fallback
  • Responsive from 320px upward
  • IBM Plex Sans + JetBrains Mono hierarchy