@intility/bifrost-react
Version:
React library for Intility's design system, Bifrost.
174 lines (173 loc) • 7.53 kB
JavaScript
"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { forwardRef } from "react";
import classnames from "classnames";
import { faAngleLeft } from "@fortawesome/free-solid-svg-icons/faAngleLeft";
import { faAngleRight } from "@fortawesome/free-solid-svg-icons/faAngleRight";
import { faAnglesLeft } from "@fortawesome/free-solid-svg-icons/faAnglesLeft";
import { faAnglesRight } from "@fortawesome/free-solid-svg-icons/faAnglesRight";
import Icon from "../Icon/Icon.js";
import useLocale from "../../hooks/useLocale.js";
/**
* Component for displaying available pages and current page in a paged environment
*/ const Pagination = /*#__PURE__*/ forwardRef(({ className, currentPage, totalPages, displayPages = 9, onChange, ...props }, ref)=>{
const locale = useLocale();
const displayPagesCapForMediumScreens = Math.min(displayPages, 9);
return /*#__PURE__*/ _jsxs("div", {
className: classnames(className, "bf-pagination bf-container"),
ref: ref,
"data-testid": "bf-pagination",
...props,
children: [
/*#__PURE__*/ _jsx("button", {
"aria-label": `${locale.goTo} ${locale.first} ${locale.page}`,
type: "button",
disabled: currentPage <= 1,
className: "bf-pagination-button bf-pagination-button-arrow to-small-container",
onClick: ()=>onChange(1),
children: /*#__PURE__*/ _jsx(Icon, {
widthAuto: true,
icon: faAnglesLeft
})
}),
/*#__PURE__*/ _jsxs("button", {
"aria-label": `${locale.goTo} ${locale.previous} ${locale.page}`,
type: "button",
className: "bf-neutral-link bf-pagination-prev",
disabled: currentPage <= 1,
onClick: ()=>onChange(currentPage - 1),
children: [
/*#__PURE__*/ _jsx(Icon, {
widthAuto: true,
icon: faAngleLeft
}),
/*#__PURE__*/ _jsx("span", {
className: "bf-neutral-link-text",
children: locale.prev
})
]
}),
/*#__PURE__*/ _jsx("span", {
className: "to-small-container",
children: `${currentPage} ${locale.of} ${totalPages}`
}),
/*#__PURE__*/ _jsx("span", {
className: "from-small-container to-medium-container",
children: totalPages > displayPagesCapForMediumScreens ? /*#__PURE__*/ _jsx(ComplexPagination, {
currentPage: currentPage,
onChange: onChange,
displayPages: displayPagesCapForMediumScreens,
totalPages: totalPages
}) : /*#__PURE__*/ _jsx(BasicPagination, {
currentPage: currentPage,
onChange: onChange,
totalPages: totalPages
})
}),
/*#__PURE__*/ _jsx("span", {
className: "from-medium-container",
children: totalPages > displayPages ? /*#__PURE__*/ _jsx(ComplexPagination, {
currentPage: currentPage,
onChange: onChange,
displayPages: displayPages,
totalPages: totalPages
}) : /*#__PURE__*/ _jsx(BasicPagination, {
currentPage: currentPage,
onChange: onChange,
totalPages: totalPages
})
}),
/*#__PURE__*/ _jsxs("button", {
"aria-label": `${locale.goTo} ${locale.next} ${locale.page}`,
type: "button",
className: "bf-neutral-link bf-pagination-next",
disabled: currentPage >= totalPages,
onClick: ()=>onChange(currentPage + 1),
children: [
/*#__PURE__*/ _jsx("span", {
className: "bf-neutral-link-text",
children: locale.next
}),
/*#__PURE__*/ _jsx(Icon, {
widthAuto: true,
icon: faAngleRight
})
]
}),
/*#__PURE__*/ _jsx("button", {
"aria-label": `${locale.goTo} ${locale.last} ${locale.page}`,
type: "button",
className: "bf-pagination-button bf-pagination-button-arrow to-small-container",
disabled: currentPage >= totalPages,
onClick: ()=>onChange(totalPages),
children: /*#__PURE__*/ _jsx(Icon, {
widthAuto: true,
icon: faAnglesRight
})
})
]
});
});
const PageButton = ({ page, currentPage, onChange })=>{
const locale = useLocale();
return /*#__PURE__*/ _jsx("button", {
"aria-label": `${locale.goTo} ${locale.page} ${page}`,
type: "button",
disabled: page === currentPage,
className: classnames("bf-pagination-button", {
"bf-pagination-button-selected": page === currentPage
}),
onClick: ()=>onChange(page),
children: page
});
};
const BasicPagination = ({ currentPage, totalPages, onChange, offset = 1 })=>/*#__PURE__*/ _jsx(_Fragment, {
children: Array(totalPages).fill(null).map((_, i)=>/*#__PURE__*/ _jsx(PageButton, {
page: i + offset,
currentPage: currentPage,
onChange: onChange
}, i + offset))
});
const ComplexPagination = ({ currentPage, totalPages, displayPages: dp = 9, onChange })=>{
const displayPages = Math.max(7, dp % 2 === 0 ? dp + 1 : dp);
const dynamicPages = displayPages - 4;
const dynamicOffset = Math.min(Math.max(currentPage - (displayPages - 5) / 2, 3), totalPages - 1 - dynamicPages);
return /*#__PURE__*/ _jsxs(_Fragment, {
children: [
/*#__PURE__*/ _jsx(PageButton, {
page: 1,
currentPage: currentPage,
onChange: onChange
}),
currentPage <= Math.ceil(displayPages / 2) ? /*#__PURE__*/ _jsx(PageButton, {
page: 2,
currentPage: currentPage,
onChange: onChange
}) : /*#__PURE__*/ _jsx("span", {
className: "bf-pagination-dots",
children: "..."
}),
/*#__PURE__*/ _jsx(BasicPagination, {
totalPages: dynamicPages,
currentPage: currentPage,
offset: dynamicOffset,
onChange: onChange
}),
currentPage >= totalPages - Math.floor(displayPages / 2) ? /*#__PURE__*/ _jsx(PageButton, {
page: totalPages - 1,
currentPage: currentPage,
onChange: onChange
}) : /*#__PURE__*/ _jsx("span", {
className: "bf-pagination-dots",
children: "..."
}),
/*#__PURE__*/ _jsx(PageButton, {
page: totalPages,
currentPage: currentPage,
onChange: onChange
})
]
});
};
Pagination.displayName = "Pagination";
export default Pagination;