@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
68 lines (65 loc) • 3.43 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import cx from 'classnames';
import Button from '../Buttons/Button/index.js';
import '../Icon/index.js';
import ChevronLeftIcon from '../Icon/__generated__/ChevronLeftIcon.js';
import DotsHorizontalIcon from '../Icon/__generated__/DotsHorizontalIcon.js';
import ChevronRightIcon from '../Icon/__generated__/ChevronRightIcon.js';
const PaginationButton = ({ currentPage, pageNumber, onPageChange, }) => {
const isActive = currentPage === pageNumber;
return (jsx(Button, { className: cx("cobalt-pagination__Button"), selected: isActive, onClick: () => !isActive && onPageChange(pageNumber), children: pageNumber }));
};
const PAGE_DOTS_VALUE = -1; // Unrevelant value only used to represent dots in the pages array
const generatePages = (currentPage, totalPages, options) => {
const pages = [];
const maxVisiblePages = options.maxVisibleLength; // Max visible pages (excluding dots)
const edgeButtons = options.edgeVisibleLength; // Number of fixed edge buttons
if (totalPages <= maxVisiblePages) {
// Show all pages
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
return pages;
}
// Calculate dynamic range for middle pages
const middlePagesCount = maxVisiblePages - 2 * edgeButtons; // Remaining pages for the middle
let startMiddlePage = Math.max(currentPage - Math.floor(middlePagesCount / 2), edgeButtons + 1);
let endMiddlePage = Math.min(currentPage + Math.floor(middlePagesCount / 2), totalPages - edgeButtons);
// Adjust start and end pages if they exceed boundaries
if (startMiddlePage === edgeButtons + 1) {
endMiddlePage = startMiddlePage + middlePagesCount - 1;
}
else if (endMiddlePage === totalPages - edgeButtons) {
startMiddlePage = endMiddlePage - middlePagesCount + 1;
}
// Add leading edge buttons
for (let i = 1; i <= edgeButtons; i++) {
pages.push(i);
}
if (startMiddlePage > edgeButtons + 1) {
pages.push(PAGE_DOTS_VALUE);
}
// Add middle pages
for (let i = startMiddlePage; i <= endMiddlePage; i++) {
pages.push(i);
}
// Add trailing edge buttons
if (endMiddlePage < totalPages - edgeButtons) {
pages.push(PAGE_DOTS_VALUE);
}
for (let i = totalPages - edgeButtons + 1; i <= totalPages; i++) {
pages.push(i);
}
return pages;
};
const Pagination = ({ onPageChange, currentPage, totalPages, options = {
maxVisibleLength: 11,
edgeVisibleLength: 3,
}, }) => {
if (totalPages <= 1)
return null;
const pages = generatePages(currentPage, totalPages, options);
return (jsxs("div", { className: "cobalt-pagination", children: [jsx(Button, { className: cx("cobalt-pagination__Button"), disabled: currentPage === 1, onClick: () => onPageChange(currentPage - 1), icon: jsx(ChevronLeftIcon, {}) }), pages.map((page) => page === PAGE_DOTS_VALUE ? (jsx(DotsHorizontalIcon, { className: "cobalt-pagination__threeDots", color: "primary" }, `dots-${page}`)) : (jsx(PaginationButton, { currentPage: currentPage, pageNumber: page, onPageChange: onPageChange }, page))), jsx(Button, { className: cx("cobalt-pagination__Button"), disabled: currentPage === totalPages, onClick: () => onPageChange(currentPage + 1), icon: jsx(ChevronRightIcon, {}) })] }));
};
export { Pagination as default };
//# sourceMappingURL=index.js.map