UNPKG

@mantine/hooks

Version:

A collection of 50+ hooks for state and UI management

76 lines (75 loc) 3.7 kB
"use client"; const require_use_isomorphic_effect = require("../use-isomorphic-effect/use-isomorphic-effect.cjs"); const require_use_window_scroll = require("../use-window-scroll/use-window-scroll.cjs"); const require_use_scroll_direction = require("../use-scroll-direction/use-scroll-direction.cjs"); let react = require("react"); //#region packages/@mantine/hooks/src/use-headroom/use-headroom.ts const isFixed = (current, fixedAt) => current <= fixedAt; const isPinnedOrReleased = (current, fixedAt, isCurrentlyPinnedRef, isScrollingUp, onPin, onRelease) => { const isInFixedPosition = isFixed(current, fixedAt); if (isInFixedPosition && !isCurrentlyPinnedRef.current) { isCurrentlyPinnedRef.current = true; onPin?.(); } else if (!isInFixedPosition && isScrollingUp && !isCurrentlyPinnedRef.current) { isCurrentlyPinnedRef.current = true; onPin?.(); } else if (!isInFixedPosition && !isScrollingUp && isCurrentlyPinnedRef.current) { isCurrentlyPinnedRef.current = false; onRelease?.(); } }; function useHeadroom({ fixedAt = 0, scrollDistance = 100, onPin, onFix, onRelease } = {}) { const isCurrentlyPinnedRef = (0, react.useRef)(false); const isScrollingUp = require_use_scroll_direction.useScrollDirection() === "up"; const [{ y: scrollPosition }] = require_use_window_scroll.useWindowScroll(); const onPinEvent = (0, react.useEffectEvent)(() => onPin?.()); const onReleaseEvent = (0, react.useEffectEvent)(() => onRelease?.()); const onFixEvent = (0, react.useEffectEvent)(() => onFix?.()); require_use_isomorphic_effect.useIsomorphicEffect(() => { isPinnedOrReleased(scrollPosition, fixedAt, isCurrentlyPinnedRef, isScrollingUp, onPinEvent, onReleaseEvent); }, [ scrollPosition, fixedAt, isScrollingUp ]); require_use_isomorphic_effect.useIsomorphicEffect(() => { if (isFixed(scrollPosition, fixedAt)) onFixEvent(); }, [scrollPosition, fixedAt]); const currentlyFixed = isFixed(scrollPosition, fixedAt); const prevIsFixedRef = (0, react.useRef)(currentlyFixed); const directionChangeScrollYRef = (0, react.useRef)(scrollPosition); const progressAtDirectionChangeRef = (0, react.useRef)(currentlyFixed ? 1 : 0); const prevIsScrollingUpRef = (0, react.useRef)(isScrollingUp); if (prevIsFixedRef.current !== currentlyFixed) { prevIsFixedRef.current = currentlyFixed; if (!currentlyFixed) { directionChangeScrollYRef.current = fixedAt; progressAtDirectionChangeRef.current = 1; } else { directionChangeScrollYRef.current = scrollPosition; progressAtDirectionChangeRef.current = 1; } prevIsScrollingUpRef.current = isScrollingUp; } if (!currentlyFixed && prevIsScrollingUpRef.current !== isScrollingUp) { const transitionDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current); const transitionProgress = prevIsScrollingUpRef.current ? Math.min(progressAtDirectionChangeRef.current + transitionDelta / scrollDistance, 1) : Math.max(progressAtDirectionChangeRef.current - transitionDelta / scrollDistance, 0); prevIsScrollingUpRef.current = isScrollingUp; directionChangeScrollYRef.current = scrollPosition; progressAtDirectionChangeRef.current = transitionProgress; } let scrollProgress; if (currentlyFixed) scrollProgress = 1; else { const scrollDelta = Math.abs(scrollPosition - directionChangeScrollYRef.current); if (isScrollingUp) scrollProgress = Math.min(progressAtDirectionChangeRef.current + scrollDelta / scrollDistance, 1); else scrollProgress = Math.max(progressAtDirectionChangeRef.current - scrollDelta / scrollDistance, 0); } return { pinned: scrollProgress > 0, scrollProgress }; } //#endregion exports.useHeadroom = useHeadroom; //# sourceMappingURL=use-headroom.cjs.map