@tanstack/virtual-core 3.0.0-beta.65 → 3.0.0-beta.68
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 +3 -3
- package/build/lib/index.esm.js +16 -16
- package/build/lib/index.esm.js.map +1 -1
- package/build/lib/index.js +16 -16
- package/build/lib/index.js.map +1 -1
- package/build/lib/index.mjs +16 -16
- package/build/lib/index.mjs.map +1 -1
- package/build/lib/utils.esm.js.map +1 -1
- package/build/lib/utils.js.map +1 -1
- package/build/lib/utils.mjs.map +1 -1
- package/build/umd/index.development.js +16 -16
- 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 +33 -30
|
@@ -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: false | string\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 lane: 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 = (rect: Rect) => {\n const { width, height } = rect\n cb({ width: Math.round(width), height: Math.round(height) })\n }\n\n handler(element.getBoundingClientRect())\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize })\n return\n }\n }\n handler(element.getBoundingClientRect())\n })\n\n observer.observe(element, { box: 'border-box' })\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 entry: ResizeObserverEntry | undefined,\n instance: Virtualizer<any, TItemElement>,\n) => {\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? 'inlineSize' : 'blockSize'],\n )\n return size\n }\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 element: TItemElement,\n entry: ResizeObserverEntry | undefined,\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 lanes?: number\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 = new Map<Key, number>()\n private pendingMeasuredCacheIndexes: number[] = []\n private scrollRect: Rect\n scrollOffset: number\n scrollDirection: ScrollDirection | null = null\n private scrollAdjustments: number = 0\n measureElementCache = new Map<Key, TItemElement>()\n private observer = (() => {\n let _ro: ResizeObserver | null = null\n\n const get = () => {\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, entry)\n })\n }))\n } else {\n return null\n }\n }\n\n return {\n disconnect: () => get()?.disconnect(),\n observe: (target: Element) =>\n get()?.observe(target, { box: 'border-box' }),\n unobserve: (target: Element) => get()?.unobserve(target),\n }\n })()\n range: { startIndex: number; endIndex: number } | null = null\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.set(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 lanes: 1,\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 this.measureElementCache.forEach(this.observer.observe)\n return () => {\n this.observer.disconnect()\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 memoOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n ],\n (count, paddingStart, scrollMargin, getItemKey) => {\n this.pendingMeasuredCacheIndexes = []\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n }\n },\n {\n key: false,\n },\n )\n\n private getFurthestMeasurement = (\n measurements: VirtualItem[],\n index: number,\n ) => {\n const furthestMeasurementsFound = new Map<number, true>()\n const furthestMeasurements = new Map<number, VirtualItem>()\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m]!\n\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue\n }\n\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane,\n )\n if (\n previousFurthestMeasurement == null ||\n measurement.end > previousFurthestMeasurement.end\n ) {\n furthestMeasurements.set(measurement.lane, measurement)\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true)\n }\n\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break\n }\n }\n\n return furthestMeasurements.size === this.options.lanes\n ? Array.from(furthestMeasurements.values()).sort(\n (a, b) => a.end - b.end,\n )[0]\n : undefined\n }\n\n private getMeasurements = memo(\n () => [this.memoOptions(), this.itemSizeCache],\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\n const furthestMeasurement =\n this.options.lanes === 1\n ? measurements[i - 1]\n : this.getFurthestMeasurement(measurements, i)\n\n const start = furthestMeasurement\n ? furthestMeasurement.end\n : paddingStart + scrollMargin\n\n const measuredSize = itemSizeCache.get(key)\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n\n const end = start + size\n\n const lane = furthestMeasurement\n ? furthestMeasurement.lane\n : i % this.options.lanes\n\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane,\n }\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 =\n measurements.length > 0 && outerSize > 0\n ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n : null)\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'calculateRange',\n debug: () => this.options.debug,\n },\n )\n\n private maybeNotify = memo(\n () => {\n this.calculateRange()\n\n return [\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n this.isScrolling,\n ]\n },\n () => {\n this.notify()\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n debug: () => this.options.debug,\n initialDeps: [\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n this.isScrolling,\n ],\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 range === null\n ? []\n : 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 = (\n node: TItemElement,\n entry: ResizeObserverEntry | undefined,\n ) => {\n const item = this.measurementsCache[this.indexFromElement(node)]\n\n if (!item || !node.isConnected) {\n this.measureElementCache.forEach((cached, key) => {\n if (cached === node) {\n this.observer.unobserve(node)\n this.measureElementCache.delete(key)\n }\n })\n return\n }\n\n const prevNode = this.measureElementCache.get(item.key)\n\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode)\n }\n this.observer.observe(node)\n this.measureElementCache.set(item.key, node)\n }\n\n const measuredItemSize = this.options.measureElement(node, entry, this)\n\n this.resizeItem(item, measuredItemSize)\n }\n\n resizeItem = (item: VirtualItem, size: number) => {\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size\n const delta = size - 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(item.index)\n this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))\n\n this.notify()\n }\n }\n\n measureElement = (node: TItemElement | null) => {\n if (!node) {\n return\n }\n\n this._measureElement(node, undefined)\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 getVirtualItemForOffset = (offset: number) => {\n const measurements = this.getMeasurements()\n\n return notUndefined(\n measurements[\n findNearestBinarySearch(\n 0,\n measurements.length - 1,\n (index: number) => notUndefined(measurements[index]).start,\n offset,\n )\n ],\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 = () => this.measureElementCache.size > 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 = this.measureElementCache.has(\n this.options.getItemKey(index),\n )\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 = new Map()\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","entry","instance","borderBoxSize","box","options","horizontal","getBoundingClientRect","findNearestBinarySearch","low","high","getCurrentValue","middle","currentValue","_ro","get","_this","this","unsubs","scrollElement","isScrolling","isScrollingTimeoutId","scrollToIndexTimeoutId","measurementsCache","itemSizeCache","Map","pendingMeasuredCacheIndexes","scrollDirection","scrollAdjustments","measureElementCache","observer","ResizeObserver","entries","forEach","_measureElement","target","disconnect","_get","observe","_get2","unobserve","_get3","setOptions","Object","_ref3","_extends","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","initialRect","width","height","scrollMargin","scrollingDelay","indexAttribute","initialMeasurementsCache","lanes","notify","cleanup","filter","Boolean","d","_didMount","_willUpdate","getScrollElement","_scrollToOffset","scrollOffset","adjustments","behavior","observeElementRect","rect","scrollRect","maybeNotify","observeElementOffset","offset","clearTimeout","setTimeout","getSize","memoOptions","getFurthestMeasurement","measurements","furthestMeasurementsFound","furthestMeasurements","m","measurement","has","lane","previousFurthestMeasurement","set","size","Array","from","values","sort","getMeasurements","_ref4","slice","furthestMeasurement","measuredSize","estimateSize","process","calculateRange","outerSize","_ref9","getIndexes","indexFromElement","node","attributeName","indexStr","getAttribute","parseInt","warn","item","isConnected","prevNode","measuredItemSize","resizeItem","cached","_this$itemSizeCache$g","delta","getVirtualItems","indexes","virtualItems","k","len","getVirtualItemForOffset","getOffsetForAlignment","toOffset","align","scrollSizeProp","maxOffset","document","documentElement","getOffsetForIndex","isDynamicMode","cancelScrollToIndex","scrollToOffset","_temp","_ref5","_ref5$align","scrollToIndex","_temp2","_ref6","_ref6$align","initialAlign","_this$getOffsetForInd","scrollBy","_temp3","getTotalSize","_this$getMeasurements","_ref8","scrollToFn","measure","_instance$scrollEleme3","_instance$scrollEleme4","_ref2$adjustments","_ref2","scrollTo","cb","handler","addEventListener","passive","removeEventListener","inlineSize","blockSize","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: false | string\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 lane: 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 = (rect: Rect) => {\n const { width, height } = rect\n cb({ width: Math.round(width), height: Math.round(height) })\n }\n\n handler(element.getBoundingClientRect())\n\n const observer = new ResizeObserver((entries) => {\n const entry = entries[0]\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n handler({ width: box.inlineSize, height: box.blockSize })\n return\n }\n }\n handler(element.getBoundingClientRect())\n })\n\n observer.observe(element, { box: 'border-box' })\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 entry: ResizeObserverEntry | undefined,\n instance: Virtualizer<any, TItemElement>,\n) => {\n if (entry?.borderBoxSize) {\n const box = entry.borderBoxSize[0]\n if (box) {\n const size = Math.round(\n box[instance.options.horizontal ? 'inlineSize' : 'blockSize'],\n )\n return size\n }\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?: (\n instance: Virtualizer<TScrollElement, TItemElement>,\n sync: boolean,\n ) => void\n measureElement?: (\n element: TItemElement,\n entry: ResizeObserverEntry | undefined,\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 lanes?: number\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 = new Map<Key, number>()\n private pendingMeasuredCacheIndexes: number[] = []\n scrollRect: Rect\n scrollOffset: number\n scrollDirection: ScrollDirection | null = null\n private scrollAdjustments: number = 0\n measureElementCache = new Map<Key, TItemElement>()\n private observer = (() => {\n let _ro: ResizeObserver | null = null\n\n const get = () => {\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, entry)\n })\n }))\n } else {\n return null\n }\n }\n\n return {\n disconnect: () => get()?.disconnect(),\n observe: (target: Element) =>\n get()?.observe(target, { box: 'border-box' }),\n unobserve: (target: Element) => get()?.unobserve(target),\n }\n })()\n range: { startIndex: number; endIndex: number } | null = null\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.set(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 lanes: 1,\n ...opts,\n }\n }\n\n private notify = (sync: boolean) => {\n this.options.onChange?.(this, sync)\n }\n\n private maybeNotify = memo(\n () => {\n this.calculateRange()\n\n return [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n ]\n },\n (isScrolling) => {\n this.notify(isScrolling)\n },\n {\n key: process.env.NODE_ENV !== 'production' && 'maybeNotify',\n debug: () => this.options.debug,\n initialDeps: [\n this.isScrolling,\n this.range ? this.range.startIndex : null,\n this.range ? this.range.endIndex : null,\n ] as [boolean, number | null, number | null],\n },\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 this.measureElementCache.forEach(this.observer.observe)\n return () => {\n this.observer.disconnect()\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 memoOptions = memo(\n () => [\n this.options.count,\n this.options.paddingStart,\n this.options.scrollMargin,\n this.options.getItemKey,\n ],\n (count, paddingStart, scrollMargin, getItemKey) => {\n this.pendingMeasuredCacheIndexes = []\n return {\n count,\n paddingStart,\n scrollMargin,\n getItemKey,\n }\n },\n {\n key: false,\n },\n )\n\n private getFurthestMeasurement = (\n measurements: VirtualItem[],\n index: number,\n ) => {\n const furthestMeasurementsFound = new Map<number, true>()\n const furthestMeasurements = new Map<number, VirtualItem>()\n for (let m = index - 1; m >= 0; m--) {\n const measurement = measurements[m]!\n\n if (furthestMeasurementsFound.has(measurement.lane)) {\n continue\n }\n\n const previousFurthestMeasurement = furthestMeasurements.get(\n measurement.lane,\n )\n if (\n previousFurthestMeasurement == null ||\n measurement.end > previousFurthestMeasurement.end\n ) {\n furthestMeasurements.set(measurement.lane, measurement)\n } else if (measurement.end < previousFurthestMeasurement.end) {\n furthestMeasurementsFound.set(measurement.lane, true)\n }\n\n if (furthestMeasurementsFound.size === this.options.lanes) {\n break\n }\n }\n\n return furthestMeasurements.size === this.options.lanes\n ? Array.from(furthestMeasurements.values()).sort(\n (a, b) => a.end - b.end,\n )[0]\n : undefined\n }\n\n private getMeasurements = memo(\n () => [this.memoOptions(), this.itemSizeCache],\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\n const furthestMeasurement =\n this.options.lanes === 1\n ? measurements[i - 1]\n : this.getFurthestMeasurement(measurements, i)\n\n const start = furthestMeasurement\n ? furthestMeasurement.end\n : paddingStart + scrollMargin\n\n const measuredSize = itemSizeCache.get(key)\n const size =\n typeof measuredSize === 'number'\n ? measuredSize\n : this.options.estimateSize(i)\n\n const end = start + size\n\n const lane = furthestMeasurement\n ? furthestMeasurement.lane\n : i % this.options.lanes\n\n measurements[i] = {\n index: i,\n start,\n size,\n end,\n key,\n lane,\n }\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 =\n measurements.length > 0 && outerSize > 0\n ? calculateRange({\n measurements,\n outerSize,\n scrollOffset,\n })\n : null)\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(),\n this.options.overscan,\n this.options.count,\n ],\n (rangeExtractor, range, overscan, count) => {\n return range === null\n ? []\n : 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 = (\n node: TItemElement,\n entry: ResizeObserverEntry | undefined,\n ) => {\n const item = this.measurementsCache[this.indexFromElement(node)]\n\n if (!item || !node.isConnected) {\n this.measureElementCache.forEach((cached, key) => {\n if (cached === node) {\n this.observer.unobserve(node)\n this.measureElementCache.delete(key)\n }\n })\n return\n }\n\n const prevNode = this.measureElementCache.get(item.key)\n\n if (prevNode !== node) {\n if (prevNode) {\n this.observer.unobserve(prevNode)\n }\n this.observer.observe(node)\n this.measureElementCache.set(item.key, node)\n }\n\n const measuredItemSize = this.options.measureElement(node, entry, this)\n\n this.resizeItem(item, measuredItemSize)\n }\n\n resizeItem = (item: VirtualItem, size: number) => {\n const itemSize = this.itemSizeCache.get(item.key) ?? item.size\n const delta = size - 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(item.index)\n this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))\n\n this.notify(false)\n }\n }\n\n measureElement = (node: TItemElement | null) => {\n if (!node) {\n return\n }\n\n this._measureElement(node, undefined)\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 getVirtualItemForOffset = (offset: number) => {\n const measurements = this.getMeasurements()\n\n return notUndefined(\n measurements[\n findNearestBinarySearch(\n 0,\n measurements.length - 1,\n (index: number) => notUndefined(measurements[index]).start,\n offset,\n )\n ],\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 = () => this.measureElementCache.size > 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 = this.measureElementCache.has(\n this.options.getItemKey(index),\n )\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 = new Map()\n this.notify(false)\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","apply","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","entry","instance","borderBoxSize","box","options","horizontal","getBoundingClientRect","findNearestBinarySearch","low","high","getCurrentValue","middle","currentValue","_ro","get","_this","this","unsubs","scrollElement","isScrolling","isScrollingTimeoutId","scrollToIndexTimeoutId","measurementsCache","itemSizeCache","Map","pendingMeasuredCacheIndexes","scrollDirection","scrollAdjustments","measureElementCache","observer","ResizeObserver","entries","forEach","_measureElement","target","disconnect","_get","observe","_get2","unobserve","_get3","setOptions","Object","_ref3","_extends","initialOffset","paddingStart","paddingEnd","scrollPaddingStart","scrollPaddingEnd","getItemKey","rangeExtractor","initialRect","width","height","scrollMargin","scrollingDelay","indexAttribute","initialMeasurementsCache","lanes","notify","sync","maybeNotify","calculateRange","process","cleanup","filter","Boolean","d","_didMount","_willUpdate","getScrollElement","_scrollToOffset","scrollOffset","adjustments","behavior","observeElementRect","rect","scrollRect","observeElementOffset","offset","clearTimeout","setTimeout","getSize","memoOptions","getFurthestMeasurement","measurements","furthestMeasurementsFound","furthestMeasurements","m","measurement","has","lane","previousFurthestMeasurement","set","size","Array","from","values","sort","getMeasurements","_ref4","slice","furthestMeasurement","measuredSize","estimateSize","outerSize","_ref9","getIndexes","indexFromElement","node","attributeName","indexStr","getAttribute","parseInt","warn","item","isConnected","prevNode","measuredItemSize","resizeItem","cached","_this$itemSizeCache$g","delta","getVirtualItems","indexes","virtualItems","k","len","getVirtualItemForOffset","getOffsetForAlignment","toOffset","align","scrollSizeProp","maxOffset","document","documentElement","getOffsetForIndex","isDynamicMode","cancelScrollToIndex","scrollToOffset","_temp","_ref5","_ref5$align","scrollToIndex","_temp2","_ref6","_ref6$align","initialAlign","_this$getOffsetForInd","scrollBy","_temp3","getTotalSize","_this$getMeasurements","_ref8","scrollToFn","measure","_ref2","_instance$scrollEleme3","_instance$scrollEleme4","_ref2$adjustments","scrollTo","cb","handler","addEventListener","passive","removeEventListener","inlineSize","blockSize","innerWidth","innerHeight","_ref","_instance$scrollEleme","_instance$scrollEleme2","_ref$adjustments"],"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.68",
|
|
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
|
@@ -243,7 +243,10 @@ export interface VirtualizerOptions<
|
|
|
243
243
|
// Optional
|
|
244
244
|
debug?: any
|
|
245
245
|
initialRect?: Rect
|
|
246
|
-
onChange?: (
|
|
246
|
+
onChange?: (
|
|
247
|
+
instance: Virtualizer<TScrollElement, TItemElement>,
|
|
248
|
+
sync: boolean,
|
|
249
|
+
) => void
|
|
247
250
|
measureElement?: (
|
|
248
251
|
element: TItemElement,
|
|
249
252
|
entry: ResizeObserverEntry | undefined,
|
|
@@ -278,7 +281,7 @@ export class Virtualizer<
|
|
|
278
281
|
measurementsCache: VirtualItem[] = []
|
|
279
282
|
private itemSizeCache = new Map<Key, number>()
|
|
280
283
|
private pendingMeasuredCacheIndexes: number[] = []
|
|
281
|
-
|
|
284
|
+
scrollRect: Rect
|
|
282
285
|
scrollOffset: number
|
|
283
286
|
scrollDirection: ScrollDirection | null = null
|
|
284
287
|
private scrollAdjustments: number = 0
|
|
@@ -349,10 +352,34 @@ export class Virtualizer<
|
|
|
349
352
|
}
|
|
350
353
|
}
|
|
351
354
|
|
|
352
|
-
private notify = () => {
|
|
353
|
-
this.options.onChange?.(this)
|
|
355
|
+
private notify = (sync: boolean) => {
|
|
356
|
+
this.options.onChange?.(this, sync)
|
|
354
357
|
}
|
|
355
358
|
|
|
359
|
+
private maybeNotify = memo(
|
|
360
|
+
() => {
|
|
361
|
+
this.calculateRange()
|
|
362
|
+
|
|
363
|
+
return [
|
|
364
|
+
this.isScrolling,
|
|
365
|
+
this.range ? this.range.startIndex : null,
|
|
366
|
+
this.range ? this.range.endIndex : null,
|
|
367
|
+
]
|
|
368
|
+
},
|
|
369
|
+
(isScrolling) => {
|
|
370
|
+
this.notify(isScrolling)
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
|
|
374
|
+
debug: () => this.options.debug,
|
|
375
|
+
initialDeps: [
|
|
376
|
+
this.isScrolling,
|
|
377
|
+
this.range ? this.range.startIndex : null,
|
|
378
|
+
this.range ? this.range.endIndex : null,
|
|
379
|
+
] as [boolean, number | null, number | null],
|
|
380
|
+
},
|
|
381
|
+
)
|
|
382
|
+
|
|
356
383
|
private cleanup = () => {
|
|
357
384
|
this.unsubs.filter(Boolean).forEach((d) => d!())
|
|
358
385
|
this.unsubs = []
|
|
@@ -554,30 +581,6 @@ export class Virtualizer<
|
|
|
554
581
|
},
|
|
555
582
|
)
|
|
556
583
|
|
|
557
|
-
private maybeNotify = memo(
|
|
558
|
-
() => {
|
|
559
|
-
this.calculateRange()
|
|
560
|
-
|
|
561
|
-
return [
|
|
562
|
-
this.range ? this.range.startIndex : null,
|
|
563
|
-
this.range ? this.range.endIndex : null,
|
|
564
|
-
this.isScrolling,
|
|
565
|
-
]
|
|
566
|
-
},
|
|
567
|
-
() => {
|
|
568
|
-
this.notify()
|
|
569
|
-
},
|
|
570
|
-
{
|
|
571
|
-
key: process.env.NODE_ENV !== 'production' && 'maybeNotify',
|
|
572
|
-
debug: () => this.options.debug,
|
|
573
|
-
initialDeps: [
|
|
574
|
-
this.range ? this.range.startIndex : null,
|
|
575
|
-
this.range ? this.range.endIndex : null,
|
|
576
|
-
this.isScrolling,
|
|
577
|
-
],
|
|
578
|
-
},
|
|
579
|
-
)
|
|
580
|
-
|
|
581
584
|
private getIndexes = memo(
|
|
582
585
|
() => [
|
|
583
586
|
this.options.rangeExtractor,
|
|
@@ -664,7 +667,7 @@ export class Virtualizer<
|
|
|
664
667
|
this.pendingMeasuredCacheIndexes.push(item.index)
|
|
665
668
|
this.itemSizeCache = new Map(this.itemSizeCache.set(item.key, size))
|
|
666
669
|
|
|
667
|
-
this.notify()
|
|
670
|
+
this.notify(false)
|
|
668
671
|
}
|
|
669
672
|
}
|
|
670
673
|
|
|
@@ -877,7 +880,7 @@ export class Virtualizer<
|
|
|
877
880
|
|
|
878
881
|
measure = () => {
|
|
879
882
|
this.itemSizeCache = new Map()
|
|
880
|
-
this.notify()
|
|
883
|
+
this.notify(false)
|
|
881
884
|
}
|
|
882
885
|
}
|
|
883
886
|
|