{"version":3,"file":"hooks.mjs","sources":["../../../components/native-scroll/hooks.ts"],"sourcesContent":["import { computed, onMounted, reactive, ref, watch } from 'vue'\r\n\r\nimport { isHiddenElement, useManualRef, useMounted, useRtl } from '@vexip-ui/hooks'\r\nimport { boundRange, debounce, debounceMinor, isElement, multipleFixed } from '@vexip-ui/utils'\r\nimport { animateScrollTo } from './helper'\r\n\r\nimport type { Ref } from 'vue'\r\nimport type { NativeScrollMode } from './symbol'\r\n\r\nexport function useScrollWrapper({\r\n  mode,\r\n  disabled,\r\n  appear,\r\n  scrollX,\r\n  scrollY,\r\n  onResize,\r\n  onBeforeRefresh,\r\n  onAfterRefresh,\r\n}: {\r\n  mode: Ref<NativeScrollMode>,\r\n  disabled: Ref<boolean>,\r\n  appear: Ref<boolean>,\r\n  // width: Ref<number | string>,\r\n  // height: Ref<number | string>,\r\n  scrollX: Ref<number>,\r\n  scrollY: Ref<number>,\r\n  onResize?: (entity: ResizeObserverEntry) => void,\r\n  onBeforeRefresh?: () => void,\r\n  onAfterRefresh?: () => void,\r\n}) {\r\n  const { manualRef, triggerUpdate } = useManualRef()\r\n\r\n  const { isRtl } = useRtl()\r\n\r\n  const contentEl = ref<HTMLElement>()\r\n\r\n  const content = reactive({\r\n    el: contentEl,\r\n    scrollWidth: 0,\r\n    offsetWidth: 0,\r\n    scrollHeight: 0,\r\n    offsetHeight: 0,\r\n  })\r\n\r\n  // 当前滚动位置\r\n  const x = manualRef(0)\r\n  const y = manualRef(0)\r\n\r\n  const percentX = manualRef(0)\r\n  const percentY = manualRef(0)\r\n\r\n  const xScrollLimit = computed(() => {\r\n    return content.el ? content.scrollWidth - content.offsetWidth : 0\r\n  })\r\n  const yScrollLimit = computed(() => {\r\n    return content.el ? content.scrollHeight - content.offsetHeight : 0\r\n  })\r\n  const enableXScroll = computed(() => {\r\n    return (\r\n      !disabled.value &&\r\n      mode.value !== 'vertical' &&\r\n      !!content.el &&\r\n      content.scrollWidth > content.offsetWidth\r\n    )\r\n  })\r\n  const enableYScroll = computed(() => {\r\n    return (\r\n      !disabled.value &&\r\n      mode.value !== 'horizontal' &&\r\n      !!content.el &&\r\n      content.scrollHeight > content.offsetHeight\r\n    )\r\n  })\r\n  const xBarLength = computed(() => {\r\n    if (content.el) {\r\n      return boundRange((content.offsetWidth / (content.scrollWidth || 1)) * 100, 5, 99)\r\n    }\r\n\r\n    return 35\r\n  })\r\n  const yBarLength = computed(() => {\r\n    if (content.el) {\r\n      return boundRange((content.offsetHeight / (content.scrollHeight || 1)) * 100, 5, 99)\r\n    }\r\n\r\n    return 35\r\n  })\r\n\r\n  watch(contentEl, () => {\r\n    computeContentSize()\r\n  })\r\n  watch(scrollX, value => {\r\n    setScrollX(value)\r\n  })\r\n  watch(scrollY, value => {\r\n    setScrollY(value)\r\n  })\r\n\r\n  function setScrollX(value: number) {\r\n    x.value = boundRange(value, 0, xScrollLimit.value)\r\n    syncScroll()\r\n  }\r\n\r\n  function setScrollY(value: number) {\r\n    y.value = boundRange(value, 0, yScrollLimit.value)\r\n    syncScroll()\r\n  }\r\n\r\n  function syncScroll() {\r\n    if (content.el) {\r\n      content.el.scrollTo({\r\n        top: y.value,\r\n        left: isRtl.value ? -x.value : x.value,\r\n        behavior: 'instant',\r\n      })\r\n    }\r\n  }\r\n\r\n  const { isMounted } = useMounted()\r\n\r\n  function computeContentSize() {\r\n    if (!content.el || isHiddenElement(content.el)) return\r\n\r\n    content.scrollWidth = content.el.scrollWidth\r\n    content.offsetWidth = content.el.offsetWidth\r\n    content.scrollHeight = content.el.scrollHeight\r\n    content.offsetHeight = content.el.offsetHeight\r\n\r\n    if (mode.value !== 'vertical') {\r\n      setScrollX(!isMounted.value && appear.value ? scrollX.value : x.value || 0)\r\n    }\r\n\r\n    if (mode.value !== 'horizontal') {\r\n      setScrollY(!isMounted.value && appear.value ? scrollY.value : y.value || 0)\r\n    }\r\n\r\n    computePercent()\r\n    triggerUpdate()\r\n  }\r\n\r\n  function computePercent() {\r\n    if (content.el) {\r\n      percentX.value = isRtl.value\r\n        ? -multipleFixed(x.value / (xScrollLimit.value || 1), 100, 2)\r\n        : multipleFixed(x.value / (xScrollLimit.value || 1), 100, 2)\r\n      percentY.value = multipleFixed(y.value / (yScrollLimit.value || 1), 100, 2)\r\n    }\r\n  }\r\n\r\n  function handleResize(entity: ResizeObserverEntry) {\r\n    refresh()\r\n    onResize?.(entity)\r\n  }\r\n\r\n  onMounted(() => {\r\n    refresh()\r\n\r\n    if (appear.value) {\r\n      scrollTo(scrollX.value, scrollY.value)\r\n    }\r\n  })\r\n\r\n  const refresh = debounceMinor(() => {\r\n    return new Promise<void>(resolve => {\r\n      if (typeof onBeforeRefresh === 'function') {\r\n        onBeforeRefresh()\r\n      }\r\n\r\n      computeContentSize()\r\n      setTimeout(() => {\r\n        if (typeof onAfterRefresh === 'function') {\r\n          onAfterRefresh()\r\n        }\r\n\r\n        resolve()\r\n      }, 0)\r\n    })\r\n  })\r\n\r\n  function scrollTo(clientX: number, clientY: number, duration = 500) {\r\n    return new Promise<void>(resolve => {\r\n      if (!content.el) return\r\n\r\n      if (!enableXScroll.value || Math.abs(x.value - clientX) < 0.01) {\r\n        clientX = x.value\r\n      }\r\n\r\n      if (!enableYScroll.value || Math.abs(y.value - clientY) < 0.01) {\r\n        clientY = y.value\r\n      }\r\n\r\n      animateScrollTo({\r\n        duration,\r\n        el: content.el,\r\n        xFrom: x.value,\r\n        xTo: boundRange(clientX, 0, xScrollLimit.value),\r\n        yFrom: y.value,\r\n        yTo: boundRange(clientY, 0, yScrollLimit.value),\r\n        callback: resolve,\r\n      })\r\n    })\r\n  }\r\n\r\n  function scrollBy(deltaX: number, deltaY: number, duration = 500) {\r\n    return scrollTo(x.value + deltaX, y.value + deltaY, duration)\r\n  }\r\n\r\n  function scrollToElement(el: string | Element, duration?: number, offset = 0) {\r\n    if (!content.el) return Promise.resolve()\r\n\r\n    if (typeof el === 'string') {\r\n      el = content.el.querySelector(el)!\r\n    }\r\n\r\n    if (!isElement(el)) return Promise.resolve()\r\n\r\n    const wrapperRect = content.el.getBoundingClientRect()\r\n    const elRect = el.getBoundingClientRect()\r\n\r\n    let clientX = 0\r\n    let clientY = 0\r\n\r\n    if (mode.value !== 'vertical') {\r\n      clientX = elRect.left - wrapperRect.left + offset\r\n    }\r\n\r\n    if (mode.value !== 'horizontal') {\r\n      clientY = elRect.top - wrapperRect.top + offset\r\n    }\r\n\r\n    return scrollTo(clientX, clientY, duration)\r\n  }\r\n\r\n  return {\r\n    contentEl,\r\n\r\n    content,\r\n    x,\r\n    y,\r\n    percentX,\r\n    percentY,\r\n    xScrollLimit,\r\n    yScrollLimit,\r\n    enableXScroll,\r\n    enableYScroll,\r\n    xBarLength,\r\n    yBarLength,\r\n\r\n    handleResize: debounce(handleResize),\r\n    setScrollX,\r\n    setScrollY,\r\n    computePercent,\r\n    refresh,\r\n    scrollTo,\r\n    scrollBy,\r\n    scrollToElement,\r\n    triggerUpdate,\r\n  }\r\n}\r\n"],"names":["useScrollWrapper","mode","disabled","appear","scrollX","scrollY","onResize","onBeforeRefresh","onAfterRefresh","manualRef","triggerUpdate","useManualRef","isRtl","useRtl","contentEl","ref","content","reactive","x","y","percentX","percentY","xScrollLimit","computed","yScrollLimit","enableXScroll","enableYScroll","xBarLength","boundRange","yBarLength","watch","computeContentSize","value","setScrollX","setScrollY","syncScroll","isMounted","useMounted","isHiddenElement","computePercent","multipleFixed","handleResize","entity","refresh","onMounted","scrollTo","debounceMinor","resolve","clientX","clientY","duration","animateScrollTo","scrollBy","deltaX","deltaY","scrollToElement","el","offset","isElement","wrapperRect","elRect","debounce"],"mappings":"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"}