Refined UI

An opinionated, customizable superset of shadcn/ui

AgentsPrimitivesSkillsSkins
Guides
  • Overview
  • Get started
  • Shadcn compatibility
  • Architecture
  • Agent surface
Primitives
  • Accordion
  • Alert
  • Alert dialog
  • Aspect ratio
  • Autocomplete
  • Avatar
  • Badge
  • Button
  • Button group
  • Calendar
  • Card
  • Checkbox
  • Checkbox Group
  • Code
  • Code Diff
  • Collapsible
  • Color Picker
  • Combobox
  • Command
  • Date Picker
  • Dialog
  • Drawer
  • Empty
  • Field
  • Form
  • Gradient Editor
  • Hover card
  • Input
  • Input group
  • Input OTP
  • Item
  • Kbd
  • Markdown
  • Menu
  • Menubar
  • Meter
  • Native select
  • Navigation menu
  • Number Field
  • Pagination
  • Popover
  • Progress
  • Radio group
  • Resizable
  • Scroll area
  • Select
  • Sidebar
  • Skeleton
  • Slider
  • Spinner
  • Switch
  • Table
  • Table of contents
  • Tabs
  • Textarea
  • Toast
  • Toggle
  • Toolbar
  • Tooltip
  • Tree
  • Trigger Menu
  • Typography
Hooks
  • Use Chat Message
  • Use Chat Input
  • Use User Ask
  • Use Audio Recorder
  • Use Environment Variables
  • Use Copy To Clipboard
  • Use Tool Call
  • Use Sidebar Resize
Utils
  • cn
  • Skin
  • Contracts
  • Serialize
Extensions
  • Control Effects
  • View Transition
  • Send Aurora
  1. Primitives
  2. Pagination
Primitives

Pagination

Page navigation for long lists and result sets.

Composition

The preferred shape for composing the installed primitive from its exported parts.

Parts

Exported compound parts from the installed source.

Pagination
├── PaginationContent
├── PaginationItem
├── PaginationLink
├── PaginationPrevious
├── PaginationNext
└── PaginationEllipsis

The refined source installs this primitive from src/registry/sources/refined/ui/pagination.tsx. Install it on its own with the command above, or inspect the source below.

Registry command
npx shadcn@latest add http://127.0.0.1:3000/r/refined/pagination.json
See registry manifest

Raw code

Primary installed primitive source

Pagination slot
src/registry/sources/refined/ui/pagination.tsx
import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react";
import type { ComponentProps } from "react";
import type { PaginationLinkProps } from "@/components/refined-ui/contracts";
import { cn } from "@/components/refined-ui/lib/cn";
import { skinSlot } from "@/components/refined-ui/skin";
​
// Refined skin slot, plain markup (no Base UI): semantic <nav>/<ul>/<li>; links control-shaped WITHOUT importing Button.
// Carry --radius-control + focus ring by hand: ghost by default, raised surface when isActive.
export function Pagination({ className, ...props }: ComponentProps<"nav">) {
return (
// A <nav> already carries the navigation role; aria-label names this landmark "pagination".
<nav
aria-label="pagination"
data-ui="agent"
data-slot="pagination"
className={cn("mx-auto flex w-full justify-center", skinSlot("pagination", {}), className)}
{...props}
/>
);
}
​
export function PaginationContent({ className, ...props }: ComponentProps<"ul">) {
return <ul data-ui="agent" data-slot="pagination-content" className={cn("flex flex-row items-center gap-1", className)} {...props} />;
}
​
export function PaginationItem({ className, ...props }: ComponentProps<"li">) {
return <li data-ui="agent" data-slot="pagination-item" className={className} {...props} />;
}
​
// Control-shaped page link: ghost when idle, raised surface (bg-card ring) when isActive.
const paginationLinkChrome =
"inline-flex h-[var(--control-h-sm)] min-w-[var(--control-h-sm)] cursor-pointer select-none items-center justify-center gap-1 whitespace-nowrap rounded-[var(--radius-control)] px-2.5 text-sm font-medium outline-none transition duration-[var(--duration-fast)] focus-visible:ring-2 focus-visible:ring-foreground/20 aria-disabled:pointer-events-none aria-disabled:opacity-45 [&>svg]:size-4 [&>svg]:shrink-0";
​
export function PaginationLink({ isActive = false, className, ...props }: PaginationLinkProps) {
return (
<a
aria-current={isActive ? "page" : undefined}
data-ui="agent"
data-slot="pagination-link"
data-control="true"
data-active={isActive ? "true" : "false"}
className={cn(
paginationLinkChrome,
isActive ? "bg-card/72 text-foreground shadow-sm ring-1 ring-inset ring-border" : "text-foreground hover:bg-foreground/6",
skinSlot("pagination-link", { active: isActive }),
className,
)}
{...props}
/>
);
}
​
export function PaginationPrevious({ className, ...props }: ComponentProps<typeof PaginationLink>) {
return (
<PaginationLink aria-label="Go to previous page" className={cn("gap-1 pr-2.5 pl-2", className)} {...props}>
<ChevronLeft />
<span>Previous</span>
</PaginationLink>
);
}
​
export function PaginationNext({ className, ...props }: ComponentProps<typeof PaginationLink>) {
return (
<PaginationLink aria-label="Go to next page" className={cn("gap-1 pr-2 pl-2.5", className)} {...props}>
<span>Next</span>
<ChevronRight />
</PaginationLink>
);
}
​
export function PaginationEllipsis({ className, ...props }: ComponentProps<"span">) {
return (
<span
aria-hidden="true"
data-ui="agent"
data-slot="pagination-ellipsis"
className={cn(
"flex h-[var(--control-h-sm)] min-w-[var(--control-h-sm)] items-center justify-center text-muted-foreground [&>svg]:size-4",
className,
)}
{...props}
>
<MoreHorizontal />
<span className="sr-only">More pages</span>
</span>
);
}
​

On this page

  • Preview
  • Composition
  • Installation
  • Source
  • Previous
  • 1
  • 2
  • 3
  • More pages
  • 8
  • Next