Backpack UI
Components
Pagination

Pagination

The Pagination component is a versatile and customizable pagination solution. It is designed to handle paginated content in your application, allowing users to navigate through pages with ease. The component consists of several subcomponents, each of which can be used to customize the appearance and functionality of the pagination.

The main Pagination component is responsible for rendering the pagination structure. It takes care of the layout and the slot management for its child components.


Importing


_10
import {
_10
Pagination,
_10
PaginationButton,
_10
PaginationButtonGroup,
_10
PaginationItem,
_10
PaginationPages,
_10
PaginationSinglePage,
_10
} from '@ef-global/backpack/Pagination';

Usage

Here's a basic example of the Pagination component:



_25
<Pagination>
_25
<PaginationButton as='button' onClick={() => {}} data-slot='PaginationPreviousButtonGroup'>
_25
<IconChevronLeft />
_25
</PaginationButton>
_25
<PaginationPages data-slot='PaginationPages'>
_25
<PaginationItem key={1}>
_25
1
_25
</PaginationItem>
_25
<PaginationItem key={2} active={true}>
_25
2
_25
</PaginationItem>
_25
<PaginationItem key={3}>
_25
3
_25
</PaginationItem>
_25
<PaginationItem key={4}>
_25
4
_25
</PaginationItem>
_25
</PaginationPages>
_25
<PaginationSinglePage>
_25
2/4
_25
</PaginationSinglePage>
_25
<PaginationButton as='button' onClick={() => {}} data-slot='PaginationNextButtonGroup'>
_25
<IconChevronRight />
_25
</PaginationButton>
_25
</Pagination>

Props

Prop NameTypeDescription
childrenArray of subcomponentsAn array of subcomponents to be rendered within the Pagination component. Can include PaginationPreviousButtonGroup, PaginationNextButtonGroup, PaginationPages, and PaginationSinglePage.

Subcomponents

PaginationButton

A button component used for the previous and next buttons in the pagination component. Inherits the properties of the Button component, while providing specific styles for pagination.

PaginationButtonGroup

A container component for grouping buttons within the pagination component. It is used for both the previous and next button groups.

PaginationItem

A component representing an individual page in the pagination component. Can be rendered as an anchor element or as a child element, and can be styled as active (for the current page) or inactive (e.g., for ellipsis).

Props

Prop NameTypeDescription
activebooleanIndicates whether the PaginationItem is the currently active page. Defaults to false.
clickablebooleanDetermines if the PaginationItem is clickable. Defaults to true.
classNamestringAn optional custom CSS class name to be applied to the PaginationItem.
childrenReact.ReactNodeThe content of the PaginationItem, usually the page number or custom content.
asChildbooleanIf true, the PaginationItem will render the provided children as direct children of the li element. Defaults to false.

PaginationPages

A container component that holds the PaginationItem components. It is responsible for managing the display and layout of the pagination page indicators.

Props

Prop NameTypeDescription
childrenReact.ReactNodeThe list of PaginationItems to be rendered within the PaginationPages component.

PaginationSinglePage

A component that displays the current page and total pages in a single-page pagination format, such as "3/10". This component is ideal to be shown on mobile.

Props

Prop NameTypeDescription
childrenReact.ReactNodeThe content to be displayed in the PaginationSinglePage component, usually a string with the format "current_page/total_pages".

Using the usePagination Hook

The usePagination hook is a custom hook that simplifies the process of generating a list of page items for a pagination component. It takes three arguments:

  1. visiblePages: The maximum number of pages that should be visible at a time, including ellipsis (the "..." symbol) if they are present.
  2. pageCount: The total number of pages.
  3. activePage: The current active (or selected) page.

The hook returns an array of items that represent the pagination structure. Each item in the array can be either a number, indicating the page number, or a special string value (usually an ellipsis) indicating a range of pages that are not directly visible.

