@primer/react
Version:
An implementation of GitHub's Primer Design System using React
115 lines (112 loc) • 3.29 kB
JavaScript
import React from 'react';
import { ChevronLeftIcon, ChevronRightIcon } from '@primer/octicons-react';
import { buildPaginationModel, buildComponentData } from './model.js';
import { viewportRanges } from '../hooks/useResponsiveValue.js';
import { clsx } from 'clsx';
import classes from './Pagination.module.css.js';
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
const getViewportRangesToHidePages = showPages => {
if (showPages && typeof showPages !== 'boolean') {
return Object.keys(showPages).filter(key => !showPages[key]);
}
if (showPages) {
return [];
} else {
return Object.keys(viewportRanges);
}
};
const PageLabel = ({
children,
direction
}) => /*#__PURE__*/jsxs(Fragment, {
children: [direction === 'page-prev' ? /*#__PURE__*/jsx(ChevronLeftIcon, {}) : null, children, direction === 'page-next' ? /*#__PURE__*/jsx(ChevronRightIcon, {}) : null]
});
function usePaginationPages({
pageCount,
currentPage,
onPageChange,
hrefBuilder,
marginPageCount,
showPages,
surroundingPageCount,
renderPage
}) {
const pageChange = React.useCallback(n => e => onPageChange(e, n), [onPageChange]);
const model = React.useMemo(() => {
return buildPaginationModel(pageCount, currentPage, !!showPages, marginPageCount, surroundingPageCount);
}, [pageCount, currentPage, showPages, marginPageCount, surroundingPageCount]);
const children = React.useMemo(() => {
return model.map(page => {
const {
props,
key,
content
} = buildComponentData(page, hrefBuilder, pageChange(page.num));
if (renderPage && props.as !== 'span') {
return renderPage({
key,
children: /*#__PURE__*/jsx(PageLabel, {
direction: key,
children: content
}),
number: page.num,
className: classes.Page,
...props
});
}
const Component = props.as || 'a';
return (
/*#__PURE__*/
// @ts-ignore giving me grief about children and "as" props
jsx(Component, {
className: clsx(classes.Page),
...props,
children: /*#__PURE__*/jsx(PageLabel, {
direction: key,
children: content
})
}, key)
);
});
}, [model, hrefBuilder, pageChange, renderPage]);
return children;
}
function Pagination({
className,
pageCount,
currentPage,
onPageChange = noop,
hrefBuilder = defaultHrefBuilder,
marginPageCount = 1,
showPages = true,
surroundingPageCount = 2,
renderPage,
...rest
}) {
const pageElements = usePaginationPages({
pageCount,
currentPage,
onPageChange,
hrefBuilder,
marginPageCount,
showPages,
surroundingPageCount,
renderPage
});
return /*#__PURE__*/jsx("nav", {
className: clsx(classes.PaginationContainer, className),
"aria-label": "Pagination",
...rest,
children: /*#__PURE__*/jsx("div", {
className: classes.TablePaginationSteps,
"data-hidden-viewport-ranges": getViewportRangesToHidePages(showPages).join(' '),
children: pageElements
})
});
}
Pagination.displayName = "Pagination";
function defaultHrefBuilder(pageNum) {
return `#${pageNum}`;
}
function noop() {}
export { Pagination as default };