Component: Pagination
Relevant source files
The following files were used as context for generating this wiki page:The Pagination component system is a set of modular React components designed to create navigation controls for paged content. It is built to be flexible and composable, allowing developers to construct various pagination UI patterns. The core components are defined in pagination.tsx and are primarily consumed by higher-order components like ReactiveDatatable to navigate through lists of data, such as the certifications database.
The components are styled using clsx for conditional class names and rely on a shared Button component for their interactive elements. This design separates the pagination logic from the data-fetching and state management, which is handled by the consuming component.
Sources: src/components/react/pagination.tsx, src/components/astro/database/reactive-datatable.tsx
Component Architecture
The pagination feature is composed of several specialized React components that are meant to be used together to build a complete pagination control.
Sources: src/components/react/pagination.tsx
Component Breakdown
The following table describes each exported component from pagination.tsx.
| Component | Description |
|---|---|
Pagination | The main navigation container element (<nav>). It acts as a wrapper for all other pagination items. |
PaginationPrevious | A button for navigating to the previous page. It is disabled if no href is provided. |
PaginationNext | A button for navigating to the next page. It is disabled if no href is provided. |
PaginationList | A container (<span>) for the list of page numbers and gaps. It is hidden on small screens (sm). |
PaginationPage | An individual, clickable page number button. It can be styled as the current page. |
PaginationGap | A non-interactive element (<span>), typically an ellipsis (…), used to indicate a gap in page numbers. |
Sources: src/components/react/pagination.tsx:5-150
Component Hierarchy
This diagram illustrates how the pagination components are typically nested.
Core Components and Props
Each component has specific props to control its behavior and appearance.
Sources: src/components/react/pagination.tsx
Pagination
The root container. It accepts standard nav element props.
aria-label: Sets the ARIA label for the navigation. Defaults to "Page navigation".
// file: src/components/react/pagination.tsx:5-15
export function Pagination({
"aria-label": ariaLabel = "Page navigation",
className,
...props
}: React.ComponentPropsWithoutRef<"nav">) {
return (
<nav
aria-label={ariaLabel}
{...props}
className={clsx(className, "flex gap-x-2")}
/>
);
}
Sources: src/components/react/pagination.tsx:5-15
PaginationPrevious & PaginationNext
These components render "Previous" and "Next" buttons. They are functionally similar.
| Prop | Type | Default | Description |
|---|---|---|---|
href | string|null | null | The URL for the link. If null, the button is rendered in a disabled state. |
children | ReactNode | "Previous" or "Next" | The text content of the button. |
These components internally use the Button component with the plain style. The disabled state is determined by whether the href prop is null.
// file: src/components/react/pagination.tsx:17-42
export function PaginationPrevious({
href = null,
className,
children = "Previous",
}: React.PropsWithChildren<{
href?: string | null;
className?: string;
}>) {
return (
<span className={clsx(className, "grow basis-0")}>
<Button
{...(href === null ? { disabled: true } : { href })}
plain
aria-label="Previous page"
>
{/* ... SVG icon ... */}
{children}
</Button>
</span>
);
}
Sources: src/components/react/pagination.tsx:17-42, src/components/react/button.tsx:210-213
PaginationPage
This component renders an individual page link.
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | - | Required. The URL for the page link. |
current | boolean | false | If true, styles the button as the current page and sets aria-current. |
children | ReactNode | - | The page number or content to display inside the button. |
// file: src/components/react/pagination.tsx:106-128
export function PaginationPage({
href,
className,
current = false,
children,
}: React.PropsWithChildren<{
href: string;
className?: string;
current?: boolean;
}>) {
return (
<Button
href={href}
plain
aria-label={`Page ${children}`}
aria-current={current ? "page" : undefined}
className={clsx(
// ... class names ...
current && "before:bg-zinc-950/5 dark:before:bg-white/10",
)}
>
<span className="-mx-0.5">{children}</span>
</Button>
);
}
Sources: src/components/react/pagination.tsx:106-128
Usage in ReactiveDatatable
The ReactiveDatatable component provides a practical implementation of the pagination components to navigate a client-side filtered list of certifications.
Sources: src/components/astro/database/reactive-datatable.tsx
State Management and URL Generation
The component manages pagination state and calculates navigation URLs.
- State: A
paginationstate object holds thepage,total_pages, andper_pagevalues. - URL Reading: On initial load,
useEffectreads thepageandqueryfrom theURLSearchParamsofwindow.location.searchto set the initial state. - URL Generation: A
useMemohook calculates an object of URLs (pagination_url) forprevious,next,first,last, and other page links. These URLs are constructed by manipulating aURLSearchParamsobject.
This diagram shows the flow of how pagination state is initialized and updated.
Rendering Logic
The ReactiveDatatable component uses complex conditional logic to render the PaginationList, showing a concise set of page numbers, including gaps for larger page ranges.
- The current page is rendered using
PaginationPagewith thecurrentprop set totrue. - Logic determines whether to show numbered pages directly or use
PaginationGapfor ranges far from the current page. - The
display_dataarray is sliced based on the current page and items per page before being mapped toTableRowcomponents.
// file: src/components/astro/database/reactive-datatable.tsx:343-350
{ display_data
.slice(
(pagination.page - 1) * pagination.per_page,
pagination.page * pagination.per_page,
)
.map((certification) => (
<TableRow /* ... */ >
{/* ... */}
</TableRow>
)) }
Sources: src/components/astro/database/reactive-datatable.tsx:343-350, 408-482
Summary
The pagination system in CertDb is a well-structured, composable set of React components. It effectively decouples the UI representation of pagination from the application's state management and data-handling logic. Its implementation within ReactiveDatatable showcases how to build a dynamic, URL-driven pagination experience for a client-rendered data table, providing a robust and user-friendly navigation system.
Sources: src/components/react/pagination.tsx, src/components/astro/database/reactive-datatable.tsx