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
_10import {_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 Name | Type | Description |
| children | Array of subcomponents | An 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 Name | Type | Description |
| active | boolean | Indicates whether the PaginationItem is the currently active page. Defaults to false. |
| clickable | boolean | Determines if the PaginationItem is clickable. Defaults to true. |
| className | string | An optional custom CSS class name to be applied to the PaginationItem. |
| children | React.ReactNode | The content of the PaginationItem, usually the page number or custom content. |
| asChild | boolean | If 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 Name | Type | Description |
| children | React.ReactNode | The 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 Name | Type | Description |
| children | React.ReactNode | The 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:
visiblePages: The maximum number of pages that should be visible at a time, including ellipsis (the "..." symbol) if they are present.pageCount: The total number of pages.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.
_58import { isDot, usePagination } from '@/src/components/hooks/usePagination';_58_58const pageCount = 30;_58const [activePage, setActivePage] = useState(15);_58_58return (_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);