The primary goal of the usePagination hook is to ensure that the pagination component can display a reasonable number of pages while still providing a way to navigate through all available pages. It does this by calculating which pages should be visible, and adding ellipsis symbols when needed to indicate that there are more pages not shown.

Examples

Uncontrolled Pagination

In this example, the pagination component is uncontrolled and the page changes are not managed by a state.


_35
<Pagination>
_35
<PaginationButtonGroup data-slot='PaginationPreviousButtonGroup'>
_35
<PaginationButton className='mobileButton' as='button' onClick={() => {}}>
_35
<IconChevronDoubleLeft />
_35
</PaginationButton>
_35
<PaginationButton as='button' onClick={() => {}}>
_35
<IconChevronLeft />
_35
</PaginationButton>
_35
</PaginationButtonGroup>
_35
<PaginationPages data-slot='PaginationPages'>
_35
<PaginationItem key={1}>
_35
1
_35
</PaginationItem>
_35
<PaginationItem key={2} active={true}>
_35
2
_35
</PaginationItem>
_35
<PaginationItem key={3}>
_35
3
_35
</PaginationItem>
_35
<PaginationItem key={4}>
_35
4
_35
</PaginationItem>
_35
</PaginationPages>
_35
<PaginationSinglePage>
_35
2/4
_35
</PaginationSinglePage>
_35
<PaginationButtonGroup data-slot='PaginationNextButtonGroup'>
_35
<PaginationButton as='button' onClick={() => {}}>
_35
<IconChevronRight />
_35
</PaginationButton>
_35
<PaginationButton className='mobileButton' as='button' onClick={() => {}}>
_35
<IconChevronDoubleRight />
_35
</PaginationButton>
_35
</PaginationButtonGroup>
_35
</Pagination>

Controlled Pagination

In this example, the pagination component is controlled, and the page changes are managed by the component's state.



_58
import { isDot, usePagination } from '@/src/components/hooks/usePagination';
_58
_58
const pageCount = 30;
_58
const [activePage, setActivePage] = useState(15);
_58
_58
return (
_58
<Pagination>
_58
<PaginationButtonGroup data-slot='PaginationPreviousButtonGroup'>
_58
<PaginationButton
_58
className='mobileButton'
_58
as='button'
_58
disabled={activePage <= 1}
_58
onClick={() => setActivePage(1)}
_58
>
_58
<IconChevronDoubleLeft />
_58
</PaginationButton>
_58
<PaginationButton
_58
as='button'
_58
disabled={activePage <= 1}
_58
onClick={() => setActivePage(activePage - 1)}
_58
>
_58
<IconChevronLeft />
_58
</PaginationButton>
_58
</PaginationButtonGroup>
_58
<PaginationPages data-slot='PaginationPages'>
_58
{usePagination(7, pageCount, activePage).map((item) => (
_58
<PaginationItem
_58
key={item}
_58
clickable={!isDot(item)}
_58
active={item === activePage}
_58
onClick={() => !isDot(item) && setActivePage(item)}
_58
>
_58
{isDot(item) ? '...' : item}
_58
</PaginationItem>
_58
))}
_58
</PaginationPages>
_58
<PaginationSinglePage>
_58
{activePage}/{pageCount}
_58
</PaginationSinglePage>
_58
<PaginationButtonGroup data-slot='PaginationNextButtonGroup'>
_58
<PaginationButton
_58
as='button'
_58
disabled={activePage >= pageCount}
_58
onClick={() => setActivePage(activePage + 1)}
_58
>
_58
<IconChevronRight />
_58
</PaginationButton>
_58
<PaginationButton
_58
className='mobileButton'
_58
as='button'
_58
disabled={activePage >= pageCount}
_58
onClick={() => setActivePage(pageCount)}
_58
>
_58
<IconChevronDoubleRight />
_58
</PaginationButton>
_58
</PaginationButtonGroup>
_58
</Pagination>
_58
);