UNPKG

@carbon/react

Version:

React components for the Carbon Design System

197 lines (193 loc) 7.16 kB
/** * 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. */ import { extends as _extends } from '../../../_virtual/_rollupPluginBabelHelpers.js'; import React, { useState } from 'react'; import PropTypes from 'prop-types'; import cx from 'classnames'; import { CaretLeft, CaretRight } from '@carbon/icons-react'; import Select from '../../Select/Select.js'; import '../../Select/Select.Skeleton.js'; import SelectItem from '../../SelectItem/SelectItem.js'; import { IconButton } from '../../IconButton/index.js'; import { usePrefix } from '../../../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] = useState(initialPage); const [currentPageSize, setCurrentPageSize] = useState(pageSize); const prefix = 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", _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, { 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, { 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(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(CaretLeft, null))), /*#__PURE__*/React.createElement(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(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 }; export { Pagination as default };