@tanstack/virtual-core 3.0.0-beta.43 → 3.0.0-beta.45
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 +8 -5
- package/build/lib/index.esm.js +108 -123
- package/build/lib/index.esm.js.map +1 -1
- package/build/lib/index.js +108 -123
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +108 -123
- package/build/lib/index.mjs.map +1 -1
- package/build/umd/index.development.js +108 -123
- 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 +119 -153
|
@@ -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 initialDeps?: TDeps\n },\n) {\n let deps = opts.initialDeps ?? []\n let result: TResult | undefined\n\n return (): 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)\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 opts?.onChange?.(result)\n\n return result!\n }\n}\n\nexport function notUndefined<T>(value: T | undefined, msg?: string): T {\n if (value === undefined) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ''}`)\n } else {\n return value\n }\n}\n\nexport const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1\n","import { approxEqual, memo, notUndefined } 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.maybeNotify()\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.maybeNotify()\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 this.isScrolling = true\n this.scrollDirection =\n this.scrollOffset < offset ? 'forward' : 'backward'\n this.scrollOffset = offset\n\n this.maybeNotify()\n\n this.isScrollingTimeoutId = setTimeout(() => {\n this.isScrollingTimeoutId = null\n this.isScrolling = false\n this.scrollDirection = null\n\n this.maybeNotify()\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) => {\n return (this.range = calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n }))\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private maybeNotify = memo(\n () => [...Object.values(this.calculateRange()), this.isScrolling],\n () => {\n this.notify()\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n debug: () => this.options.debug,\n initialDeps: [...Object.values(this.range), this.isScrolling],\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.calculateRange(),\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 index = Math.max(0, Math.min(index, this.options.count - 1))\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 measurement = notUndefined(this.getMeasurements()[index])\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 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(\n notUndefined(this.getMeasurements()[index]),\n )\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","_opts$initialDeps","result","deps","initialDeps","depTime","key","debug","Date","now","resultTime","newDeps","length","some","dep","index","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min","onChange","notUndefined","value","msg","undefined","Error","approxEqual","a","b","abs","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","behavior","observeElementRect","rect","scrollRect","maybeNotify","clearTimeout","setTimeout","getSize","getMeasurements","measurements","slice","measuredSize","size","estimateSize","process","calculateRange","outerSize","_ref8","low","high","getCurrentValue","middle","currentValue","findNearestBinarySearch","concat","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","getOffsetForIndexAndAlignment","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<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 initialDeps?: TDeps\n },\n) {\n let deps = opts.initialDeps ?? []\n let result: TResult | undefined\n\n return (): 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)\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 opts?.onChange?.(result)\n\n return result!\n }\n}\n\nexport function notUndefined<T>(value: T | undefined, msg?: string): T {\n if (value === undefined) {\n throw new Error(`Unexpected undefined${msg ? `: ${msg}` : ''}`)\n } else {\n return value\n }\n}\n\nexport const approxEqual = (a: number, b: number) => Math.abs(a - b) < 1\n","import { approxEqual, memo, notUndefined } 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\nexport const observeElementRect = <T extends Element>(\n instance: Virtualizer<T, any>,\n cb: (rect: Rect) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n\n const handler = () => {\n const { width, height } = element.getBoundingClientRect()\n cb({ width: Math.round(width), height: Math.round(height) })\n }\n handler()\n\n const observer = new ResizeObserver(() => {\n handler()\n })\n\n observer.observe(element)\n\n return () => {\n observer.unobserve(element)\n }\n}\n\nexport const observeWindowRect = (\n instance: Virtualizer<Window, any>,\n cb: (rect: Rect) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n\n const handler = () => {\n cb({ width: element.innerWidth, height: element.innerHeight })\n }\n handler()\n\n element.addEventListener('resize', handler, {\n passive: true,\n })\n\n return () => {\n element.removeEventListener('resize', handler)\n }\n}\n\nexport const observeElementOffset = <T extends Element>(\n instance: Virtualizer<T, any>,\n cb: (offset: number) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n\n const handler = () => {\n cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop'])\n }\n handler()\n\n element.addEventListener('scroll', handler, {\n passive: true,\n })\n\n return () => {\n element.removeEventListener('scroll', handler)\n }\n}\n\nexport const observeWindowOffset = (\n instance: Virtualizer<Window, any>,\n cb: (offset: number) => void,\n) => {\n const element = instance.scrollElement\n if (!element) {\n return\n }\n\n const handler = () => {\n cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY'])\n }\n handler()\n\n element.addEventListener('scroll', handler, {\n passive: true,\n })\n\n return () => {\n element.removeEventListener('scroll', handler)\n }\n}\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.maybeNotify()\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 const prev = this.scrollRect\n this.scrollRect = rect\n if (\n this.options.horizontal\n ? rect.width !== prev.width\n : rect.height !== prev.height\n ) {\n this.maybeNotify()\n }\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 this.isScrolling = true\n this.scrollDirection =\n this.scrollOffset < offset ? 'forward' : 'backward'\n this.scrollOffset = offset\n\n this.maybeNotify()\n\n this.isScrollingTimeoutId = setTimeout(() => {\n this.isScrollingTimeoutId = null\n this.isScrolling = false\n this.scrollDirection = null\n\n this.maybeNotify()\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) => {\n return (this.range = calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n }))\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private maybeNotify = memo(\n () => [...Object.values(this.calculateRange()), this.isScrolling],\n () => {\n this.notify()\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n debug: () => this.options.debug,\n initialDeps: [...Object.values(this.range), this.isScrolling],\n },\n )\n\n private getIndexes = memo(\n () => [\n this.options.rangeExtractor,\n this.calculateRange(),\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 getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {\n index = Math.max(0, Math.min(index, this.options.count - 1))\n\n const measurement = notUndefined(this.getMeasurements()[index])\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 [this.scrollOffset, align] as const\n }\n }\n\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), align] as const\n }\n\n private isDynamicMode = () => Object.keys(this.measureElementCache).length > 0\n\n private cancelScrollToIndex = () => {\n if (this.scrollToIndexTimeoutId !== null) {\n clearTimeout(this.scrollToIndexTimeoutId)\n this.scrollToIndexTimeoutId = null\n }\n }\n\n scrollToOffset = (\n toOffset: number,\n { align = 'start', behavior }: ScrollToOffsetOptions = {},\n ) => {\n this.cancelScrollToIndex()\n\n if (behavior === 'smooth' && this.isDynamicMode()) {\n console.warn(\n 'The `smooth` scroll behavior is not fully supported with dynamic size.',\n )\n }\n\n this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {\n adjustments: undefined,\n behavior,\n })\n }\n\n scrollToIndex = (\n index: number,\n { align: initialAlign = 'auto', behavior }: ScrollToIndexOptions = {},\n ) => {\n index = Math.max(0, Math.min(index, this.options.count - 1))\n\n this.cancelScrollToIndex()\n\n if (behavior === 'smooth' && this.isDynamicMode()) {\n console.warn(\n 'The `smooth` scroll behavior is not fully supported with dynamic size.',\n )\n }\n\n const [toOffset, align] = this.getOffsetForIndex(index, initialAlign)\n\n this._scrollToOffset(toOffset, { adjustments: undefined, behavior })\n\n if (behavior !== 'smooth' && this.isDynamicMode()) {\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] = this.getOffsetForIndex(index, align)\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 this.cancelScrollToIndex()\n\n if (behavior === 'smooth' && this.isDynamicMode()) {\n console.warn(\n 'The `smooth` scroll behavior is not fully supported with dynamic size.',\n )\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","_opts$initialDeps","result","deps","initialDeps","depTime","key","debug","Date","now","resultTime","newDeps","length","some","dep","index","depEndTime","Math","round","resultEndTime","resultFpsPercentage","pad","str","num","String","console","info","max","min","onChange","notUndefined","value","msg","undefined","Error","approxEqual","a","b","abs","defaultKeyExtractor","defaultRangeExtractor","range","start","startIndex","overscan","end","endIndex","count","arr","i","push","measureElement","element","instance","getBoundingClientRect","options","horizontal","_ro","_this","this","unsubs","scrollElement","isScrolling","isScrollingTimeoutId","scrollToIndexTimeoutId","measurementsCache","itemSizeCache","pendingMeasuredCacheIndexes","scrollDirection","scrollAdjustments","measureElementCache","getResizeObserver","ResizeObserver","entries","forEach","entry","_measureElement","target","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","behavior","observeElementRect","rect","prev","scrollRect","maybeNotify","observeElementOffset","offset","clearTimeout","setTimeout","getSize","getMeasurements","measurements","slice","measuredSize","size","estimateSize","process","calculateRange","outerSize","_ref8","low","high","getCurrentValue","middle","currentValue","findNearestBinarySearch","concat","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","getOffsetForIndex","isDynamicMode","keys","cancelScrollToIndex","scrollToOffset","_temp","_ref4","_ref4$align","scrollToIndex","_temp2","_ref5","_ref5$align","initialAlign","_this$getOffsetForInd","scrollBy","_temp3","getTotalSize","_this$getMeasurements","_ref7","scrollToFn","measure","_instance$scrollEleme3","_instance$scrollEleme4","_ref2$adjustments","_ref2","scrollTo","cb","handler","addEventListener","passive","removeEventListener","observer","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.45",
|
|
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
|
@@ -58,137 +58,101 @@ export const defaultRangeExtractor = (range: Range) => {
|
|
|
58
58
|
return arr
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
const
|
|
62
|
-
instance: Virtualizer<
|
|
61
|
+
export const observeElementRect = <T extends Element>(
|
|
62
|
+
instance: Virtualizer<T, any>,
|
|
63
63
|
cb: (rect: Rect) => void,
|
|
64
64
|
) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
instance.options.horizontal
|
|
70
|
-
? rect.width !== prev.width
|
|
71
|
-
: rect.height !== prev.height
|
|
72
|
-
) {
|
|
73
|
-
cb(rect)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
prev = rect
|
|
65
|
+
const element = instance.scrollElement
|
|
66
|
+
if (!element) {
|
|
67
|
+
return
|
|
77
68
|
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export const observeElementRect = (
|
|
81
|
-
instance: Virtualizer<any, any>,
|
|
82
|
-
cb: (rect: Rect) => void,
|
|
83
|
-
) => {
|
|
84
|
-
const observer = new ResizeObserver((entries) => {
|
|
85
|
-
const entry = entries[0]
|
|
86
|
-
if (entry) {
|
|
87
|
-
const { width, height } = entry.contentRect
|
|
88
|
-
cb({
|
|
89
|
-
width: Math.round(width),
|
|
90
|
-
height: Math.round(height),
|
|
91
|
-
})
|
|
92
|
-
} else {
|
|
93
|
-
cb({ width: 0, height: 0 })
|
|
94
|
-
}
|
|
95
|
-
})
|
|
96
69
|
|
|
97
|
-
|
|
98
|
-
|
|
70
|
+
const handler = () => {
|
|
71
|
+
const { width, height } = element.getBoundingClientRect()
|
|
72
|
+
cb({ width: Math.round(width), height: Math.round(height) })
|
|
99
73
|
}
|
|
74
|
+
handler()
|
|
100
75
|
|
|
101
|
-
|
|
76
|
+
const observer = new ResizeObserver(() => {
|
|
77
|
+
handler()
|
|
78
|
+
})
|
|
102
79
|
|
|
103
|
-
observer.observe(
|
|
80
|
+
observer.observe(element)
|
|
104
81
|
|
|
105
82
|
return () => {
|
|
106
|
-
observer.unobserve(
|
|
83
|
+
observer.unobserve(element)
|
|
107
84
|
}
|
|
108
85
|
}
|
|
109
86
|
|
|
110
87
|
export const observeWindowRect = (
|
|
111
|
-
instance: Virtualizer<
|
|
88
|
+
instance: Virtualizer<Window, any>,
|
|
112
89
|
cb: (rect: Rect) => void,
|
|
113
90
|
) => {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
memoizedCallback({
|
|
117
|
-
width: instance.scrollElement.innerWidth,
|
|
118
|
-
height: instance.scrollElement.innerHeight,
|
|
119
|
-
})
|
|
120
|
-
|
|
121
|
-
if (!instance.scrollElement) {
|
|
91
|
+
const element = instance.scrollElement
|
|
92
|
+
if (!element) {
|
|
122
93
|
return
|
|
123
94
|
}
|
|
124
95
|
|
|
125
|
-
|
|
96
|
+
const handler = () => {
|
|
97
|
+
cb({ width: element.innerWidth, height: element.innerHeight })
|
|
98
|
+
}
|
|
99
|
+
handler()
|
|
126
100
|
|
|
127
|
-
|
|
128
|
-
capture: false,
|
|
101
|
+
element.addEventListener('resize', handler, {
|
|
129
102
|
passive: true,
|
|
130
103
|
})
|
|
131
104
|
|
|
132
105
|
return () => {
|
|
133
|
-
|
|
106
|
+
element.removeEventListener('resize', handler)
|
|
134
107
|
}
|
|
135
108
|
}
|
|
136
109
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return (instance: Virtualizer<any, any>, cb: (offset: number) => void) => {
|
|
146
|
-
if (!instance.scrollElement) {
|
|
147
|
-
return
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const propX = scrollProps[mode][0]
|
|
151
|
-
const propY = scrollProps[mode][1]
|
|
152
|
-
|
|
153
|
-
let prevX: number = instance.scrollElement[propX]
|
|
154
|
-
let prevY: number = instance.scrollElement[propY]
|
|
155
|
-
|
|
156
|
-
const scroll = () => {
|
|
157
|
-
const offset =
|
|
158
|
-
instance.scrollElement[instance.options.horizontal ? propX : propY]
|
|
110
|
+
export const observeElementOffset = <T extends Element>(
|
|
111
|
+
instance: Virtualizer<T, any>,
|
|
112
|
+
cb: (offset: number) => void,
|
|
113
|
+
) => {
|
|
114
|
+
const element = instance.scrollElement
|
|
115
|
+
if (!element) {
|
|
116
|
+
return
|
|
117
|
+
}
|
|
159
118
|
|
|
160
|
-
|
|
161
|
-
|
|
119
|
+
const handler = () => {
|
|
120
|
+
cb(element[instance.options.horizontal ? 'scrollLeft' : 'scrollTop'])
|
|
121
|
+
}
|
|
122
|
+
handler()
|
|
162
123
|
|
|
163
|
-
|
|
124
|
+
element.addEventListener('scroll', handler, {
|
|
125
|
+
passive: true,
|
|
126
|
+
})
|
|
164
127
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
128
|
+
return () => {
|
|
129
|
+
element.removeEventListener('scroll', handler)
|
|
130
|
+
}
|
|
131
|
+
}
|
|
169
132
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
133
|
+
export const observeWindowOffset = (
|
|
134
|
+
instance: Virtualizer<Window, any>,
|
|
135
|
+
cb: (offset: number) => void,
|
|
136
|
+
) => {
|
|
137
|
+
const element = instance.scrollElement
|
|
138
|
+
if (!element) {
|
|
139
|
+
return
|
|
140
|
+
}
|
|
173
141
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
142
|
+
const handler = () => {
|
|
143
|
+
cb(element[instance.options.horizontal ? 'scrollX' : 'scrollY'])
|
|
144
|
+
}
|
|
145
|
+
handler()
|
|
177
146
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
})
|
|
147
|
+
element.addEventListener('scroll', handler, {
|
|
148
|
+
passive: true,
|
|
149
|
+
})
|
|
182
150
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
151
|
+
return () => {
|
|
152
|
+
element.removeEventListener('scroll', handler)
|
|
186
153
|
}
|
|
187
154
|
}
|
|
188
155
|
|
|
189
|
-
export const observeElementOffset = createOffsetObserver('element')
|
|
190
|
-
export const observeWindowOffset = createOffsetObserver('window')
|
|
191
|
-
|
|
192
156
|
export const measureElement = <TItemElement extends Element>(
|
|
193
157
|
element: TItemElement,
|
|
194
158
|
instance: Virtualizer<any, TItemElement>,
|
|
@@ -397,8 +361,15 @@ export class Virtualizer<
|
|
|
397
361
|
|
|
398
362
|
this.unsubs.push(
|
|
399
363
|
this.options.observeElementRect(this, (rect) => {
|
|
364
|
+
const prev = this.scrollRect
|
|
400
365
|
this.scrollRect = rect
|
|
401
|
-
|
|
366
|
+
if (
|
|
367
|
+
this.options.horizontal
|
|
368
|
+
? rect.width !== prev.width
|
|
369
|
+
: rect.height !== prev.height
|
|
370
|
+
) {
|
|
371
|
+
this.maybeNotify()
|
|
372
|
+
}
|
|
402
373
|
}),
|
|
403
374
|
)
|
|
404
375
|
|
|
@@ -663,47 +634,9 @@ export class Virtualizer<
|
|
|
663
634
|
return Math.max(Math.min(maxOffset, toOffset), 0)
|
|
664
635
|
}
|
|
665
636
|
|
|
666
|
-
|
|
667
|
-
toOffset: number,
|
|
668
|
-
{ align = 'start', behavior }: ScrollToOffsetOptions = {},
|
|
669
|
-
) => {
|
|
670
|
-
const isDynamic = Object.keys(this.measureElementCache).length > 0
|
|
671
|
-
|
|
672
|
-
if (isDynamic && behavior === 'smooth') {
|
|
673
|
-
console.warn(
|
|
674
|
-
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
675
|
-
)
|
|
676
|
-
return
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
const options = {
|
|
680
|
-
adjustments: undefined,
|
|
681
|
-
behavior,
|
|
682
|
-
sync: false,
|
|
683
|
-
}
|
|
684
|
-
this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), options)
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
scrollToIndex = (
|
|
688
|
-
index: number,
|
|
689
|
-
{ align = 'auto', behavior }: ScrollToIndexOptions = {},
|
|
690
|
-
) => {
|
|
637
|
+
getOffsetForIndex = (index: number, align: ScrollAlignment = 'auto') => {
|
|
691
638
|
index = Math.max(0, Math.min(index, this.options.count - 1))
|
|
692
639
|
|
|
693
|
-
if (this.scrollToIndexTimeoutId !== null) {
|
|
694
|
-
clearTimeout(this.scrollToIndexTimeoutId)
|
|
695
|
-
this.scrollToIndexTimeoutId = null
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
const isDynamic = Object.keys(this.measureElementCache).length > 0
|
|
699
|
-
|
|
700
|
-
if (isDynamic && behavior === 'smooth') {
|
|
701
|
-
console.warn(
|
|
702
|
-
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
703
|
-
)
|
|
704
|
-
return
|
|
705
|
-
}
|
|
706
|
-
|
|
707
640
|
const measurement = notUndefined(this.getMeasurements()[index])
|
|
708
641
|
|
|
709
642
|
if (align === 'auto') {
|
|
@@ -718,28 +651,64 @@ export class Virtualizer<
|
|
|
718
651
|
) {
|
|
719
652
|
align = 'start'
|
|
720
653
|
} else {
|
|
721
|
-
return
|
|
654
|
+
return [this.scrollOffset, align] as const
|
|
722
655
|
}
|
|
723
656
|
}
|
|
724
657
|
|
|
725
|
-
const
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
658
|
+
const toOffset =
|
|
659
|
+
align === 'end'
|
|
660
|
+
? measurement.end + this.options.scrollPaddingEnd
|
|
661
|
+
: measurement.start - this.options.scrollPaddingStart
|
|
662
|
+
|
|
663
|
+
return [this.getOffsetForAlignment(toOffset, align), align] as const
|
|
664
|
+
}
|
|
730
665
|
|
|
731
|
-
|
|
666
|
+
private isDynamicMode = () => Object.keys(this.measureElementCache).length > 0
|
|
667
|
+
|
|
668
|
+
private cancelScrollToIndex = () => {
|
|
669
|
+
if (this.scrollToIndexTimeoutId !== null) {
|
|
670
|
+
clearTimeout(this.scrollToIndexTimeoutId)
|
|
671
|
+
this.scrollToIndexTimeoutId = null
|
|
732
672
|
}
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
scrollToOffset = (
|
|
676
|
+
toOffset: number,
|
|
677
|
+
{ align = 'start', behavior }: ScrollToOffsetOptions = {},
|
|
678
|
+
) => {
|
|
679
|
+
this.cancelScrollToIndex()
|
|
733
680
|
|
|
734
|
-
|
|
681
|
+
if (behavior === 'smooth' && this.isDynamicMode()) {
|
|
682
|
+
console.warn(
|
|
683
|
+
'The `smooth` scroll behavior is not fully supported with dynamic size.',
|
|
684
|
+
)
|
|
685
|
+
}
|
|
735
686
|
|
|
736
|
-
|
|
687
|
+
this._scrollToOffset(this.getOffsetForAlignment(toOffset, align), {
|
|
737
688
|
adjustments: undefined,
|
|
738
689
|
behavior,
|
|
690
|
+
})
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
scrollToIndex = (
|
|
694
|
+
index: number,
|
|
695
|
+
{ align: initialAlign = 'auto', behavior }: ScrollToIndexOptions = {},
|
|
696
|
+
) => {
|
|
697
|
+
index = Math.max(0, Math.min(index, this.options.count - 1))
|
|
698
|
+
|
|
699
|
+
this.cancelScrollToIndex()
|
|
700
|
+
|
|
701
|
+
if (behavior === 'smooth' && this.isDynamicMode()) {
|
|
702
|
+
console.warn(
|
|
703
|
+
'The `smooth` scroll behavior is not fully supported with dynamic size.',
|
|
704
|
+
)
|
|
739
705
|
}
|
|
740
|
-
this._scrollToOffset(toOffset, options)
|
|
741
706
|
|
|
742
|
-
|
|
707
|
+
const [toOffset, align] = this.getOffsetForIndex(index, initialAlign)
|
|
708
|
+
|
|
709
|
+
this._scrollToOffset(toOffset, { adjustments: undefined, behavior })
|
|
710
|
+
|
|
711
|
+
if (behavior !== 'smooth' && this.isDynamicMode()) {
|
|
743
712
|
this.scrollToIndexTimeoutId = setTimeout(() => {
|
|
744
713
|
this.scrollToIndexTimeoutId = null
|
|
745
714
|
|
|
@@ -747,9 +716,7 @@ export class Virtualizer<
|
|
|
747
716
|
!!this.measureElementCache[this.options.getItemKey(index)]
|
|
748
717
|
|
|
749
718
|
if (elementInDOM) {
|
|
750
|
-
const toOffset =
|
|
751
|
-
notUndefined(this.getMeasurements()[index]),
|
|
752
|
-
)
|
|
719
|
+
const [toOffset] = this.getOffsetForIndex(index, align)
|
|
753
720
|
|
|
754
721
|
if (!approxEqual(toOffset, this.scrollOffset)) {
|
|
755
722
|
this.scrollToIndex(index, { align, behavior })
|
|
@@ -762,13 +729,12 @@ export class Virtualizer<
|
|
|
762
729
|
}
|
|
763
730
|
|
|
764
731
|
scrollBy = (delta: number, { behavior }: ScrollToOffsetOptions = {}) => {
|
|
765
|
-
|
|
732
|
+
this.cancelScrollToIndex()
|
|
766
733
|
|
|
767
|
-
if (
|
|
734
|
+
if (behavior === 'smooth' && this.isDynamicMode()) {
|
|
768
735
|
console.warn(
|
|
769
|
-
'The `smooth` scroll behavior is not supported with dynamic size.',
|
|
736
|
+
'The `smooth` scroll behavior is not fully supported with dynamic size.',
|
|
770
737
|
)
|
|
771
|
-
return
|
|
772
738
|
}
|
|
773
739
|
|
|
774
740
|
this._scrollToOffset(this.scrollOffset + delta, {
|