{"version":3,"file":"virtual.mjs","names":["useDisplay","useResizeObserver","computed","ref","shallowRef","watch","watchEffect","clamp","createRange","propsFactory","UP","DOWN","makeVirtualProps","itemHeight","type","Number","String","default","useVirtual","props","items","offset","first","baseItemHeight","get","parseInt","value","set","val","containerRef","resizeRef","contentRect","display","sizeMap","Map","sizes","Array","from","length","visibleItems","height","document","documentElement","Math","ceil","handleItemResize","index","max","calculateOffset","slice","reduce","acc","calculateMidPointIndex","scrollTop","end","middle","middleOffset","lastScrollTop","handleScroll","direction","midPointIndex","buffer","round","firstIndex","lastIndex","scrollToIndex","last","min","computedItems","map","item","raw","paddingTop","paddingBottom","forEach","indexOf","delete"],"sources":["../../src/composables/virtual.ts"],"sourcesContent":["// Composables\nimport { useDisplay } from '@/composables/display'\nimport { useResizeObserver } from '@/composables/resizeObserver'\n\n// Utilities\nimport { computed, ref, shallowRef, watch, watchEffect } from 'vue'\nimport {\n clamp,\n createRange,\n propsFactory,\n} from '@/util'\n\n// Types\nimport type { Ref } from 'vue'\n\nconst UP = -1\nconst DOWN = 1\n\ntype VirtualProps = {\n itemHeight?: number | string\n}\n\nexport const makeVirtualProps = propsFactory({\n itemHeight: {\n type: [Number, String],\n default: 48,\n },\n}, 'virtual')\n\nexport function useVirtual (props: VirtualProps, items: Ref, offset?: Ref) {\n const first = shallowRef(0)\n const baseItemHeight = shallowRef(props.itemHeight)\n const itemHeight = computed({\n get: () => parseInt(baseItemHeight.value ?? 0, 10),\n set (val) {\n baseItemHeight.value = val\n },\n })\n const containerRef = ref()\n const { resizeRef, contentRect } = useResizeObserver()\n watchEffect(() => {\n resizeRef.value = containerRef.value\n })\n const display = useDisplay()\n\n const sizeMap = new Map()\n let sizes = Array.from({ length: items.value.length })\n const visibleItems = computed(() => {\n const height = (\n !contentRect.value || containerRef.value === document.documentElement\n ? display.height.value\n : contentRect.value.height\n ) - (offset?.value ?? 0)\n return Math.ceil((height / itemHeight.value) * 1.7 + 1)\n })\n\n function handleItemResize (index: number, height: number) {\n itemHeight.value = Math.max(itemHeight.value, height)\n sizes[index] = height\n sizeMap.set(items.value[index], height)\n }\n\n function calculateOffset (index: number) {\n return sizes.slice(0, index)\n .reduce((acc, val) => acc! + (val || itemHeight.value), 0)!\n }\n\n function calculateMidPointIndex (scrollTop: number) {\n const end = items.value.length\n\n let middle = 0\n let middleOffset = 0\n while (middleOffset < scrollTop && middle < end) {\n middleOffset += sizes[middle++] || itemHeight.value\n }\n\n return middle - 1\n }\n\n let lastScrollTop = 0\n function handleScroll () {\n if (!containerRef.value || !contentRect.value) return\n\n const height = contentRect.value.height - 56\n const scrollTop = containerRef.value.scrollTop\n const direction = scrollTop < lastScrollTop ? UP : DOWN\n\n const midPointIndex = calculateMidPointIndex(scrollTop + height / 2)\n const buffer = Math.round(visibleItems.value / 3)\n const firstIndex = midPointIndex - buffer\n const lastIndex = first.value + (buffer * 2) - 1\n if (direction === UP && midPointIndex <= lastIndex) {\n first.value = clamp(firstIndex, 0, items.value.length)\n } else if (direction === DOWN && midPointIndex >= lastIndex) {\n first.value = clamp(firstIndex, 0, items.value.length - visibleItems.value)\n }\n\n lastScrollTop = scrollTop\n }\n\n function scrollToIndex (index: number) {\n if (!containerRef.value) return\n\n const offset = calculateOffset(index)\n containerRef.value.scrollTop = offset\n }\n\n const last = computed(() => Math.min(items.value.length, first.value + visibleItems.value))\n const computedItems = computed(() => {\n return items.value.slice(first.value, last.value).map((item, index) => ({\n raw: item,\n index: index + first.value,\n }))\n })\n const paddingTop = computed(() => calculateOffset(first.value))\n const paddingBottom = computed(() => calculateOffset(items.value.length) - calculateOffset(last.value))\n\n watch(() => items.value.length, () => {\n sizes = createRange(items.value.length).map(() => itemHeight.value)\n sizeMap.forEach((height, item) => {\n const index = items.value.indexOf(item)\n if (index === -1) {\n sizeMap.delete(item)\n } else {\n sizes[index] = height\n }\n })\n })\n\n return {\n containerRef,\n computedItems,\n itemHeight,\n paddingTop,\n paddingBottom,\n scrollToIndex,\n handleScroll,\n handleItemResize,\n }\n}\n"],"mappings":"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"}