@itwin/itwinui-react
Version:
A react component library for iTwinUI
362 lines (361 loc) • 10.9 kB
JavaScript
;
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',
}),
),
);
};