@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
182 lines (181 loc) • 6.05 kB
JavaScript
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 };