UNPKG

@trail-ui/react

Version:
217 lines (214 loc) 7.82 kB
import { customSelect_default } from "./chunk-VCCE27QM.mjs"; import { Positions } from "./chunk-DFBZCBP4.mjs"; import { _IconButton } from "./chunk-CTOQKVKR.mjs"; // src/pagination/pagination.tsx import { ChevronLeftIcon, ChevronRightIcon } from "@trail-ui/icons"; import { useEffect, useMemo, useRef } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; function Pagination({ readsResults = true, ...props }) { var _a; const paginationButtonsRef = useRef(null); const lastClickedPageRef = useRef(null); const totalPages = useMemo(() => { return Math.ceil(props.totalCount / props.size); }, [props.totalCount, props.size]); const pageNumberArray = useMemo(() => { const maxButtonsToShow = 5; const pageNumbers = []; if (totalPages <= maxButtonsToShow) { for (let i = 1; i <= totalPages; i++) { pageNumbers.push(i); } return pageNumbers; } let startPage, endPage; const middleButtonsToShow = maxButtonsToShow - 2; const halfMiddleButtonsToShow = Math.floor(middleButtonsToShow / 2); if (props.currentPage <= halfMiddleButtonsToShow + 1) { startPage = 2; endPage = middleButtonsToShow + 1; } else if (props.currentPage + halfMiddleButtonsToShow >= totalPages) { startPage = totalPages - middleButtonsToShow; endPage = totalPages - 1; } else { startPage = props.currentPage - halfMiddleButtonsToShow; endPage = props.currentPage + halfMiddleButtonsToShow; } pageNumbers.push(1); if (startPage > 2) { pageNumbers.push("..."); } for (let i = startPage; i <= endPage; i++) { pageNumbers.push(i); } if (endPage < totalPages - 1) { pageNumbers.push("..."); } pageNumbers.push(totalPages); return pageNumbers; }, [props.totalCount, props.size, props.currentPage]); useEffect(() => { var _a2; if (lastClickedPageRef.current !== null) { const button = (_a2 = paginationButtonsRef.current) == null ? void 0 : _a2.querySelector( `button[data-id="${lastClickedPageRef.current}"]` ); if (button) button.focus(); } }, [pageNumberArray]); return /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between space-x-2", children: [ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [ props.onPageSizeChange && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [ /* @__PURE__ */ jsx("span", { className: "min-w-[fit-content] text-sm font-normal text-neutral-600", children: "Items per page" }), /* @__PURE__ */ jsx( customSelect_default, { label: "Items per page", classNames: { label: "hidden" }, value: props.size, isRequired: false, options: ((_a = props.sizeOptions) == null ? void 0 : _a.map((size) => ({ label: size.toString(), value: size }))) || [ { label: "100", value: 100 }, { label: "250", value: 250 }, { label: "500", value: 500 } ], errorMessage: "", errorId: "", onChange: (e) => { var _a2; (_a2 = props.onPageSizeChange) == null ? void 0 : _a2.call(props, Number(e)); props.onPageChange(1); }, position: Positions.topLeft, popover: { width: 100 } } ) ] }), readsResults ? ( // biome-ignore lint/a11y/useSemanticElements: <explanation> /* @__PURE__ */ jsxs( "p", { role: "status", "aria-live": "polite", "aria-atomic": "true", className: "text-sm text-neutral-600", children: [ "Showing ", (props.currentPage - 1) * props.size + 1, "-", Math.min(props.currentPage * props.size, props.totalCount), " of ", props.totalCount, " ", props.totalCount === 1 ? "result" : "results" ] } ) ) : /* @__PURE__ */ jsxs("p", { className: "text-sm text-neutral-600", children: [ "Showing ", (props.currentPage - 1) * props.size + 1, "-", Math.min(props.currentPage * props.size, props.totalCount), " of ", props.totalCount, " ", props.totalCount === 1 ? "result" : "results" ] }) ] }), props.selectedCount > 0 && /* @__PURE__ */ jsxs( "p", { role: props.selectedCount < 1 ? "none" : "alert", "aria-live": props.selectedCount < 1 ? "off" : "polite", className: `${props.selectedCount < 1 ? "sr-only" : ""} text-sm font-medium text-purple-600`, children: [ props.selectedCount, " selected" ] } ), /* @__PURE__ */ jsx("nav", { "aria-label": "Pagination", className: "flex justify-end", children: /* @__PURE__ */ jsxs("ul", { className: "flex items-center justify-end gap-2", ref: paginationButtonsRef, children: [ /* @__PURE__ */ jsx("li", { className: "flex h-8 w-8 items-center justify-center", children: /* @__PURE__ */ jsx( _IconButton, { "aria-label": "Previous Page", appearance: "transparent", isDisabled: props.currentPage === 1, onPress: () => { var _a2; (_a2 = props.onPageChange) == null ? void 0 : _a2.call(props, props.currentPage - 1); }, children: /* @__PURE__ */ jsx( ChevronLeftIcon, { color: `${props.currentPage === 1 ? "#B0ACBB" : "#302E38"}`, width: 24, height: 24 } ) } ) }), pageNumberArray.map((pageNumber, index) => /* @__PURE__ */ jsx( "li", { className: "flex h-8 w-8 items-center justify-center", children: pageNumber === "..." ? /* @__PURE__ */ jsx("span", { children: "..." }) : /* @__PURE__ */ jsx( "button", { "data-id": pageNumber, ...pageNumber === props.currentPage ? { "aria-current": "page" } : {}, "aria-current": pageNumber === props.currentPage ? "page" : void 0, "aria-label": `Page ${pageNumber}`, onClick: () => { if (pageNumber !== "..." && props.onPageChange) { lastClickedPageRef.current = pageNumber; props.onPageChange(pageNumber); } }, className: `h-full w-full text-sm font-normal text-neutral-800 focus:outline-purple-600 ${pageNumber === props.currentPage ? "rounded border border-purple-600 bg-purple-100" : "bg-white"} `, children: pageNumber } ) }, `${pageNumber}-${// biome-ignore lint/suspicious/noArrayIndexKey: <explanation> index}` )), /* @__PURE__ */ jsx("li", { className: "flex h-8 w-8 items-center justify-center", children: /* @__PURE__ */ jsx( _IconButton, { "aria-label": "Next Page", appearance: "transparent", isDisabled: props.currentPage >= totalPages, onPress: () => { var _a2; (_a2 = props.onPageChange) == null ? void 0 : _a2.call(props, props.currentPage + 1); }, children: /* @__PURE__ */ jsx( ChevronRightIcon, { color: props.currentPage === totalPages ? "#B0ACBB" : "#302E38", width: 24, height: 24 } ) } ) }) ] }) }) ] }); } export { Pagination };