UNPKG

@hitachivantara/uikit-react-core

Version:
182 lines (181 loc) 6.05 kB
import { HvIcon } from "../icons.js"; import { HvBaseInput } from "../BaseInput/BaseInput.js"; import { useLabels } from "../hooks/useLabels.js"; import { HvIconButton } from "../IconButton/IconButton.js"; import { useClasses } from "./Pagination.styles.js"; import HvSelect, { Option } from "./Select.js"; import { clamp, useDefaultProps } from "@hitachivantara/uikit-react-utils"; import { forwardRef, useCallback, useEffect, useState } from "react"; import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime"; import { useTheme as useTheme$1 } from "@mui/material/styles"; import useMediaQuery from "@mui/material/useMediaQuery"; //#region src/Pagination/Pagination.tsx var defaultPageSizeOptions = [ 5, 10, 20, 25, 50, 100 ]; var DEFAULT_LABELS = { /** The show label. */ pageSizePrev: "", /** Indicate the units of the page size selection. */ pageSizeEntryName: "rows", /** Used for the aria-label of the selection of number of unit.s */ pageSizeSelectorDescription: "Select how many to display", /** Separator of current page and total pages. */ pagesSeparator: "/", /** Aria-label passed to the page input. */ paginationInputLabel: "Current page", /** Label of the first page button */ firstPage: "First Page", /** Label of the previous page button */ previousPage: "Previous Page", /** Label of the next page button */ nextPage: "Next Page", /** Label of the last page button */ lastPage: "Last Page" }; /** * Pagination is the process of dividing a document into discrete pages. It relates to how users interact * with structured content on a website or application. */ var HvPagination = forwardRef(function HvPagination(props, ref) { const { classes: classesProp, className, pages = 1, page = 0, showPageSizeOptions = true, pageSizeOptions = defaultPageSizeOptions, pageSize = defaultPageSizeOptions[1], showPageJump = true, canPrevious, canNext, onPageChange, onPageSizeChange, labels: labelsProp, showPageProps, navigationProps, currentPageInputProps, ...others } = useDefaultProps("HvPagination", props); const { classes, cx } = useClasses(classesProp); const labels = useLabels(DEFAULT_LABELS, labelsProp); const isXsDown = useMediaQuery(useTheme$1().breakpoints.only("xs")); const [pageInput, setPageInput] = useState(page); const changePage = useCallback((newPage) => { const safePage = Number.isNaN(newPage) ? page : clamp(newPage, pages - 1); onPageChange?.(safePage); setPageInput(safePage); }, [ page, pages, onPageChange ]); useEffect(() => { if (page >= pages && pages > 0) changePage(page); }, [ changePage, page, pages ]); useEffect(() => { setPageInput(page); }, [page]); const renderPageJump = () => /* @__PURE__ */ jsx(HvBaseInput, { inputProps: { "aria-label": labels?.paginationInputLabel, type: "number" }, classes: { root: classes.pageJump, input: classes.pageSizeInput }, value: String(pageInput + 1), onChange: (event, value) => setPageInput(Number(value) - 1), onBlur: (evt) => changePage(Math.round(Number(evt.target.value)) - 1), onKeyDown: (evt) => { if (evt.key !== "Enter") return; changePage(Math.round(Number(evt.currentTarget.value)) - 1); }, disabled: pageSize === 0, ...currentPageInputProps }); return /* @__PURE__ */ jsxs("div", { ref, className: cx(classes.root, className), ...others, children: [showPageSizeOptions && /* @__PURE__ */ jsx("div", { className: classes.pageSizeOptions, ...showPageProps, children: /* @__PURE__ */ jsxs(Fragment$1, { children: [ !isXsDown && labels.pageSizePrev && /* @__PURE__ */ jsx("span", { className: classes.pageSizeTextContainer, children: labels.pageSizePrev }), /* @__PURE__ */ jsx(HvSelect, { disabled: pageSize === 0, "aria-label": labels.pageSizeSelectorDescription, onChange: (evt, val) => onPageSizeChange?.(val), value: pageSize, classes: { header: classes.pageSizeHeader, root: classes.pageSizeRoot }, children: pageSizeOptions.map((option) => /* @__PURE__ */ jsx(Option, { value: option, children: option }, option)) }), !isXsDown && labels.pageSizeEntryName && /* @__PURE__ */ jsx("span", { className: classes.pageSizeTextContainer, children: labels.pageSizeEntryName }) ] }) }), /* @__PURE__ */ jsxs("div", { className: classes.pageNavigator, ...navigationProps, children: [ /* @__PURE__ */ jsx(HvIconButton, { className: classes.iconContainer, disabled: !canPrevious, onClick: () => changePage(0), title: labels?.firstPage, children: /* @__PURE__ */ jsx(HvIcon, { name: "Start", className: classes.icon, size: "xs" }) }), /* @__PURE__ */ jsx(HvIconButton, { className: classes.iconContainer, disabled: !canPrevious, onClick: () => changePage(page - 1), title: labels?.previousPage, children: /* @__PURE__ */ jsx(HvIcon, { name: "Backwards", className: classes.icon, size: "xs" }) }), /* @__PURE__ */ jsxs("div", { className: classes.pageInfo, children: [ showPageJump ? renderPageJump() : /* @__PURE__ */ jsx("span", { children: `${page + 1}` }), /* @__PURE__ */ jsx("span", { children: `${labels?.pagesSeparator} ` }), /* @__PURE__ */ jsx("span", { children: pages }) ] }), /* @__PURE__ */ jsx(HvIconButton, { className: classes.iconContainer, disabled: !canNext, onClick: () => changePage(page + 1), title: labels?.nextPage, children: /* @__PURE__ */ jsx(HvIcon, { name: "Forwards", className: classes.icon, size: "xs" }) }), /* @__PURE__ */ jsx(HvIconButton, { className: classes.iconContainer, disabled: !canNext, onClick: () => changePage(pages - 1), title: labels?.lastPage, children: /* @__PURE__ */ jsx(HvIcon, { name: "End", className: classes.icon, size: "xs" }) }) ] })] }); }); //#endregion export { HvPagination };