@vielzeug/scroll 3.0.0 → 26.10.0
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/dist/_validation.cjs +1 -1
- package/dist/_validation.cjs.map +1 -1
- package/dist/_validation.js +1 -1
- package/dist/_validation.js.map +1 -1
- package/dist/dom-virtual-list.cjs +1 -1
- package/dist/dom-virtual-list.cjs.map +1 -1
- package/dist/dom-virtual-list.d.ts +0 -2
- package/dist/dom-virtual-list.d.ts.map +1 -1
- package/dist/dom-virtual-list.js +1 -1
- package/dist/dom-virtual-list.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/grid-virtualizer.cjs +1 -1
- package/dist/grid-virtualizer.cjs.map +1 -1
- package/dist/grid-virtualizer.d.ts +0 -3
- package/dist/grid-virtualizer.d.ts.map +1 -1
- package/dist/grid-virtualizer.js +1 -1
- package/dist/grid-virtualizer.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/scroll.cjs +1 -1
- package/dist/scroll.cjs.map +1 -1
- package/dist/scroll.iife.js +1 -1
- package/dist/scroll.iife.js.map +1 -1
- package/dist/scroll.js +1 -1
- package/dist/scroll.js.map +1 -1
- package/dist/virtualizer.cjs +1 -1
- package/dist/virtualizer.cjs.map +1 -1
- package/dist/virtualizer.d.ts +7 -3
- package/dist/virtualizer.d.ts.map +1 -1
- package/dist/virtualizer.js +1 -1
- package/dist/virtualizer.js.map +1 -1
- package/package.json +5 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-virtualizer.cjs","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { alignOffset } from './_alignment';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n createSnapshotStore,\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n type Overscan,\n observeResize,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\nimport {\n requireNonNegativeInteger,\n requireNonNegativeNumber,\n requirePositiveNumber,\n validateOverscan,\n} from './_validation';\nimport type { ScrollStore } from './virtualizer';\n\nexport type { VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n colGap?: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /** Enable keyboard navigation (Arrow/Page/Home/End keys). */\n keyboardScroll?: boolean;\n /** Called after every render cycle with the new state. Replace through `update()`. */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n rowGap?: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n keyboardScroll?: boolean;\n onChange?: ((state: GridVirtualizerState) => void) | undefined;\n onRangeChange?: ((range: GridRangeChangeEvent) => void) | undefined;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer extends ScrollStore<GridVirtualizerState> {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n dispose: () => void;\n readonly disposed: boolean;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n readonly scrollTop: number;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n readonly totalHeight: number;\n readonly totalWidth: number;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n if (typeof options.estimateRowSize === 'number') requirePositiveNumber(options.estimateRowSize, 'estimateRowSize');\n\n if (typeof options.estimateColSize === 'number') requirePositiveNumber(options.estimateColSize, 'estimateColSize');\n\n if (options.initialScrollTop !== undefined) requireNonNegativeNumber(options.initialScrollTop, 'initialScrollTop');\n\n if (options.initialScrollLeft !== undefined) requireNonNegativeNumber(options.initialScrollLeft, 'initialScrollLeft');\n\n if (options.rowGap !== undefined) requireNonNegativeInteger(options.rowGap, 'rowGap');\n\n if (options.colGap !== undefined) requireNonNegativeInteger(options.colGap, 'colGap');\n\n if (options.overscanY !== undefined) validateOverscan(options.overscanY, 'overscanY');\n\n if (options.overscanX !== undefined) validateOverscan(options.overscanX, 'overscanX');\n\n let rowCount = requireNonNegativeInteger(options.rowCount, 'rowCount');\n let colCount = requireNonNegativeInteger(options.colCount, 'colCount');\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n let keyboardScrollEnabled = options.keyboardScroll ?? false;\n\n let onChange = options.onChange;\n let onRangeChange = options.onRangeChange;\n\n // Publish state before invoking the render callback.\n function emitState(state: GridVirtualizerState): void {\n stateStore.publish(state);\n onChange?.(state);\n }\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n const stateStore = createSnapshotStore<GridVirtualizerState>({ cols, rows, totalHeight: 0, totalWidth: 0 });\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n emitState({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n emitState({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n if (next.rowCount !== undefined) requireNonNegativeInteger(next.rowCount, 'rowCount');\n\n if (next.colCount !== undefined) requireNonNegativeInteger(next.colCount, 'colCount');\n\n if (typeof next.estimateRowSize === 'number') requirePositiveNumber(next.estimateRowSize, 'estimateRowSize');\n\n if (typeof next.estimateColSize === 'number') requirePositiveNumber(next.estimateColSize, 'estimateColSize');\n\n if (next.rowGap !== undefined) requireNonNegativeInteger(next.rowGap, 'rowGap');\n\n if (next.colGap !== undefined) requireNonNegativeInteger(next.colGap, 'colGap');\n\n if (next.overscanY !== undefined) validateOverscan(next.overscanY, 'overscanY');\n\n if (next.overscanX !== undefined) validateOverscan(next.overscanX, 'overscanX');\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (Object.hasOwn(next, 'onChange')) onChange = next.onChange;\n\n if (Object.hasOwn(next, 'onRangeChange')) onRangeChange = next.onRangeChange;\n\n if (next.rowCount !== undefined) {\n const n = next.rowCount;\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = next.colCount;\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = next.rowGap;\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = next.colGap;\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (Object.hasOwn(next, 'keyboardScroll')) {\n keyboardScrollEnabled = next.keyboardScroll ?? false;\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n stateStore.dispose();\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n // ─── Keyboard scroll support ──────────────────────────────────────────────────\n\n if (keyboardScrollEnabled) {\n const handleKeyDown = (e: Event): void => {\n if (disposed) return;\n if (!(e instanceof KeyboardEvent)) return;\n if (rowCount === 0 || colCount === 0) return;\n\n let handled = false;\n let newTop = scrollTop;\n let newLeft = scrollLeft;\n const pageScrollSize = Math.max(viewportHeight * 0.8, viewportHeight - 100);\n const rowStepSize =\n (typeof estimateRowFn(0) === 'number' ? estimateRowFn(0) : DEFAULT_ESTIMATE_SIZE) +\n toNonNegativeInt(options.rowGap ?? 0);\n const colStepSize =\n (typeof estimateColFn(0) === 'number' ? estimateColFn(0) : DEFAULT_ESTIMATE_SIZE) +\n toNonNegativeInt(options.colGap ?? 0);\n\n switch (e.key) {\n case 'ArrowUp':\n newTop = Math.max(0, scrollTop - rowStepSize);\n handled = true;\n break;\n case 'ArrowDown':\n newTop = Math.min(rowAx.totalSize - viewportHeight, scrollTop + rowStepSize);\n handled = true;\n break;\n case 'ArrowLeft':\n newLeft = Math.max(0, scrollLeft - colStepSize);\n handled = true;\n break;\n case 'ArrowRight':\n newLeft = Math.min(colAx.totalSize - viewportWidth, scrollLeft + colStepSize);\n handled = true;\n break;\n case 'PageUp':\n newTop = Math.max(0, scrollTop - pageScrollSize);\n handled = true;\n break;\n case 'PageDown':\n newTop = Math.min(rowAx.totalSize - viewportHeight, scrollTop + pageScrollSize);\n handled = true;\n break;\n case 'Home':\n newTop = 0;\n handled = true;\n break;\n case 'End':\n newTop = Math.max(0, rowAx.totalSize - viewportHeight);\n handled = true;\n break;\n }\n\n if (handled) {\n e.preventDefault();\n adapter.scrollTo(newLeft, newTop, 'auto');\n scrollTop = clampTop(newTop);\n scrollLeft = clampLeft(newLeft);\n if (!disposed) computeVisible();\n }\n };\n\n if (typeof target === 'object' && target !== null && 'addEventListener' in target) {\n (target as EventTarget).addEventListener('keydown', handleKeyDown);\n ac.signal.addEventListener('abort', () => {\n (target as EventTarget).removeEventListener('keydown', handleKeyDown);\n });\n }\n }\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n getSnapshot: stateStore.getSnapshot,\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n subscribe: stateStore.subscribe,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grid-virtualizer.cjs","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { alignOffset } from './_alignment';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n createSnapshotStore,\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n type Overscan,\n observeResize,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\nimport {\n requireNonNegativeInteger,\n requireNonNegativeNumber,\n requirePositiveNumber,\n validateOverscan,\n} from './_validation';\nimport type { ScrollStore } from './virtualizer';\n\nexport type { VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n colGap?: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /** Called after every render cycle with the new state. Replace through `update()`. */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n rowGap?: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n onChange?: ((state: GridVirtualizerState) => void) | undefined;\n onRangeChange?: ((range: GridRangeChangeEvent) => void) | undefined;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer extends ScrollStore<GridVirtualizerState> {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n dispose: () => void;\n readonly disposed: boolean;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n readonly scrollTop: number;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n readonly totalHeight: number;\n readonly totalWidth: number;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n if (typeof options.estimateRowSize === 'number') requirePositiveNumber(options.estimateRowSize, 'estimateRowSize');\n\n if (typeof options.estimateColSize === 'number') requirePositiveNumber(options.estimateColSize, 'estimateColSize');\n\n if (options.initialScrollTop !== undefined) requireNonNegativeNumber(options.initialScrollTop, 'initialScrollTop');\n\n if (options.initialScrollLeft !== undefined) requireNonNegativeNumber(options.initialScrollLeft, 'initialScrollLeft');\n\n if (options.rowGap !== undefined) requireNonNegativeInteger(options.rowGap, 'rowGap');\n\n if (options.colGap !== undefined) requireNonNegativeInteger(options.colGap, 'colGap');\n\n if (options.overscanY !== undefined) validateOverscan(options.overscanY, 'overscanY');\n\n if (options.overscanX !== undefined) validateOverscan(options.overscanX, 'overscanX');\n\n let rowCount = requireNonNegativeInteger(options.rowCount, 'rowCount');\n let colCount = requireNonNegativeInteger(options.colCount, 'colCount');\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n let onChange = options.onChange;\n let onRangeChange = options.onRangeChange;\n\n // Publish state before invoking the render callback.\n function emitState(state: GridVirtualizerState): void {\n stateStore.publish(state);\n onChange?.(state);\n }\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n const stateStore = createSnapshotStore<GridVirtualizerState>({ cols, rows, totalHeight: 0, totalWidth: 0 });\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n emitState({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n emitState({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n if (next.rowCount !== undefined) requireNonNegativeInteger(next.rowCount, 'rowCount');\n\n if (next.colCount !== undefined) requireNonNegativeInteger(next.colCount, 'colCount');\n\n if (typeof next.estimateRowSize === 'number') requirePositiveNumber(next.estimateRowSize, 'estimateRowSize');\n\n if (typeof next.estimateColSize === 'number') requirePositiveNumber(next.estimateColSize, 'estimateColSize');\n\n if (next.rowGap !== undefined) requireNonNegativeInteger(next.rowGap, 'rowGap');\n\n if (next.colGap !== undefined) requireNonNegativeInteger(next.colGap, 'colGap');\n\n if (next.overscanY !== undefined) validateOverscan(next.overscanY, 'overscanY');\n\n if (next.overscanX !== undefined) validateOverscan(next.overscanX, 'overscanX');\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (Object.hasOwn(next, 'onChange')) onChange = next.onChange;\n\n if (Object.hasOwn(next, 'onRangeChange')) onRangeChange = next.onRangeChange;\n\n if (next.rowCount !== undefined) {\n const n = next.rowCount;\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = next.colCount;\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = next.rowGap;\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = next.colGap;\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n stateStore.dispose();\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n getSnapshot: stateStore.getSnapshot,\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n subscribe: stateStore.subscribe,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
|
@@ -34,8 +34,6 @@ export interface GridVirtualizerOptions {
|
|
|
34
34
|
estimateRowSize?: number | ((row: number) => number);
|
|
35
35
|
initialScrollLeft?: number;
|
|
36
36
|
initialScrollTop?: number;
|
|
37
|
-
/** Enable keyboard navigation (Arrow/Page/Home/End keys). */
|
|
38
|
-
keyboardScroll?: boolean;
|
|
39
37
|
/** Called after every render cycle with the new state. Replace through `update()`. */
|
|
40
38
|
onChange?: (state: GridVirtualizerState) => void;
|
|
41
39
|
/** Zero-allocation alternative to onChange for range-based consumers. */
|
|
@@ -56,7 +54,6 @@ export interface GridVirtualizerUpdateOptions {
|
|
|
56
54
|
colGap?: number;
|
|
57
55
|
estimateColSize?: number | ((col: number) => number);
|
|
58
56
|
estimateRowSize?: number | ((row: number) => number);
|
|
59
|
-
keyboardScroll?: boolean;
|
|
60
57
|
onChange?: ((state: GridVirtualizerState) => void) | undefined;
|
|
61
58
|
onRangeChange?: ((range: GridRangeChangeEvent) => void) | undefined;
|
|
62
59
|
overscanX?: Overscan;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-virtualizer.d.ts","sourceRoot":"","sources":["../src/grid-virtualizer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,OAAO,EAKL,KAAK,QAAQ,EAGb,KAAK,YAAY,EAGlB,MAAM,UAAU,CAAC;AAOlB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,YAAY,EAAE,WAAW,EAAE,CAAC;AAI5B,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAC7B,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;CAChD;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6FAA6F;IAC7F,mBAAmB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,eAAe,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IACrD,eAAe,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IACrD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,
|
|
1
|
+
{"version":3,"file":"grid-virtualizer.d.ts","sourceRoot":"","sources":["../src/grid-virtualizer.ts"],"names":[],"mappings":"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"}
|
package/dist/grid-virtualizer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{createSnapshotStore as e,normalizeOverscan as t,observeResize as n,resolveEstimateFn as r,toNonNegativeInt as i,toPositiveNumber as a}from"./_utils.js";import{requireNonNegativeInteger as o,requireNonNegativeNumber as s,requirePositiveNumber as c,validateOverscan as l}from"./_validation.js";import{createScrollAdapter as u}from"./_adapter.js";import{createAxis1D as d}from"./_axis1d.js";import{alignOffset as f}from"./_alignment.js";function p(p,m){typeof m.estimateRowSize==`number`&&c(m.estimateRowSize,`estimateRowSize`),typeof m.estimateColSize==`number`&&c(m.estimateColSize,`estimateColSize`),m.initialScrollTop!==void 0&&s(m.initialScrollTop,`initialScrollTop`),m.initialScrollLeft!==void 0&&s(m.initialScrollLeft,`initialScrollLeft`),m.rowGap!==void 0&&o(m.rowGap,`rowGap`),m.colGap!==void 0&&o(m.colGap,`colGap`),m.overscanY!==void 0&&l(m.overscanY,`overscanY`),m.overscanX!==void 0&&l(m.overscanX,`overscanX`);let h=o(m.rowCount,`rowCount`),g=o(m.colCount,`colCount`),_=r(m.estimateRowSize,36),v=r(m.estimateColSize,36),y=t(m.overscanY,3),b=t(m.overscanX,3),x=m.
|
|
1
|
+
import{createSnapshotStore as e,normalizeOverscan as t,observeResize as n,resolveEstimateFn as r,toNonNegativeInt as i,toPositiveNumber as a}from"./_utils.js";import{requireNonNegativeInteger as o,requireNonNegativeNumber as s,requirePositiveNumber as c,validateOverscan as l}from"./_validation.js";import{createScrollAdapter as u}from"./_adapter.js";import{createAxis1D as d}from"./_axis1d.js";import{alignOffset as f}from"./_alignment.js";function p(p,m){typeof m.estimateRowSize==`number`&&c(m.estimateRowSize,`estimateRowSize`),typeof m.estimateColSize==`number`&&c(m.estimateColSize,`estimateColSize`),m.initialScrollTop!==void 0&&s(m.initialScrollTop,`initialScrollTop`),m.initialScrollLeft!==void 0&&s(m.initialScrollLeft,`initialScrollLeft`),m.rowGap!==void 0&&o(m.rowGap,`rowGap`),m.colGap!==void 0&&o(m.colGap,`colGap`),m.overscanY!==void 0&&l(m.overscanY,`overscanY`),m.overscanX!==void 0&&l(m.overscanX,`overscanX`);let h=o(m.rowCount,`rowCount`),g=o(m.colCount,`colCount`),_=r(m.estimateRowSize,36),v=r(m.estimateColSize,36),y=t(m.overscanY,3),b=t(m.overscanX,3),x=m.onChange,S=m.onRangeChange;function C(e){M.publish(e),x?.(e)}let w=m.rowMeasurementCache??new Map,T=m.colMeasurementCache??new Map,E=0,D=0,O=0,k=0,A=[],j=[],M=e({cols:j,rows:A,totalHeight:0,totalWidth:0}),N=!1,P=d(h,e=>w.get(e)??_(e),i(m.rowGap??0)),F=d(g,e=>T.get(e)??v(e),i(m.colGap??0)),I=!1;function L(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,P.totalSize-O),Math.max(0,t))}function R(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,F.totalSize-k),Math.max(0,t))}function z(){if(N)return;let e=P.totalSize,t=F.totalSize;if(h===0||g===0||O<=0||k<=0){(P.prevStart!==-1||P.prevTotalSize!==e||F.prevTotalSize!==t)&&(P.commitDedup(-1,-1),F.commitDedup(-1,-1),A=[],j=[],C({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:n,renderStart:r}=P.computeRange(E,E+O,y.start,y.end),{renderEnd:i,renderStart:a}=F.computeRange(D,D+k,b.start,b.end),o=P.isDedupSame(r,n),s=F.isDedupSame(a,i);if(o&&s)return;P.commitDedup(r,n),F.commitDedup(a,i),(!o||!s)&&S&&S({firstCol:a,firstRow:r,lastCol:i,lastRow:n});let c=[];for(let e=r;e<=n;e++)c.push(P.itemAt(e));let l=[];for(let e=a;e<=i;e++)l.push(F.itemAt(e));A=c,j=l,C({cols:j,rows:A,totalHeight:e,totalWidth:t})}function B(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=h)return!1;let r=a(t,-1);return r<=0||w.get(n)===r?!1:(w.set(n,r),P.markChanged(n),!0)}function V(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=g)return!1;let r=a(t,-1);return r<=0||T.get(n)===r?!1:(T.set(n,r),F.markChanged(n),!0)}function H(){I||(I=!0,queueMicrotask(()=>{I=!1;let e=P.consumeMinChangedIndex();e!==1/0&&P.rebuildFrom(e);let t=F.consumeMinChangedIndex();t!==1/0&&F.rebuildFrom(t),z()}))}function U(e,t){N||B(e,t)&&H()}function W(e,t){N||V(e,t)&&H()}function G(e,t){if(N)return;let n=!1;for(let{index:t,size:r}of e)B(t,r)&&(n=!0);for(let{index:e,size:r}of t)V(e,r)&&(n=!0);n&&H()}function K(e,t){return N?()=>{}:n(Z.signal,t,t=>U(e,t.contentRect.height))}function q(e,t){return N?()=>{}:n(Z.signal,t,t=>W(e,t.contentRect.width))}function J(){N||(w.clear(),T.clear(),P.rebuild(!0),F.rebuild(!0),z())}function Y(){N||(P.rebuild(!0),F.rebuild(!0),z())}function X(e){if(N)return;let t=i(e);if(t===0)return;h+=t,P.setCount(h),P.rebuild(!0);let n=P.startAt(t),r=L(E+n);$.scrollTo(D,r,`auto`),E=r,z()}function ee(e,t={}){if(N||h===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),h-1)),r=t.behavior??`auto`,i=P.startAt(n),a=P.sizeAt(n),o=f(i,i+a,a,E,O,t.rowAlign??`auto`);o!==null&&$.scrollTo(D,L(o),r)}function te(e,t={}){if(N||g===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),g-1)),r=t.behavior??`auto`,i=F.startAt(n),a=F.sizeAt(n),o=f(i,i+a,a,D,k,t.colAlign??`auto`);o!==null&&$.scrollTo(R(o),E,r)}function ne(e,t,n={}){if(N||h===0||g===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),h-1)),i=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),g-1)),a=n.behavior??`auto`,o=P.startAt(r),s=P.sizeAt(r),c=F.startAt(i),l=F.sizeAt(i),u=f(o,o+s,s,E,O,n.rowAlign??`auto`),d=f(c,c+l,l,D,k,n.colAlign??`auto`);(u!==null||d!==null)&&$.scrollTo(d===null?D:R(d),u===null?E:L(u),a)}function re(e){if(N)return;e.rowCount!==void 0&&o(e.rowCount,`rowCount`),e.colCount!==void 0&&o(e.colCount,`colCount`),typeof e.estimateRowSize==`number`&&c(e.estimateRowSize,`estimateRowSize`),typeof e.estimateColSize==`number`&&c(e.estimateColSize,`estimateColSize`),e.rowGap!==void 0&&o(e.rowGap,`rowGap`),e.colGap!==void 0&&o(e.colGap,`colGap`),e.overscanY!==void 0&&l(e.overscanY,`overscanY`),e.overscanX!==void 0&&l(e.overscanX,`overscanX`);let n=!1,i=!1,a=!1;if(Object.hasOwn(e,`onChange`)&&(x=e.onChange),Object.hasOwn(e,`onRangeChange`)&&(S=e.onRangeChange),e.rowCount!==void 0){let t=e.rowCount;t!==h&&(h=t,P.setCount(h),n=!0)}if(e.colCount!==void 0){let t=e.colCount;t!==g&&(g=t,F.setCount(g),i=!0)}if(e.rowGap!==void 0){let t=e.rowGap;t!==P.gap&&(P.setGap(t),n=!0)}if(e.colGap!==void 0){let t=e.colGap;t!==F.gap&&(F.setGap(t),i=!0)}if(`estimateRowSize`in e&&(_=r(e.estimateRowSize,36),w.clear(),n=!0),`estimateColSize`in e&&(v=r(e.estimateColSize,36),T.clear(),i=!0),e.overscanY!==void 0){let n=t(e.overscanY,3);(n.start!==y.start||n.end!==y.end)&&(y=n,a=!0)}if(e.overscanX!==void 0){let n=t(e.overscanX,3);(n.start!==b.start||n.end!==b.end)&&(b=n,a=!0)}n&&P.rebuild(!0),i&&F.rebuild(!0),(n||i||a)&&z()}let Z=new AbortController;function Q(){N||(N=!0,M.dispose(),Z.abort(),$.detach())}function ie(){E=L($.y.readOffset()),D=R($.x.readOffset()),z()}function ae(){O=$.y.readViewportSize(),k=$.x.readViewportSize(),z()}let $=u(p,ie,ae);return P.rebuild(!0),F.rebuild(!0),O=$.y.readViewportSize(),k=$.x.readViewportSize(),m.initialScrollTop===void 0?m.initialScrollLeft!==void 0&&$.scrollTo(R(m.initialScrollLeft),0,`auto`):$.scrollTo(m.initialScrollLeft??0,L(m.initialScrollTop),`auto`),E=L($.y.readOffset()),D=R($.x.readOffset()),z(),{get cols(){return j},get disposalSignal(){return Z.signal},dispose:Q,get disposed(){return N},getSnapshot:M.getSnapshot,invalidate:J,measureBatch:G,measureColEl:q,measureColumn:W,measureRow:U,measureRowEl:K,prependRows:X,refresh:Y,get rows(){return A},get scrollLeft(){return D},scrollToCell:ne,scrollToColumn:te,get scrollTop(){return E},scrollToRow:ee,subscribe:M.subscribe,[Symbol.dispose]:Q,get totalHeight(){return P.totalSize},get totalWidth(){return F.totalSize},update:re}}export{p as createGridVirtualizer};
|
|
2
2
|
//# sourceMappingURL=grid-virtualizer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grid-virtualizer.js","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { alignOffset } from './_alignment';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n createSnapshotStore,\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n type Overscan,\n observeResize,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\nimport {\n requireNonNegativeInteger,\n requireNonNegativeNumber,\n requirePositiveNumber,\n validateOverscan,\n} from './_validation';\nimport type { ScrollStore } from './virtualizer';\n\nexport type { VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n colGap?: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /** Enable keyboard navigation (Arrow/Page/Home/End keys). */\n keyboardScroll?: boolean;\n /** Called after every render cycle with the new state. Replace through `update()`. */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n rowGap?: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n keyboardScroll?: boolean;\n onChange?: ((state: GridVirtualizerState) => void) | undefined;\n onRangeChange?: ((range: GridRangeChangeEvent) => void) | undefined;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer extends ScrollStore<GridVirtualizerState> {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n dispose: () => void;\n readonly disposed: boolean;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n readonly scrollTop: number;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n readonly totalHeight: number;\n readonly totalWidth: number;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n if (typeof options.estimateRowSize === 'number') requirePositiveNumber(options.estimateRowSize, 'estimateRowSize');\n\n if (typeof options.estimateColSize === 'number') requirePositiveNumber(options.estimateColSize, 'estimateColSize');\n\n if (options.initialScrollTop !== undefined) requireNonNegativeNumber(options.initialScrollTop, 'initialScrollTop');\n\n if (options.initialScrollLeft !== undefined) requireNonNegativeNumber(options.initialScrollLeft, 'initialScrollLeft');\n\n if (options.rowGap !== undefined) requireNonNegativeInteger(options.rowGap, 'rowGap');\n\n if (options.colGap !== undefined) requireNonNegativeInteger(options.colGap, 'colGap');\n\n if (options.overscanY !== undefined) validateOverscan(options.overscanY, 'overscanY');\n\n if (options.overscanX !== undefined) validateOverscan(options.overscanX, 'overscanX');\n\n let rowCount = requireNonNegativeInteger(options.rowCount, 'rowCount');\n let colCount = requireNonNegativeInteger(options.colCount, 'colCount');\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n let keyboardScrollEnabled = options.keyboardScroll ?? false;\n\n let onChange = options.onChange;\n let onRangeChange = options.onRangeChange;\n\n // Publish state before invoking the render callback.\n function emitState(state: GridVirtualizerState): void {\n stateStore.publish(state);\n onChange?.(state);\n }\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n const stateStore = createSnapshotStore<GridVirtualizerState>({ cols, rows, totalHeight: 0, totalWidth: 0 });\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n emitState({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n emitState({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n if (next.rowCount !== undefined) requireNonNegativeInteger(next.rowCount, 'rowCount');\n\n if (next.colCount !== undefined) requireNonNegativeInteger(next.colCount, 'colCount');\n\n if (typeof next.estimateRowSize === 'number') requirePositiveNumber(next.estimateRowSize, 'estimateRowSize');\n\n if (typeof next.estimateColSize === 'number') requirePositiveNumber(next.estimateColSize, 'estimateColSize');\n\n if (next.rowGap !== undefined) requireNonNegativeInteger(next.rowGap, 'rowGap');\n\n if (next.colGap !== undefined) requireNonNegativeInteger(next.colGap, 'colGap');\n\n if (next.overscanY !== undefined) validateOverscan(next.overscanY, 'overscanY');\n\n if (next.overscanX !== undefined) validateOverscan(next.overscanX, 'overscanX');\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (Object.hasOwn(next, 'onChange')) onChange = next.onChange;\n\n if (Object.hasOwn(next, 'onRangeChange')) onRangeChange = next.onRangeChange;\n\n if (next.rowCount !== undefined) {\n const n = next.rowCount;\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = next.colCount;\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = next.rowGap;\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = next.colGap;\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (Object.hasOwn(next, 'keyboardScroll')) {\n keyboardScrollEnabled = next.keyboardScroll ?? false;\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n stateStore.dispose();\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n // ─── Keyboard scroll support ──────────────────────────────────────────────────\n\n if (keyboardScrollEnabled) {\n const handleKeyDown = (e: Event): void => {\n if (disposed) return;\n if (!(e instanceof KeyboardEvent)) return;\n if (rowCount === 0 || colCount === 0) return;\n\n let handled = false;\n let newTop = scrollTop;\n let newLeft = scrollLeft;\n const pageScrollSize = Math.max(viewportHeight * 0.8, viewportHeight - 100);\n const rowStepSize =\n (typeof estimateRowFn(0) === 'number' ? estimateRowFn(0) : DEFAULT_ESTIMATE_SIZE) +\n toNonNegativeInt(options.rowGap ?? 0);\n const colStepSize =\n (typeof estimateColFn(0) === 'number' ? estimateColFn(0) : DEFAULT_ESTIMATE_SIZE) +\n toNonNegativeInt(options.colGap ?? 0);\n\n switch (e.key) {\n case 'ArrowUp':\n newTop = Math.max(0, scrollTop - rowStepSize);\n handled = true;\n break;\n case 'ArrowDown':\n newTop = Math.min(rowAx.totalSize - viewportHeight, scrollTop + rowStepSize);\n handled = true;\n break;\n case 'ArrowLeft':\n newLeft = Math.max(0, scrollLeft - colStepSize);\n handled = true;\n break;\n case 'ArrowRight':\n newLeft = Math.min(colAx.totalSize - viewportWidth, scrollLeft + colStepSize);\n handled = true;\n break;\n case 'PageUp':\n newTop = Math.max(0, scrollTop - pageScrollSize);\n handled = true;\n break;\n case 'PageDown':\n newTop = Math.min(rowAx.totalSize - viewportHeight, scrollTop + pageScrollSize);\n handled = true;\n break;\n case 'Home':\n newTop = 0;\n handled = true;\n break;\n case 'End':\n newTop = Math.max(0, rowAx.totalSize - viewportHeight);\n handled = true;\n break;\n }\n\n if (handled) {\n e.preventDefault();\n adapter.scrollTo(newLeft, newTop, 'auto');\n scrollTop = clampTop(newTop);\n scrollLeft = clampLeft(newLeft);\n if (!disposed) computeVisible();\n }\n };\n\n if (typeof target === 'object' && target !== null && 'addEventListener' in target) {\n (target as EventTarget).addEventListener('keydown', handleKeyDown);\n ac.signal.addEventListener('abort', () => {\n (target as EventTarget).removeEventListener('keydown', handleKeyDown);\n });\n }\n }\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n getSnapshot: stateStore.getSnapshot,\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n subscribe: stateStore.subscribe,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grid-virtualizer.js","names":[],"sources":["../src/grid-virtualizer.ts"],"sourcesContent":["import { createScrollAdapter } from './_adapter';\nimport { alignOffset } from './_alignment';\nimport { createAxis1D, type VirtualItem } from './_axis1d';\nimport {\n createSnapshotStore,\n DEFAULT_ESTIMATE_SIZE,\n DEFAULT_OVERSCAN,\n normalizeOverscan,\n type Overscan,\n observeResize,\n resolveEstimateFn,\n type ScrollTarget,\n toNonNegativeInt,\n toPositiveNumber,\n} from './_utils';\nimport {\n requireNonNegativeInteger,\n requireNonNegativeNumber,\n requirePositiveNumber,\n validateOverscan,\n} from './_validation';\nimport type { ScrollStore } from './virtualizer';\n\nexport type { VirtualItem };\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface GridVirtualizerState {\n /**\n * Visible column descriptors.\n * Callers form the cross-product `rows × cols` as needed — no O(r×c) Cell\n * allocation per scroll tick (R8).\n */\n readonly cols: VirtualItem[];\n /** Visible row descriptors. */\n readonly rows: VirtualItem[];\n readonly totalHeight: number;\n readonly totalWidth: number;\n}\n\nexport interface GridRangeChangeEvent {\n firstCol: number;\n firstRow: number;\n lastCol: number;\n lastRow: number;\n}\n\nexport interface ScrollToCellOptions {\n behavior?: ScrollBehavior;\n colAlign?: 'auto' | 'center' | 'end' | 'start';\n rowAlign?: 'auto' | 'center' | 'end' | 'start';\n}\n\nexport interface GridVirtualizerOptions {\n colCount: number;\n colGap?: number;\n /** External measurement cache for columns. Share across instances for scroll restoration. */\n colMeasurementCache?: Map<number, number>;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n initialScrollLeft?: number;\n initialScrollTop?: number;\n /** Called after every render cycle with the new state. Replace through `update()`. */\n onChange?: (state: GridVirtualizerState) => void;\n /** Zero-allocation alternative to onChange for range-based consumers. */\n onRangeChange?: (range: GridRangeChangeEvent) => void;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount: number;\n rowGap?: number;\n /** External measurement cache for rows. Share across instances for scroll restoration. */\n rowMeasurementCache?: Map<number, number>;\n}\n\n/**\n * Options accepted by `update()`. Explicit interface instead of\n * `Partial<Omit<...>>` for better IDE hover (R7).\n */\nexport interface GridVirtualizerUpdateOptions {\n colCount?: number;\n colGap?: number;\n estimateColSize?: number | ((col: number) => number);\n estimateRowSize?: number | ((row: number) => number);\n onChange?: ((state: GridVirtualizerState) => void) | undefined;\n onRangeChange?: ((range: GridRangeChangeEvent) => void) | undefined;\n overscanX?: Overscan;\n overscanY?: Overscan;\n rowCount?: number;\n rowGap?: number;\n}\n\nexport interface GridVirtualizer extends ScrollStore<GridVirtualizerState> {\n readonly cols: VirtualItem[];\n readonly disposalSignal: AbortSignal;\n dispose: () => void;\n readonly disposed: boolean;\n invalidate: () => void;\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n measureBatch: (rows: Array<{ index: number; size: number }>, cols: Array<{ index: number; size: number }>) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the column width on resize. Returns disconnect fn. */\n measureColEl: (col: number, el: HTMLElement) => () => void;\n measureColumn: (col: number, size: number) => void;\n measureRow: (row: number, size: number) => void;\n /** Attach a ResizeObserver to `el` to auto-measure the row height on resize. Returns disconnect fn. */\n measureRowEl: (row: number, el: HTMLElement) => () => void;\n /** Prepend `additionalRowCount` rows at the top while keeping the viewport visually stable. */\n prependRows: (additionalRowCount: number) => void;\n refresh: () => void;\n readonly rows: VirtualItem[];\n readonly scrollLeft: number;\n scrollToCell: (row: number, col: number, options?: ScrollToCellOptions) => void;\n /** Scroll to bring a row into view without changing the horizontal position. */\n scrollToColumn: (col: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'>) => void;\n readonly scrollTop: number;\n /** Scroll to bring a column into view without changing the vertical position. */\n scrollToRow: (row: number, options?: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'>) => void;\n readonly totalHeight: number;\n readonly totalWidth: number;\n update: (next: GridVirtualizerUpdateOptions) => void;\n [Symbol.dispose]: () => void;\n}\n\n// ─── Implementation ────────────────────────────────────────────────────────────\n\nexport function createGridVirtualizer(target: ScrollTarget, options: GridVirtualizerOptions): GridVirtualizer {\n if (typeof options.estimateRowSize === 'number') requirePositiveNumber(options.estimateRowSize, 'estimateRowSize');\n\n if (typeof options.estimateColSize === 'number') requirePositiveNumber(options.estimateColSize, 'estimateColSize');\n\n if (options.initialScrollTop !== undefined) requireNonNegativeNumber(options.initialScrollTop, 'initialScrollTop');\n\n if (options.initialScrollLeft !== undefined) requireNonNegativeNumber(options.initialScrollLeft, 'initialScrollLeft');\n\n if (options.rowGap !== undefined) requireNonNegativeInteger(options.rowGap, 'rowGap');\n\n if (options.colGap !== undefined) requireNonNegativeInteger(options.colGap, 'colGap');\n\n if (options.overscanY !== undefined) validateOverscan(options.overscanY, 'overscanY');\n\n if (options.overscanX !== undefined) validateOverscan(options.overscanX, 'overscanX');\n\n let rowCount = requireNonNegativeInteger(options.rowCount, 'rowCount');\n let colCount = requireNonNegativeInteger(options.colCount, 'colCount');\n let estimateRowFn = resolveEstimateFn(options.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n let estimateColFn = resolveEstimateFn(options.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n let overscanY = normalizeOverscan(options.overscanY, DEFAULT_OVERSCAN);\n let overscanX = normalizeOverscan(options.overscanX, DEFAULT_OVERSCAN);\n\n let onChange = options.onChange;\n let onRangeChange = options.onRangeChange;\n\n // Publish state before invoking the render callback.\n function emitState(state: GridVirtualizerState): void {\n stateStore.publish(state);\n onChange?.(state);\n }\n\n // External or internal measurement caches (numeric row/col index keys).\n const measuredRows: Map<number, number> = options.rowMeasurementCache ?? new Map();\n const measuredCols: Map<number, number> = options.colMeasurementCache ?? new Map();\n\n let scrollTop = 0;\n let scrollLeft = 0;\n let viewportHeight = 0;\n let viewportWidth = 0;\n let rows: VirtualItem[] = [];\n let cols: VirtualItem[] = [];\n const stateStore = createSnapshotStore<GridVirtualizerState>({ cols, rows, totalHeight: 0, totalWidth: 0 });\n let disposed = false;\n\n // ─── Axis1D instances (R1) ─────────────────────────────────────────────────\n // sizeAt closures capture live `measuredRows/Cols` and `estimateFn` vars.\n\n const rowAx = createAxis1D(\n rowCount,\n (r) => measuredRows.get(r) ?? estimateRowFn(r),\n toNonNegativeInt(options.rowGap ?? 0),\n );\n\n const colAx = createAxis1D(\n colCount,\n (c) => measuredCols.get(c) ?? estimateColFn(c),\n toNonNegativeInt(options.colGap ?? 0),\n );\n\n // R4: Single coordinated flush flag — prevents two separate microtasks.\n let pendingBatchBuild = false;\n\n // ─── Clamping ──────────────────────────────────────────────────────────────\n\n function clampTop(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, rowAx.totalSize - viewportHeight), Math.max(0, safe));\n }\n\n function clampLeft(offset: number): number {\n const safe = Number.isFinite(offset) ? offset : 0;\n\n return Math.min(Math.max(0, colAx.totalSize - viewportWidth), Math.max(0, safe));\n }\n\n // ─── Compute and emit ──────────────────────────────────────────────────────\n\n function computeVisible(): void {\n if (disposed) return;\n\n const totalHeight = rowAx.totalSize;\n const totalWidth = colAx.totalSize;\n\n if (rowCount === 0 || colCount === 0 || viewportHeight <= 0 || viewportWidth <= 0) {\n const wasEmpty =\n rowAx.prevStart === -1 && rowAx.prevTotalSize === totalHeight && colAx.prevTotalSize === totalWidth;\n\n if (!wasEmpty) {\n // commitDedup(-1, -1) captures the current totalSize so the guard doesn't\n // fire on every subsequent event while the empty state persists (Bug 2).\n rowAx.commitDedup(-1, -1);\n colAx.commitDedup(-1, -1);\n rows = [];\n cols = [];\n emitState({ cols: [], rows: [], totalHeight, totalWidth });\n }\n\n return;\n }\n\n const { renderEnd: renderLastRow, renderStart: renderFirstRow } = rowAx.computeRange(\n scrollTop,\n scrollTop + viewportHeight,\n overscanY.start,\n overscanY.end,\n );\n\n const { renderEnd: renderLastCol, renderStart: renderFirstCol } = colAx.computeRange(\n scrollLeft,\n scrollLeft + viewportWidth,\n overscanX.start,\n overscanX.end,\n );\n\n const rowSame = rowAx.isDedupSame(renderFirstRow, renderLastRow);\n const colSame = colAx.isDedupSame(renderFirstCol, renderLastCol);\n\n if (rowSame && colSame) return;\n\n rowAx.commitDedup(renderFirstRow, renderLastRow);\n colAx.commitDedup(renderFirstCol, renderLastCol);\n\n const rangeChanged = !rowSame || !colSame;\n\n if (rangeChanged && onRangeChange) {\n onRangeChange({\n firstCol: renderFirstCol,\n firstRow: renderFirstRow,\n lastCol: renderLastCol,\n lastRow: renderLastRow,\n });\n }\n\n // R8: Build rows[] and cols[] separately — no cross-product VirtualCell[].\n const nextRows: VirtualItem[] = [];\n\n for (let r = renderFirstRow; r <= renderLastRow; r++) {\n nextRows.push(rowAx.itemAt(r));\n }\n\n const nextCols: VirtualItem[] = [];\n\n for (let c = renderFirstCol; c <= renderLastCol; c++) {\n nextCols.push(colAx.itemAt(c));\n }\n\n rows = nextRows;\n cols = nextCols;\n\n emitState({ cols, rows, totalHeight, totalWidth });\n }\n\n // ─── Measurement helpers ───────────────────────────────────────────────────\n\n function recordRowMeasurement(row: number, size: number): boolean {\n if (!Number.isFinite(row)) return false;\n\n const r = Math.floor(row);\n\n if (r < 0 || r >= rowCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredRows.get(r) === s) return false;\n\n measuredRows.set(r, s);\n rowAx.markChanged(r);\n\n return true;\n }\n\n function recordColMeasurement(col: number, size: number): boolean {\n if (!Number.isFinite(col)) return false;\n\n const c = Math.floor(col);\n\n if (c < 0 || c >= colCount) return false;\n\n const s = toPositiveNumber(size, -1);\n\n if (s <= 0) return false;\n\n if (measuredCols.get(c) === s) return false;\n\n measuredCols.set(c, s);\n colAx.markChanged(c);\n\n return true;\n }\n\n /**\n * R4: Single coordinated flush for both axes.\n * Replaces the previous two independent microtask schedules.\n */\n function scheduleFlush(): void {\n if (pendingBatchBuild) return;\n\n pendingBatchBuild = true;\n queueMicrotask(() => {\n pendingBatchBuild = false;\n\n // consumeMinChangedIndex() atomically reads and resets minChangedIndex.\n // Without the reset, every subsequent flush would rebuild from index 0\n // instead of the actual earliest changed index (Bug 3).\n const fromRow = rowAx.consumeMinChangedIndex();\n\n if (fromRow !== Infinity) rowAx.rebuildFrom(fromRow);\n\n const fromCol = colAx.consumeMinChangedIndex();\n\n if (fromCol !== Infinity) colAx.rebuildFrom(fromCol);\n\n computeVisible();\n });\n }\n\n // ─── Public measurement API ────────────────────────────────────────────────\n\n function measureRow(row: number, size: number): void {\n if (disposed) return;\n\n if (recordRowMeasurement(row, size)) scheduleFlush();\n }\n\n function measureColumn(col: number, size: number): void {\n if (disposed) return;\n\n if (recordColMeasurement(col, size)) scheduleFlush();\n }\n\n /** Measure rows and columns in a single coordinated rebuild pass (R4). */\n function measureBatch(\n rowEntries: Array<{ index: number; size: number }>,\n colEntries: Array<{ index: number; size: number }>,\n ): void {\n if (disposed) return;\n\n let changed = false;\n\n for (const { index, size } of rowEntries) {\n if (recordRowMeasurement(index, size)) changed = true;\n }\n\n for (const { index, size } of colEntries) {\n if (recordColMeasurement(index, size)) changed = true;\n }\n\n if (changed) scheduleFlush();\n }\n\n function measureRowEl(row: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureRow(row, entry.contentRect.height));\n }\n\n function measureColEl(col: number, el: HTMLElement): () => void {\n if (disposed) return () => {};\n\n return observeResize(ac.signal, el, (entry) => measureColumn(col, entry.contentRect.width));\n }\n\n function invalidate(): void {\n if (disposed) return;\n\n measuredRows.clear();\n measuredCols.clear();\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function refresh(): void {\n if (disposed) return;\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n computeVisible();\n }\n\n function prependRows(additionalRowCount: number): void {\n if (disposed) return;\n\n const n = toNonNegativeInt(additionalRowCount);\n\n if (n === 0) return;\n\n rowCount += n;\n rowAx.setCount(rowCount);\n rowAx.rebuild(true);\n\n const prependedHeight = rowAx.startAt(n);\n const newScrollTop = clampTop(scrollTop + prependedHeight);\n\n adapter.scrollTo(scrollLeft, newScrollTop, 'auto');\n scrollTop = newScrollTop;\n\n computeVisible();\n }\n\n function scrollToRow(row: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'rowAlign'> = {}): void {\n if (disposed || rowCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n\n if (targetTop === null) return;\n\n adapter.scrollTo(scrollLeft, clampTop(targetTop), behavior);\n }\n\n function scrollToColumn(col: number, opts: Pick<ScrollToCellOptions, 'behavior' | 'colAlign'> = {}): void {\n if (disposed || colCount === 0) return;\n\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetLeft === null) return;\n\n adapter.scrollTo(clampLeft(targetLeft), scrollTop, behavior);\n }\n\n function scrollToCell(row: number, col: number, opts: ScrollToCellOptions = {}): void {\n if (disposed || rowCount === 0 || colCount === 0) return;\n\n const safeRow = Math.max(0, Math.min(Math.floor(Number.isFinite(row) ? row : 0), rowCount - 1));\n const safeCol = Math.max(0, Math.min(Math.floor(Number.isFinite(col) ? col : 0), colCount - 1));\n const behavior = opts.behavior ?? 'auto';\n\n const rowStart = rowAx.startAt(safeRow);\n const rowSize = rowAx.sizeAt(safeRow);\n const colStart = colAx.startAt(safeCol);\n const colSize = colAx.sizeAt(safeCol);\n\n const targetTop = alignOffset(\n rowStart,\n rowStart + rowSize,\n rowSize,\n scrollTop,\n viewportHeight,\n opts.rowAlign ?? 'auto',\n );\n const targetLeft = alignOffset(\n colStart,\n colStart + colSize,\n colSize,\n scrollLeft,\n viewportWidth,\n opts.colAlign ?? 'auto',\n );\n\n if (targetTop === null && targetLeft === null) return;\n\n adapter.scrollTo(\n targetLeft !== null ? clampLeft(targetLeft) : scrollLeft,\n targetTop !== null ? clampTop(targetTop) : scrollTop,\n behavior,\n );\n }\n\n function update(next: GridVirtualizerUpdateOptions): void {\n if (disposed) return;\n\n if (next.rowCount !== undefined) requireNonNegativeInteger(next.rowCount, 'rowCount');\n\n if (next.colCount !== undefined) requireNonNegativeInteger(next.colCount, 'colCount');\n\n if (typeof next.estimateRowSize === 'number') requirePositiveNumber(next.estimateRowSize, 'estimateRowSize');\n\n if (typeof next.estimateColSize === 'number') requirePositiveNumber(next.estimateColSize, 'estimateColSize');\n\n if (next.rowGap !== undefined) requireNonNegativeInteger(next.rowGap, 'rowGap');\n\n if (next.colGap !== undefined) requireNonNegativeInteger(next.colGap, 'colGap');\n\n if (next.overscanY !== undefined) validateOverscan(next.overscanY, 'overscanY');\n\n if (next.overscanX !== undefined) validateOverscan(next.overscanX, 'overscanX');\n\n let rebuildRows = false;\n let rebuildCols = false;\n let needsCompute = false;\n\n if (Object.hasOwn(next, 'onChange')) onChange = next.onChange;\n\n if (Object.hasOwn(next, 'onRangeChange')) onRangeChange = next.onRangeChange;\n\n if (next.rowCount !== undefined) {\n const n = next.rowCount;\n\n if (n !== rowCount) {\n rowCount = n;\n rowAx.setCount(rowCount);\n rebuildRows = true;\n }\n }\n\n if (next.colCount !== undefined) {\n const n = next.colCount;\n\n if (n !== colCount) {\n colCount = n;\n colAx.setCount(colCount);\n rebuildCols = true;\n }\n }\n\n if (next.rowGap !== undefined) {\n const n = next.rowGap;\n\n if (n !== rowAx.gap) {\n rowAx.setGap(n);\n rebuildRows = true;\n }\n }\n\n if (next.colGap !== undefined) {\n const n = next.colGap;\n\n if (n !== colAx.gap) {\n colAx.setGap(n);\n rebuildCols = true;\n }\n }\n\n if ('estimateRowSize' in next) {\n estimateRowFn = resolveEstimateFn(next.estimateRowSize, DEFAULT_ESTIMATE_SIZE);\n measuredRows.clear();\n rebuildRows = true;\n }\n\n if ('estimateColSize' in next) {\n estimateColFn = resolveEstimateFn(next.estimateColSize, DEFAULT_ESTIMATE_SIZE);\n measuredCols.clear();\n rebuildCols = true;\n }\n\n if (next.overscanY !== undefined) {\n const n = normalizeOverscan(next.overscanY, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanY.start || n.end !== overscanY.end) {\n overscanY = n;\n needsCompute = true;\n }\n }\n\n if (next.overscanX !== undefined) {\n const n = normalizeOverscan(next.overscanX, DEFAULT_OVERSCAN);\n\n if (n.start !== overscanX.start || n.end !== overscanX.end) {\n overscanX = n;\n needsCompute = true;\n }\n }\n\n if (rebuildRows) rowAx.rebuild(true);\n\n if (rebuildCols) colAx.rebuild(true);\n\n if (rebuildRows || rebuildCols || needsCompute) computeVisible();\n }\n\n const ac = new AbortController();\n\n function disposeImpl(): void {\n if (disposed) return;\n\n disposed = true;\n stateStore.dispose();\n ac.abort();\n adapter.detach();\n }\n\n // ─── Bootstrap (R9: read viewport BEFORE writing initial scroll) ───────────\n\n function handleScroll(): void {\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n computeVisible();\n }\n\n function handleResize(): void {\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n computeVisible();\n }\n\n const adapter = createScrollAdapter(target, handleScroll, handleResize);\n\n rowAx.rebuild(true);\n colAx.rebuild(true);\n\n // R9: Read viewport dimensions BEFORE writing initial scroll positions so that\n // computeVisible() sees a valid viewport on the very first call.\n viewportHeight = adapter.y.readViewportSize();\n viewportWidth = adapter.x.readViewportSize();\n\n if (options.initialScrollTop !== undefined) {\n adapter.scrollTo(options.initialScrollLeft ?? 0, clampTop(options.initialScrollTop), 'auto');\n } else if (options.initialScrollLeft !== undefined) {\n adapter.scrollTo(clampLeft(options.initialScrollLeft), 0, 'auto');\n }\n\n scrollTop = clampTop(adapter.y.readOffset());\n scrollLeft = clampLeft(adapter.x.readOffset());\n\n computeVisible();\n\n return {\n get cols() {\n return cols;\n },\n get disposalSignal() {\n return ac.signal;\n },\n dispose: disposeImpl,\n get disposed() {\n return disposed;\n },\n getSnapshot: stateStore.getSnapshot,\n invalidate,\n measureBatch,\n measureColEl,\n measureColumn,\n measureRow,\n measureRowEl,\n prependRows,\n refresh,\n get rows() {\n return rows;\n },\n get scrollLeft() {\n return scrollLeft;\n },\n scrollToCell,\n scrollToColumn,\n get scrollTop() {\n return scrollTop;\n },\n scrollToRow,\n subscribe: stateStore.subscribe,\n [Symbol.dispose]: disposeImpl,\n get totalHeight() {\n return rowAx.totalSize;\n },\n get totalWidth() {\n return colAx.totalSize;\n },\n update,\n };\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_utils.cjs"),t=require("./errors.cjs"),n=require("./virtualizer.cjs"),r=require("./dom-virtual-list.cjs"),i=require("./grid-virtualizer.cjs"),a=require("./grouped-virtualizer.cjs");exports.DEFAULT_ESTIMATE_SIZE=e.DEFAULT_ESTIMATE_SIZE,exports.DEFAULT_OVERSCAN=e.DEFAULT_OVERSCAN,exports.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./_utils.cjs"),t=require("./errors.cjs"),n=require("./virtualizer.cjs"),r=require("./dom-virtual-list.cjs"),i=require("./grid-virtualizer.cjs"),a=require("./grouped-virtualizer.cjs");exports.DEFAULT_ESTIMATE_SIZE=e.DEFAULT_ESTIMATE_SIZE,exports.DEFAULT_OVERSCAN=e.DEFAULT_OVERSCAN,exports.ScrollConfigError=t.ScrollConfigError,exports.ScrollError=t.ScrollError,exports.ScrollRangeError=t.ScrollRangeError,exports.createDomVirtualList=r.createDomVirtualList,exports.createGridVirtualizer=i.createGridVirtualizer,exports.createGroupedVirtualizer=a.createGroupedVirtualizer,exports.createMeasurementCache=e.createMeasurementCache,exports.createVirtualScroller=r.createVirtualScroller,exports.createVirtualizer=n.createVirtualizer;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { DomVirtualListController, DomVirtualListOptions, DomVirtualListRenderArgs, RecycleFn, StickToBottomOptions, VirtualRenderItem, VirtualScrollerOptions, } from './dom-virtual-list';
|
|
2
2
|
export { createDomVirtualList, createVirtualScroller } from './dom-virtual-list';
|
|
3
|
-
export {
|
|
3
|
+
export { ScrollConfigError, ScrollError, ScrollRangeError } from './errors';
|
|
4
4
|
export type { GridRangeChangeEvent, GridVirtualizer, GridVirtualizerOptions, GridVirtualizerState, GridVirtualizerUpdateOptions, ScrollToCellOptions, } from './grid-virtualizer';
|
|
5
5
|
export { createGridVirtualizer } from './grid-virtualizer';
|
|
6
6
|
export type { GroupSection, GroupVirtualHeader, GroupVirtualItem, GroupVirtualizer, GroupVirtualizerOptions, GroupVirtualizerState, GroupVirtualizerUpdateOptions, } from './grouped-virtualizer';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,SAAS,EACT,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,SAAS,EACT,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5E,YAAY,EACV,oBAAoB,EACpB,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,uBAAuB,EACvB,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,YAAY,EACV,gBAAgB,EAChB,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,wBAAwB,EACxB,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DEFAULT_ESTIMATE_SIZE as e,DEFAULT_OVERSCAN as t,createMeasurementCache as n}from"./_utils.js";import{
|
|
1
|
+
import{DEFAULT_ESTIMATE_SIZE as e,DEFAULT_OVERSCAN as t,createMeasurementCache as n}from"./_utils.js";import{ScrollConfigError as r,ScrollError as i,ScrollRangeError as a}from"./errors.js";import{createVirtualizer as o}from"./virtualizer.js";import{createDomVirtualList as s,createVirtualScroller as c}from"./dom-virtual-list.js";import{createGridVirtualizer as l}from"./grid-virtualizer.js";import{createGroupedVirtualizer as u}from"./grouped-virtualizer.js";export{e as DEFAULT_ESTIMATE_SIZE,t as DEFAULT_OVERSCAN,r as ScrollConfigError,i as ScrollError,a as ScrollRangeError,s as createDomVirtualList,l as createGridVirtualizer,u as createGroupedVirtualizer,n as createMeasurementCache,c as createVirtualScroller,o as createVirtualizer};
|
package/dist/scroll.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(){return new Map}var t=36,n=3;function r(e){let t=new Set,n=e,r=!1;return{dispose(){r=!0,t.clear()},getSnapshot(){return n},publish(e){if(!r){n=e;for(let e of[...t])try{e()}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(t.add(e),()=>t.delete(e))}}}function i(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function a(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function o(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function s(e,t){if(typeof e==`number`){let n=i(e,t);return{end:n,start:n}}return{end:i(e?.end??t),start:i(e?.start??t)}}function c(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function l(e,t){if(typeof e==`function`)return n=>{try{return a(e(n),t)}catch(e){return`${n}${e}`,t}};let n=typeof e==`number`?a(e,t):t;return()=>n}var u=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},d=class extends u{},f=class extends u{};function p(e,t){if(!Number.isFinite(e)||!Number.isInteger(e)||e<0)throw new d(`${t} must be a finite non-negative integer.`);return e}function m(e,t){if(!Number.isFinite(e)||e<0)throw new d(`${t} must be a finite non-negative number.`);return e}function h(e,t){if(!Number.isFinite(e)||e<=0||e>1e7)throw new d(`${t} must be a finite positive number no greater than 10000000.`);return e}function g(e,t=`overscan`){if(typeof e==`number`){p(e,t);return}if(typeof e!=`object`||!e||Array.isArray(e))throw new d(`${t} must be a finite non-negative integer or an overscan object.`);e.start!==void 0&&p(e.start,`${t}.start`),e.end!==void 0&&p(e.end,`${t}.end`)}function _(e,t,n){if(o(e))return e.addEventListener(`scroll`,t,{passive:!0}),e.addEventListener(`resize`,n,{passive:!0}),{detach(){e.removeEventListener(`scroll`,t),e.removeEventListener(`resize`,n)},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollX,readViewportSize:()=>e.innerWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollY,readViewportSize:()=>e.innerHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}};let r=new ResizeObserver(n);return e.addEventListener(`scroll`,t,{passive:!0}),r.observe(e),{detach(){e.removeEventListener(`scroll`,t),r.disconnect()},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollLeft,readViewportSize:()=>e.clientWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollTop,readViewportSize:()=>e.clientHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}}}function v(e,t,n){let r=e,i=n,a=t,o=[],s=0,c=-1,l=-1,u=-1,d=!1,f=1/0;function p(e){return o[e]??0}function m(e){return p(e)+a(e)}function h(e=!1){e&&(c=-1,l=-1,u=-1);let t=[0],n=0;for(let e=0;e<r;e++)n+=a(e)+(e<r-1?i:0),t.push(n);o=t,s=n}function g(e){if(!Number.isFinite(e)||e>=r)return;c=-1,l=-1,u=-1;let t=o[e]??0;for(let n=e;n<r;n++)o[n]=t,t+=a(n)+(n<r-1?i:0);o[r]=t,s=t}function _(e){let t=0,n=r-1;for(;t<n;){let r=t+n>>1;m(r)<=e?t=r+1:n=r}return t}function v(e,t){let n=t,i=r-1;for(;n<i;){let t=n+i+1>>1;p(t)<e?n=t:i=t-1}return n}function y(e,t,n,i){let a=_(e),o=v(t,a);return{renderEnd:Math.min(r-1,o+i),renderStart:Math.max(0,a-n)}}function b(e,t){return e===c&&t===l&&s===u}function x(e,t){c=e,l=t,u=s}function S(){c=-1,l=-1,u=-1}function C(e){d||(d=!0,queueMicrotask(()=>{d=!1;let t=f;f=1/0,g(t),e()}))}function w(e){e<f&&(f=e)}function T(e){let t=p(e),n=a(e);return{end:t+n,index:e,size:n,start:t}}return{commitDedup:x,computeRange:y,consumeMinChangedIndex(){let e=f;return f=1/0,e},get count(){return r},endAt:m,findFirst:_,findLast:v,get gap(){return i},isDedupSame:b,itemAt:T,markChanged:w,get minChangedIndex(){return f},get pendingBuild(){return d},get prevEnd(){return l},get prevStart(){return c},get prevTotalSize(){return u},rebuild:h,rebuildFrom:g,resetDedup:S,scheduleBuild:C,setCount(e){r=e},setGap(e){i=e},sizeAt(e){return a(e)},startAt:p,get totalSize(){return s}}}function y(e){if(!e.stickyFn||e.count===0||e.scrollOffset<=0)return[];let t=-1,n=0,r=e.count-1;for(;n<=r;){let i=n+r>>1;e.startAt(i)<e.scrollOffset?(t=i,n=i+1):r=i-1}if(t<0)return[];let i=-1;for(let n=t;n>=0;n--)if(e.stickyFn(n)){i=n;break}if(i===-1)return[];let a=e.sizeAt(i),o=1/0;for(let t=i+1;t<e.count;t++)if(e.stickyFn(t)){o=e.startAt(t);break}let s=Math.min(e.scrollOffset,o-a);return[{end:s+a,index:i,size:a,start:s}]}function b(e,t){typeof t.estimateSize==`number`&&h(t.estimateSize,`estimateSize`),t.gap!==void 0&&p(t.gap,`gap`),t.initialOffset!==void 0&&m(t.initialOffset,`initialOffset`),t.overscan!==void 0&&g(t.overscan),t.scrollEndDelay!==void 0&&m(t.scrollEndDelay,`scrollEndDelay`);let n=!!t.horizontal,o=e=>e,u=t.keyboardScroll??!1,d=p(t.count,`count`),f=l(t.estimateSize,36),b=i(t.gap??0),x=t.getItemKey??o,S=s(t.overscan,3),C=t.sticky??null,w=u,T=t.autoMeasure??!1,E=t.onChange,D=t.onScrollEnd,O=t.onScrollingChange,k=t.scrollEndDelay??150;function A(e){R.publish(e),E?.(e)}let j=null,M=`onscrollend`in e;function N(){K&&(K=!1,O?.(!1),D?.(H))}function P(){K||(K=!0,O?.(!0)),M||(j!==null&&clearTimeout(j),j=setTimeout(N,k))}let F=t.measurementCache??new Map,I=[],L=[],R=r({items:I,stickyItems:L,totalSize:0}),z=v(d,e=>F.get(x(e))??f(e),b),B=-1,V=0,H=0,U=0,W=-1,G=!1,K=!1;function q(e){let t=Number.isFinite(e)?e:0,n=Math.max(0,z.totalSize-U);return Math.min(n,Math.max(0,t))}function J(){if(G)return;if(d===0||U<=0){(z.prevStart!==-1||z.prevTotalSize!==z.totalSize)&&(z.commitDedup(-1,-1),I=[],L=[],A({items:I,stickyItems:L,totalSize:z.totalSize}));return}let{renderEnd:t,renderStart:n}=z.computeRange(H,H+U,S.start,S.end),r=C!==null&&H!==W;if(z.isDedupSame(n,t)&&!r)return;z.commitDedup(n,t),W=H;let i=[];for(let e=n;e<=t;e++)i.push(z.itemAt(e));I=i,L=C?y({count:d,scrollOffset:H,sizeAt:z.sizeAt,startAt:z.startAt,stickyFn:C}):[],A({items:I,stickyItems:L,totalSize:z.totalSize}),T&&I.length>0&&queueMicrotask(()=>{if(!(G||e instanceof Window))for(let t of I){let n=x(t.index),r=e?.querySelector?.(`[data-vz-key="${n}"]`);r instanceof HTMLElement&&Y(t.index,r)}})}function ee(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=d)return!1;let r=a(t,-1);if(r<=0)return!1;let i=x(n);return F.get(i)!==r&&(F.set(i,r),z.markChanged(n),!0)}function te(){if(H<=0||d===0){B=-1;return}B=z.findFirst(H),V=H-z.startAt(B)}function ne(){if(B<0)return;let e=z.startAt(B)+V-H;if(B=-1,Math.abs(e)>=1){let t=q(H+e);$.writeOffset(t,`auto`),H=t}}function re(e){if(G)return;let t=!1;for(let{index:n,size:r}of e)ee(n,r)&&(t=!0);t&&(z.pendingBuild||te(),z.scheduleBuild(()=>{ne(),J()}))}function ie(e,t){re([{index:e,size:t}])}function Y(e,t){return G?()=>{}:c(Q.signal,t,t=>{ie(e,n?t.contentRect.width:t.contentRect.height)})}function ae(e){e.count!==void 0&&p(e.count,`count`),typeof e.estimateSize==`number`&&h(e.estimateSize,`estimateSize`),e.gap!==void 0&&p(e.gap,`gap`),e.overscan!==void 0&&g(e.overscan),e.scrollEndDelay!==void 0&&m(e.scrollEndDelay,`scrollEndDelay`);let t=!1,n=!1;if(Object.hasOwn(e,`onChange`)&&(E=e.onChange),Object.hasOwn(e,`onScrollEnd`)&&(D=e.onScrollEnd),Object.hasOwn(e,`onScrollingChange`)&&(O=e.onScrollingChange),e.scrollEndDelay!==void 0&&(k=e.scrollEndDelay),e.count!==void 0){let n=e.count;n!==d&&(d=n,z.setCount(d),t=!0)}if(Object.hasOwn(e,`estimateSize`)&&(f=l(e.estimateSize,36),F.clear(),t=!0),e.gap!==void 0){let n=e.gap;n!==b&&(b=n,z.setGap(b),t=!0)}if(Object.hasOwn(e,`getItemKey`)){let n=e.getItemKey??o;n!==x&&(x=n,F.clear(),t=!0)}if(Object.hasOwn(e,`measurementCache`)&&e.measurementCache!==void 0&&(F=e.measurementCache,t=!0),e.overscan!==void 0){let t=s(e.overscan,3);(t.start!==S.start||t.end!==S.end)&&(S=t,n=!0)}if(Object.hasOwn(e,`sticky`)){let t=e.sticky??null;t!==C&&(C=t,z.resetDedup()),n=!0}Object.hasOwn(e,`keyboardScroll`)&&(w=e.keyboardScroll??!1),Object.hasOwn(e,`autoMeasure`)&&(T=e.autoMeasure??!1),t&&(te(),z.rebuild(!0),ne()),(n||t)&&J()}function X(){G||(F.clear(),z.rebuild(!0),J())}function oe(){G||(z.rebuild(!0),J())}function se(e){if(G)return;let t=i(e);if(t===0)return;d+=t,z.setCount(d),z.rebuild(!0);let n=z.startAt(t),r=q(H+n);$.writeOffset(r,`auto`),H=r,J()}function ce(e){G||ae(e)}function Z(t,n={}){if(G||d<=0)return;let r=Math.max(0,Math.min(Number.isFinite(t)?Math.floor(t):0,d-1)),i=n.align??`auto`,a=n.behavior??`auto`,o=z.startAt(r),s=z.sizeAt(r),c=o+s,l;if(i===`start`)l=o;else if(i===`end`)l=c-U;else if(i===`center`)l=o-(U-s)/2;else{let e=H,t=e+U;if(o>=e&&c<=t){n.onComplete&&queueMicrotask(n.onComplete);return}l=o<e?o:c-U}$.writeOffset(q(l),a),n.onComplete&&(a===`smooth`&&`onscrollend`in e?e.addEventListener(`scrollend`,n.onComplete,{once:!0}):queueMicrotask(n.onComplete))}function le(e,t={}){G||$.writeOffset(q(e),t.behavior??`auto`)}function ue(e={}){le(0,e)}function de(e={}){le(Math.max(0,z.totalSize-U),e)}function fe(e=0){return z.totalSize-(H+U)<=e}let Q=new AbortController;function pe(){G||(G=!0,R.dispose(),Q.abort(),j!==null&&(clearTimeout(j),j=null),M&&e.removeEventListener(`scrollend`,N),ge.detach())}function me(){H=q($.readOffset()),P(),J()}function he(){U=$.readViewportSize(),J()}let ge=_(e,me,he),$=n?ge.x:ge.y;if(w){let t=e=>{if(G||!(e instanceof KeyboardEvent)||d===0)return;let t=!1,n=H,r=Math.max(U*.8,U-100);switch(e.key){case`ArrowUp`:case`ArrowLeft`:{let e=typeof f(0)==`number`?f(0):36;n=Math.max(0,H-(e+b)),t=!0;break}case`ArrowDown`:case`ArrowRight`:{let e=typeof f(0)==`number`?f(0):36;n=Math.min(z.totalSize-U,H+(e+b)),t=!0;break}case`PageUp`:n=Math.max(0,H-r),t=!0;break;case`PageDown`:n=Math.min(z.totalSize-U,H+r),t=!0;break;case`Home`:n=0,t=!0;break;case`End`:n=Math.max(0,z.totalSize-U),t=!0}t&&(e.preventDefault(),$.writeOffset(n,`auto`),H=q(n),J())};typeof e==`object`&&e&&`addEventListener`in e&&(e.addEventListener(`keydown`,t),Q.signal.addEventListener(`abort`,()=>{e.removeEventListener(`keydown`,t)}))}return M&&e.addEventListener(`scrollend`,N,{passive:!0}),z.rebuild(!0),t.initialOffset!==void 0&&$.writeOffset(q(t.initialOffset),`auto`),H=q($.readOffset()),U=$.readViewportSize(),J(),{get count(){return d},get disposalSignal(){return Q.signal},dispose:pe,get disposed(){return G},getSnapshot:R.getSnapshot,invalidate:X,isAtEnd:fe,get isScrolling(){return K},get items(){return I},measure:ie,measureBatch:re,measureEl:Y,prepend:se,refresh:oe,get scrollOffset(){return H},scrollToBottom:de,scrollToIndex:Z,scrollToOffset:le,scrollToTop:ue,get stickyItems(){return L},subscribe:R.subscribe,[Symbol.dispose]:pe,get totalSize(){return z.totalSize},update:ce}}function x(){let e=new Map,t=new Map,n=[],r=!1;return{acquire(i,a){if(!r)return a();let o=e.get(i);if(o)return t.set(i,o),o;let s=n.pop()??a();return t.set(i,s),s},beginCycle(){t=new Map,r=!0},clear(){for(let t of e.values())t.remove();e.clear(),t.clear(),n.length=0,r=!1},endCycle(){if(r){r=!1;for(let[r,i]of e)t.has(r)||(i.remove(),n.push(i));e=t}}}}function S(e){if(typeof e.estimateSize==`number`&&h(e.estimateSize,`estimateSize`),e.gap!==void 0&&p(e.gap,`gap`),e.overscan!==void 0&&g(e.overscan),e.stickToBottom!==void 0&&typeof e.stickToBottom!=`boolean`){if(e.stickToBottom===null||Array.isArray(e.stickToBottom))throw new d(`stickToBottom must be a boolean or options object.`);e.stickToBottom.threshold!==void 0&&m(e.stickToBottom.threshold,`stickToBottom.threshold`)}let t=[],n=!1,i=new AbortController,a=e.listElement,o=r({items:[],stickyItems:[],totalSize:0});function s(e){o.publish(e),S(e)}let c=x(),l=null;function u(n){let r=t[n];return r!==void 0&&e.getItemKey?e.getItemKey(n,r):n}function _(n){if(e.estimateSize===void 0)return 36;if(typeof e.estimateSize==`number`)return e.estimateSize;let r=t[n];return r===void 0?36:e.estimateSize(n,r)}function v(t){e.horizontal?(a.style.height=``,a.style.width=`${t}px`):(a.style.height=`${t}px`,a.style.width=``)}function y(e){let n=t[e.index];if(n===void 0)throw new f(`toRenderItem: index ${e.index} is out of range (currentItems.length=${t.length})`);return{...e,data:n}}function S(t){v(t.totalSize),c.beginCycle();try{e.render({items:t.items.map(y),listEl:a,recycle:(e,t)=>c.acquire(e,t),stickyItems:t.stickyItems.map(y),totalSize:t.totalSize})}finally{c.endCycle()}}function C(){c.clear(),e.clear?e.clear(a):a.textContent=``,a.style.height=``,a.style.width=``,a.style.position=``,a.style.contain=``}function w(){let t=e.stickToBottom;return t?t===!0?{enabled:!0,threshold:48}:{enabled:t.enabled??!0,threshold:t.threshold??48}:{enabled:!1,threshold:48}}function T(){let n=b(e.scrollElement,{count:t.length,estimateSize:_,gap:e.gap,getItemKey:u,horizontal:e.horizontal,keyboardScroll:e.keyboardScroll,measurementCache:e.measurementCache,onChange:s,overscan:e.overscan??3,sticky:e.sticky?n=>{let r=t[n];return r!==void 0&&e.sticky(n,r)}:void 0});return l=n,a.style.position=`relative`,a.style.contain=`layout`,n}function E(){n||(n=!0,o.dispose(),i.abort(),l?.dispose(),l=null,C())}return{get count(){return l?.count??0},get disposalSignal(){return i.signal},dispose:E,get disposed(){return n},getSnapshot:o.getSnapshot,invalidate(){n||l?.invalidate()},isAtEnd(e){return l?.isAtEnd(e)??!0},get isScrolling(){return l?.isScrolling??!1},get items(){return l?.items??[]},measure(e,t){n||l?.measure(e,t)},measureBatch(e){n||l?.measureBatch(e)},measureEl(e,t){return n?()=>{}:l?.measureEl(e,t)??(()=>{})},refresh(){n||l?.refresh()},get scrollOffset(){return l?.scrollOffset??0},scrollToBottom(e){n||l?.scrollToBottom(e)},scrollToIndex(e,t){n||l?.scrollToIndex(e,t)},scrollToOffset(e,t){n||l?.scrollToOffset(e,t)},scrollToTop(e){n||l?.scrollToTop(e)},setItems(r){if(n)return;let i=w(),a=i.enabled&&(l?.isAtEnd(i.threshold)??!0);if(t=r,r.length===0){l?.dispose(),l=null,o.publish({items:[],stickyItems:[],totalSize:0}),C();return}if(!l){let e=T();a&&e.scrollToBottom();return}let s=r.length!==l.count;l.update({count:r.length}),s?e.getItemKey||l.invalidate():e.getItemKey?l.refresh():l.invalidate(),a&&l.scrollToBottom()},get stickyItems(){return l?.stickyItems??[]},subscribe:o.subscribe,[Symbol.dispose]:E,get totalSize(){return l?.totalSize??0}}}function C(e,t){let n=document.createElement(`div`);n.style.cssText=t.horizontal?`overflow: auto hidden; width: 100%; height: 100%;`:`overflow: hidden auto; width: 100%; height: 100%;`,t.containerClass&&(n.className=t.containerClass);let r=document.createElement(`div`);n.appendChild(r),e.appendChild(n);let i;try{i=S({...t,listElement:r,scrollElement:n})}catch(e){throw n.remove(),e}let a=i.dispose.bind(i);return Object.assign(i,{dispose(){a(),n.remove()},[Symbol.dispose](){a(),n.remove()}})}function w(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function T(e,t){typeof t.estimateRowSize==`number`&&h(t.estimateRowSize,`estimateRowSize`),typeof t.estimateColSize==`number`&&h(t.estimateColSize,`estimateColSize`),t.initialScrollTop!==void 0&&m(t.initialScrollTop,`initialScrollTop`),t.initialScrollLeft!==void 0&&m(t.initialScrollLeft,`initialScrollLeft`),t.rowGap!==void 0&&p(t.rowGap,`rowGap`),t.colGap!==void 0&&p(t.colGap,`colGap`),t.overscanY!==void 0&&g(t.overscanY,`overscanY`),t.overscanX!==void 0&&g(t.overscanX,`overscanX`);let n=p(t.rowCount,`rowCount`),o=p(t.colCount,`colCount`),u=l(t.estimateRowSize,36),d=l(t.estimateColSize,36),f=s(t.overscanY,3),y=s(t.overscanX,3),b=t.keyboardScroll??!1,x=t.onChange,S=t.onRangeChange;function C(e){N.publish(e),x?.(e)}let T=t.rowMeasurementCache??new Map,E=t.colMeasurementCache??new Map,D=0,O=0,k=0,A=0,j=[],M=[],N=r({cols:M,rows:j,totalHeight:0,totalWidth:0}),P=!1,F=v(n,e=>T.get(e)??u(e),i(t.rowGap??0)),I=v(o,e=>E.get(e)??d(e),i(t.colGap??0)),L=!1;function R(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,F.totalSize-k),Math.max(0,t))}function z(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,I.totalSize-A),Math.max(0,t))}function B(){if(P)return;let e=F.totalSize,t=I.totalSize;if(n===0||o===0||k<=0||A<=0){(F.prevStart!==-1||F.prevTotalSize!==e||I.prevTotalSize!==t)&&(F.commitDedup(-1,-1),I.commitDedup(-1,-1),j=[],M=[],C({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:r,renderStart:i}=F.computeRange(D,D+k,f.start,f.end),{renderEnd:a,renderStart:s}=I.computeRange(O,O+A,y.start,y.end),c=F.isDedupSame(i,r),l=I.isDedupSame(s,a);if(c&&l)return;F.commitDedup(i,r),I.commitDedup(s,a),(!c||!l)&&S&&S({firstCol:s,firstRow:i,lastCol:a,lastRow:r});let u=[];for(let e=i;e<=r;e++)u.push(F.itemAt(e));let d=[];for(let e=s;e<=a;e++)d.push(I.itemAt(e));j=u,M=d,C({cols:M,rows:j,totalHeight:e,totalWidth:t})}function V(e,t){if(!Number.isFinite(e))return!1;let r=Math.floor(e);if(r<0||r>=n)return!1;let i=a(t,-1);return i<=0||T.get(r)===i?!1:(T.set(r,i),F.markChanged(r),!0)}function H(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=o)return!1;let r=a(t,-1);return r<=0||E.get(n)===r?!1:(E.set(n,r),I.markChanged(n),!0)}function U(){L||(L=!0,queueMicrotask(()=>{L=!1;let e=F.consumeMinChangedIndex();e!==1/0&&F.rebuildFrom(e);let t=I.consumeMinChangedIndex();t!==1/0&&I.rebuildFrom(t),B()}))}function W(e,t){P||V(e,t)&&U()}function G(e,t){P||H(e,t)&&U()}function K(e,t){if(P)return;let n=!1;for(let{index:t,size:r}of e)V(t,r)&&(n=!0);for(let{index:e,size:r}of t)H(e,r)&&(n=!0);n&&U()}function q(e,t){return P?()=>{}:c(X.signal,t,t=>W(e,t.contentRect.height))}function J(e,t){return P?()=>{}:c(X.signal,t,t=>G(e,t.contentRect.width))}function ee(){P||(T.clear(),E.clear(),F.rebuild(!0),I.rebuild(!0),B())}function te(){P||(F.rebuild(!0),I.rebuild(!0),B())}function ne(e){if(P)return;let t=i(e);if(t===0)return;n+=t,F.setCount(n),F.rebuild(!0);let r=F.startAt(t),a=R(D+r);Z.scrollTo(O,a,`auto`),D=a,B()}function re(e,t={}){if(P||n===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),i=t.behavior??`auto`,a=F.startAt(r),o=F.sizeAt(r),s=w(a,a+o,o,D,k,t.rowAlign??`auto`);s!==null&&Z.scrollTo(O,R(s),i)}function ie(e,t={}){if(P||o===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),o-1)),r=t.behavior??`auto`,i=I.startAt(n),a=I.sizeAt(n),s=w(i,i+a,a,O,A,t.colAlign??`auto`);s!==null&&Z.scrollTo(z(s),D,r)}function Y(e,t,r={}){if(P||n===0||o===0)return;let i=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),a=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),o-1)),s=r.behavior??`auto`,c=F.startAt(i),l=F.sizeAt(i),u=I.startAt(a),d=I.sizeAt(a),f=w(c,c+l,l,D,k,r.rowAlign??`auto`),p=w(u,u+d,d,O,A,r.colAlign??`auto`);(f!==null||p!==null)&&Z.scrollTo(p===null?O:z(p),f===null?D:R(f),s)}function ae(e){if(P)return;e.rowCount!==void 0&&p(e.rowCount,`rowCount`),e.colCount!==void 0&&p(e.colCount,`colCount`),typeof e.estimateRowSize==`number`&&h(e.estimateRowSize,`estimateRowSize`),typeof e.estimateColSize==`number`&&h(e.estimateColSize,`estimateColSize`),e.rowGap!==void 0&&p(e.rowGap,`rowGap`),e.colGap!==void 0&&p(e.colGap,`colGap`),e.overscanY!==void 0&&g(e.overscanY,`overscanY`),e.overscanX!==void 0&&g(e.overscanX,`overscanX`);let t=!1,r=!1,i=!1;if(Object.hasOwn(e,`onChange`)&&(x=e.onChange),Object.hasOwn(e,`onRangeChange`)&&(S=e.onRangeChange),e.rowCount!==void 0){let r=e.rowCount;r!==n&&(n=r,F.setCount(n),t=!0)}if(e.colCount!==void 0){let t=e.colCount;t!==o&&(o=t,I.setCount(o),r=!0)}if(e.rowGap!==void 0){let n=e.rowGap;n!==F.gap&&(F.setGap(n),t=!0)}if(e.colGap!==void 0){let t=e.colGap;t!==I.gap&&(I.setGap(t),r=!0)}if(`estimateRowSize`in e&&(u=l(e.estimateRowSize,36),T.clear(),t=!0),`estimateColSize`in e&&(d=l(e.estimateColSize,36),E.clear(),r=!0),e.overscanY!==void 0){let t=s(e.overscanY,3);(t.start!==f.start||t.end!==f.end)&&(f=t,i=!0)}if(e.overscanX!==void 0){let t=s(e.overscanX,3);(t.start!==y.start||t.end!==y.end)&&(y=t,i=!0)}Object.hasOwn(e,`keyboardScroll`)&&(b=e.keyboardScroll??!1),t&&F.rebuild(!0),r&&I.rebuild(!0),(t||r||i)&&B()}let X=new AbortController;function oe(){P||(P=!0,N.dispose(),X.abort(),Z.detach())}function se(){D=R(Z.y.readOffset()),O=z(Z.x.readOffset()),B()}function ce(){k=Z.y.readViewportSize(),A=Z.x.readViewportSize(),B()}let Z=_(e,se,ce);if(F.rebuild(!0),I.rebuild(!0),k=Z.y.readViewportSize(),A=Z.x.readViewportSize(),t.initialScrollTop===void 0?t.initialScrollLeft!==void 0&&Z.scrollTo(z(t.initialScrollLeft),0,`auto`):Z.scrollTo(t.initialScrollLeft??0,R(t.initialScrollTop),`auto`),D=R(Z.y.readOffset()),O=z(Z.x.readOffset()),B(),b){let r=e=>{if(P||!(e instanceof KeyboardEvent)||n===0||o===0)return;let r=!1,a=D,s=O,c=Math.max(k*.8,k-100),l=(typeof u(0)==`number`?u(0):36)+i(t.rowGap??0),f=(typeof d(0)==`number`?d(0):36)+i(t.colGap??0);switch(e.key){case`ArrowUp`:a=Math.max(0,D-l),r=!0;break;case`ArrowDown`:a=Math.min(F.totalSize-k,D+l),r=!0;break;case`ArrowLeft`:s=Math.max(0,O-f),r=!0;break;case`ArrowRight`:s=Math.min(I.totalSize-A,O+f),r=!0;break;case`PageUp`:a=Math.max(0,D-c),r=!0;break;case`PageDown`:a=Math.min(F.totalSize-k,D+c),r=!0;break;case`Home`:a=0,r=!0;break;case`End`:a=Math.max(0,F.totalSize-k),r=!0}r&&(e.preventDefault(),Z.scrollTo(s,a,`auto`),D=R(a),O=z(s),P||B())};typeof e==`object`&&e&&`addEventListener`in e&&(e.addEventListener(`keydown`,r),X.signal.addEventListener(`abort`,()=>{e.removeEventListener(`keydown`,r)}))}return{get cols(){return M},get disposalSignal(){return X.signal},dispose:oe,get disposed(){return P},getSnapshot:N.getSnapshot,invalidate:ee,measureBatch:K,measureColEl:J,measureColumn:G,measureRow:W,measureRowEl:q,prependRows:ne,refresh:te,get rows(){return j},get scrollLeft(){return O},scrollToCell:Y,scrollToColumn:ie,get scrollTop(){return D},scrollToRow:re,subscribe:N.subscribe,[Symbol.dispose]:oe,get totalHeight(){return F.totalSize},get totalWidth(){return I.totalSize},update:ae}}function E(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n];t.push({isHeader:!0,itemIndex:-1,label:r.label,sectionIndex:n});for(let e=0;e<r.items.length;e++)t.push({isHeader:!1,item:r.items[e],itemIndex:e,sectionIndex:n})}return t}function D(e,t){typeof t.estimateHeaderSize==`number`&&h(t.estimateHeaderSize,`estimateHeaderSize`),typeof t.estimateItemSize==`number`&&h(t.estimateItemSize,`estimateItemSize`),t.overscan!==void 0&&g(t.overscan),t.scrollEndDelay!==void 0&&m(t.scrollEndDelay,`scrollEndDelay`);let n=t.sections,i=E(n);function a(e){return typeof e==`function`?t=>{let r=i[t];return e(n[r.sectionIndex],r.sectionIndex)}:l(typeof e==`number`?e:void 0,36)}let o=a(t.estimateHeaderSize),s=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,c=s?null:l(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36),u=t.getItemKey;function d(e){let t=i[e];return t?t.isHeader?o(e):s?s(t.item,t.itemIndex,t.sectionIndex):c(e):36}function f(e){let t=i[e];return t?t.isHeader?`__header_${t.sectionIndex}`:u?u(t.item,t.itemIndex,t.sectionIndex):e:e}let p=!1,_=[],v=r({headers:[],items:[],stickyHeader:null,totalSize:0}),y=t.onChange,x=t.onScrollEnd,S=t.onScrollingChange;function C(e){v.publish(e),y?.(e)}function w(e){let t=[],n=[],r=null;for(let r of e.items){let e=i[r.index];e&&(e.isHeader?n.push({...r,label:e.label??``,sectionIndex:e.sectionIndex}):t.push({...r,data:e.item,itemIndex:e.itemIndex,sectionIndex:e.sectionIndex}))}if(e.stickyItems.length>0){let t=e.stickyItems[0],n=i[t.index];n?.isHeader&&(r={...t,label:n.label??``,sectionIndex:n.sectionIndex})}return _=t,{headers:n,items:t,stickyHeader:r,totalSize:e.totalSize}}let T=b(e,{count:i.length,estimateSize:d,getItemKey:f,horizontal:t.horizontal,measurementCache:t.measurementCache,onChange:e=>{C(w(e))},onScrollEnd:e=>x?.(e),onScrollingChange:e=>S?.(e),overscan:t.overscan??3,scrollEndDelay:t.scrollEndDelay,sticky:e=>i[e]?.isHeader??!1}),D=new AbortController;function O(){p||(p=!0,v.dispose(),D.abort(),T.dispose())}function k(e,t){if(e<0||e>=n.length)return-1;let r=0;for(let i=0;i<n.length;i++){if(i===e)return t===void 0?r:r+1+t;r+=1+n[i].items.length}return-1}return{get count(){return T.count},get disposalSignal(){return D.signal},dispose:O,get disposed(){return p},getSnapshot:v.getSnapshot,invalidate(){p||T.invalidate()},get isScrolling(){return T.isScrolling},get items(){return _},measure(e,t){p||T.measure(e,t)},measureBatch(e){p||T.measureBatch(e)},measureEl(e,t){return p?()=>{}:T.measureEl(e,t)},refresh(){p||T.refresh()},get scrollOffset(){return T.scrollOffset},scrollToBottom(e){p||T.scrollToBottom(e)},scrollToIndex(e,t){p||T.scrollToIndex(e,t)},scrollToItem(e,t,n={}){if(p)return;let r=k(e,t);r<0||T.scrollToIndex(r,n)},scrollToOffset(e,t){p||T.scrollToOffset(e,t)},scrollToSection(e,t={}){if(p)return;let n=k(e);n<0||T.scrollToIndex(n,t)},scrollToTop(e){p||T.scrollToTop(e)},get stickyItems(){return T.stickyItems},subscribe:v.subscribe,[Symbol.dispose]:O,get totalSize(){return T.totalSize},update(e,t){if(p)return;t&&(typeof t.estimateHeaderSize==`number`&&h(t.estimateHeaderSize,`estimateHeaderSize`),typeof t.estimateItemSize==`number`&&h(t.estimateItemSize,`estimateItemSize`),t.overscan!==void 0&&g(t.overscan),t.scrollEndDelay!==void 0&&m(t.scrollEndDelay,`scrollEndDelay`),Object.hasOwn(t,`onChange`)&&(y=t.onChange),Object.hasOwn(t,`onScrollEnd`)&&(x=t.onScrollEnd),Object.hasOwn(t,`onScrollingChange`)&&(S=t.onScrollingChange),t.estimateHeaderSize!==void 0&&(o=a(t.estimateHeaderSize)),t.estimateItemSize!==void 0&&(s=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,c=s?null:l(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36)),t.getItemKey!==void 0&&(u=t.getItemKey)),n=e;let r=i.length;i=E(n);let d={count:i.length};t?.measurementCache!==void 0&&(d.measurementCache=t.measurementCache),t?.overscan!==void 0&&(d.overscan=t.overscan),t?.scrollEndDelay!==void 0&&(d.scrollEndDelay=t.scrollEndDelay),i.length!==r||t?.measurementCache!==void 0||t?.overscan!==void 0||t?.scrollEndDelay!==void 0?T.update(d):T.refresh()}}}exports.DEFAULT_ESTIMATE_SIZE=t,exports.DEFAULT_OVERSCAN=n,exports.ScrollConfigurationError=d,exports.ScrollError=u,exports.ScrollRangeError=f,exports.createDomVirtualList=S,exports.createGridVirtualizer=T,exports.createGroupedVirtualizer=D,exports.createMeasurementCache=e,exports.createVirtualScroller=C,exports.createVirtualizer=b;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function createMeasurementCache(){return new Map}var e=36,t=3;function createSnapshotStore(e){let t=new Set,n=e,r=!1;return{dispose(){r=!0,t.clear()},getSnapshot(){return n},publish(e){if(!r){n=e;for(let e of[...t])try{e()}catch(e){queueMicrotask(()=>{throw e})}}},subscribe(e){return r?()=>{}:(t.add(e),()=>t.delete(e))}}}function toNonNegativeInt(e,t=0){return Number.isFinite(e)?Math.max(0,Math.floor(e)):t}function toPositiveNumber(e,t){return!Number.isFinite(e)||e<=0||e>1e7?t:e}function isWindowTarget(e){return typeof Window<`u`&&e instanceof Window||typeof e.innerHeight==`number`&&typeof e.document==`object`}function normalizeOverscan(e,t){if(typeof e==`number`){let n=toNonNegativeInt(e,t);return{end:n,start:n}}return{end:toNonNegativeInt(e?.end??t),start:toNonNegativeInt(e?.start??t)}}function observeResize(e,t,n){let r=new ResizeObserver(e=>{for(let t of e)n(t)});return r.observe(t),e.addEventListener(`abort`,()=>r.disconnect(),{once:!0}),()=>r.disconnect()}function resolveEstimateFn(e,t){if(typeof e==`function`)return n=>{try{return toPositiveNumber(e(n),t)}catch(e){return`${n}${e}`,t}};let n=typeof e==`number`?toPositiveNumber(e,t):t;return()=>n}var ScrollError=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},ScrollConfigError=class extends ScrollError{},ScrollRangeError=class extends ScrollError{};function requireNonNegativeInteger(e,t){if(!Number.isFinite(e)||!Number.isInteger(e)||e<0)throw new ScrollConfigError(`${t} must be a finite non-negative integer.`);return e}function requireNonNegativeNumber(e,t){if(!Number.isFinite(e)||e<0)throw new ScrollConfigError(`${t} must be a finite non-negative number.`);return e}function requirePositiveNumber(e,t){if(!Number.isFinite(e)||e<=0||e>1e7)throw new ScrollConfigError(`${t} must be a finite positive number no greater than 10000000.`);return e}function validateOverscan(e,t=`overscan`){if(typeof e==`number`){requireNonNegativeInteger(e,t);return}if(typeof e!=`object`||!e||Array.isArray(e))throw new ScrollConfigError(`${t} must be a finite non-negative integer or an overscan object.`);e.start!==void 0&&requireNonNegativeInteger(e.start,`${t}.start`),e.end!==void 0&&requireNonNegativeInteger(e.end,`${t}.end`)}function createScrollAdapter(e,t,n){if(isWindowTarget(e))return e.addEventListener(`scroll`,t,{passive:!0}),e.addEventListener(`resize`,n,{passive:!0}),{detach(){e.removeEventListener(`scroll`,t),e.removeEventListener(`resize`,n)},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollX,readViewportSize:()=>e.innerWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollY,readViewportSize:()=>e.innerHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}};let r=new ResizeObserver(n);return e.addEventListener(`scroll`,t,{passive:!0}),r.observe(e),{detach(){e.removeEventListener(`scroll`,t),r.disconnect()},scrollTo:(t,n,r)=>e.scrollTo({behavior:r,left:t,top:n}),x:{readOffset:()=>e.scrollLeft,readViewportSize:()=>e.clientWidth,writeOffset:(t,n)=>e.scrollTo({behavior:n,left:t})},y:{readOffset:()=>e.scrollTop,readViewportSize:()=>e.clientHeight,writeOffset:(t,n)=>e.scrollTo({behavior:n,top:t})}}}function createAxis1D(e,t,n){let r=e,i=n,a=t,o=[],s=0,c=-1,l=-1,u=-1,d=!1,f=1/0;function startAt(e){return o[e]??0}function endAt(e){return startAt(e)+a(e)}function rebuild(e=!1){e&&(c=-1,l=-1,u=-1);let t=[0],n=0;for(let e=0;e<r;e++)n+=a(e)+(e<r-1?i:0),t.push(n);o=t,s=n}function rebuildFrom(e){if(!Number.isFinite(e)||e>=r)return;c=-1,l=-1,u=-1;let t=o[e]??0;for(let n=e;n<r;n++)o[n]=t,t+=a(n)+(n<r-1?i:0);o[r]=t,s=t}function findFirst(e){let t=0,n=r-1;for(;t<n;){let r=t+n>>1;endAt(r)<=e?t=r+1:n=r}return t}function findLast(e,t){let n=t,i=r-1;for(;n<i;){let t=n+i+1>>1;startAt(t)<e?n=t:i=t-1}return n}function computeRange(e,t,n,i){let a=findFirst(e),o=findLast(t,a);return{renderEnd:Math.min(r-1,o+i),renderStart:Math.max(0,a-n)}}function isDedupSame(e,t){return e===c&&t===l&&s===u}function commitDedup(e,t){c=e,l=t,u=s}function resetDedup(){c=-1,l=-1,u=-1}function scheduleBuild(e){d||(d=!0,queueMicrotask(()=>{d=!1;let t=f;f=1/0,rebuildFrom(t),e()}))}function markChanged(e){e<f&&(f=e)}function itemAt(e){let t=startAt(e),n=a(e);return{end:t+n,index:e,size:n,start:t}}return{commitDedup,computeRange,consumeMinChangedIndex(){let e=f;return f=1/0,e},get count(){return r},endAt,findFirst,findLast,get gap(){return i},isDedupSame,itemAt,markChanged,get minChangedIndex(){return f},get pendingBuild(){return d},get prevEnd(){return l},get prevStart(){return c},get prevTotalSize(){return u},rebuild,rebuildFrom,resetDedup,scheduleBuild,setCount(e){r=e},setGap(e){i=e},sizeAt(e){return a(e)},startAt,get totalSize(){return s}}}function computeStickyItems(e){if(!e.stickyFn||e.count===0||e.scrollOffset<=0)return[];let t=-1,n=0,r=e.count-1;for(;n<=r;){let i=n+r>>1;e.startAt(i)<e.scrollOffset?(t=i,n=i+1):r=i-1}if(t<0)return[];let i=-1;for(let n=t;n>=0;n--)if(e.stickyFn(n)){i=n;break}if(i===-1)return[];let a=e.sizeAt(i),o=1/0;for(let t=i+1;t<e.count;t++)if(e.stickyFn(t)){o=e.startAt(t);break}let s=Math.min(e.scrollOffset,o-a);return[{end:s+a,index:i,size:a,start:s}]}function createVirtualizer(e,t){typeof t.estimateSize==`number`&&requirePositiveNumber(t.estimateSize,`estimateSize`),t.gap!==void 0&&requireNonNegativeInteger(t.gap,`gap`),t.initialOffset!==void 0&&requireNonNegativeNumber(t.initialOffset,`initialOffset`),t.overscan!==void 0&&validateOverscan(t.overscan),t.scrollEndDelay!==void 0&&requireNonNegativeNumber(t.scrollEndDelay,`scrollEndDelay`);let n=!!t.horizontal,defaultItemKey=e=>e,r=requireNonNegativeInteger(t.count,`count`),i=resolveEstimateFn(t.estimateSize,36),a=toNonNegativeInt(t.gap??0),o=t.getItemKey??defaultItemKey,s=normalizeOverscan(t.overscan,3),c=t.sticky??null,l=t.autoMeasure??!1,u=t.onChange,d=t.onScrollEnd,f=t.onScrollingChange,p=t.scrollEndDelay??150;function emitState(e){y.publish(e),u?.(e)}let m=null,h=`onscrollend`in e;function notifyScrollEnd(){D&&(D=!1,f?.(!1),d?.(C))}function handleScrollStart(){D||(D=!0,f?.(!0)),h||(m!==null&&clearTimeout(m),m=setTimeout(notifyScrollEnd,p))}let g=t.measurementCache??new Map,_=[],v=[],y=createSnapshotStore({items:_,stickyItems:v,totalSize:0}),b=createAxis1D(r,e=>g.get(o(e))??i(e),a),x=-1,S=0,C=0,w=0,T=-1,E=!1,D=!1;function clampScrollOffset(e){let t=Number.isFinite(e)?e:0,n=Math.max(0,b.totalSize-w);return Math.min(n,Math.max(0,t))}function computeVisible(){if(E)return;if(r===0||w<=0){(b.prevStart!==-1||b.prevTotalSize!==b.totalSize)&&(b.commitDedup(-1,-1),_=[],v=[],emitState({items:_,stickyItems:v,totalSize:b.totalSize}));return}let{renderEnd:t,renderStart:n}=b.computeRange(C,C+w,s.start,s.end),i=c!==null&&C!==T;if(b.isDedupSame(n,t)&&!i)return;b.commitDedup(n,t),T=C;let a=[];for(let e=n;e<=t;e++)a.push(b.itemAt(e));_=a,v=c?computeStickyItems({count:r,scrollOffset:C,sizeAt:b.sizeAt,startAt:b.startAt,stickyFn:c}):[],emitState({items:_,stickyItems:v,totalSize:b.totalSize}),l&&_.length>0&&queueMicrotask(()=>{if(!(E||e instanceof Window))for(let t of _){let n=o(t.index),r=e?.querySelector?.(`[data-vz-key="${n}"]`);r instanceof HTMLElement&&measureEl(t.index,r)}})}function recordMeasurement(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=r)return!1;let i=toPositiveNumber(t,-1);if(i<=0)return!1;let a=o(n);return g.get(a)!==i&&(g.set(a,i),b.markChanged(n),!0)}function recordScrollAnchor(){if(C<=0||r===0){x=-1;return}x=b.findFirst(C),S=C-b.startAt(x)}function restoreScrollAnchor(){if(x<0)return;let e=b.startAt(x)+S-C;if(x=-1,Math.abs(e)>=1){let t=clampScrollOffset(C+e);A.writeOffset(t,`auto`),C=t}}function measureBatch(e){if(E)return;let t=!1;for(let{index:n,size:r}of e)recordMeasurement(n,r)&&(t=!0);t&&(b.pendingBuild||recordScrollAnchor(),b.scheduleBuild(()=>{restoreScrollAnchor(),computeVisible()}))}function measure(e,t){measureBatch([{index:e,size:t}])}function measureEl(e,t){return E?()=>{}:observeResize(O.signal,t,t=>{measure(e,n?t.contentRect.width:t.contentRect.height)})}function applyOptions(e){e.count!==void 0&&requireNonNegativeInteger(e.count,`count`),typeof e.estimateSize==`number`&&requirePositiveNumber(e.estimateSize,`estimateSize`),e.gap!==void 0&&requireNonNegativeInteger(e.gap,`gap`),e.overscan!==void 0&&validateOverscan(e.overscan),e.scrollEndDelay!==void 0&&requireNonNegativeNumber(e.scrollEndDelay,`scrollEndDelay`);let t=!1,n=!1;if(Object.hasOwn(e,`onChange`)&&(u=e.onChange),Object.hasOwn(e,`onScrollEnd`)&&(d=e.onScrollEnd),Object.hasOwn(e,`onScrollingChange`)&&(f=e.onScrollingChange),e.scrollEndDelay!==void 0&&(p=e.scrollEndDelay),e.count!==void 0){let n=e.count;n!==r&&(r=n,b.setCount(r),t=!0)}if(Object.hasOwn(e,`estimateSize`)&&(i=resolveEstimateFn(e.estimateSize,36),g.clear(),t=!0),e.gap!==void 0){let n=e.gap;n!==a&&(a=n,b.setGap(a),t=!0)}if(Object.hasOwn(e,`getItemKey`)){let n=e.getItemKey??defaultItemKey;n!==o&&(o=n,g.clear(),t=!0)}if(Object.hasOwn(e,`measurementCache`)&&e.measurementCache!==void 0&&(g=e.measurementCache,t=!0),e.overscan!==void 0){let t=normalizeOverscan(e.overscan,3);(t.start!==s.start||t.end!==s.end)&&(s=t,n=!0)}if(Object.hasOwn(e,`sticky`)){let t=e.sticky??null;t!==c&&(c=t,b.resetDedup()),n=!0}Object.hasOwn(e,`autoMeasure`)&&(l=e.autoMeasure??!1),t&&(recordScrollAnchor(),b.rebuild(!0),restoreScrollAnchor()),(n||t)&&(w=A.readViewportSize(),C=clampScrollOffset(A.readOffset()),computeVisible())}function remeasure(){E||(w=A.readViewportSize(),C=clampScrollOffset(A.readOffset()),computeVisible())}function invalidate(){E||(g.clear(),b.rebuild(!0),computeVisible())}function refresh(){E||(b.rebuild(!0),computeVisible())}function prepend(e){if(E)return;let t=toNonNegativeInt(e);if(t===0)return;r+=t,b.setCount(r),b.rebuild(!0);let n=b.startAt(t),i=clampScrollOffset(C+n);A.writeOffset(i,`auto`),C=i,computeVisible()}function update(e){E||applyOptions(e)}function scrollToIndex(t,n={}){if(E||r<=0)return;let i=Math.max(0,Math.min(Number.isFinite(t)?Math.floor(t):0,r-1)),a=n.align??`auto`,o=n.behavior??`auto`,s=b.startAt(i),c=b.sizeAt(i),l=s+c,u;if(a===`start`)u=s;else if(a===`end`)u=l-w;else if(a===`center`)u=s-(w-c)/2;else{let e=C,t=e+w;if(s>=e&&l<=t){n.onComplete&&queueMicrotask(n.onComplete);return}u=s<e?s:l-w}A.writeOffset(clampScrollOffset(u),o),n.onComplete&&(o===`smooth`&&`onscrollend`in e?e.addEventListener(`scrollend`,n.onComplete,{once:!0}):queueMicrotask(n.onComplete))}function scrollToOffset(e,t={}){E||A.writeOffset(clampScrollOffset(e),t.behavior??`auto`)}function scrollToTop(e={}){scrollToOffset(0,e)}function scrollToBottom(e={}){scrollToOffset(Math.max(0,b.totalSize-w),e)}function isAtEnd(e=0){return b.totalSize-(C+w)<=e}let O=new AbortController;function _dispose(){E||(E=!0,y.dispose(),O.abort(),m!==null&&(clearTimeout(m),m=null),h&&e.removeEventListener(`scrollend`,notifyScrollEnd),k.detach())}function handleScroll(){C=clampScrollOffset(A.readOffset()),handleScrollStart(),computeVisible()}function handleResize(){w=A.readViewportSize(),computeVisible()}let k=createScrollAdapter(e,handleScroll,handleResize),A=n?k.x:k.y;return h&&e.addEventListener(`scrollend`,notifyScrollEnd,{passive:!0}),b.rebuild(!0),t.initialOffset!==void 0&&A.writeOffset(clampScrollOffset(t.initialOffset),`auto`),C=clampScrollOffset(A.readOffset()),w=A.readViewportSize(),computeVisible(),{get count(){return r},get disposalSignal(){return O.signal},dispose:_dispose,get disposed(){return E},getSnapshot:y.getSnapshot,invalidate,isAtEnd,get isScrolling(){return D},get items(){return _},measure,measureBatch,measureEl,prepend,refresh,remeasure,get scrollOffset(){return C},scrollToBottom,scrollToIndex,scrollToOffset,scrollToTop,get stickyItems(){return v},subscribe:y.subscribe,[Symbol.dispose]:_dispose,get totalSize(){return b.totalSize},update}}function createNodePool(){let e=new Map,t=new Map,n=[],r=!1;return{acquire(i,a){if(!r)return a();let o=e.get(i);if(o)return t.set(i,o),o;let s=n.pop()??a();return t.set(i,s),s},beginCycle(){t=new Map,r=!0},clear(){for(let t of e.values())t.remove();e.clear(),t.clear(),n.length=0,r=!1},endCycle(){if(r){r=!1;for(let[r,i]of e)t.has(r)||(i.remove(),n.push(i));e=t}}}}function createDomVirtualList(e){if(typeof e.estimateSize==`number`&&requirePositiveNumber(e.estimateSize,`estimateSize`),e.gap!==void 0&&requireNonNegativeInteger(e.gap,`gap`),e.overscan!==void 0&&validateOverscan(e.overscan),e.stickToBottom!==void 0&&typeof e.stickToBottom!=`boolean`){if(e.stickToBottom===null||Array.isArray(e.stickToBottom))throw new ScrollConfigError(`stickToBottom must be a boolean or options object.`);e.stickToBottom.threshold!==void 0&&requireNonNegativeNumber(e.stickToBottom.threshold,`stickToBottom.threshold`)}let t=[],n=!1,r=new AbortController,i=e.listElement,a=createSnapshotStore({items:[],stickyItems:[],totalSize:0});function emitState(e){a.publish(e),handleChange(e)}let o=createNodePool(),s=null;function resolveKey(n){let r=t[n];return r!==void 0&&e.getItemKey?e.getItemKey(n,r):n}function resolveEstimate(n){if(e.estimateSize===void 0)return 36;if(typeof e.estimateSize==`number`)return e.estimateSize;let r=t[n];return r===void 0?36:e.estimateSize(n,r)}function applyListSize(t){e.horizontal?(i.style.height=``,i.style.width=`${t}px`):(i.style.height=`${t}px`,i.style.width=``)}function toRenderItem(e){let n=t[e.index];if(n===void 0)throw new ScrollRangeError(`toRenderItem: index ${e.index} is out of range (currentItems.length=${t.length})`);return{...e,data:n}}function handleChange(t){applyListSize(t.totalSize),o.beginCycle();try{e.render({items:t.items.map(toRenderItem),listEl:i,recycle:(e,t)=>o.acquire(e,t),stickyItems:t.stickyItems.map(toRenderItem),totalSize:t.totalSize})}finally{o.endCycle()}}function clearAndReset(){o.clear(),e.clear?e.clear(i):i.textContent=``,i.style.height=``,i.style.width=``,i.style.position=``,i.style.contain=``}function resolveStickToBottom(){let t=e.stickToBottom;return t?t===!0?{enabled:!0,threshold:48}:{enabled:t.enabled??!0,threshold:t.threshold??48}:{enabled:!1,threshold:48}}function spawnVirtualizer(){let n=createVirtualizer(e.scrollElement,{count:t.length,estimateSize:resolveEstimate,gap:e.gap,getItemKey:resolveKey,horizontal:e.horizontal,measurementCache:e.measurementCache,onChange:emitState,overscan:e.overscan??3,sticky:e.sticky?n=>{let r=t[n];return r!==void 0&&e.sticky(n,r)}:void 0});return s=n,i.style.position=`relative`,i.style.contain=`layout`,n}function _dispose(){n||(n=!0,a.dispose(),r.abort(),s?.dispose(),s=null,clearAndReset())}return{get count(){return s?.count??0},get disposalSignal(){return r.signal},dispose:_dispose,get disposed(){return n},getSnapshot:a.getSnapshot,invalidate(){n||s?.invalidate()},isAtEnd(e){return s?.isAtEnd(e)??!0},get isScrolling(){return s?.isScrolling??!1},get items(){return s?.items??[]},measure(e,t){n||s?.measure(e,t)},measureBatch(e){n||s?.measureBatch(e)},measureEl(e,t){return n?()=>{}:s?.measureEl(e,t)??(()=>{})},refresh(){n||s?.refresh()},remeasure(){n||s?.remeasure()},get scrollOffset(){return s?.scrollOffset??0},scrollToBottom(e){n||s?.scrollToBottom(e)},scrollToIndex(e,t){n||s?.scrollToIndex(e,t)},scrollToOffset(e,t){n||s?.scrollToOffset(e,t)},scrollToTop(e){n||s?.scrollToTop(e)},setItems(r){if(n)return;let i=resolveStickToBottom(),o=i.enabled&&(s?.isAtEnd(i.threshold)??!0);if(t=r,r.length===0){s?.dispose(),s=null,a.publish({items:[],stickyItems:[],totalSize:0}),clearAndReset();return}if(!s){let e=spawnVirtualizer();o&&e.scrollToBottom();return}let c=r.length!==s.count;s.update({count:r.length}),c?e.getItemKey||s.invalidate():e.getItemKey?s.refresh():s.invalidate(),o&&s.scrollToBottom()},get stickyItems(){return s?.stickyItems??[]},subscribe:a.subscribe,[Symbol.dispose]:_dispose,get totalSize(){return s?.totalSize??0}}}function createVirtualScroller(e,t){let n=document.createElement(`div`);n.style.cssText=t.horizontal?`overflow: auto hidden; width: 100%; height: 100%;`:`overflow: hidden auto; width: 100%; height: 100%;`,t.containerClass&&(n.className=t.containerClass);let r=document.createElement(`div`);n.appendChild(r),e.appendChild(n);let i;try{i=createDomVirtualList({...t,listElement:r,scrollElement:n})}catch(e){throw n.remove(),e}let a=i.dispose.bind(i);return Object.assign(i,{dispose(){a(),n.remove()},[Symbol.dispose](){a(),n.remove()}})}function alignOffset(e,t,n,r,i,a){return a===`start`?e:a===`end`?t-i:a===`center`?e-(i-n)/2:e>=r&&t<=r+i?null:e<r?e:t-i}function createGridVirtualizer(e,t){typeof t.estimateRowSize==`number`&&requirePositiveNumber(t.estimateRowSize,`estimateRowSize`),typeof t.estimateColSize==`number`&&requirePositiveNumber(t.estimateColSize,`estimateColSize`),t.initialScrollTop!==void 0&&requireNonNegativeNumber(t.initialScrollTop,`initialScrollTop`),t.initialScrollLeft!==void 0&&requireNonNegativeNumber(t.initialScrollLeft,`initialScrollLeft`),t.rowGap!==void 0&&requireNonNegativeInteger(t.rowGap,`rowGap`),t.colGap!==void 0&&requireNonNegativeInteger(t.colGap,`colGap`),t.overscanY!==void 0&&validateOverscan(t.overscanY,`overscanY`),t.overscanX!==void 0&&validateOverscan(t.overscanX,`overscanX`);let n=requireNonNegativeInteger(t.rowCount,`rowCount`),r=requireNonNegativeInteger(t.colCount,`colCount`),i=resolveEstimateFn(t.estimateRowSize,36),a=resolveEstimateFn(t.estimateColSize,36),o=normalizeOverscan(t.overscanY,3),s=normalizeOverscan(t.overscanX,3),c=t.onChange,l=t.onRangeChange;function emitState(e){v.publish(e),c?.(e)}let u=t.rowMeasurementCache??new Map,d=t.colMeasurementCache??new Map,f=0,p=0,m=0,h=0,g=[],_=[],v=createSnapshotStore({cols:_,rows:g,totalHeight:0,totalWidth:0}),y=!1,b=createAxis1D(n,e=>u.get(e)??i(e),toNonNegativeInt(t.rowGap??0)),x=createAxis1D(r,e=>d.get(e)??a(e),toNonNegativeInt(t.colGap??0)),S=!1;function clampTop(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,b.totalSize-m),Math.max(0,t))}function clampLeft(e){let t=Number.isFinite(e)?e:0;return Math.min(Math.max(0,x.totalSize-h),Math.max(0,t))}function computeVisible(){if(y)return;let e=b.totalSize,t=x.totalSize;if(n===0||r===0||m<=0||h<=0){(b.prevStart!==-1||b.prevTotalSize!==e||x.prevTotalSize!==t)&&(b.commitDedup(-1,-1),x.commitDedup(-1,-1),g=[],_=[],emitState({cols:[],rows:[],totalHeight:e,totalWidth:t}));return}let{renderEnd:i,renderStart:a}=b.computeRange(f,f+m,o.start,o.end),{renderEnd:c,renderStart:u}=x.computeRange(p,p+h,s.start,s.end),d=b.isDedupSame(a,i),v=x.isDedupSame(u,c);if(d&&v)return;b.commitDedup(a,i),x.commitDedup(u,c),(!d||!v)&&l&&l({firstCol:u,firstRow:a,lastCol:c,lastRow:i});let S=[];for(let e=a;e<=i;e++)S.push(b.itemAt(e));let C=[];for(let e=u;e<=c;e++)C.push(x.itemAt(e));g=S,_=C,emitState({cols:_,rows:g,totalHeight:e,totalWidth:t})}function recordRowMeasurement(e,t){if(!Number.isFinite(e))return!1;let r=Math.floor(e);if(r<0||r>=n)return!1;let i=toPositiveNumber(t,-1);return i<=0||u.get(r)===i?!1:(u.set(r,i),b.markChanged(r),!0)}function recordColMeasurement(e,t){if(!Number.isFinite(e))return!1;let n=Math.floor(e);if(n<0||n>=r)return!1;let i=toPositiveNumber(t,-1);return i<=0||d.get(n)===i?!1:(d.set(n,i),x.markChanged(n),!0)}function scheduleFlush(){S||(S=!0,queueMicrotask(()=>{S=!1;let e=b.consumeMinChangedIndex();e!==1/0&&b.rebuildFrom(e);let t=x.consumeMinChangedIndex();t!==1/0&&x.rebuildFrom(t),computeVisible()}))}function measureRow(e,t){y||recordRowMeasurement(e,t)&&scheduleFlush()}function measureColumn(e,t){y||recordColMeasurement(e,t)&&scheduleFlush()}function measureBatch(e,t){if(y)return;let n=!1;for(let{index:t,size:r}of e)recordRowMeasurement(t,r)&&(n=!0);for(let{index:e,size:r}of t)recordColMeasurement(e,r)&&(n=!0);n&&scheduleFlush()}function measureRowEl(e,t){return y?()=>{}:observeResize(C.signal,t,t=>measureRow(e,t.contentRect.height))}function measureColEl(e,t){return y?()=>{}:observeResize(C.signal,t,t=>measureColumn(e,t.contentRect.width))}function invalidate(){y||(u.clear(),d.clear(),b.rebuild(!0),x.rebuild(!0),computeVisible())}function refresh(){y||(b.rebuild(!0),x.rebuild(!0),computeVisible())}function prependRows(e){if(y)return;let t=toNonNegativeInt(e);if(t===0)return;n+=t,b.setCount(n),b.rebuild(!0);let r=b.startAt(t),i=clampTop(f+r);w.scrollTo(p,i,`auto`),f=i,computeVisible()}function scrollToRow(e,t={}){if(y||n===0)return;let r=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),i=t.behavior??`auto`,a=b.startAt(r),o=b.sizeAt(r),s=alignOffset(a,a+o,o,f,m,t.rowAlign??`auto`);s!==null&&w.scrollTo(p,clampTop(s),i)}function scrollToColumn(e,t={}){if(y||r===0)return;let n=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),r-1)),i=t.behavior??`auto`,a=x.startAt(n),o=x.sizeAt(n),s=alignOffset(a,a+o,o,p,h,t.colAlign??`auto`);s!==null&&w.scrollTo(clampLeft(s),f,i)}function scrollToCell(e,t,i={}){if(y||n===0||r===0)return;let a=Math.max(0,Math.min(Math.floor(Number.isFinite(e)?e:0),n-1)),o=Math.max(0,Math.min(Math.floor(Number.isFinite(t)?t:0),r-1)),s=i.behavior??`auto`,c=b.startAt(a),l=b.sizeAt(a),u=x.startAt(o),d=x.sizeAt(o),g=alignOffset(c,c+l,l,f,m,i.rowAlign??`auto`),_=alignOffset(u,u+d,d,p,h,i.colAlign??`auto`);(g!==null||_!==null)&&w.scrollTo(_===null?p:clampLeft(_),g===null?f:clampTop(g),s)}function update(e){if(y)return;e.rowCount!==void 0&&requireNonNegativeInteger(e.rowCount,`rowCount`),e.colCount!==void 0&&requireNonNegativeInteger(e.colCount,`colCount`),typeof e.estimateRowSize==`number`&&requirePositiveNumber(e.estimateRowSize,`estimateRowSize`),typeof e.estimateColSize==`number`&&requirePositiveNumber(e.estimateColSize,`estimateColSize`),e.rowGap!==void 0&&requireNonNegativeInteger(e.rowGap,`rowGap`),e.colGap!==void 0&&requireNonNegativeInteger(e.colGap,`colGap`),e.overscanY!==void 0&&validateOverscan(e.overscanY,`overscanY`),e.overscanX!==void 0&&validateOverscan(e.overscanX,`overscanX`);let t=!1,f=!1,p=!1;if(Object.hasOwn(e,`onChange`)&&(c=e.onChange),Object.hasOwn(e,`onRangeChange`)&&(l=e.onRangeChange),e.rowCount!==void 0){let r=e.rowCount;r!==n&&(n=r,b.setCount(n),t=!0)}if(e.colCount!==void 0){let t=e.colCount;t!==r&&(r=t,x.setCount(r),f=!0)}if(e.rowGap!==void 0){let n=e.rowGap;n!==b.gap&&(b.setGap(n),t=!0)}if(e.colGap!==void 0){let t=e.colGap;t!==x.gap&&(x.setGap(t),f=!0)}if(`estimateRowSize`in e&&(i=resolveEstimateFn(e.estimateRowSize,36),u.clear(),t=!0),`estimateColSize`in e&&(a=resolveEstimateFn(e.estimateColSize,36),d.clear(),f=!0),e.overscanY!==void 0){let t=normalizeOverscan(e.overscanY,3);(t.start!==o.start||t.end!==o.end)&&(o=t,p=!0)}if(e.overscanX!==void 0){let t=normalizeOverscan(e.overscanX,3);(t.start!==s.start||t.end!==s.end)&&(s=t,p=!0)}t&&b.rebuild(!0),f&&x.rebuild(!0),(t||f||p)&&computeVisible()}let C=new AbortController;function disposeImpl(){y||(y=!0,v.dispose(),C.abort(),w.detach())}function handleScroll(){f=clampTop(w.y.readOffset()),p=clampLeft(w.x.readOffset()),computeVisible()}function handleResize(){m=w.y.readViewportSize(),h=w.x.readViewportSize(),computeVisible()}let w=createScrollAdapter(e,handleScroll,handleResize);return b.rebuild(!0),x.rebuild(!0),m=w.y.readViewportSize(),h=w.x.readViewportSize(),t.initialScrollTop===void 0?t.initialScrollLeft!==void 0&&w.scrollTo(clampLeft(t.initialScrollLeft),0,`auto`):w.scrollTo(t.initialScrollLeft??0,clampTop(t.initialScrollTop),`auto`),f=clampTop(w.y.readOffset()),p=clampLeft(w.x.readOffset()),computeVisible(),{get cols(){return _},get disposalSignal(){return C.signal},dispose:disposeImpl,get disposed(){return y},getSnapshot:v.getSnapshot,invalidate,measureBatch,measureColEl,measureColumn,measureRow,measureRowEl,prependRows,refresh,get rows(){return g},get scrollLeft(){return p},scrollToCell,scrollToColumn,get scrollTop(){return f},scrollToRow,subscribe:v.subscribe,[Symbol.dispose]:disposeImpl,get totalHeight(){return b.totalSize},get totalWidth(){return x.totalSize},update}}function buildFlatEntries(e){let t=[];for(let n=0;n<e.length;n++){let r=e[n];t.push({isHeader:!0,itemIndex:-1,label:r.label,sectionIndex:n});for(let e=0;e<r.items.length;e++)t.push({isHeader:!1,item:r.items[e],itemIndex:e,sectionIndex:n})}return t}function createGroupedVirtualizer(e,t){typeof t.estimateHeaderSize==`number`&&requirePositiveNumber(t.estimateHeaderSize,`estimateHeaderSize`),typeof t.estimateItemSize==`number`&&requirePositiveNumber(t.estimateItemSize,`estimateItemSize`),t.overscan!==void 0&&validateOverscan(t.overscan),t.scrollEndDelay!==void 0&&requireNonNegativeNumber(t.scrollEndDelay,`scrollEndDelay`);let n=t.sections,r=buildFlatEntries(n);function buildEstimateHeader(e){return typeof e==`function`?t=>{let i=r[t];return e(n[i.sectionIndex],i.sectionIndex)}:resolveEstimateFn(typeof e==`number`?e:void 0,36)}let i=buildEstimateHeader(t.estimateHeaderSize),a=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,o=a?null:resolveEstimateFn(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36),s=t.getItemKey;function estimateFn(e){let t=r[e];return t?t.isHeader?i(e):a?a(t.item,t.itemIndex,t.sectionIndex):o(e):36}function getItemKey(e){let t=r[e];return t?t.isHeader?`__header_${t.sectionIndex}`:s?s(t.item,t.itemIndex,t.sectionIndex):e:e}let c=!1,l=[],u=createSnapshotStore({headers:[],items:[],stickyHeader:null,totalSize:0}),d=t.onChange,f=t.onScrollEnd,p=t.onScrollingChange;function emitState(e){u.publish(e),d?.(e)}function mapState(e){let t=[],n=[],i=null;for(let i of e.items){let e=r[i.index];e&&(e.isHeader?n.push({...i,label:e.label??``,sectionIndex:e.sectionIndex}):t.push({...i,data:e.item,itemIndex:e.itemIndex,sectionIndex:e.sectionIndex}))}if(e.stickyItems.length>0){let t=e.stickyItems[0],n=r[t.index];n?.isHeader&&(i={...t,label:n.label??``,sectionIndex:n.sectionIndex})}return l=t,{headers:n,items:t,stickyHeader:i,totalSize:e.totalSize}}let m=createVirtualizer(e,{count:r.length,estimateSize:estimateFn,getItemKey,horizontal:t.horizontal,measurementCache:t.measurementCache,onChange:e=>{emitState(mapState(e))},onScrollEnd:e=>f?.(e),onScrollingChange:e=>p?.(e),overscan:t.overscan??3,scrollEndDelay:t.scrollEndDelay,sticky:e=>r[e]?.isHeader??!1}),h=new AbortController;function _dispose(){c||(c=!0,u.dispose(),h.abort(),m.dispose())}function flatIndexOf(e,t){if(e<0||e>=n.length)return-1;let r=0;for(let i=0;i<n.length;i++){if(i===e)return t===void 0?r:r+1+t;r+=1+n[i].items.length}return-1}return{get count(){return m.count},get disposalSignal(){return h.signal},dispose:_dispose,get disposed(){return c},getSnapshot:u.getSnapshot,invalidate(){c||m.invalidate()},get isScrolling(){return m.isScrolling},get items(){return l},measure(e,t){c||m.measure(e,t)},measureBatch(e){c||m.measureBatch(e)},measureEl(e,t){return c?()=>{}:m.measureEl(e,t)},refresh(){c||m.refresh()},get scrollOffset(){return m.scrollOffset},scrollToBottom(e){c||m.scrollToBottom(e)},scrollToIndex(e,t){c||m.scrollToIndex(e,t)},scrollToItem(e,t,n={}){if(c)return;let r=flatIndexOf(e,t);r<0||m.scrollToIndex(r,n)},scrollToOffset(e,t){c||m.scrollToOffset(e,t)},scrollToSection(e,t={}){if(c)return;let n=flatIndexOf(e);n<0||m.scrollToIndex(n,t)},scrollToTop(e){c||m.scrollToTop(e)},get stickyItems(){return m.stickyItems},subscribe:u.subscribe,[Symbol.dispose]:_dispose,get totalSize(){return m.totalSize},update(e,t){if(c)return;t&&(typeof t.estimateHeaderSize==`number`&&requirePositiveNumber(t.estimateHeaderSize,`estimateHeaderSize`),typeof t.estimateItemSize==`number`&&requirePositiveNumber(t.estimateItemSize,`estimateItemSize`),t.overscan!==void 0&&validateOverscan(t.overscan),t.scrollEndDelay!==void 0&&requireNonNegativeNumber(t.scrollEndDelay,`scrollEndDelay`),Object.hasOwn(t,`onChange`)&&(d=t.onChange),Object.hasOwn(t,`onScrollEnd`)&&(f=t.onScrollEnd),Object.hasOwn(t,`onScrollingChange`)&&(p=t.onScrollingChange),t.estimateHeaderSize!==void 0&&(i=buildEstimateHeader(t.estimateHeaderSize)),t.estimateItemSize!==void 0&&(a=typeof t.estimateItemSize==`function`?t.estimateItemSize:null,o=a?null:resolveEstimateFn(typeof t.estimateItemSize==`number`?t.estimateItemSize:void 0,36)),t.getItemKey!==void 0&&(s=t.getItemKey)),n=e;let l=r.length;r=buildFlatEntries(n);let u={count:r.length};t?.measurementCache!==void 0&&(u.measurementCache=t.measurementCache),t?.overscan!==void 0&&(u.overscan=t.overscan),t?.scrollEndDelay!==void 0&&(u.scrollEndDelay=t.scrollEndDelay),r.length!==l||t?.measurementCache!==void 0||t?.overscan!==void 0||t?.scrollEndDelay!==void 0?m.update(u):m.refresh()}}}exports.DEFAULT_ESTIMATE_SIZE=e,exports.DEFAULT_OVERSCAN=t,exports.ScrollConfigError=ScrollConfigError,exports.ScrollError=ScrollError,exports.ScrollRangeError=ScrollRangeError,exports.createDomVirtualList=createDomVirtualList,exports.createGridVirtualizer=createGridVirtualizer,exports.createGroupedVirtualizer=createGroupedVirtualizer,exports.createMeasurementCache=createMeasurementCache,exports.createVirtualScroller=createVirtualScroller,exports.createVirtualizer=createVirtualizer;
|
|
2
2
|
//# sourceMappingURL=scroll.cjs.map
|