"use client"; // src/use-pagination.ts import { objectToDeps } from "@heroui/shared-utils"; import { PaginationItemType } from "@heroui/use-pagination"; import { useEffect, useRef, useMemo } from "react"; import { mapPropsVariants, useProviderContext } from "@heroui/system"; import { usePagination as useBasePagination } from "@heroui/use-pagination"; import scrollIntoView from "scroll-into-view-if-needed"; import { pagination } from "@heroui/theme"; import { useDOMRef } from "@heroui/react-utils"; import { clsx, dataAttr } from "@heroui/shared-utils"; import { useIntersectionObserver } from "@heroui/use-intersection-observer"; var CURSOR_TRANSITION_TIMEOUT = 300; function usePagination(originalProps) { var _a, _b, _c, _d; const globalContext = useProviderContext(); const [props, variantProps] = mapPropsVariants(originalProps, pagination.variantKeys); const { as, ref, classNames, dotsJump = 5, loop = false, showControls = false, total = 1, initialPage = 1, page, siblings, boundaries, onChange, className, renderItem, getItemAriaLabel: getItemAriaLabelProp, ...otherProps } = props; const Component = as || "nav"; const domRef = useDOMRef(ref); const cursorRef = useRef(null); const itemsRef = useRef(); const cursorTimer = useRef(); const disableAnimation = (_b = (_a = originalProps == null ? void 0 : originalProps.disableAnimation) != null ? _a : globalContext == null ? void 0 : globalContext.disableAnimation) != null ? _b : false; const disableCursorAnimation = (_d = (_c = originalProps == null ? void 0 : originalProps.disableCursorAnimation) != null ? _c : disableAnimation) != null ? _d : false; function getItemsRefMap() { if (!itemsRef.current) { itemsRef.current = /* @__PURE__ */ new Map(); } return itemsRef.current; } function getItemRef(node, value) { const map = getItemsRefMap(); if (node) { map.set(value, node); } else { map.delete(value); } } function scrollTo(value, skipAnimation) { const map = getItemsRefMap(); const node = map.get(value); if (!node || !cursorRef.current) return; cursorTimer.current && clearTimeout(cursorTimer.current); scrollIntoView(node, { scrollMode: "always", behavior: "smooth", block: "start", inline: "start", boundary: domRef.current }); const { offsetLeft } = node; if (skipAnimation) { cursorRef.current.setAttribute("data-moving", "false"); cursorRef.current.style.transform = `translateX(${offsetLeft}px) scale(1)`; return; } cursorRef.current.setAttribute("data-moving", "true"); cursorRef.current.style.transform = `translateX(${offsetLeft}px) scale(1.1)`; cursorTimer.current = setTimeout(() => { if (cursorRef.current) { cursorRef.current.style.transform = `translateX(${offsetLeft}px) scale(1)`; } cursorTimer.current = setTimeout(() => { var _a2; (_a2 = cursorRef.current) == null ? void 0 : _a2.setAttribute("data-moving", "false"); cursorTimer.current && clearTimeout(cursorTimer.current); }, CURSOR_TRANSITION_TIMEOUT); }, CURSOR_TRANSITION_TIMEOUT); } const { range, activePage, setPage, previous, next, first, last } = useBasePagination({ page, total, initialPage, siblings, boundaries, showControls, onChange }); const [setRef, isVisible] = useIntersectionObserver(); useEffect(() => { if (domRef.current) { setRef(domRef.current); } }, [domRef.current]); const activePageRef = useRef(activePage); useEffect(() => { if (activePage && !disableAnimation && isVisible) { scrollTo(activePage, activePage === activePageRef.current); } activePageRef.current = activePage; }, [ page, activePage, disableAnimation, disableCursorAnimation, isVisible, originalProps.dotsJump, originalProps.isCompact, originalProps.showControls ]); const slots = useMemo( () => pagination({ ...variantProps, disableAnimation, disableCursorAnimation }), [objectToDeps(variantProps), disableCursorAnimation, disableAnimation] ); const baseStyles = clsx(classNames == null ? void 0 : classNames.base, className); const onNext = () => { if (loop && activePage === total) { return first(); } return next(); }; const onPrevious = () => { if (loop && activePage === 1) { return last(); } return previous(); }; const getBaseProps = (props2 = {}) => { return { ...props2, ref: domRef, role: "navigation", "aria-label": props2["aria-label"] || "pagination navigation", "data-slot": "base", "data-controls": dataAttr(showControls), "data-loop": dataAttr(loop), "data-dots-jump": dotsJump, "data-total": total, "data-active-page": activePage, className: slots.base({ class: clsx(baseStyles, props2 == null ? void 0 : props2.className) }), ...otherProps }; }; const getWrapperProps = (props2 = {}) => { return { ...props2, "data-slot": "wrapper", className: slots.wrapper({ class: clsx(classNames == null ? void 0 : classNames.wrapper, props2 == null ? void 0 : props2.className) }) }; }; const getItemAriaLabel = (page2) => { if (!page2) return; if (getItemAriaLabelProp) { return getItemAriaLabelProp(page2); } switch (page2) { case PaginationItemType.DOTS: return "dots element"; case PaginationItemType.PREV: return "previous page button"; case PaginationItemType.NEXT: return "next page button"; case "first": return "first page button"; case "last": return "last page button"; default: return `pagination item ${page2}`; } }; const getItemProps = (props2 = {}) => { return { ...props2, ref: (node) => getItemRef(node, props2.value), "data-slot": "item", isActive: props2.value === activePage, className: slots.item({ class: clsx(classNames == null ? void 0 : classNames.item, props2 == null ? void 0 : props2.className) }), onPress: () => { if (props2.value !== activePage) { setPage(props2.value); } } }; }; const getCursorProps = (props2 = {}) => { return { ...props2, ref: cursorRef, activePage, "data-slot": "cursor", className: slots.cursor({ class: clsx(classNames == null ? void 0 : classNames.cursor, props2 == null ? void 0 : props2.className) }) }; }; return { Component, showControls, dotsJump, slots, classNames, loop, total, range, activePage, getItemRef, disableAnimation, disableCursorAnimation, setPage, onPrevious, onNext, renderItem, getBaseProps, getWrapperProps, getItemProps, getCursorProps, getItemAriaLabel }; } export { CURSOR_TRANSITION_TIMEOUT, usePagination };