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

Loading...
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:

npx mcoli-ui@latest add mc-pagination
pnpm dlx mcoli-ui@latest add mc-pagination
yarn dlx mcoli-ui@latest add mc-pagination
bunx mcoli-ui@latest add mc-pagination

Manual Setup

If you prefer manual control:

Install the core dependencies
npm install @base-ui/react lucide-react
pnpm add @base-ui/react lucide-react
yarn add @base-ui/react lucide-react
bun add @base-ui/react lucide-react
Copy the source code
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,};
Adjust import paths

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

ComponentDescription
McPaginationRoot navigation landmark for the pagination control
McPaginationContentList container for pagination items
McPaginationItemIndividual list item wrapper
McPaginationLinkPage link button
McPaginationPreviousPrevious page control
McPaginationNextNext page control
McPaginationEllipsisNon-interactive ellipsis indicator
PropTypeDefaultDescription
isActivebooleanfalseMarks the link as the current page
isRoundedbooleanfalseApplies fully rounded pill styling
classNamestringundefinedAdditional CSS classes

McPaginationPrevious and McPaginationNext Props

PropTypeDefaultDescription
textstring"Back" or "Next"Label shown beside the icon on larger screens
showTextbooleantrueToggles label visibility for icon-only mode
isRoundedbooleanfalseApplies fully rounded pill styling
classNamestringundefinedAdditional CSS classes

McPaginationEllipsis Props

PropTypeDefaultDescription
classNamestringundefinedAdditional CSS classes

All other props supported by the underlying navigation, list, list item, and anchor elements are also supported.

On this page