{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/hooks/useScrollEvent/index.ts"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react';\nimport { throttle } from '@modern-kit/utils';\nimport { getScrollDirection, getScrollProgress } from './useScrollEvent.utils';\n\ninterface UseScrollProps {\n  throttleDelay?: number;\n  throttleLeading?: boolean;\n  throttleTrailing?: boolean;\n  enabled?: boolean;\n}\n\ninterface UpdateScrollPositionProps {\n  scrollX: number;\n  scrollY: number;\n  scrollWidth: number;\n  scrollHeight: number;\n  clientWidth: number;\n  clientHeight: number;\n}\n\ninterface ScrollState {\n  scrollX: number;\n  scrollY: number;\n  scrollWidth: number;\n  scrollHeight: number;\n  direction: {\n    y: 'up' | 'down' | 'none';\n    x: 'left' | 'right' | 'none';\n  };\n  progress: {\n    y: number;\n    x: number;\n  };\n}\n\n/**\n * @description 특정 요소나 window의 스크롤 위치를 추적하는 React 커스텀 훅입니다.\n * 스크롤 방향, 진행도, 위치 등 스크롤 관련 정보를 제공합니다.\n *\n * @template T - HTMLElement를 상속하는 제네릭 타입\n * @param {UseScrollProps} props - 훅의 설정 객체\n * @param {boolean} [props.enabled=true] - 스크롤 이벤트 활성화 여부\n * @param {number} [props.throttleDelay=0] - 스크롤 이벤트 쓰로틀링 딜레이(밀리초)\n * @param {boolean} [props.throttleLeading=true] - 스크롤 이벤트 쓰로틀링 시작 시점 이벤트 무시 여부\n * @param {boolean} [props.throttleTrailing=true] - 스크롤 이벤트 쓰로틀링 마지막 이벤트 무시 여부\n * @returns {{\n *  ref: React.RefObject<T>;\n *  scrollState: ScrollState;\n * }} 스크롤 관련 데이터와 ref\n * - `ref`: 스크롤을 추적할 요소에 연결할 ref 객체\n * - `scrollState.scrollX`: 현재 스크롤 위치의 X좌표\n * - `scrollState.scrollY`: 현재 스크롤 위치의 Y좌표\n * - `scrollState.scrollWidth`: 스크롤 가능한 최대 너비\n * - `scrollState.scrollHeight`: 스크롤 가능한 최대 높이\n * - `scrollState.direction`: 현재 스크롤 방향\n * - `scrollState.progress`: 현재 스크롤 진행도\n *\n * @example\n * ```tsx\n * // ref를 전달하지 않으면 기본적으로 window의 스크롤 위치를 추적\n * const { scrollState } = useScrollEvent();\n * ```\n *\n * @example\n * ```tsx\n * // ref를 전달하면 해당 요소를 기준으로 스크롤 위치를 추적\n * const { ref, scrollState } = useScrollEvent<HTMLDivElement>();\n *\n * return <div ref={ref}>{...}</div>\n * ```\n *\n * @example\n * ```tsx\n * // 스크롤 이벤트 쓰로틀링 딜레이를 설정\n * const { scrollState } = useScrollEvent({ throttleDelay: 300, enabled: true });\n * ```\n */\nexport function useScrollEvent<T extends HTMLElement>({\n  throttleDelay = 0,\n  throttleLeading = true,\n  throttleTrailing = true,\n  enabled = true,\n}: UseScrollProps = {}): {\n  ref: React.RefObject<T | null>;\n  scrollState: ScrollState;\n} {\n  const ref = useRef<T>(null);\n  const prevScrollY = useRef(0);\n  const prevScrollX = useRef(0);\n\n  const [scrollState, setScrollState] = useState<ScrollState>({\n    scrollX: 0,\n    scrollY: 0,\n    scrollWidth: 0,\n    scrollHeight: 0,\n    direction: {\n      y: 'none',\n      x: 'none',\n    },\n    progress: {\n      y: 0,\n      x: 0,\n    },\n  });\n\n  const updateScrollPosition = useCallback(\n    ({\n      scrollX,\n      scrollY,\n      scrollWidth,\n      scrollHeight,\n      clientWidth,\n      clientHeight,\n    }: UpdateScrollPositionProps) => {\n      setScrollState({\n        scrollX,\n        scrollY,\n        scrollWidth,\n        scrollHeight,\n        direction: getScrollDirection(\n          scrollX,\n          scrollY,\n          prevScrollY.current,\n          prevScrollX.current\n        ),\n        progress: {\n          y: getScrollProgress(scrollY, scrollHeight, clientHeight),\n          x: getScrollProgress(scrollX, scrollWidth, clientWidth),\n        },\n      });\n\n      // 이전 스크롤 위치 업데이트\n      prevScrollY.current = scrollY;\n      prevScrollX.current = scrollX;\n    },\n    []\n  );\n\n  const handleScrollByRef = useCallback(() => {\n    if (!ref.current) return;\n    const targetElement = ref.current;\n\n    updateScrollPosition({\n      scrollX: targetElement.scrollLeft,\n      scrollY: targetElement.scrollTop,\n      scrollWidth: targetElement.scrollWidth,\n      scrollHeight: targetElement.scrollHeight,\n      clientWidth: targetElement.clientWidth,\n      clientHeight: targetElement.clientHeight,\n    });\n  }, [updateScrollPosition]);\n\n  const handleScrollByWindow = useCallback(() => {\n    updateScrollPosition({\n      scrollX: window.scrollX,\n      scrollY: window.scrollY,\n      scrollWidth: document.documentElement.scrollWidth,\n      scrollHeight: document.documentElement.scrollHeight,\n      clientWidth: window.innerWidth,\n      clientHeight: window.innerHeight,\n    });\n  }, [updateScrollPosition]);\n\n  useEffect(() => {\n    if (!enabled) return;\n\n    const targetElement = ref.current ?? window;\n\n    const scrollHandler = ref.current\n      ? handleScrollByRef\n      : handleScrollByWindow;\n\n    const throttledScrollHandler = throttle(scrollHandler, throttleDelay, {\n      leading: throttleLeading,\n      trailing: throttleTrailing,\n    });\n\n    scrollHandler(); // 초기 스크롤 위치 업데이트\n    targetElement.addEventListener('scroll', throttledScrollHandler);\n\n    return () => {\n      targetElement.removeEventListener('scroll', throttledScrollHandler);\n      throttledScrollHandler.cancel();\n    };\n  }, [\n    handleScrollByRef,\n    handleScrollByWindow,\n    enabled,\n    throttleDelay,\n    throttleLeading,\n    throttleTrailing,\n  ]);\n\n  return {\n    ref,\n    scrollState,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,SAAgB,eAAsC,EACpD,gBAAgB,GAChB,kBAAkB,MAClB,mBAAmB,MACnB,UAAU,SACQ,EAAE,EAGpB;CACA,MAAM,MAAM,OAAU,KAAK;CAC3B,MAAM,cAAc,OAAO,EAAE;CAC7B,MAAM,cAAc,OAAO,EAAE;CAE7B,MAAM,CAAC,aAAa,kBAAkB,SAAsB;EAC1D,SAAS;EACT,SAAS;EACT,aAAa;EACb,cAAc;EACd,WAAW;GACT,GAAG;GACH,GAAG;GACJ;EACD,UAAU;GACR,GAAG;GACH,GAAG;GACJ;EACF,CAAC;CAEF,MAAM,uBAAuB,aAC1B,EACC,SACA,SACA,aACA,cACA,aACA,mBAC+B;EAC/B,eAAe;GACb;GACA;GACA;GACA;GACA,WAAW,mBACT,SACA,SACA,YAAY,SACZ,YAAY,QACb;GACD,UAAU;IACR,GAAG,kBAAkB,SAAS,cAAc,aAAa;IACzD,GAAG,kBAAkB,SAAS,aAAa,YAAY;IACxD;GACF,CAAC;EAGF,YAAY,UAAU;EACtB,YAAY,UAAU;IAExB,EAAE,CACH;CAED,MAAM,oBAAoB,kBAAkB;EAC1C,IAAI,CAAC,IAAI,SAAS;EAClB,MAAM,gBAAgB,IAAI;EAE1B,qBAAqB;GACnB,SAAS,cAAc;GACvB,SAAS,cAAc;GACvB,aAAa,cAAc;GAC3B,cAAc,cAAc;GAC5B,aAAa,cAAc;GAC3B,cAAc,cAAc;GAC7B,CAAC;IACD,CAAC,qBAAqB,CAAC;CAE1B,MAAM,uBAAuB,kBAAkB;EAC7C,qBAAqB;GACnB,SAAS,OAAO;GAChB,SAAS,OAAO;GAChB,aAAa,SAAS,gBAAgB;GACtC,cAAc,SAAS,gBAAgB;GACvC,aAAa,OAAO;GACpB,cAAc,OAAO;GACtB,CAAC;IACD,CAAC,qBAAqB,CAAC;CAE1B,gBAAgB;EACd,IAAI,CAAC,SAAS;EAEd,MAAM,gBAAgB,IAAI,WAAW;EAErC,MAAM,gBAAgB,IAAI,UACtB,oBACA;EAEJ,MAAM,yBAAyB,SAAS,eAAe,eAAe;GACpE,SAAS;GACT,UAAU;GACX,CAAC;EAEF,eAAe;EACf,cAAc,iBAAiB,UAAU,uBAAuB;EAEhE,aAAa;GACX,cAAc,oBAAoB,UAAU,uBAAuB;GACnE,uBAAuB,QAAQ;;IAEhC;EACD;EACA;EACA;EACA;EACA;EACA;EACD,CAAC;CAEF,OAAO;EACL;EACA;EACD"}