UNPKG

@yamada-ui/react

Version:

React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion

118 lines (114 loc) 3.51 kB
"use client"; import { useSafeLayoutEffect } from "../../utils/effect.js"; import { mergeRefs } from "../../utils/ref.js"; import { utils_exports } from "../../utils/index.js"; import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"; //#region src/components/scroll-area/use-scroll-area.ts const useScrollArea = ({ id, ref, type = "hover", scrollHideDelay = 1e3, onScrollPositionChange,...rest } = {}) => { const [isHovered, setIsHovered] = useState(false); const [isScrolling, setIsScrolling] = useState(false); const isAlways = type === "always"; const isNever = type === "never"; const isHidden = !isAlways && !isHovered && !isScrolling; const isSafari = (0, utils_exports.isMac)() && (0, utils_exports.vendor)(/apple/i); const uuid = useId(); const key = `${id ?? uuid}-${isHovered}-${isScrolling}`; const hoverTimeout = useRef(void 0); const scrollTimeout = useRef(void 0); const scrollAreaRef = useRef(null); const scrollPosition = useRef({ x: 0, y: 0 }); useSafeLayoutEffect(() => { if (!scrollAreaRef.current || !isSafari) return; scrollAreaRef.current.scrollLeft = scrollPosition.current.x; scrollAreaRef.current.scrollTop = scrollPosition.current.y; }); const onMouseEnter = useCallback(() => { if (type !== "hover") return; clearTimeout(hoverTimeout.current); setIsHovered(true); }, [type]); const onMouseLeave = useCallback(() => { if (type !== "hover") return; hoverTimeout.current = setTimeout(() => setIsHovered(false), scrollHideDelay); }, [scrollHideDelay, type]); const onScroll = useCallback((ev) => { const { scrollLeft: x, scrollTop: y } = ev.target; const { x: prevX, y: prevY } = scrollPosition.current; const isEqual = Math.abs(x - prevX) <= 5 && Math.abs(y - prevY) <= 5; onScrollPositionChange?.({ x, y }); scrollPosition.current = { x, y }; if (type !== "scroll" || isEqual) return; if (!isScrolling) setIsScrolling(true); clearTimeout(scrollTimeout.current); scrollTimeout.current = setTimeout(() => setIsScrolling(false), scrollHideDelay); }, [ isScrolling, onScrollPositionChange, scrollHideDelay, type ]); useEffect(() => { return () => { if (hoverTimeout.current) clearTimeout(hoverTimeout.current); if (scrollTimeout.current) clearTimeout(scrollTimeout.current); }; }, []); const safariProps = useMemo(() => ({ key, ref: mergeRefs(ref, scrollAreaRef), "data-key": key }), [ key, ref, scrollAreaRef ]); return { isAlways, isHidden, isHovered, isNever, isScrolling, getRootProps: useCallback(({ style,...props } = {}) => ({ ref, style: { overflow: "auto", ...style }, ...rest, ...isSafari ? safariProps : {}, ...props, "data-hidden": (0, utils_exports.dataAttr)(isHidden), "data-hover": (0, utils_exports.dataAttr)(isHovered), "data-never": (0, utils_exports.dataAttr)(isNever), "data-scroll": (0, utils_exports.dataAttr)(isScrolling), tabIndex: 0, onMouseEnter: (0, utils_exports.handlerAll)(props.onMouseEnter, rest.onMouseEnter, onMouseEnter), onMouseLeave: (0, utils_exports.handlerAll)(props.onMouseLeave, rest.onMouseLeave, onMouseLeave), onScroll: (0, utils_exports.handlerAll)(props.onScroll, rest.onScroll, onScroll) }), [ isNever, ref, isHidden, isHovered, isScrolling, isSafari, safariProps, rest, onMouseEnter, onMouseLeave, onScroll ]) }; }; //#endregion export { useScrollArea }; //# sourceMappingURL=use-scroll-area.js.map