UNPKG

@itwin/itwinui-react

Version:

A react component library for iTwinUI

362 lines (361 loc) 10.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true, }); Object.defineProperty(exports, 'TablePaginator', { enumerable: true, get: function () { return TablePaginator; }, }); const _interop_require_default = require('@swc/helpers/_/_interop_require_default'); const _interop_require_wildcard = require('@swc/helpers/_/_interop_require_wildcard'); const _react = /*#__PURE__*/ _interop_require_wildcard._(require('react')); const _classnames = /*#__PURE__*/ _interop_require_default._( require('classnames'), ); const _IconButton = require('../Buttons/IconButton.js'); const _Button = require('../Buttons/Button.js'); const _DropdownButton = require('../Buttons/DropdownButton.js'); const _ProgressRadial = require('../ProgressIndicators/ProgressRadial.js'); const _MenuItem = require('../Menu/MenuItem.js'); const _index = require('../../utils/index.js'); const _styles = require('../../styles.js'); const defaultLocalization = { pageSizeLabel: (size) => `${size} per page`, rangeLabel: (startIndex, endIndex, totalRows, isLoading) => isLoading ? `${startIndex}-${endIndex}…` : `${startIndex}-${endIndex} of ${totalRows}`, previousPage: 'Previous page', nextPage: 'Next page', goToPageLabel: (page) => `Go to page ${page}`, rowsPerPageLabel: 'Rows per page', rowsSelectedLabel: (totalSelectedRowsCount) => `${totalSelectedRowsCount} ${ 1 === totalSelectedRowsCount ? 'row' : 'rows' } selected`, }; const TablePaginator = (props) => { let { currentPage, totalRowsCount, pageSize, onPageChange, totalSelectedRowsCount = 0, focusActivationMode = 'manual', isLoading = false, size = 'default', pageSizeList, onPageSizeChange, localization: userLocalization, className, ...rest } = props; (0, _index.useGlobals)(); let localization = _react.useMemo( () => ({ ...defaultLocalization, ...userLocalization, }), [userLocalization], ); let pageListRef = _react.useRef(null); let [focusedIndex, setFocusedIndex] = _react.useState(currentPage); (0, _index.useLayoutEffect)(() => { setFocusedIndex(currentPage); }, [currentPage]); let needFocus = _react.useRef(false); let isMounted = _react.useRef(false); _react.useEffect(() => { if (isMounted.current && needFocus.current) { let buttonToFocus = Array.from( pageListRef.current?.querySelectorAll( `.${_styles.styles['iui-table-paginator-page-button']}`, ) ?? [], ).find((el) => el.textContent?.trim() === (focusedIndex + 1).toString()); buttonToFocus?.focus(); needFocus.current = false; } isMounted.current = true; }, [focusedIndex]); let buttonSize = 'default' != size ? 'small' : void 0; let totalPagesCount = Math.ceil(totalRowsCount / pageSize); let onKeyDown = (event) => { if (event.altKey) return; let focusPage = (delta) => { let newFocusedIndex = (0, _index.getBoundedValue)( focusedIndex + delta, 0, totalPagesCount - 1, ); needFocus.current = true; if ('auto' === focusActivationMode) onPageChange(newFocusedIndex); else setFocusedIndex(newFocusedIndex); }; switch (event.key) { case 'ArrowRight': focusPage(1); event.preventDefault(); break; case 'ArrowLeft': focusPage(-1); event.preventDefault(); break; case 'Enter': case ' ': case 'Spacebar': if ('manual' === focusActivationMode) onPageChange(focusedIndex); break; default: break; } }; let [paginatorResizeRef, paginatorWidth] = (0, _index.useContainerWidth)(); let showPagesList = totalPagesCount > 1 || isLoading; let showPageSizeList = pageSizeList && !!onPageSizeChange && !!totalRowsCount; let hasNoRows = 0 === totalPagesCount; let noRowsContent = _react.createElement( _react.Fragment, null, isLoading ? _react.createElement(_ProgressRadial.ProgressRadial, { indeterminate: true, size: 'small', }) : _react.createElement( _Button.Button, { styleType: 'borderless', disabled: true, size: buttonSize, }, '1', ), ); if (!showPagesList && !showPageSizeList) return null; return _react.createElement( _index.Box, { className: (0, _classnames.default)('iui-table-paginator', className), ref: paginatorResizeRef, ...rest, }, _react.createElement( _index.Box, { className: 'iui-left', }, totalSelectedRowsCount > 0 && _react.createElement( 'span', null, localization.rowsSelectedLabel(totalSelectedRowsCount), ), ), showPagesList && _react.createElement( _index.OverflowContainer, { className: 'iui-center', itemsCount: totalPagesCount, }, _react.createElement( _IconButton.IconButton, { styleType: 'borderless', disabled: 0 === currentPage, onClick: () => onPageChange(currentPage - 1), size: buttonSize, 'aria-label': localization.previousPage, }, _react.createElement(_index.SvgChevronLeft, null), ), _react.createElement( _index.Box, { as: 'span', className: 'iui-table-paginator-pages-group', onKeyDown: onKeyDown, ref: pageListRef, }, hasNoRows ? noRowsContent : _react.createElement(TablePaginatorPageButtons, { size: size, focusedIndex: focusedIndex, setFocusedIndex: setFocusedIndex, totalPagesCount: totalPagesCount, onPageChange: onPageChange, currentPage: currentPage, localization: localization, isLoading: isLoading, }), ), _react.createElement( _IconButton.IconButton, { styleType: 'borderless', disabled: currentPage === totalPagesCount - 1 || hasNoRows, onClick: () => onPageChange(currentPage + 1), size: buttonSize, 'aria-label': localization.nextPage, }, _react.createElement(_index.SvgChevronRight, null), ), ), _react.createElement( _index.Box, { className: 'iui-right', }, showPageSizeList && _react.createElement( _react.Fragment, null, null !== localization.rowsPerPageLabel && paginatorWidth >= 1024 && _react.createElement( _index.Box, { as: 'span', className: 'iui-table-paginator-page-size-label', }, localization.rowsPerPageLabel, ), _react.createElement( _DropdownButton.DropdownButton, { styleType: 'borderless', size: buttonSize, menuItems: (close) => pageSizeList.map((size) => _react.createElement( _MenuItem.MenuItem, { key: size, isSelected: size === pageSize, onClick: () => { close(); onPageSizeChange(size); }, }, localization.pageSizeLabel(size), ), ), }, localization.rangeLabel( currentPage * pageSize + 1, Math.min(totalRowsCount, (currentPage + 1) * pageSize), totalRowsCount, isLoading, ), ), ), ), ); }; const TablePaginatorPageButtons = (props) => { let { focusedIndex, setFocusedIndex, totalPagesCount, onPageChange, currentPage, localization, isLoading, size, } = props; let { visibleCount } = _index.OverflowContainer.useContext(); let buttonSize = 'default' != size ? 'small' : void 0; let pageButton = _react.useCallback( (index, tabIndex = index === focusedIndex ? 0 : -1) => _react.createElement( _Button.Button, { key: index, className: 'iui-table-paginator-page-button', styleType: 'borderless', size: buttonSize, 'data-iui-active': index === currentPage, onClick: () => { setFocusedIndex(index); onPageChange(index); }, 'aria-current': index === currentPage, 'aria-label': localization.goToPageLabel?.(index + 1), tabIndex: tabIndex, }, index + 1, ), [ focusedIndex, buttonSize, currentPage, localization, setFocusedIndex, onPageChange, ], ); let pageList = _react.useMemo( () => new Array(totalPagesCount) .fill(null) .map((_, index) => pageButton(index)), [pageButton, totalPagesCount], ); let halfVisibleCount = Math.floor(visibleCount / 2); let startPage = focusedIndex - halfVisibleCount; let endPage = focusedIndex + halfVisibleCount + 1; if (startPage < 0) { endPage = Math.min(totalPagesCount, endPage + Math.abs(startPage)); startPage = 0; } if (endPage > totalPagesCount) { startPage = Math.max(0, startPage - (endPage - totalPagesCount)); endPage = totalPagesCount; } let ellipsis = _react.createElement( _index.Box, { as: 'span', className: (0, _classnames.default)('iui-table-paginator-ellipsis', { 'iui-table-paginator-ellipsis-small': 'small' === size, }), }, '…', ); if (1 === visibleCount) return pageButton(focusedIndex); let showStartEllipsis = startPage > 1; let showEndEllipsis = endPage < totalPagesCount - 1; return _react.createElement( _react.Fragment, null, 0 !== startPage && _react.createElement( _react.Fragment, null, pageButton(0, 0), showStartEllipsis ? ellipsis : null, ), pageList.slice(startPage, endPage), endPage !== totalPagesCount && !isLoading && _react.createElement( _react.Fragment, null, showEndEllipsis ? ellipsis : null, pageButton(totalPagesCount - 1, 0), ), isLoading && _react.createElement( _react.Fragment, null, ellipsis, _react.createElement(_ProgressRadial.ProgressRadial, { indeterminate: true, size: 'small', }), ), ); };