MC Pagination
A component for navigating between pages of content.
Overview
The mc-pagination component provides a compact, accessible way to move through paginated content.
It is built from a navigation landmark, list semantics, and link-based page controls so it works well
with both keyboard users and assistive technologies.
As a part of the MicroClub library, this component is designed for instant deployment into your codebase, giving you full ownership of its look and behavior.
Preview
import * as React from 'react';import { McPagination, McPaginationContent, McPaginationEllipsis, McPaginationItem, McPaginationLink, McPaginationNext, McPaginationPrevious,} from '@/registry/ui/mc-pagination';export default function McPaginationComponentDemo() { const [activePage, setActivePage] = React.useState(2); const pages = [1, 2, 3]; const selectPage = (page: number) => (event: React.MouseEvent<HTMLAnchorElement>) => { event.preventDefault(); setActivePage(page); }; const goToPreviousPage = (event: React.MouseEvent<HTMLAnchorElement>) => { event.preventDefault(); setActivePage((currentPage) => Math.max(1, currentPage - 1)); }; const goToNextPage = (event: React.MouseEvent<HTMLAnchorElement>) => { event.preventDefault(); setActivePage((currentPage) => Math.min(pages.length, currentPage + 1)); }; return ( <McPagination> <McPaginationContent> <McPaginationItem> <McPaginationPrevious href="#" onClick={goToPreviousPage} /> </McPaginationItem> {pages.map((page) => ( <McPaginationItem key={page}> <McPaginationLink href="#" isActive={activePage === page} onClick={selectPage(page)}> {page} </McPaginationLink> </McPaginationItem> ))} <McPaginationItem> <McPaginationEllipsis /> </McPaginationItem> <McPaginationItem> <McPaginationNext href="#" onClick={goToNextPage} /> </McPaginationItem> </McPaginationContent> </McPagination> );}Add to Your Project
Deploy the mc-pagination directly to your components/ui directory:
Manual Setup
If you prefer manual control:
import * as React from 'react';import { ChevronLeftIcon, ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react';import { cn } from '@/lib/utils';import { Button as ButtonPrimitive } from '@base-ui/react/button';function McPagination({ className, ...props }: React.ComponentProps<'nav'>) { return ( <nav role="navigation" aria-label="pagination" data-slot="pagination" className={cn('mx-auto flex w-full justify-center', className)} {...props} /> );}function McPaginationContent({ className, ...props }: React.ComponentProps<'ul'>) { return ( <ul data-slot="pagination-content" className={cn('flex items-center gap-4 p-4', className)} {...props} /> );}function McPaginationItem({ ...props }: React.ComponentProps<'li'>) { return <li className="" data-slot="pagination-item" {...props} />;}type PaginationLinkProps = { isActive?: boolean; isRounded?: boolean;} & React.ComponentProps<'a'>;function McPaginationLink({ className, isActive, isRounded, ...props}: PaginationLinkProps) { return ( <ButtonPrimitive className={cn( 'group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding whitespace-nowrap transition-all outline-none select-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 flex items-center rounded-[6px] px-4 py-2 hover:bg-secondary paragraph-md font-normal justify-center gap-2 font-sans', isActive && 'rounded-[6px] bg-primary px-4 py-2 text-md font-dm-sans h-min-[40px] w-min-[37px] pointer-events-none cursor-default text-primary-foreground hover:bg-primary hover:text-primary-foreground active:bg-primary active:text-primary-foreground active:ring-0', isRounded && 'rounded-full', className )} nativeButton={false} render={ <a aria-current={isActive ? 'page' : undefined} data-slot="pagination-link" data-active={isActive} {...props} /> } /> );}function McPaginationPrevious({ className, text = 'Back', showText = true, ...props}: React.ComponentProps<typeof McPaginationLink> & { text?: string; showText?: boolean }) { return ( <McPaginationLink aria-label="Go to previous page" className={cn('pl-1.5!', className)} {...props} > <ChevronLeftIcon data-icon="inline-start" className={cn('cn-rtl-flip shrink-0')} /> {showText && text && ( <span className="hidden items-center leading-none font-dm-sans font-normal sm:inline-flex"> {text} </span> )} </McPaginationLink> );}function McPaginationNext({ className, text = 'Next', showText = true, ...props}: React.ComponentProps<typeof McPaginationLink> & { text?: string; showText?: boolean }) { return ( <McPaginationLink aria-label="Go to next page" className={cn('pr-1.5!', className)} {...props}> {showText && text && ( <span className="hidden items-center leading-none font-dm-sans paragraph-md font-normal sm:inline-flex"> {text} </span> )} <ChevronRightIcon data-icon="inline-end" className={cn('cn-rtl-flip shrink-0')} /> </McPaginationLink> );}function McPaginationEllipsis({ className, ...props }: React.ComponentProps<'span'>) { return ( <span aria-hidden data-slot="pagination-ellipsis" className={cn( "flex size-8 items-center justify-center [&_svg:not([class*='size-'])]:size-4", className )} {...props} > <MoreHorizontalIcon /> <span className="sr-only">More pages</span> </span> );}export { McPagination, McPaginationContent, McPaginationEllipsis, McPaginationItem, McPaginationLink, McPaginationNext, McPaginationPrevious,};Ensure your @/lib/utils and @/components/ui/button imports are correctly mapped in your
project.
Usage
import * as React from 'react';
import {
McPagination,
McPaginationContent,
McPaginationEllipsis,
McPaginationItem,
McPaginationLink,
McPaginationNext,
McPaginationPrevious,
} from '@/components/ui/mc-pagination';
export default function Example() {
const [activePage, setActivePage] = React.useState(2);
const pages = [1, 2, 3];
const selectPage = (page: number) => (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
setActivePage(page);
};
const goToPreviousPage = (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
setActivePage((currentPage) => Math.max(1, currentPage - 1));
};
const goToNextPage = (event: React.MouseEvent<HTMLAnchorElement>) => {
event.preventDefault();
setActivePage((currentPage) => Math.min(pages.length, currentPage + 1));
};
return (
<McPagination>
<McPaginationContent>
<McPaginationItem>
<McPaginationPrevious href="#" onClick={goToPreviousPage} />
</McPaginationItem>
{pages.map((page) => (
<McPaginationItem key={page}>
<McPaginationLink href="#" isActive={activePage === page} onClick={selectPage(page)}>
{page}
</McPaginationLink>
</McPaginationItem>
))}
<McPaginationItem>
<McPaginationEllipsis />
</McPaginationItem>
<McPaginationItem>
<McPaginationNext href="#" onClick={goToNextPage} />
</McPaginationItem>
</McPaginationContent>
</McPagination>
);
}Examples
Active Page
Use isActive to mark the current page and apply the active visual state.
<McPaginationLink href="#" isActive>
3
</McPaginationLink>Previous and Next
The previous and next controls render the appropriate directional icons and default labels.
<McPaginationPrevious href="#" />
<McPaginationNext href="#" />Custom Labels
Override the default button text when you need more descriptive copy.
<McPaginationPrevious href="#" text="Back to results" />
<McPaginationNext href="#" text="Load more" />Icon-Only Navigation
Hide the labels and keep only the directional icons by setting showText to false.
<McPaginationPrevious href="#" showText={false} />
<McPaginationNext href="#" showText={false} />Rounded Mode
Enable fully rounded pagination controls with isRounded.
<McPaginationPrevious href="#" isRounded />
<McPaginationLink href="#" isActive isRounded>
2
</McPaginationLink>
<McPaginationNext href="#" isRounded />Ellipsis
Use the ellipsis item to indicate skipped pages in longer ranges.
<McPaginationItem>
<McPaginationEllipsis />
</McPaginationItem>API Reference
Components
| Component | Description |
|---|---|
McPagination | Root navigation landmark for the pagination control |
McPaginationContent | List container for pagination items |
McPaginationItem | Individual list item wrapper |
McPaginationLink | Page link button |
McPaginationPrevious | Previous page control |
McPaginationNext | Next page control |
McPaginationEllipsis | Non-interactive ellipsis indicator |
McPaginationLink Props
| Prop | Type | Default | Description |
|---|---|---|---|
isActive | boolean | false | Marks the link as the current page |
isRounded | boolean | false | Applies fully rounded pill styling |
className | string | undefined | Additional CSS classes |
McPaginationPrevious and McPaginationNext Props
| Prop | Type | Default | Description |
|---|---|---|---|
text | string | "Back" or "Next" | Label shown beside the icon on larger screens |
showText | boolean | true | Toggles label visibility for icon-only mode |
isRounded | boolean | false | Applies fully rounded pill styling |
className | string | undefined | Additional CSS classes |
McPaginationEllipsis Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | undefined | Additional CSS classes |
All other props supported by the underlying navigation, list, list item, and anchor elements are also supported.