{"version":3,"sources":["../../src/use-infinite-scroll/index.ts"],"sourcesContent":["import { useRef } from 'react'\nimport { useEventListener } from '../use-event-listener'\nimport { useLatest } from '../use-latest'\nimport { useMount } from '../use-mount'\nimport { useStableFn } from '../use-stable-fn'\nimport { useTargetElement } from '../use-target-element'\nimport { useTrackedRefState } from '../use-tracked-ref-state'\nimport { useUpdateEffect } from '../use-update-effect'\nimport { useVersionedAction } from '../use-versioned-action'\n\nimport type { ElementTarget } from '../use-target-element'\n\nexport interface UseInfiniteScrollOptions<R> {\n  /**\n   * Whether to trigger the first load immediately\n   *\n   * @defaultValue true\n   */\n  immediate?: boolean\n  /**\n   * distance from the bottom of the scroll container\n   *\n   * @defaultValue 0\n   */\n  distance?: number\n  /**\n   * scroll direction\n   *\n   * @defaultValue 'bottom'\n   */\n  direction?: 'top' | 'bottom' | 'left' | 'right'\n  /**\n   * interval between each scroll event\n   *\n   * @defaultValue 100\n   */\n  interval?: number\n  /**\n   * check if can load more\n   */\n  canLoadMore?: (previousReturn: R | undefined) => boolean\n  /**\n   * scroll event callback\n   */\n  onScroll?: (event: Event) => void\n}\n\nexport interface UseInfiniteScrollReturns {\n  /**\n   * Loading state\n   *\n   * @deprecated use `loading` instead\n   */\n  isLoading: boolean\n  /**\n   * Loading state\n   *\n   * @since 1.7.0\n   */\n  loading: boolean\n  /**\n   * Load done state\n   */\n  isLoadDone: boolean\n  /**\n   * Load more function\n   *\n   * @since 1.7.0\n   */\n  loadMore: () => Promise<void>\n  /**\n   * Calculate the current scroll position to determine whether to load more\n   */\n  calculate(): void\n  /**\n   * Reset the state to the initial state.\n   *\n   * @since 1.7.0\n   */\n  reset(): void\n}\n\n/**\n * A React Hook that allows you to use infinite scroll in your components.\n */\nexport function useInfiniteScroll<R = any, T extends HTMLElement = HTMLElement>(\n  target: ElementTarget<T>,\n  onLoadMore: (previousReturn: R | undefined) => R | Promise<R>,\n  options: UseInfiniteScrollOptions<R> = {},\n): UseInfiniteScrollReturns {\n  const {\n    immediate = true,\n    distance = 100,\n    direction = 'bottom',\n    interval = 100,\n    canLoadMore = () => true,\n    onScroll,\n  } = options\n\n  const el = useTargetElement<T>(target)\n  const isCalculating = useRef(false)\n  const previousReturn = useRef<R | undefined>(undefined)\n  const [incVersion, runVersionedAction] = useVersionedAction()\n  const [state, { updateRefState }, stateRef] = useTrackedRefState({\n    version: 0,\n    loading: false,\n    isLoadDone: false,\n  })\n\n  const latest = useLatest({ state, canLoadMore, direction, onScroll, onLoadMore, interval })\n\n  const loadMore = useStableFn(async () => {\n    if (stateRef.isLoadDone.value || stateRef.loading.value) return\n\n    const version = incVersion()\n    updateRefState('loading', true)\n\n    const [result, _] = await Promise.all([\n      latest.current.onLoadMore(previousReturn.current),\n      new Promise((resolve) => setTimeout(resolve, latest.current.interval)),\n    ])\n\n    runVersionedAction(version, () => {\n      isCalculating.current = false\n      previousReturn.current = result\n      updateRefState('loading', false)\n      updateRefState('isLoadDone', !latest.current.canLoadMore(previousReturn.current))\n    })\n  })\n\n  const calculate = useStableFn(async () => {\n    if (!el.current || stateRef.isLoadDone.value || stateRef.loading.value) return\n\n    if (isCalculating.current) return\n\n    isCalculating.current = true\n\n    const { scrollHeight, scrollTop, clientHeight, scrollWidth, clientWidth } = el.current\n\n    const isYScroll = latest.current.direction === 'bottom' || latest.current.direction === 'top'\n    const isScrollNarrower = isYScroll ? scrollHeight <= clientHeight : scrollWidth <= clientWidth\n\n    const isAlmostBottom = isYScroll\n      ? scrollHeight - scrollTop <= clientHeight + distance\n      : scrollWidth - scrollTop <= clientWidth + distance\n\n    if (isScrollNarrower || isAlmostBottom) {\n      await loadMore()\n    }\n\n    isCalculating.current = false\n  })\n\n  useMount(immediate && calculate)\n\n  // biome-ignore lint/correctness/useExhaustiveDependencies: need to detect `isLoadDone` change\n  useUpdateEffect(() => {\n    calculate()\n  }, [state.isLoadDone, state.loading, state.version])\n\n  useEventListener(\n    el,\n    'scroll',\n    (event) => {\n      calculate()\n      latest.current.onScroll?.(event)\n    },\n    { passive: true },\n  )\n\n  const reset = useStableFn(() => {\n    previousReturn.current = undefined\n    isCalculating.current = false\n    incVersion()\n    updateRefState('loading', false)\n    updateRefState('isLoadDone', false)\n    updateRefState('version', stateRef.version.value + 1)\n  })\n\n  return {\n    get isLoadDone() {\n      return state.isLoadDone\n    },\n    get loading() {\n      return state.loading\n    },\n    get isLoading() {\n      return state.loading\n    },\n    loadMore,\n    reset,\n    calculate,\n  }\n}\n"],"names":["useInfiniteScroll","target","onLoadMore","options","immediate","distance","direction","interval","canLoadMore","onScroll","el","useTargetElement","isCalculating","useRef","previousReturn","undefined","useVersionedAction","incVersion","runVersionedAction","useTrackedRefState","version","loading","isLoadDone","state","updateRefState","stateRef","latest","useLatest","loadMore","useStableFn","result","_","value","Promise","all","current","resolve","setTimeout","calculate","scrollHeight","scrollTop","clientHeight","scrollWidth","clientWidth","isYScroll","isScrollNarrower","isAlmostBottom","useMount","useUpdateEffect","useEventListener","event","passive","reset","isLoading"],"mappings":"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"}