@carbon/react
Version:
React components for the Carbon Design System
201 lines (195 loc) • 7.32 kB
JavaScript
/**
* Copyright IBM Corp. 2016, 2023
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
;
Object.defineProperty(exports, '__esModule', { value: true });
var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var PropTypes = require('prop-types');
var cx = require('classnames');
var iconsReact = require('@carbon/icons-react');
var Select = require('../../Select/Select.js');
require('../../Select/Select.Skeleton.js');
var SelectItem = require('../../SelectItem/SelectItem.js');
var index = require('../../IconButton/index.js');
var usePrefix = require('../../../internal/usePrefix.js');
var _CaretLeft, _CaretRight;
function Pagination({
backwardText = 'Previous page',
children = undefined,
className = null,
disabled = false,
forwardText = 'Next page',
id = 1,
initialPage = 1,
itemsPerPageText = 'Items per page:',
itemRangeText = (min, max, total) => `${min}–${max} of ${total} items`,
itemText = (min, max) => `${min}–${max} items`,
onChange,
pageRangeText = (current, total) => `${current} of ${total} pages`,
pageSize = 10,
pageSizes = undefined,
pageText = page => `page ${page}`,
pagesUnknown = false,
totalItems = undefined,
...other
}) {
const [currentPage, setCurrentPage] = React.useState(initialPage);
const [currentPageSize, setCurrentPageSize] = React.useState(pageSize);
const prefix = usePrefix.usePrefix();
const totalPages = totalItems ? Math.max(Math.ceil(totalItems / currentPageSize), 1) : undefined;
const backButtonDisabled = disabled || currentPage === 1;
const forwardButtonDisabled = disabled || currentPage === totalPages;
function onSetPage(newPage) {
setCurrentPage(Number(newPage));
}
function incrementPage() {
const page = currentPage + 1;
setCurrentPage(page);
onChange({
page,
pageSize: currentPageSize
});
}
function decrementPage() {
const page = currentPage - 1;
setCurrentPage(page);
onChange({
page,
pageSize: currentPageSize
});
}
const namespace = `${prefix}--unstable-pagination`;
return /*#__PURE__*/React.createElement("section", _rollupPluginBabelHelpers.extends({
className: cx(namespace, className)
}, other), /*#__PURE__*/React.createElement("div", {
className: `${namespace}__left`
}, pageSizes && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("label", {
id: `${namespace}__page-sizer__counter-${id}`,
className: `${namespace}__text`,
htmlFor: `${namespace}__page-sizer__input-${id}`
}, itemsPerPageText), /*#__PURE__*/React.createElement(Select.default, {
id: `${namespace}__page-sizer__input-${id}`,
className: `${namespace}__page-sizer`,
labelText: "",
hideLabel: true,
noLabel: true,
inline: true,
onChange: event => setCurrentPageSize(Number(event.target.value)),
value: currentPageSize
}, pageSizes.map(size => /*#__PURE__*/React.createElement(SelectItem.default, {
key: size,
value: size,
text: String(size)
})))), /*#__PURE__*/React.createElement("span", {
className: `${namespace}__text`
}, totalItems && !pagesUnknown && itemRangeText(Math.min(currentPageSize * (currentPage - 1) + 1, totalItems), Math.min(currentPage * currentPageSize, totalItems), totalItems), totalItems && pagesUnknown && itemText(currentPageSize * (currentPage - 1) + 1, currentPage * currentPageSize), !totalItems && itemText(currentPageSize * (currentPage - 1) + 1, currentPage * currentPageSize))), /*#__PURE__*/React.createElement("div", {
className: `${namespace}__right`
}, children && totalItems && children({
currentPage,
currentPageSize,
onSetPage,
totalPages
}), children && totalItems && !pagesUnknown && /*#__PURE__*/React.createElement("span", {
className: `${namespace}__text`
}, pageRangeText('', totalPages)), children && !totalItems && /*#__PURE__*/React.createElement("span", {
className: `${namespace}__text`
}, pageText(currentPage)), !children && /*#__PURE__*/React.createElement("span", {
className: `${namespace}__text`
}, !totalItems ? pageText(currentPage) : pageRangeText(currentPage, totalPages)), /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(index.IconButton, {
align: "top",
disabled: backButtonDisabled,
kind: "ghost",
className: cx(`${namespace}__button`, `${namespace}__button--backward`, {
[`${namespace}__button--no-index`]: backButtonDisabled
}),
label: backwardText,
onClick: () => decrementPage()
}, _CaretLeft || (_CaretLeft = /*#__PURE__*/React.createElement(iconsReact.CaretLeft, null))), /*#__PURE__*/React.createElement(index.IconButton, {
align: "top-right",
disabled: forwardButtonDisabled,
kind: "ghost",
className: cx(`${namespace}__button`, `${namespace}__button--forward`, {
[`${namespace}__button--no-index`]: forwardButtonDisabled
}),
label: forwardText,
onClick: () => incrementPage()
}, _CaretRight || (_CaretRight = /*#__PURE__*/React.createElement(iconsReact.CaretRight, null))))));
}
Pagination.propTypes = {
/**
* The description for the backward icon.
*/
backwardText: PropTypes.string,
/**
* The children of the pagination component.
*/
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
/**
* Extra classes to add.
*/
className: PropTypes.string,
/**
* `true` if the backward/forward buttons should be disabled.
*/
disabled: PropTypes.bool,
/**
* The description for the forward icon.
*/
forwardText: PropTypes.string,
/** The unique ID of this component instance. */
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
/**
* The initial active page when the component is first mounted.
*/
initialPage: PropTypes.number,
/**
* The function returning a translatable text showing where the current page is,
* in a manner of the range of items.
*/
itemRangeText: PropTypes.func,
/**
* A variant of `itemRangeText`, used if the total number of items is unknown.
*/
itemText: PropTypes.func,
/**
* The translatable text indicating the number of items per page.
*/
itemsPerPageText: PropTypes.string,
/**
* The callback function called when the current page changes.
*/
onChange: PropTypes.func,
/**
* The function returning a translatable text showing where the current page is,
* in a manner of the total number of pages.
*/
pageRangeText: PropTypes.func,
/**
* The number dictating how many items a page contains.
*/
pageSize: PropTypes.number,
/**
* The choices for `pageSize`.
*/
pageSizes: PropTypes.arrayOf(PropTypes.number),
/**
* The translatable text showing the current page.
*/
pageText: PropTypes.func,
/**
* `true` if total number of pages is unknown.
*/
pagesUnknown: PropTypes.bool,
/**
* The total number of items.
* You need to provide total items to calculate total page,
* which is required by a child like the `PageSelector`
* to know how many pages to display.
*/
totalItems: PropTypes.number
};
exports.default = Pagination;