Pagination
Provides direct navigation through a sequence of result pages.
Preview
Example code
Page 2 of 3
Playground
currentPageSets the active demo page, clamped from 1 to 3.
schemeSets the link highlight color.
Usage
tsx
import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from "earthling-ui/pagination";
export function Example() {
return (
<>
<Pagination aria-label="Search results pages">
<PaginationContent>
<PaginationItem>
<PaginationPrevious href="?page=1" />
</PaginationItem>
<PaginationItem>
<PaginationLink href="?page=2" isActive>
2
</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
<PaginationItem>
<PaginationNext href="?page=3" />
</PaginationItem>
</PaginationContent>
</Pagination>
</>
);
}
- Use real href values so pagination works with standard browser navigation and link actions.
- Mark exactly one PaginationLink active to expose aria-current=page.
- The currentPage control sets the demo's active page; its links update local state while retaining real fallback URLs.
Installation
Start with the project setup for React and Tailwind CSS 4. Both paths use the same component and theme.
Import package
Own the source
bash
npm install earthling-uiUse the component import shown above. Package updates keep the implementation current.
API reference
Declarations from the current library build, including inherited primitive props. Playground controls above show selected options; they are not the complete API.
tsx
// Generated by dts-bundle-generator v9.5.1
import { VariantProps } from 'class-variance-authority';
import { ComponentProps } from 'react';
export declare const Pagination: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & import("react").RefAttributes<HTMLElement>>;
export declare const PaginationContent: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & import("react").RefAttributes<HTMLUListElement>>;
export declare const PaginationItem: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & import("react").RefAttributes<HTMLLIElement>>;
export declare const paginationLinkVariants: (props?: ({
scheme?: "default" | "primary" | "secondary" | "tertiary" | "neutral" | "muted" | "good" | "caution" | "bad" | null | undefined;
size?: "sm" | "md" | "lg" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
export interface PaginationLinkProps extends ComponentProps<"a">, VariantProps<typeof paginationLinkVariants> {
/** Marks this link as the current page (sets `aria-current="page"`). */
isActive?: boolean;
}
export declare const PaginationLink: import("react").ForwardRefExoticComponent<Omit<PaginationLinkProps, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
export declare const PaginationPrevious: import("react").ForwardRefExoticComponent<Omit<PaginationLinkProps, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
export declare const PaginationNext: import("react").ForwardRefExoticComponent<Omit<PaginationLinkProps, "ref"> & import("react").RefAttributes<HTMLAnchorElement>>;
export declare const PaginationEllipsis: import("react").ForwardRefExoticComponent<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
export {};Runtime dependencies: class-variance-authority, cnfast.
Source
Use the eject command to copy this implementation with its required helpers and project-specific imports.
View Pagination implementation
tsx
"use client";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/utils/cn";
import { schemes } from "@/utils/variants";
import { type ComponentProps, forwardRef } from "react";
// Pagination (nav landmark)
const Pagination = forwardRef<HTMLElement, ComponentProps<"nav">>(
({ className, ...props }, ref) => (
<nav
ref={ref}
role="navigation"
aria-label="pagination"
className={cn("mx-auto flex w-full justify-center", className)}
{...props}
/>
),
);
Pagination.displayName = "Pagination";
// PaginationContent
const PaginationContent = forwardRef<HTMLUListElement, ComponentProps<"ul">>(
({ className, ...props }, ref) => (
<ul
ref={ref}
className={cn(
"m-0 flex list-none flex-row items-center gap-1 p-0",
className,
)}
{...props}
/>
),
);
PaginationContent.displayName = "PaginationContent";
// PaginationItem
const PaginationItem = forwardRef<HTMLLIElement, ComponentProps<"li">>(
({ className, ...props }, ref) => (
<li ref={ref} className={cn("flex", className)} {...props} />
),
);
PaginationItem.displayName = "PaginationItem";
// PaginationLink
const paginationLinkVariants = cva(
"inline-flex cursor-pointer items-center justify-center gap-1 rounded-(--radius-control) border border-transparent text-sm font-medium whitespace-nowrap tabular-nums hover:bg-(--scheme-tint)/5 focus-visible:ring-2 focus-visible:ring-outline focus-visible:outline-hidden aria-[current=page]:border-(--scheme-tint)/30 aria-[current=page]:bg-(--scheme-tint)/10 aria-disabled:pointer-events-none aria-disabled:opacity-50",
{
variants: {
scheme: schemes,
size: {
sm: "h-9 min-w-9 px-2",
md: "h-10 min-w-10 px-3",
lg: "h-11 min-w-11 px-4",
},
},
defaultVariants: { scheme: "primary", size: "md" },
},
);
export interface PaginationLinkProps
extends ComponentProps<"a">, VariantProps<typeof paginationLinkVariants> {
/** Marks this link as the current page (sets `aria-current="page"`). */
isActive?: boolean;
}
const PaginationLink = forwardRef<HTMLAnchorElement, PaginationLinkProps>(
({ className, isActive, scheme, size, ...props }, ref) => (
<a
ref={ref}
aria-current={isActive ? "page" : undefined}
data-scheme={scheme}
className={cn(paginationLinkVariants({ scheme, size }), className)}
{...props}
/>
),
);
PaginationLink.displayName = "PaginationLink";
// PaginationPrevious
const PaginationPrevious = forwardRef<HTMLAnchorElement, PaginationLinkProps>(
({ className, children, ...props }, ref) => (
<PaginationLink
ref={ref}
aria-label="Go to previous page"
className={cn("gap-1 pl-2.5", className)}
{...props}
>
<i aria-hidden="true" className="size-4 icon-[lucide--chevron-left]" />
{children ?? <span>Previous</span>}
</PaginationLink>
),
);
PaginationPrevious.displayName = "PaginationPrevious";
// PaginationNext
const PaginationNext = forwardRef<HTMLAnchorElement, PaginationLinkProps>(
({ className, children, ...props }, ref) => (
<PaginationLink
ref={ref}
aria-label="Go to next page"
className={cn("gap-1 pr-2.5", className)}
{...props}
>
{children ?? <span>Next</span>}
<i aria-hidden="true" className="size-4 icon-[lucide--chevron-right]" />
</PaginationLink>
),
);
PaginationNext.displayName = "PaginationNext";
// PaginationEllipsis
const PaginationEllipsis = forwardRef<HTMLSpanElement, ComponentProps<"span">>(
({ className, ...props }, ref) => (
<span
ref={ref}
aria-hidden
className={cn("flex h-10 w-10 items-center justify-center", className)}
{...props}
>
<i className="size-4 icon-[lucide--ellipsis]" />
<span className="sr-only">More pages</span>
</span>
),
);
PaginationEllipsis.displayName = "PaginationEllipsis";
export {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationPrevious,
PaginationNext,
PaginationEllipsis,
paginationLinkVariants,
};