@tanstack/virtual-core 3.0.0-beta.40 → 3.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/lib/index.d.ts +2 -2
- package/build/lib/index.esm.js +24 -22
- package/build/lib/index.esm.js.map +1 -1
- package/build/lib/index.js +24 -22
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +24 -22
- package/build/lib/index.mjs.map +1 -1
- package/build/lib/utils.d.ts +2 -2
- package/build/lib/utils.esm.js +4 -1
- package/build/lib/utils.esm.js.map +1 -1
- package/build/lib/utils.js +4 -1
- package/build/lib/utils.js.map +1 -1
- package/build/lib/utils.mjs +4 -1
- package/build/lib/utils.mjs.map +1 -1
- package/build/umd/index.development.js +28 -23
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +1 -1
- package/build/umd/index.production.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +5 -5
- package/src/utils.ts +9 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.production.js","sources":["../../src/utils.ts","../../src/index.ts"],"sourcesContent":["export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<TDeps extends readonly any[], TResult>(\n getDeps: () => [...TDeps],\n fn: (...args: NoInfer<[...TDeps]>) => TResult,\n opts: {\n key: any\n debug?: () => any\n onChange?: (result: TResult) => void\n },\n): () => TResult {\n let deps: any[] = []\n let result: TResult | undefined\n\n return () => {\n let depTime: number\n if (opts.key && opts.debug?.()) depTime = Date.now()\n\n const newDeps = getDeps()\n\n const depsChanged =\n newDeps.length !== deps.length ||\n newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n let resultTime: number\n if (opts.key && opts.debug?.()) resultTime = Date.now()\n\n result = fn(...newDeps)\n opts?.onChange?.(result)\n\n if (opts.key && opts.debug?.()) {\n const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100\n const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100\n const resultFpsPercentage = resultEndTime / 16\n\n const pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n }\n\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120),\n )}deg 100% 31%);`,\n opts?.key,\n )\n }\n\n return result!\n }\n}\n","import { memo } from './utils'\n\nexport * from './utils'\n\n//\n\ntype ScrollDirection = 'forward' | 'backward'\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ntype ScrollBehavior = 'auto' | 'smooth'\n\nexport interface ScrollToOptions {\n align?: ScrollAlignment\n behavior?: ScrollBehavior\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\nexport interface Range {\n startIndex: number\n endIndex: number\n overscan: number\n count: number\n}\n\ntype Key = number | string\n\nexport interface VirtualItem {\n key: Key\n index: number\n start: number\n end: number\n size: number\n}\n\ninterface Rect {\n width: number\n height: number\n}\n\n//\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n const start = Math.max(range.startIndex - range.overscan, 0)\n const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n\n const arr = []\n\n for (let i = start; i <= end; i++) {\n arr.push(i)\n }\n\n return arr\n}\n\nconst memoRectCallback = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n let prev: Rect = { height: -1, width: -1 }\n\n return (rect: Rect) => {\n if (\n instance.options.horizontal\n ? rect.width !== prev.width\n : rect.height !== prev.height\n ) {\n cb(rect)\n }\n\n prev = rect\n }\n}\n\nexport const observeElementRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n const { width, height } = entry.contentRect\n cb({\n width: Math.round(width),\n height: Math.round(height),\n })\n } else {\n cb({ width: 0, height: 0 })\n }\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n cb(instance.scrollElement.getBoundingClientRect())\n\n observer.observe(instance.scrollElement)\n\n return () => {\n observer.unobserve(instance.scrollElement)\n }\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const memoizedCallback = memoRectCallback(instance, cb)\n const onResize = () =>\n memoizedCallback({\n width: instance.scrollElement.innerWidth,\n height: instance.scrollElement.innerHeight,\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n onResize()\n\n instance.scrollElement.addEventListener('resize', onResize, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('resize', onResize)\n }\n}\n\ntype ObserverMode = 'element' | 'window'\n\nconst scrollProps = {\n element: ['scrollLeft', 'scrollTop'],\n window: ['scrollX', 'scrollY'],\n} as const\n\nconst createOffsetObserver = (mode: ObserverMode) => {\n return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => {\n if (!instance.scrollElement) {\n return\n }\n\n const propX = scrollProps[mode][0]\n const propY = scrollProps[mode][1]\n\n let prevX: number = instance.scrollElement[propX]\n let prevY: number = instance.scrollElement[propY]\n\n const scroll = () => {\n const offset =\n instance.scrollElement[instance.options.horizontal ? propX : propY]\n\n cb(offset)\n }\n\n scroll()\n\n const onScroll = (e: Event) => {\n const target = e.currentTarget as HTMLElement & Window\n const scrollX = target[propX]\n const scrollY = target[propY]\n\n if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {\n scroll()\n }\n\n prevX = scrollX\n prevY = scrollY\n }\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n }\n}\n\nexport const observeElementOffset = createOffsetObserver('element')\nexport const observeWindowOffset = createOffsetObserver('window')\n\nexport const measureElement = <TItemElement extends Element>(\n element: TItemElement,\n instance: Virtualizer<any, TItemElement>,\n) => {\n return Math.round(\n element.getBoundingClientRect()[\n instance.options.horizontal ? 'width' : 'height'\n ],\n )\n}\n\nexport const windowScroll = <T extends Window>(\n offset: number,\n {\n adjustments = 0,\n behavior,\n }: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => {\n const toOffset = offset + adjustments\n\n instance.scrollElement?.scrollTo?.({\n [instance.options.horizontal ? 'left' : 'top']: toOffset,\n behavior,\n })\n}\n\nexport const elementScroll = <T extends Element>(\n offset: number,\n {\n adjustments = 0,\n behavior,\n }: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => {\n const toOffset = offset + adjustments\n\n instance.scrollElement?.scrollTo?.({\n [instance.options.horizontal ? 'left' : 'top']: toOffset,\n behavior,\n })\n}\n\nexport interface VirtualizerOptions<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n // Required from the user\n count: number\n getScrollElement: () => TScrollElement | null\n estimateSize: (index: number) => number\n\n // Required from the framework adapter (but can be overridden)\n scrollToFn: (\n offset: number,\n options: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => void\n observeElementRect: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (rect: Rect) => void,\n ) => void | (() => void)\n observeElementOffset: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (offset: number) => void,\n ) => void | (() => void)\n\n // Optional\n debug?: any\n initialRect?: Rect\n onChange?: (instance: Virtualizer<TScrollElement, TItemElement>) => void\n measureElement?: (\n el: TItemElement,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => number\n overscan?: number\n horizontal?: boolean\n paddingStart?: number\n paddingEnd?: number\n scrollPaddingStart?: number\n scrollPaddingEnd?: number\n initialOffset?: number\n getItemKey?: (index: number) => Key\n rangeExtractor?: (range: Range) => number[]\n scrollMargin?: number\n scrollingDelay?: number\n indexAttribute?: string\n initialMeasurementsCache?: VirtualItem[]\n}\n\nexport class Virtualizer<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n private unsubs: (void | (() => void))[] = []\n options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n scrollElement: TScrollElement | null = null\n isScrolling: boolean = false\n private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null\n private scrollToIndexTimeoutId: ReturnType<typeof setTimeout> | null = null\n measurementsCache: VirtualItem[] = []\n private itemSizeCache: Record<Key, number> = {}\n private pendingMeasuredCacheIndexes: number[] = []\n private scrollRect: Rect\n scrollOffset: number\n scrollDirection: ScrollDirection | null = null\n private scrollAdjustments: number = 0\n private measureElementCache: Record<\n Key,\n TItemElement & { __virtualizerSkipFirstNotSync?: boolean }\n > = {}\n private getResizeObserver = (() => {\n let _ro: ResizeObserver | null = null\n\n return () => {\n if (_ro) {\n return _ro\n } else if (typeof ResizeObserver !== 'undefined') {\n return (_ro = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n this._measureElement(entry.target as TItemElement, false)\n })\n }))\n } else {\n return null\n }\n }\n })()\n range: { startIndex: number; endIndex: number } = {\n startIndex: 0,\n endIndex: 0,\n }\n\n constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n this.setOptions(opts)\n this.scrollRect = this.options.initialRect\n this.scrollOffset = this.options.initialOffset\n this.measurementsCache = this.options.initialMeasurementsCache\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache[item.key] = item.size\n })\n\n this.calculateRange()\n }\n\n setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n Object.entries(opts).forEach(([key, value]) => {\n if (typeof value === 'undefined') delete (opts as any)[key]\n })\n\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {},\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n scrollingDelay: 150,\n indexAttribute: 'data-index',\n initialMeasurementsCache: [],\n ...opts,\n }\n }\n\n private notify = () => {\n this.options.onChange?.(this)\n }\n\n private cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d!())\n this.unsubs = []\n this.scrollElement = null\n }\n\n _didMount = () => {\n const ro = this.getResizeObserver()\n Object.values(this.measureElementCache).forEach((node) => ro?.observe(node))\n\n return () => {\n ro?.disconnect()\n\n this.cleanup()\n }\n }\n\n _willUpdate = () => {\n const scrollElement = this.options.getScrollElement()\n\n if (this.scrollElement !== scrollElement) {\n this.cleanup()\n\n this.scrollElement = scrollElement\n\n this._scrollToOffset(this.scrollOffset, {\n adjustments: undefined,\n behavior: undefined,\n })\n\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect\n this.calculateRange()\n }),\n )\n\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset) => {\n this.scrollAdjustments = 0\n\n if (this.scrollOffset === offset) {\n return\n }\n\n if (this.isScrollingTimeoutId !== null) {\n clearTimeout(this.isScrollingTimeoutId)\n this.isScrollingTimeoutId = null\n }\n\n const onIsScrollingChange = (isScrolling: boolean) => {\n if (this.isScrolling !== isScrolling) {\n this.isScrolling = isScrolling\n this.notify()\n }\n }\n\n this.scrollDirection =\n this.scrollOffset < offset ? 'forward' : 'backward'\n\n this.scrollOffset = offset\n\n this.calculateRange()\n\n onIsScrollingChange(true)\n\n this.isScrollingTimeoutId = setTimeout(() => {\n this.isScrollingTimeoutId = null\n this.scrollDirection = null\n onIsScrollingChange(false)\n }, this.options.scrollingDelay)\n }),\n )\n } else if (!this.isScrolling) {\n this.calculateRange()\n }\n }\n\n private getSize = () => {\n return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n }\n\n private getMeasurements = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.itemSizeCache,\n ],\n (count, paddingStart, scrollMargin, getItemKey, itemSizeCache) => {\n const min =\n this.pendingMeasuredCacheIndexes.length > 0\n ? Math.min(...this.pendingMeasuredCacheIndexes)\n : 0\n this.pendingMeasuredCacheIndexes = []\n\n const measurements = this.measurementsCache.slice(0, min)\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n const measuredSize = itemSizeCache[key]\n const start = measurements[i - 1]\n ? measurements[i - 1]!.end\n : paddingStart + scrollMargin\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n const end = start + size\n measurements[i] = { index: i, start, size, end, key }\n }\n\n this.measurementsCache = measurements\n\n return measurements\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getMeasurements',\n debug: () => this.options.debug,\n },\n )\n\n calculateRange = memo(\n () => [this.getMeasurements(), this.getSize(), this.scrollOffset],\n (measurements, outerSize, scrollOffset) => {\n const range = calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n if (\n range.startIndex !== this.range.startIndex ||\n range.endIndex !== this.range.endIndex\n ) {\n this.range = range\n this.notify()\n }\n return this.range\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.range,\n this.options.overscan,\n this.options.count,\n ],\n (rangeExtractor, range, overscan, count) => {\n return rangeExtractor({\n ...range,\n overscan,\n count,\n })\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getIndexes',\n debug: () => this.options.debug,\n },\n )\n\n indexFromElement = (node: TItemElement) => {\n const attributeName = this.options.indexAttribute\n const indexStr = node.getAttribute(attributeName)\n\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`,\n )\n return -1\n }\n\n return parseInt(indexStr, 10)\n }\n\n private _measureElement = (node: TItemElement, sync: boolean) => {\n const index = this.indexFromElement(node)\n\n const item = this.measurementsCache[index]\n if (!item) {\n return\n }\n\n const prevNode = this.measureElementCache[item.key]\n\n const ro = this.getResizeObserver()\n\n if (!node.isConnected) {\n ro?.unobserve(node)\n if (node === prevNode) {\n delete this.measureElementCache[item.key]\n }\n return\n }\n\n if (prevNode !== node) {\n if (prevNode) {\n ro?.unobserve(prevNode)\n }\n ro?.observe(node)\n this.measureElementCache[item.key] = node\n } else {\n if (!sync && !prevNode.__virtualizerSkipFirstNotSync) {\n prevNode.__virtualizerSkipFirstNotSync = true\n return\n }\n }\n\n const measuredItemSize = this.options.measureElement(node, this)\n\n const itemSize = this.itemSizeCache[item.key] ?? item.size\n\n const delta = measuredItemSize - itemSize\n\n if (delta !== 0) {\n if (item.start < this.scrollOffset) {\n if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n console.info('correction', delta)\n }\n\n this._scrollToOffset(this.scrollOffset, {\n adjustments: (this.scrollAdjustments += delta),\n behavior: undefined,\n })\n }\n\n this.pendingMeasuredCacheIndexes.push(index)\n this.itemSizeCache = {\n ...this.itemSizeCache,\n [item.key]: measuredItemSize,\n }\n this.notify()\n }\n }\n\n measureElement = (node: TItemElement | null) => {\n if (!node) {\n return\n }\n\n this._measureElement(node, true)\n }\n\n getVirtualItems = memo(\n () => [this.getIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems: VirtualItem[] = []\n\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k]!\n const measurement = measurements[i]!\n\n virtualItems.push(measurement)\n }\n\n return virtualItems\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getIndexes',\n debug: () => this.options.debug,\n },\n )\n\n getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {\n const size = this.getSize()\n\n if (align === 'auto') {\n if (toOffset <= this.scrollOffset) {\n align = 'start'\n } else if (toOffset >= this.scrollOffset + size) {\n align = 'end'\n } else {\n align = 'start'\n }\n }\n\n if (align === 'start') {\n toOffset = toOffset\n } else if (align === 'end') {\n toOffset = toOffset - size\n } else if (align === 'center') {\n toOffset = toOffset - size / 2\n }\n\n const scrollSizeProp = this.options.horizontal\n ? 'scrollWidth'\n : 'scrollHeight'\n const scrollSize = this.scrollElement\n ? 'document' in this.scrollElement\n ? this.scrollElement.document.documentElement[scrollSizeProp]\n : this.scrollElement[scrollSizeProp]\n : 0\n\n const maxOffset = scrollSize - this.getSize()\n\n return Math.max(Math.min(maxOffset, toOffset), 0)\n }\n\n scrollToOffset = (\n toOffset: number,\n { align = 'start', behavior }: ScrollToOffsetOptions = {},\n ) => {\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n const options = {\n adjustments: undefined,\n behavior,\n sync: false,\n }\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), options)\n }\n\n scrollToIndex = (\n index: number,\n { align = 'auto', behavior }: ScrollToIndexOptions = {},\n ) => {\n if (this.scrollToIndexTimeoutId !== null) {\n clearTimeout(this.scrollToIndexTimeoutId)\n this.scrollToIndexTimeoutId = null\n }\n\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n const getMeasurement = () => {\n const measurements = this.getMeasurements()\n const measurement =\n measurements[Math.max(0, Math.min(index, this.options.count - 1))]\n\n if (!measurement) {\n throw new Error(`VirtualItem not found for index = ${index}`)\n }\n\n return measurement\n }\n\n const measurement = getMeasurement()\n\n if (align === 'auto') {\n if (\n measurement.end >=\n this.scrollOffset + this.getSize() - this.options.scrollPaddingEnd\n ) {\n align = 'end'\n } else if (\n measurement.start <=\n this.scrollOffset + this.options.scrollPaddingStart\n ) {\n align = 'start'\n } else {\n return\n }\n }\n\n const getOffsetForIndexAndAlignment = (measurement: VirtualItem) => {\n const toOffset =\n align === 'end'\n ? measurement.end + this.options.scrollPaddingEnd\n : measurement.start - this.options.scrollPaddingStart\n\n return this.getOffsetForAlignment(toOffset, align)\n }\n\n const toOffset = getOffsetForIndexAndAlignment(measurement)\n\n const options = {\n adjustments: undefined,\n behavior,\n }\n this._scrollToOffset(toOffset, options)\n\n const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1\n\n if (isDynamic) {\n this.scrollToIndexTimeoutId = setTimeout(() => {\n this.scrollToIndexTimeoutId = null\n\n const elementInDOM =\n !!this.measureElementCache[this.options.getItemKey(index)]\n\n if (elementInDOM) {\n const toOffset = getOffsetForIndexAndAlignment(getMeasurement())\n\n if (!approxEqual(toOffset, this.scrollOffset)) {\n this.scrollToIndex(index, { align, behavior })\n }\n } else {\n this.scrollToIndex(index, { align, behavior })\n }\n })\n }\n }\n\n scrollBy = (delta: number, { behavior }: ScrollToOffsetOptions = {}) => {\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n this._scrollToOffset(this.scrollOffset + delta, {\n adjustments: undefined,\n behavior,\n })\n }\n\n getTotalSize = () =>\n (this.getMeasurements()[this.options.count - 1]?.end ||\n this.options.paddingStart) -\n this.options.scrollMargin +\n this.options.paddingEnd\n\n private _scrollToOffset = (\n offset: number,\n {\n adjustments,\n behavior,\n }: {\n adjustments: number | undefined\n behavior: ScrollBehavior | undefined\n },\n ) => {\n this.options.scrollToFn(offset, { behavior, adjustments }, this)\n }\n\n measure = () => {\n this.itemSizeCache = {}\n this.notify()\n }\n}\n\nconst findNearestBinarySearch = (\n low: number,\n high: number,\n getCurrentValue: (i: number) => number,\n value: number,\n) => {\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = getCurrentValue(middle)\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n\n if (low > 0) {\n return low - 1\n } else {\n return 0\n }\n}\n\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n}: {\n measurements: VirtualItem[]\n outerSize: number\n scrollOffset: number\n}) {\n const count = measurements.length - 1\n const getOffset = (index: number) => measurements[index]!.start\n\n const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset)\n let endIndex = startIndex\n\n while (\n endIndex < count &&\n measurements[endIndex]!.end < scrollOffset + outerSize\n ) {\n endIndex++\n }\n\n return { startIndex, endIndex }\n}\n"],"names":["memo","getDeps","fn","opts","result","deps","depTime","key","debug","Date","now","resultTime","newDeps","length","some","dep","index","onChange","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min","defaultKeyExtractor","defaultRangeExtractor","range","start","startIndex","overscan","end","endIndex","count","arr","i","push","scrollProps","element","window","createOffsetObserver","mode","instance","cb","scrollElement","propX","propY","prevX","prevY","scroll","offset","options","horizontal","onScroll","e","target","currentTarget","scrollX","scrollY","addEventListener","capture","passive","removeEventListener","observeElementOffset","observeWindowOffset","measureElement","getBoundingClientRect","_ro","_this","this","unsubs","isScrolling","isScrollingTimeoutId","scrollToIndexTimeoutId","measurementsCache","itemSizeCache","pendingMeasuredCacheIndexes","scrollDirection","scrollAdjustments","measureElementCache","getResizeObserver","ResizeObserver","entries","forEach","entry","_measureElement","setOptions","Object","_ref3","_extends","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","initialRect","width","height","scrollMargin","scrollingDelay","indexAttribute","initialMeasurementsCache","notify","cleanup","filter","Boolean","d","_didMount","ro","values","node","observe","disconnect","_willUpdate","getScrollElement","_scrollToOffset","scrollOffset","adjustments","undefined","behavior","observeElementRect","rect","scrollRect","calculateRange","clearTimeout","onIsScrollingChange","setTimeout","getSize","getMeasurements","measurements","slice","measuredSize","size","estimateSize","process","outerSize","_ref8","low","high","getCurrentValue","value","middle","currentValue","findNearestBinarySearch","getIndexes","indexFromElement","attributeName","indexStr","getAttribute","parseInt","warn","sync","_this$itemSizeCache$i","item","prevNode","isConnected","unobserve","__virtualizerSkipFirstNotSync","_extends2","measuredItemSize","delta","getVirtualItems","indexes","virtualItems","k","len","measurement","getOffsetForAlignment","toOffset","align","scrollSizeProp","maxOffset","document","documentElement","scrollToOffset","_temp","_ref4","_ref4$align","keys","scrollToIndex","_temp2","_ref5","_ref5$align","isDynamic","getMeasurement","Error","getOffsetForIndexAndAlignment","a","b","abs","scrollBy","_temp3","getTotalSize","_this$getMeasurements","_ref7","scrollToFn","measure","_instance$scrollEleme3","_instance$scrollEleme4","_ref2$adjustments","_ref2","scrollTo","observer","contentRect","memoizedCallback","prev","memoRectCallback","onResize","innerWidth","innerHeight","_instance$scrollEleme","_instance$scrollEleme2","_ref$adjustments","_ref"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.production.js","sources":["../../src/utils.ts","../../src/index.ts"],"sourcesContent":["export type NoInfer<A extends any> = [A][A extends any ? 0 : never]\n\nexport type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>\n\nexport function memo<\n TDeps extends readonly any[],\n TResult,\n FArgs extends readonly any[],\n>(\n getDeps: () => [...TDeps],\n fn: (...args: [...TDeps, FArgs]) => TResult,\n opts: {\n key: any\n debug?: () => any\n onChange?: (result: TResult) => void\n },\n) {\n let deps: any[] = []\n let result: TResult | undefined\n\n return (...fArgs: FArgs): TResult => {\n let depTime: number\n if (opts.key && opts.debug?.()) depTime = Date.now()\n\n const newDeps = getDeps()\n\n const depsChanged =\n newDeps.length !== deps.length ||\n newDeps.some((dep: any, index: number) => deps[index] !== dep)\n\n if (!depsChanged) {\n return result!\n }\n\n deps = newDeps\n\n let resultTime: number\n if (opts.key && opts.debug?.()) resultTime = Date.now()\n\n result = fn(...newDeps, fArgs)\n opts?.onChange?.(result)\n\n if (opts.key && opts.debug?.()) {\n const depEndTime = Math.round((Date.now() - depTime!) * 100) / 100\n const resultEndTime = Math.round((Date.now() - resultTime!) * 100) / 100\n const resultFpsPercentage = resultEndTime / 16\n\n const pad = (str: number | string, num: number) => {\n str = String(str)\n while (str.length < num) {\n str = ' ' + str\n }\n return str\n }\n\n console.info(\n `%c⏱ ${pad(resultEndTime, 5)} /${pad(depEndTime, 5)} ms`,\n `\n font-size: .6rem;\n font-weight: bold;\n color: hsl(${Math.max(\n 0,\n Math.min(120 - 120 * resultFpsPercentage, 120),\n )}deg 100% 31%);`,\n opts?.key,\n )\n }\n\n return result!\n }\n}\n","import { memo } from './utils'\n\nexport * from './utils'\n\n//\n\ntype ScrollDirection = 'forward' | 'backward'\n\ntype ScrollAlignment = 'start' | 'center' | 'end' | 'auto'\n\ntype ScrollBehavior = 'auto' | 'smooth'\n\nexport interface ScrollToOptions {\n align?: ScrollAlignment\n behavior?: ScrollBehavior\n}\n\ntype ScrollToOffsetOptions = ScrollToOptions\n\ntype ScrollToIndexOptions = ScrollToOptions\n\nexport interface Range {\n startIndex: number\n endIndex: number\n overscan: number\n count: number\n}\n\ntype Key = number | string\n\nexport interface VirtualItem {\n key: Key\n index: number\n start: number\n end: number\n size: number\n}\n\ninterface Rect {\n width: number\n height: number\n}\n\n//\n\nexport const defaultKeyExtractor = (index: number) => index\n\nexport const defaultRangeExtractor = (range: Range) => {\n const start = Math.max(range.startIndex - range.overscan, 0)\n const end = Math.min(range.endIndex + range.overscan, range.count - 1)\n\n const arr = []\n\n for (let i = start; i <= end; i++) {\n arr.push(i)\n }\n\n return arr\n}\n\nconst memoRectCallback = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n let prev: Rect = { height: -1, width: -1 }\n\n return (rect: Rect) => {\n if (\n instance.options.horizontal\n ? rect.width !== prev.width\n : rect.height !== prev.height\n ) {\n cb(rect)\n }\n\n prev = rect\n }\n}\n\nexport const observeElementRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry) {\n const { width, height } = entry.contentRect\n cb({\n width: Math.round(width),\n height: Math.round(height),\n })\n } else {\n cb({ width: 0, height: 0 })\n }\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n cb(instance.scrollElement.getBoundingClientRect())\n\n observer.observe(instance.scrollElement)\n\n return () => {\n observer.unobserve(instance.scrollElement)\n }\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<any, any>,\n cb: (rect: Rect) => void,\n) => {\n const memoizedCallback = memoRectCallback(instance, cb)\n const onResize = () =>\n memoizedCallback({\n width: instance.scrollElement.innerWidth,\n height: instance.scrollElement.innerHeight,\n })\n\n if (!instance.scrollElement) {\n return\n }\n\n onResize()\n\n instance.scrollElement.addEventListener('resize', onResize, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('resize', onResize)\n }\n}\n\ntype ObserverMode = 'element' | 'window'\n\nconst scrollProps = {\n element: ['scrollLeft', 'scrollTop'],\n window: ['scrollX', 'scrollY'],\n} as const\n\nconst createOffsetObserver = (mode: ObserverMode) => {\n return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => {\n if (!instance.scrollElement) {\n return\n }\n\n const propX = scrollProps[mode][0]\n const propY = scrollProps[mode][1]\n\n let prevX: number = instance.scrollElement[propX]\n let prevY: number = instance.scrollElement[propY]\n\n const scroll = () => {\n const offset =\n instance.scrollElement[instance.options.horizontal ? propX : propY]\n\n cb(offset)\n }\n\n scroll()\n\n const onScroll = (e: Event) => {\n const target = e.currentTarget as HTMLElement & Window\n const scrollX = target[propX]\n const scrollY = target[propY]\n\n if (instance.options.horizontal ? prevX - scrollX : prevY - scrollY) {\n scroll()\n }\n\n prevX = scrollX\n prevY = scrollY\n }\n\n instance.scrollElement.addEventListener('scroll', onScroll, {\n capture: false,\n passive: true,\n })\n\n return () => {\n instance.scrollElement.removeEventListener('scroll', onScroll)\n }\n }\n}\n\nexport const observeElementOffset = createOffsetObserver('element')\nexport const observeWindowOffset = createOffsetObserver('window')\n\nexport const measureElement = <TItemElement extends Element>(\n element: TItemElement,\n instance: Virtualizer<any, TItemElement>,\n) => {\n return Math.round(\n element.getBoundingClientRect()[\n instance.options.horizontal ? 'width' : 'height'\n ],\n )\n}\n\nexport const windowScroll = <T extends Window>(\n offset: number,\n {\n adjustments = 0,\n behavior,\n }: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => {\n const toOffset = offset + adjustments\n\n instance.scrollElement?.scrollTo?.({\n [instance.options.horizontal ? 'left' : 'top']: toOffset,\n behavior,\n })\n}\n\nexport const elementScroll = <T extends Element>(\n offset: number,\n {\n adjustments = 0,\n behavior,\n }: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<T, any>,\n) => {\n const toOffset = offset + adjustments\n\n instance.scrollElement?.scrollTo?.({\n [instance.options.horizontal ? 'left' : 'top']: toOffset,\n behavior,\n })\n}\n\nexport interface VirtualizerOptions<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n // Required from the user\n count: number\n getScrollElement: () => TScrollElement | null\n estimateSize: (index: number) => number\n\n // Required from the framework adapter (but can be overridden)\n scrollToFn: (\n offset: number,\n options: { adjustments?: number; behavior?: ScrollBehavior },\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => void\n observeElementRect: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (rect: Rect) => void,\n ) => void | (() => void)\n observeElementOffset: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n cb: (offset: number) => void,\n ) => void | (() => void)\n\n // Optional\n debug?: any\n initialRect?: Rect\n onChange?: (instance: Virtualizer<TScrollElement, TItemElement>) => void\n measureElement?: (\n el: TItemElement,\n instance: Virtualizer<TScrollElement, TItemElement>,\n ) => number\n overscan?: number\n horizontal?: boolean\n paddingStart?: number\n paddingEnd?: number\n scrollPaddingStart?: number\n scrollPaddingEnd?: number\n initialOffset?: number\n getItemKey?: (index: number) => Key\n rangeExtractor?: (range: Range) => number[]\n scrollMargin?: number\n scrollingDelay?: number\n indexAttribute?: string\n initialMeasurementsCache?: VirtualItem[]\n}\n\nexport class Virtualizer<\n TScrollElement extends Element | Window,\n TItemElement extends Element,\n> {\n private unsubs: (void | (() => void))[] = []\n options!: Required<VirtualizerOptions<TScrollElement, TItemElement>>\n scrollElement: TScrollElement | null = null\n isScrolling: boolean = false\n private isScrollingTimeoutId: ReturnType<typeof setTimeout> | null = null\n private scrollToIndexTimeoutId: ReturnType<typeof setTimeout> | null = null\n measurementsCache: VirtualItem[] = []\n private itemSizeCache: Record<Key, number> = {}\n private pendingMeasuredCacheIndexes: number[] = []\n private scrollRect: Rect\n scrollOffset: number\n scrollDirection: ScrollDirection | null = null\n private scrollAdjustments: number = 0\n private measureElementCache: Record<\n Key,\n TItemElement & { __virtualizerSkipFirstNotSync?: boolean }\n > = {}\n private getResizeObserver = (() => {\n let _ro: ResizeObserver | null = null\n\n return () => {\n if (_ro) {\n return _ro\n } else if (typeof ResizeObserver !== 'undefined') {\n return (_ro = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n this._measureElement(entry.target as TItemElement, false)\n })\n }))\n } else {\n return null\n }\n }\n })()\n range: { startIndex: number; endIndex: number } = {\n startIndex: 0,\n endIndex: 0,\n }\n\n constructor(opts: VirtualizerOptions<TScrollElement, TItemElement>) {\n this.setOptions(opts)\n this.scrollRect = this.options.initialRect\n this.scrollOffset = this.options.initialOffset\n this.measurementsCache = this.options.initialMeasurementsCache\n this.measurementsCache.forEach((item) => {\n this.itemSizeCache[item.key] = item.size\n })\n\n this.calculateRange()\n }\n\n setOptions = (opts: VirtualizerOptions<TScrollElement, TItemElement>) => {\n Object.entries(opts).forEach(([key, value]) => {\n if (typeof value === 'undefined') delete (opts as any)[key]\n })\n\n this.options = {\n debug: false,\n initialOffset: 0,\n overscan: 1,\n paddingStart: 0,\n paddingEnd: 0,\n scrollPaddingStart: 0,\n scrollPaddingEnd: 0,\n horizontal: false,\n getItemKey: defaultKeyExtractor,\n rangeExtractor: defaultRangeExtractor,\n onChange: () => {},\n measureElement,\n initialRect: { width: 0, height: 0 },\n scrollMargin: 0,\n scrollingDelay: 150,\n indexAttribute: 'data-index',\n initialMeasurementsCache: [],\n ...opts,\n }\n }\n\n private notify = () => {\n this.options.onChange?.(this)\n }\n\n private cleanup = () => {\n this.unsubs.filter(Boolean).forEach((d) => d!())\n this.unsubs = []\n this.scrollElement = null\n }\n\n _didMount = () => {\n const ro = this.getResizeObserver()\n Object.values(this.measureElementCache).forEach((node) => ro?.observe(node))\n\n return () => {\n ro?.disconnect()\n\n this.cleanup()\n }\n }\n\n _willUpdate = () => {\n const scrollElement = this.options.getScrollElement()\n\n if (this.scrollElement !== scrollElement) {\n this.cleanup()\n\n this.scrollElement = scrollElement\n\n this._scrollToOffset(this.scrollOffset, {\n adjustments: undefined,\n behavior: undefined,\n })\n\n this.unsubs.push(\n this.options.observeElementRect(this, (rect) => {\n this.scrollRect = rect\n this.calculateRange()\n }),\n )\n\n this.unsubs.push(\n this.options.observeElementOffset(this, (offset) => {\n this.scrollAdjustments = 0\n\n if (this.scrollOffset === offset) {\n return\n }\n\n if (this.isScrollingTimeoutId !== null) {\n clearTimeout(this.isScrollingTimeoutId)\n this.isScrollingTimeoutId = null\n }\n\n const onIsScrollingChange = (isScrolling: boolean) => {\n if (this.isScrolling !== isScrolling) {\n this.isScrolling = isScrolling\n this.notify()\n }\n }\n\n this.scrollDirection =\n this.scrollOffset < offset ? 'forward' : 'backward'\n\n this.scrollOffset = offset\n\n this.calculateRange()\n\n onIsScrollingChange(true)\n\n this.isScrollingTimeoutId = setTimeout(() => {\n this.isScrollingTimeoutId = null\n this.scrollDirection = null\n onIsScrollingChange(false)\n }, this.options.scrollingDelay)\n }),\n )\n }\n }\n\n private getSize = () => {\n return this.scrollRect[this.options.horizontal ? 'width' : 'height']\n }\n\n private getMeasurements = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n this.itemSizeCache,\n ],\n (count, paddingStart, scrollMargin, getItemKey, itemSizeCache) => {\n const min =\n this.pendingMeasuredCacheIndexes.length > 0\n ? Math.min(...this.pendingMeasuredCacheIndexes)\n : 0\n this.pendingMeasuredCacheIndexes = []\n\n const measurements = this.measurementsCache.slice(0, min)\n\n for (let i = min; i < count; i++) {\n const key = getItemKey(i)\n const measuredSize = itemSizeCache[key]\n const start = measurements[i - 1]\n ? measurements[i - 1]!.end\n : paddingStart + scrollMargin\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n const end = start + size\n measurements[i] = { index: i, start, size, end, key }\n }\n\n this.measurementsCache = measurements\n\n return measurements\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getMeasurements',\n debug: () => this.options.debug,\n },\n )\n\n calculateRange = memo(\n () => [this.getMeasurements(), this.getSize(), this.scrollOffset],\n (measurements, outerSize, scrollOffset, [flush = true]: [boolean?]) => {\n const range = calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n if (\n range.startIndex !== this.range.startIndex ||\n range.endIndex !== this.range.endIndex\n ) {\n this.range = range\n if (flush) {\n this.notify()\n }\n }\n return this.range\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.calculateRange(false),\n this.options.overscan,\n this.options.count,\n ],\n (rangeExtractor, range, overscan, count) => {\n return rangeExtractor({\n ...range,\n overscan,\n count,\n })\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getIndexes',\n debug: () => this.options.debug,\n },\n )\n\n indexFromElement = (node: TItemElement) => {\n const attributeName = this.options.indexAttribute\n const indexStr = node.getAttribute(attributeName)\n\n if (!indexStr) {\n console.warn(\n `Missing attribute name '${attributeName}={index}' on measured element.`,\n )\n return -1\n }\n\n return parseInt(indexStr, 10)\n }\n\n private _measureElement = (node: TItemElement, sync: boolean) => {\n const index = this.indexFromElement(node)\n\n const item = this.measurementsCache[index]\n if (!item) {\n return\n }\n\n const prevNode = this.measureElementCache[item.key]\n\n const ro = this.getResizeObserver()\n\n if (!node.isConnected) {\n ro?.unobserve(node)\n if (node === prevNode) {\n delete this.measureElementCache[item.key]\n }\n return\n }\n\n if (prevNode !== node) {\n if (prevNode) {\n ro?.unobserve(prevNode)\n }\n ro?.observe(node)\n this.measureElementCache[item.key] = node\n } else {\n if (!sync && !prevNode.__virtualizerSkipFirstNotSync) {\n prevNode.__virtualizerSkipFirstNotSync = true\n return\n }\n }\n\n const measuredItemSize = this.options.measureElement(node, this)\n\n const itemSize = this.itemSizeCache[item.key] ?? item.size\n\n const delta = measuredItemSize - itemSize\n\n if (delta !== 0) {\n if (item.start < this.scrollOffset) {\n if (process.env.NODE_ENV !== 'production' && this.options.debug) {\n console.info('correction', delta)\n }\n\n this._scrollToOffset(this.scrollOffset, {\n adjustments: (this.scrollAdjustments += delta),\n behavior: undefined,\n })\n }\n\n this.pendingMeasuredCacheIndexes.push(index)\n this.itemSizeCache = {\n ...this.itemSizeCache,\n [item.key]: measuredItemSize,\n }\n this.notify()\n }\n }\n\n measureElement = (node: TItemElement | null) => {\n if (!node) {\n return\n }\n\n this._measureElement(node, true)\n }\n\n getVirtualItems = memo(\n () => [this.getIndexes(), this.getMeasurements()],\n (indexes, measurements) => {\n const virtualItems: VirtualItem[] = []\n\n for (let k = 0, len = indexes.length; k < len; k++) {\n const i = indexes[k]!\n const measurement = measurements[i]!\n\n virtualItems.push(measurement)\n }\n\n return virtualItems\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'getIndexes',\n debug: () => this.options.debug,\n },\n )\n\n getOffsetForAlignment = (toOffset: number, align: ScrollAlignment) => {\n const size = this.getSize()\n\n if (align === 'auto') {\n if (toOffset <= this.scrollOffset) {\n align = 'start'\n } else if (toOffset >= this.scrollOffset + size) {\n align = 'end'\n } else {\n align = 'start'\n }\n }\n\n if (align === 'start') {\n toOffset = toOffset\n } else if (align === 'end') {\n toOffset = toOffset - size\n } else if (align === 'center') {\n toOffset = toOffset - size / 2\n }\n\n const scrollSizeProp = this.options.horizontal\n ? 'scrollWidth'\n : 'scrollHeight'\n const scrollSize = this.scrollElement\n ? 'document' in this.scrollElement\n ? this.scrollElement.document.documentElement[scrollSizeProp]\n : this.scrollElement[scrollSizeProp]\n : 0\n\n const maxOffset = scrollSize - this.getSize()\n\n return Math.max(Math.min(maxOffset, toOffset), 0)\n }\n\n scrollToOffset = (\n toOffset: number,\n { align = 'start', behavior }: ScrollToOffsetOptions = {},\n ) => {\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n const options = {\n adjustments: undefined,\n behavior,\n sync: false,\n }\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), options)\n }\n\n scrollToIndex = (\n index: number,\n { align = 'auto', behavior }: ScrollToIndexOptions = {},\n ) => {\n if (this.scrollToIndexTimeoutId !== null) {\n clearTimeout(this.scrollToIndexTimeoutId)\n this.scrollToIndexTimeoutId = null\n }\n\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n const getMeasurement = () => {\n const measurements = this.getMeasurements()\n const measurement =\n measurements[Math.max(0, Math.min(index, this.options.count - 1))]\n\n if (!measurement) {\n throw new Error(`VirtualItem not found for index = ${index}`)\n }\n\n return measurement\n }\n\n const measurement = getMeasurement()\n\n if (align === 'auto') {\n if (\n measurement.end >=\n this.scrollOffset + this.getSize() - this.options.scrollPaddingEnd\n ) {\n align = 'end'\n } else if (\n measurement.start <=\n this.scrollOffset + this.options.scrollPaddingStart\n ) {\n align = 'start'\n } else {\n return\n }\n }\n\n const getOffsetForIndexAndAlignment = (measurement: VirtualItem) => {\n const toOffset =\n align === 'end'\n ? measurement.end + this.options.scrollPaddingEnd\n : measurement.start - this.options.scrollPaddingStart\n\n return this.getOffsetForAlignment(toOffset, align)\n }\n\n const toOffset = getOffsetForIndexAndAlignment(measurement)\n\n const options = {\n adjustments: undefined,\n behavior,\n }\n this._scrollToOffset(toOffset, options)\n\n const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1\n\n if (isDynamic) {\n this.scrollToIndexTimeoutId = setTimeout(() => {\n this.scrollToIndexTimeoutId = null\n\n const elementInDOM =\n !!this.measureElementCache[this.options.getItemKey(index)]\n\n if (elementInDOM) {\n const toOffset = getOffsetForIndexAndAlignment(getMeasurement())\n\n if (!approxEqual(toOffset, this.scrollOffset)) {\n this.scrollToIndex(index, { align, behavior })\n }\n } else {\n this.scrollToIndex(index, { align, behavior })\n }\n })\n }\n }\n\n scrollBy = (delta: number, { behavior }: ScrollToOffsetOptions = {}) => {\n const isDynamic = Object.keys(this.measureElementCache).length > 0\n\n if (isDynamic && behavior === 'smooth') {\n console.warn(\n 'The `smooth` scroll behavior is not supported with dynamic size.',\n )\n return\n }\n\n this._scrollToOffset(this.scrollOffset + delta, {\n adjustments: undefined,\n behavior,\n })\n }\n\n getTotalSize = () =>\n (this.getMeasurements()[this.options.count - 1]?.end ||\n this.options.paddingStart) -\n this.options.scrollMargin +\n this.options.paddingEnd\n\n private _scrollToOffset = (\n offset: number,\n {\n adjustments,\n behavior,\n }: {\n adjustments: number | undefined\n behavior: ScrollBehavior | undefined\n },\n ) => {\n this.options.scrollToFn(offset, { behavior, adjustments }, this)\n }\n\n measure = () => {\n this.itemSizeCache = {}\n this.notify()\n }\n}\n\nconst findNearestBinarySearch = (\n low: number,\n high: number,\n getCurrentValue: (i: number) => number,\n value: number,\n) => {\n while (low <= high) {\n const middle = ((low + high) / 2) | 0\n const currentValue = getCurrentValue(middle)\n\n if (currentValue < value) {\n low = middle + 1\n } else if (currentValue > value) {\n high = middle - 1\n } else {\n return middle\n }\n }\n\n if (low > 0) {\n return low - 1\n } else {\n return 0\n }\n}\n\nfunction calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n}: {\n measurements: VirtualItem[]\n outerSize: number\n scrollOffset: number\n}) {\n const count = measurements.length - 1\n const getOffset = (index: number) => measurements[index]!.start\n\n const startIndex = findNearestBinarySearch(0, count, getOffset, scrollOffset)\n let endIndex = startIndex\n\n while (\n endIndex < count &&\n measurements[endIndex]!.end < scrollOffset + outerSize\n ) {\n endIndex++\n }\n\n return { startIndex, endIndex }\n}\n"],"names":["memo","getDeps","fn","opts","result","deps","depTime","key","debug","Date","now","resultTime","newDeps","depsChanged","length","some","dep","index","_len","arguments","fArgs","Array","_key","apply","concat","onChange","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min","defaultKeyExtractor","defaultRangeExtractor","range","start","startIndex","overscan","end","endIndex","count","arr","i","push","scrollProps","element","window","createOffsetObserver","mode","instance","cb","scrollElement","propX","propY","prevX","prevY","scroll","offset","options","horizontal","onScroll","e","target","currentTarget","scrollX","scrollY","addEventListener","capture","passive","removeEventListener","observeElementOffset","observeWindowOffset","measureElement","getBoundingClientRect","_ro","_this","this","unsubs","isScrolling","isScrollingTimeoutId","scrollToIndexTimeoutId","measurementsCache","itemSizeCache","pendingMeasuredCacheIndexes","scrollDirection","scrollAdjustments","measureElementCache","getResizeObserver","ResizeObserver","entries","forEach","entry","_measureElement","setOptions","Object","_ref3","_extends","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","initialRect","width","height","scrollMargin","scrollingDelay","indexAttribute","initialMeasurementsCache","notify","cleanup","filter","Boolean","d","_didMount","ro","values","node","observe","disconnect","_willUpdate","getScrollElement","_scrollToOffset","scrollOffset","adjustments","undefined","behavior","observeElementRect","rect","scrollRect","calculateRange","clearTimeout","onIsScrollingChange","setTimeout","getSize","getMeasurements","measurements","slice","measuredSize","size","estimateSize","process","outerSize","_ref4","_ref4$","flush","_ref9","low","high","getCurrentValue","value","middle","currentValue","findNearestBinarySearch","getIndexes","indexFromElement","attributeName","indexStr","getAttribute","parseInt","warn","sync","_this$itemSizeCache$i","item","prevNode","isConnected","unobserve","__virtualizerSkipFirstNotSync","_extends2","measuredItemSize","delta","getVirtualItems","indexes","virtualItems","k","len","measurement","getOffsetForAlignment","toOffset","align","scrollSizeProp","maxOffset","document","documentElement","scrollToOffset","_temp","_ref5","_ref5$align","keys","scrollToIndex","_temp2","_ref6","_ref6$align","isDynamic","getMeasurement","Error","getOffsetForIndexAndAlignment","a","b","abs","scrollBy","_temp3","getTotalSize","_this$getMeasurements","_ref8","scrollToFn","measure","_instance$scrollEleme3","_instance$scrollEleme4","_ref2$adjustments","_ref2","scrollTo","observer","contentRect","memoizedCallback","prev","memoRectCallback","onResize","innerWidth","innerHeight","_instance$scrollEleme","_instance$scrollEleme2","_ref$adjustments","_ref"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/virtual-core",
|
|
3
3
|
"author": "Tanner Linsley",
|
|
4
|
-
"version": "3.0.0-beta.
|
|
4
|
+
"version": "3.0.0-beta.41",
|
|
5
5
|
"description": "Headless UI for virtualizing scrollable elements in TS/JS + Frameworks",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/tanstack/virtual#readme",
|
package/src/index.ts
CHANGED
|
@@ -438,8 +438,6 @@ export class Virtualizer<
|
|
|
438
438
|
}, this.options.scrollingDelay)
|
|
439
439
|
}),
|
|
440
440
|
)
|
|
441
|
-
} else if (!this.isScrolling) {
|
|
442
|
-
this.calculateRange()
|
|
443
441
|
}
|
|
444
442
|
}
|
|
445
443
|
|
|
@@ -490,7 +488,7 @@ export class Virtualizer<
|
|
|
490
488
|
|
|
491
489
|
calculateRange = memo(
|
|
492
490
|
() => [this.getMeasurements(), this.getSize(), this.scrollOffset],
|
|
493
|
-
(measurements, outerSize, scrollOffset) => {
|
|
491
|
+
(measurements, outerSize, scrollOffset, [flush = true]: [boolean?]) => {
|
|
494
492
|
const range = calculateRange({
|
|
495
493
|
measurements,
|
|
496
494
|
outerSize,
|
|
@@ -501,7 +499,9 @@ export class Virtualizer<
|
|
|
501
499
|
range.endIndex !== this.range.endIndex
|
|
502
500
|
) {
|
|
503
501
|
this.range = range
|
|
504
|
-
|
|
502
|
+
if (flush) {
|
|
503
|
+
this.notify()
|
|
504
|
+
}
|
|
505
505
|
}
|
|
506
506
|
return this.range
|
|
507
507
|
},
|
|
@@ -514,7 +514,7 @@ export class Virtualizer<
|
|
|
514
514
|
private getIndexes = memo(
|
|
515
515
|
() => [
|
|
516
516
|
this.options.rangeExtractor,
|
|
517
|
-
this.
|
|
517
|
+
this.calculateRange(false),
|
|
518
518
|
this.options.overscan,
|
|
519
519
|
this.options.count,
|
|
520
520
|
],
|
package/src/utils.ts
CHANGED
|
@@ -2,19 +2,23 @@ export type NoInfer<A extends any> = [A][A extends any ? 0 : never]
|
|
|
2
2
|
|
|
3
3
|
export type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
|
|
4
4
|
|
|
5
|
-
export function memo<
|
|
5
|
+
export function memo<
|
|
6
|
+
TDeps extends readonly any[],
|
|
7
|
+
TResult,
|
|
8
|
+
FArgs extends readonly any[],
|
|
9
|
+
>(
|
|
6
10
|
getDeps: () => [...TDeps],
|
|
7
|
-
fn: (...args:
|
|
11
|
+
fn: (...args: [...TDeps, FArgs]) => TResult,
|
|
8
12
|
opts: {
|
|
9
13
|
key: any
|
|
10
14
|
debug?: () => any
|
|
11
15
|
onChange?: (result: TResult) => void
|
|
12
16
|
},
|
|
13
|
-
)
|
|
17
|
+
) {
|
|
14
18
|
let deps: any[] = []
|
|
15
19
|
let result: TResult | undefined
|
|
16
20
|
|
|
17
|
-
return () => {
|
|
21
|
+
return (...fArgs: FArgs): TResult => {
|
|
18
22
|
let depTime: number
|
|
19
23
|
if (opts.key && opts.debug?.()) depTime = Date.now()
|
|
20
24
|
|
|
@@ -33,7 +37,7 @@ export function memo<TDeps extends readonly any[], TResult>(
|
|
|
33
37
|
let resultTime: number
|
|
34
38
|
if (opts.key && opts.debug?.()) resultTime = Date.now()
|
|
35
39
|
|
|
36
|
-
result = fn(...newDeps)
|
|
40
|
+
result = fn(...newDeps, fArgs)
|
|
37
41
|
opts?.onChange?.(result)
|
|
38
42
|
|
|
39
43
|
if (opts.key && opts.debug?.()) {
|