UNPKG

vexip-ui

Version:

A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good

1 lines 11.5 kB
{"version":3,"file":"hooks.mjs","sources":["../../../components/scroll/hooks.ts"],"sourcesContent":["import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'\n\nimport { useManualRef } from '@vexip-ui/hooks'\nimport { multipleFixed, toNumber } from '@vexip-ui/utils'\n\nimport type { Ref } from 'vue'\nimport type { ScrollMode } from './symbol'\n\nexport function useScrollWrapper({\n mode,\n disabled,\n width,\n height,\n scrollX,\n scrollY,\n onResize,\n onBeforeRefresh,\n onAfterRefresh,\n}: {\n mode: Ref<Exclude<ScrollMode, 'horizontal-exact'>>,\n disabled: Ref<boolean>,\n width: Ref<number | string>,\n height: Ref<number | string>,\n scrollX: Ref<number>,\n scrollY: Ref<number>,\n onResize?: (entry: ResizeObserverEntry) => void,\n onBeforeRefresh?: () => void,\n onAfterRefresh?: () => void,\n}) {\n const { manualRef, triggerUpdate } = useManualRef()\n\n const wrapperEl = ref<HTMLElement>()\n const contentEl = ref<HTMLElement>()\n\n // 容器长宽\n const wrapper = reactive({\n el: wrapperEl,\n width: toNumber(width.value),\n height: toNumber(height.value),\n })\n\n // 内容长宽\n const content = reactive({\n el: contentEl,\n width: 0,\n height: 0,\n })\n\n const x = manualRef(-scrollX.value)\n const y = manualRef(-scrollY.value)\n\n const isReady = ref(false)\n\n const percentX = manualRef(0)\n const percentY = manualRef(0)\n\n const xScrollLimit = computed(() => {\n return wrapper.width ? wrapper.width - content.width : 0\n })\n const yScrollLimit = computed(() => {\n return wrapper.height ? wrapper.height - content.height : 0\n })\n const enableXScroll = computed(() => {\n return (\n !disabled.value &&\n mode.value !== 'vertical' &&\n !!wrapper.width &&\n content.width - wrapper.width > 1\n )\n })\n const enableYScroll = computed(() => {\n return (\n !disabled.value &&\n mode.value !== 'horizontal' &&\n !!wrapper.height &&\n content.height - wrapper.height > 1\n )\n })\n const xBarLength = computed(() => {\n if (wrapper.width) {\n return Math.max(Math.min((wrapper.width / (content.width || 1)) * 100, 99), 5)\n }\n\n return 35\n })\n const yBarLength = computed(() => {\n if (wrapper.height) {\n return Math.max(Math.min((wrapper.height / (content.height || 1)) * 100, 99), 5)\n }\n\n return 35\n })\n\n watch(wrapperEl, () => {\n refreshWrapper()\n })\n watch(contentEl, () => {\n computeContentSize()\n })\n watch(scrollX, value => {\n x.value = -value\n verifyScroll()\n })\n watch(scrollY, value => {\n y.value = -value\n verifyScroll()\n })\n watch(width, () => {\n refreshWrapper().then(verifyScroll)\n })\n watch(height, () => {\n refreshWrapper().then(verifyScroll)\n })\n\n function computeWrapperSize(sizeType: 'width' | 'height') {\n return nextTick(() => {\n if (!wrapper.el) return\n\n const size = sizeType === 'width' ? width.value : height.value\n const titleCaseSizeType = sizeType.slice(0, 1).toUpperCase() + sizeType.slice(1)\n\n // 获取 wrapper 的 px 大小\n if (typeof size === 'string') {\n if (!size.endsWith('px') && (!size || Number.isNaN(Number(size)))) {\n wrapper[sizeType] =\n wrapper.el[`offset${titleCaseSizeType}` as 'offsetWidth' | 'offsetHeight']\n } else {\n wrapper[sizeType] = parseInt(size)\n }\n } else {\n wrapper[sizeType] = size\n }\n })\n }\n\n async function refreshWrapper() {\n const promises: Promise<void>[] = []\n\n if (mode.value !== 'vertical') {\n promises.push(computeWrapperSize('width'))\n }\n\n if (mode.value !== 'horizontal') {\n promises.push(computeWrapperSize('height'))\n }\n\n await Promise.all(promises)\n }\n\n let timer: ReturnType<typeof setTimeout>\n\n function computeContentSize() {\n clearTimeout(timer)\n\n return new Promise<void>(resolve => {\n isReady.value = false\n\n timer = setTimeout(() => {\n if (!content.el) {\n resolve()\n return\n }\n\n if (mode.value !== 'vertical') {\n content.width = content.el.offsetWidth\n\n if (wrapper.width >= content.width) {\n x.value = 0\n } else {\n if (x.value === 0) {\n x.value = -scrollX.value\n }\n }\n }\n\n if (mode.value !== 'horizontal') {\n content.height = content.el.offsetHeight\n\n if (wrapper.height >= content.height) {\n y.value = 0\n } else {\n if (y.value === 0) {\n y.value = -scrollY.value\n }\n }\n }\n\n setTimeout(() => {\n isReady.value = true\n verifyScroll()\n resolve()\n }, 1)\n }, 0)\n })\n }\n\n /**\n * Will post process the percent scroll values.\n */\n function verifyScroll() {\n if (!isReady.value) {\n return\n }\n\n if (mode.value !== 'vertical') {\n x.value = Math.min(0, Math.max(x.value, xScrollLimit.value))\n\n if (mode.value !== 'both') {\n y.value = 0\n }\n }\n\n if (mode.value !== 'horizontal') {\n y.value = Math.min(0, Math.max(y.value, yScrollLimit.value))\n\n if (mode.value !== 'both') {\n x.value = 0\n }\n }\n\n computePercent()\n triggerUpdate()\n }\n\n function computePercent() {\n percentX.value = multipleFixed(x.value / (xScrollLimit.value || -1), 100, 2)\n percentY.value = multipleFixed(y.value / (yScrollLimit.value || -1), 100, 2)\n\n percentX.value = Math.max(0, Math.min(percentX.value, 100))\n percentY.value = Math.max(0, Math.min(percentY.value, 100))\n }\n\n function handleResize(entity: ResizeObserverEntry) {\n refresh()\n onResize?.(entity)\n }\n\n let isMounted = false\n\n onMounted(() => {\n refresh()\n isMounted = true\n })\n\n async function refresh() {\n if (typeof onBeforeRefresh === 'function') {\n onBeforeRefresh()\n }\n\n refreshWrapper()\n await computeContentSize().then(() => {\n setTimeout(\n () => {\n verifyScroll()\n\n if (typeof onAfterRefresh === 'function') {\n onAfterRefresh()\n }\n },\n isMounted ? 20 : 100,\n )\n })\n }\n\n return {\n wrapperEl,\n contentEl,\n\n wrapper,\n content,\n isReady,\n x,\n y,\n percentX,\n percentY,\n xScrollLimit,\n yScrollLimit,\n enableXScroll,\n enableYScroll,\n xBarLength,\n yBarLength,\n\n handleResize,\n verifyScroll,\n computePercent,\n refresh,\n triggerUpdate,\n }\n}\n"],"names":["useScrollWrapper","mode","disabled","width","height","scrollX","scrollY","onResize","onBeforeRefresh","onAfterRefresh","manualRef","triggerUpdate","useManualRef","wrapperEl","ref","contentEl","wrapper","reactive","toNumber","content","x","y","isReady","percentX","percentY","xScrollLimit","computed","yScrollLimit","enableXScroll","enableYScroll","xBarLength","yBarLength","watch","refreshWrapper","computeContentSize","value","verifyScroll","computeWrapperSize","sizeType","nextTick","size","titleCaseSizeType","promises","timer","resolve","computePercent","multipleFixed","handleResize","entity","refresh","isMounted","onMounted"],"mappings":"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"}