API Reference
Complete documentation for @pdanpdan/virtual-scroll.
Introduction
@pdanpdan/virtual-scroll is a high-performance Vue 3 virtual scroll library designed to handle massive lists with ease. It supports vertical, horizontal, and bidirectional (grid) scrolling, dynamic item sizes using ResizeObserver, and full support for Right-to-Left (RTL) layouts.
Key Features
Bidirectional Scrolling
Virtualize both rows and columns for massive data grids.
Dynamic Item Sizes
Automatic measurement via ResizeObserver for precise scrolling.
RTL Support
Automatic direction detection and correct coordinate mapping for RTL layouts.
Native Window Scroll
Use the browser window/body as the scroll container.
Sticky Headers/Footers
iOS-style pushing headers for segmented lists and groups.
Scroll Restoration
Maintains position when prepending items (perfect for chat).
SSR & Hydration
Full support for server-side rendering and client hydration.
Massive List Support
Handles 10M+ items via automatic coordinate scaling (except for window/body containers).
Virtual Scrollbars
Fully customizable virtual scrollbars that replace native ones.
Quick Start
Install the package using your favorite package manager:
pnpm add @pdanpdan/virtual-scrollBasic usage in a Vue component:
<script setup>
import { VirtualScroll } from "@pdanpdan/virtual-scroll";
import "@pdanpdan/virtual-scroll/style.css";
const items = Array.from({ length: 1000 }, (_, i) => ({ id: i, name: `Item ${i}` }));
</script>
<template>
<VirtualScroll :items="items" :item-size="50" class="h-96">
<template #item="{ item }">
<div class="h-12 flex items-center px-4 border-b border-base-200">
{{ item.name }}
</div>
</template>
</VirtualScroll>
</template>Usage Modes
Compiled Component
Recommended for most projects. Uses pre-compiled JS.
import { VirtualScroll } from "@pdanpdan/virtual-scroll";
import "@pdanpdan/virtual-scroll/style.css";- Compatible with all modern bundlers.
- Note: Manual CSS import is required.
Original Vue SFC
Import raw source for custom compilation.
import VS from "@pdanpdan/virtual-scroll/VirtualScroll.vue";- Enables better tree-shaking in your build.
- Styles handled by your Vue loader.
CDN Usage
Use directly in browser without build step.
<script src="https://unpkg.com/vue@3"></script>
<link rel="stylesheet" href="https://unpkg.com/@pdanpdan/virtual-scroll/dist/style.css">
<script src="https://unpkg.com/@pdanpdan/virtual-scroll"></script>- No installation required.
- Available via
window.VirtualScroll.
Sizing Guide
The library offers flexible ways to define item and column sizes. Calculations are optimized based on the type of sizing used.
| Type | itemSize / columnWidth | Perf | Description |
|---|---|---|---|
| Fixed | number | Best | Uniform size for all items. Calculations are O(1). |
| Array | number[] (cols only) | Great | Fixed sizes from array (cycles if shorter). O(log n). |
| Function | (item, idx) => number | Good | Known but variable sizes. No ResizeObserver overhead unless measured size differs. |
| Dynamic | 0, null, undefined | Fair | Sizes measured via ResizeObserver after rendering. |
VirtualScroll Component
The VirtualScroll component is the primary way to use this library. It provides a declarative Vue interface for virtualizing large lists and grids, handling all rendering, recycling, and scroll logic automatically.
Props
Core Configuration
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | - | The array of items to render. Required. |
itemSize | number | fn | null | 40 | Fixed size or function. See Sizing Guide. |
direction | 'vertical' | 'horizontal' | 'both' | 'vertical' | The scroll direction. |
gap | number | 0 | Spacings between items (vertical or horizontal). |
Grid Configuration (only for direction="both")
| Prop | Type | Default | Description |
|---|---|---|---|
columnCount | number | 0 | Number of columns for grid mode. |
columnWidth | num | arr | fn | null | 100 | Width for columns in grid mode. |
columnGap | number | 0 | Spacings between columns. |
Features & Behavior
| Prop | Type | Default | Description |
|---|---|---|---|
stickyIndices | number[] | [] | Indices of items that should remain sticky. |
stickyHeader / stickyFooter | boolean | false | If true, header/footer size is measured and added to padding. |
ssrRange | {start, end, ...} | - | Range of items to pre-render. See SSR Support. |
loading | boolean | false | Shows #loading slot and prevents multiple load events. |
loadDistance | number | 200 | Distance from end to trigger load event. |
virtualScrollbar | boolean | false | Whether to force use of virtual scrollbars. Automatically enabled for massive lists. Note: Disabled when using window/body as container. |
restoreScrollOnPrepend | boolean | false | Maintain scroll position when items are added to the top. |
initialScrollIndex | number | - | Index to jump to on mount. |
initialScrollAlign | ScrollAlignment | Options | 'start' | Alignment for initial index. |
Accessibility
| Prop | Type | Default | Description |
|---|---|---|---|
role | string | 'list' | 'grid' | ARIA role for the container. Automatically detected based on direction. |
ariaLabel | string | - | Accessible label for the scroll container. |
ariaLabelledby | string | - | ID of the element that labels the scroll container. |
itemRole | string | - | ARIA role for each item. Set to 'none' to manually apply roles using getItemAriaProps. |
ScrollAlignment
Controls the item's final position in the viewport: 'start' | 'center' | 'end' | 'auto'.
Advanced & Performance
| Prop | Type | Default | Description |
|---|---|---|---|
container | El | Window | null | undefined | The scrollable container. Defaults to component root. |
scrollPaddingStart / End | num | {x, y} | 0 | Additional padding for scroll offsets. |
containerTag / wrapperTag / itemTag | string | 'div' | HTML tags for different parts of the component. |
bufferBefore / bufferAfter | number | 5 | Number of items to render outside the viewport. |
defaultItemSize | number | 40 | Estimated size for items before measurement. |
defaultColumnWidth | number | 100 | Estimated width for columns before measurement. |
debug | boolean | false | Enables debug mode (visible offsets and indices). |
Slots
#item
Scoped slot for individual items.
item: T: The data item from the source array.index: number: The original 0-based index of the item.isSticky: boolean:trueif the item is configured to be sticky viastickyIndices.isStickyActive: boolean:trueif the item is currently stuck at the threshold.isStickyActiveX / Y: boolean:trueif the item is stuck at the horizontal/vertical threshold.offset: { x, y }: Calculated physical position (DU).columnRange: ColumnRange: Precise indices and paddings for visible columns.getColumnWidth: (index: number) => number: Helper to get the calculated width of any column.getItemAriaProps: (index: number) => object: Helper to get ARIA attributes for an item (e.g.role="listitem",aria-posinset).getCellAriaProps: (index: number) => object: Helper to get ARIA attributes for a cell (e.g.role="gridcell",aria-colindex).gap: number: Vertical gap between items.columnGap: number: Horizontal gap between columns.
#scrollbar
Scoped slot for custom scrollbar implementation.
axis: 'vertical' | 'horizontal': The scrollbar axis.positionPercent: number: Current scroll position (0 to 1).viewportPercent: number: Viewport as percentage of total size.thumbSizePercent: number: Calculated thumb size (0 to 100).thumbPositionPercent: number: Calculated thumb position (0 to 100).trackProps: object: Attributes and listeners for the track element.thumbProps: object: Attributes and listeners for the thumb element.isDragging: boolean: Whether the thumb is currently being dragged.scrollbarProps: object: Grouped properties forVirtualScrollbar.axis: 'vertical' | 'horizontal'totalSize: numberposition: numberviewportSize: numberscrollToOffset: (offset: number) => voidcontainerId: stringisRtl: boolean
#header / #footer
Content rendered above/below the virtualized items. Can be made sticky using the stickyHeader / stickyFooter props.
#loading
Shown at the end of the scrollable area when loading prop is true. Prevents redundant load events.
ScrollbarSlotProps
Properties passed to the 'scrollbar' scoped slot and useVirtualScrollbar return value.
<template>
<VirtualScroll :items="items" direction="both" virtual-scrollbar>
<template #scrollbar="{ trackProps, thumbProps, axis }">
<!-- Vertical Track -->
<div v-if="axis === 'vertical'" v-bind="trackProps" class="w-2 bg-base-300">
<div v-bind="thumbProps" class="bg-primary rounded" />
</div>
<!-- Horizontal Track -->
<div v-else v-bind="trackProps" class="h-2 bg-base-300">
<div v-bind="thumbProps" class="bg-secondary rounded" />
</div>
</template>
</VirtualScroll>
</template>| Property | Type | Description |
|---|---|---|
axis | 'vertical' | 'horizontal' | The scrollbar axis. |
totalSize | number | Total scrollable content size. |
position | number | Current scroll offset. |
positionPercent | number | Scroll position percentage (0-1). |
viewportSize | number | Visible viewport size. |
viewportPercent | number | Viewport percentage of total (0-1). |
thumbSizePercent | number | Calculated thumb size percentage (0-100). |
thumbPositionPercent | number | Calculated thumb position percentage (0-100). |
scrollToOffset | Function | Scroll to pixel offset on this axis. |
isRtl | boolean | Current RTL state. |
trackProps | Record<string, unknown> | Attributes/listeners for the track. Bind with v-bind="trackProps". Includes class and style. |
thumbProps | Record<string, unknown> | Attributes/listeners for the thumb. Bind with v-bind="thumbProps". Includes class and style. |
isDragging | boolean | Whether the thumb is currently being dragged. |
Events
| Event | Payload | Description |
|---|---|---|
scroll | ScrollDetails<T> | Emitted on every scroll position change. |
load | 'vertical' | 'horizontal' | Triggered when the user scrolls within loadDistance of the end. |
visibleRangeChange | { start, end, colStart, colEnd } | Emitted when the set of rendered indices changes. |
Keyboard Navigation
The container is keyboard-accessible when focused (tabindex="0"). It supports standard navigation keys:
CSS Classes
| Class | Description |
|---|---|
.virtual-scroll-container | The root scrollable container element. |
.virtual-scroll-wrapper | Wraps rendered items and provides total scrollable dimensions. |
.virtual-scroll-item | Applied to each individual rendered item. Use for general item styling. |
.virtual-scroll-header / .virtual-scroll-footer | Containers for header and footer slots. |
.virtual-scroll-loading | Container for the loading slot. |
.virtual-scroll--vertical / --horizontal / --both | Direction modifiers applied to the root container. |
.virtual-scroll--hydrated | Applied after client-side mount and hydration is complete. |
.virtual-scroll--window | Applied when scrolling via the global window object. |
.virtual-scroll--table | Applied when containerTag="table" is used. |
.virtual-scroll--sticky | Applied to items that are currently stuck to the viewport edge. |
.virtual-scroll--debug | Visible when debug prop is active. |
.virtual-scroll--hide-scrollbar | Applied when virtual scrollbars are enabled or content is massive. |
CSS Variables
The default VirtualScrollbar can be styled using the following CSS variables:
| Variable | Default (Light/Dark) | Description |
|---|---|---|
--vs-scrollbar-bg | rgba(230,230,230,0.9) / rgba(30,30,30,0.9) | Track background color. |
--vs-scrollbar-thumb-bg | rgba(0,0,0,0.3) / rgba(255,255,255,0.3) | Thumb background color. |
--vs-scrollbar-thumb-hover-bg | rgba(0,0,0,0.6) / rgba(255,255,255,0.6) | Thumb background on hover/active. |
--vs-scrollbar-size | 8px | Width (vertical) or height (horizontal) of the scrollbar. |
--vs-scrollbar-radius | 4px | Border radius for track and thumb. |
--vs-scrollbar-cross-gap | var(--vs-scrollbar-size) | Size of gap to use where scrollbars meet. |
--vs-scrollbar-has-cross-gap | 0 | If gap should be shown where scrollbars meet. |
Exposed Members
The VirtualScroll component exposes several reactive properties and methods from the underlying logic. You can access these via a template ref.
Properties
All PropsAll component props are available on the instance.
scrollDetailsFull reactive state of the virtualizer.
columnRangeVisible column indices and paddings.
isHydratedMounted and ready for virtualization.
isRtlRight-to-Left mode active.
scrollbarPropsVerticalReactive vertical scrollbar properties.
scrollbarPropsHorizontalReactive horizontal scrollbar properties.
scaleX / scaleYCurrent coordinate scaling factors.
componentOffsetAbsolute offset of the component within its container.
renderedWidth / renderedHeightPhysical dimensions in DOM (clamped).
Methods
scrollToIndex()Scroll to a specific row/column.
scrollToOffset()Scroll to precise pixel position.
stopProgrammaticScroll()Halt smooth scroll animations.
getColumnWidth()Get calculated width of a column.
getRowHeight()Get calculated height of a row.
getRowOffset()Get virtual offset of a row.
getColumnOffset()Get virtual offset of a column.
getItemOffset()Get virtual offset of an item.
getItemSize()Get item size along scroll axis.
getItemAriaProps()Get ARIA attributes for an item.
getCellAriaProps()Get ARIA attributes for a cell.
refresh()Reset all dynamic measurements.
updateDirection()Trigger RTL/LTR detection.
updateHostOffset()Recalculate container position.
updateItemSize()Manually register measurement.
updateItemSizes()Batch register measurements.
VirtualScrollbar Component
The VirtualScrollbar component provides a cross-browser consistent scrollbar that can be used independently or within the VirtualScroll component. Check out the Independent Scrollbars example to see it in action without virtualization.
<script setup>
import { VirtualScrollbar } from "@pdanpdan/virtual-scroll";
import { ref } from "vue";
const scrollX = ref(0);
const scrollY = ref(0);
</script>
<template>
<div class="relative overflow-hidden h-96">
<!-- Vertical Scrollbar -->
<VirtualScrollbar
axis="vertical"
:total-size="10000"
:viewport-size="400"
:position="scrollY"
@scroll-to-offset="val => scrollY = val"
/>
<!-- Horizontal Scrollbar -->
<VirtualScrollbar
axis="horizontal"
:total-size="10000"
:viewport-size="800"
:position="scrollX"
@scroll-to-offset="val => scrollX = val"
/>
</div>
</template>Props
| Prop | Type | Default | Description |
|---|---|---|---|
axis | 'vertical' | 'horizontal' | - | The axis of the scrollbar. Required. |
totalSize | number | - | Total size of the scrollable content in pixels. Required. |
viewportSize | number | - | Size of the visible viewport in pixels. Required. |
position | number | - | Current scroll position in pixels. Required. |
containerId | string | undefined | ID of the container element for accessibility. |
ariaLabel | string | - | Accessible label for the scrollbar. |
Events
| Event | Payload | Description |
|---|---|---|
scroll-to-offset | number | Emitted when the user interacts with the scrollbar to change position. |
Composables
useVirtualScroll
Provides the core virtualization logic. Recommended for advanced use cases or when building custom wrappers.
import { useVirtualScroll } from '@pdanpdan/virtual-scroll';
import { computed, ref } from 'vue';
const items = ref([...]);
const props = computed(() => ({
items: items.value,
itemSize: 50,
direction: 'vertical'
}));
const {
renderedItems,
scrollDetails,
totalHeight,
scrollToIndex
} = useVirtualScroll(props);Parameters
Accepts a single MaybeRefOrGetter to a VirtualScrollProps object.
Return Value
| Member | Type | Description |
|---|---|---|
| renderedItems | Ref<RenderedItem<T>[]> | List of items to render in the current buffer. |
| scrollDetails | Ref<ScrollDetails<T>> | Full reactive state of the virtual scroll system. |
totalWidth / totalHeight | Ref<number> | Calculated dimensions of the entire list/grid (VU). |
renderedWidth / renderedHeight | Ref<number> | Total dimensions to be rendered in the DOM (clamped to browser limits, DU). |
| columnRange | Ref<ColumnRange> | Visible columns and their associated paddings. |
isHydrated | Ref<boolean> | true when the component is mounted and hydrated. |
isRtl | Ref<boolean> | true if the scroll container is in Right-to-Left mode. |
| scrollToIndex | Function | Programmatic scroll to a specific index. |
| scrollToOffset | Function | Programmatic scroll to a pixel offset. |
| stopProgrammaticScroll | Function | Cancel any active smooth scroll animation. |
| updateItemSize | Function | Register a manual item measurement. |
| updateItemSizes | Function | Register multiple manual item measurements. |
| updateHostOffset | Function | Force update the container's relative position. |
updateDirection | Function | Manually trigger direction (LTR/RTL) detection. |
getItemAriaProps | Function | Helper to get ARIA attributes for an item. |
getCellAriaProps | Function | Helper to get ARIA attributes for a cell. |
getColumnWidth | Function | Helper to get a column's width. |
| getRowHeight | Function | Helper to get a row's height. |
| getRowOffset | Function | Helper to get a row's virtual offset (VU). |
| getColumnOffset | Function | Helper to get a column's virtual offset (VU). |
| getItemOffset | Function | Helper to get an item's virtual offset (VU). |
| getItemSize | Function | Helper to get an item's size along scroll axis (VU). |
| refresh | Function | Resets all measurements and state. |
scaleX / scaleY | Ref<number> | Current coordinate scaling factors (VU / DU). |
componentOffset | { x: Ref<number>, y: Ref<number> } | Absolute offset of the component in its container (DU). |
useVirtualScrollbar
Provides the logic for virtual scrollbar interactions. It handles track clicks, thumb dragging, and coordinate mapping (including RTL).
import { useVirtualScrollbar } from '@pdanpdan/virtual-scroll';
const {
trackProps,
thumbProps,
thumbSizePercent,
thumbPositionPercent
} = useVirtualScrollbar({
axis: 'vertical',
totalSize: 10000,
viewportSize: 500,
position: scrollPos,
scrollToOffset: (val) => { scrollPos = val; }
});Parameters
Accepts a UseVirtualScrollbarProps object where each property can be a MaybeRefOrGetter.
Return Value
| Member | Type | Description |
|---|---|---|
trackProps | ComputedRef<object> | Attributes and listeners for the track element. Includes class and style. |
thumbProps | ComputedRef<object> | Attributes and listeners for the thumb element. Includes class and style. |
viewportPercent | ComputedRef<number> | Viewport size as percentage of total size (0-1). |
positionPercent | ComputedRef<number> | Scroll position as percentage of scrollable range (0-1). |
thumbSizePercent | ComputedRef<number> | Calculated thumb size (percentage of track, 0-100). |
thumbPositionPercent | ComputedRef<number> | Calculated thumb position (percentage of track, 0-100). |
isDragging | Ref<boolean> | Whether the thumb is currently being dragged. |
API Reference
Types
ScrollDirection
'vertical' | 'horizontal' | 'both'Defines the virtualization axes for the VirtualScroll component.
ScrollAxis
'vertical' | 'horizontal'Used specifically for individual scrollbar instances.
ScrollDetails<T>
| Property | Type | Description |
|---|---|---|
items | RenderedItem<T>[] | Rendered items in the buffer. |
currentIndex | number | First visible row index below any sticky header. |
currentColIndex | number | First visible column index after any sticky column. |
scrollOffset | { x, y } | Current relative scroll position in virtual units (VU). |
displayScrollOffset | { x, y } | Current physical scroll position in display pixels (DU). |
viewportSize | { width, height } | Dimensions of the visible viewport in virtual units (VU). |
displayViewportSize | { width, height } | Physical dimensions of the visible viewport in display pixels (DU). |
totalSize | { width, height } | Estimated total content dimensions (VU). |
isScrolling | boolean | Active scrolling state. |
isProgrammaticScroll | boolean | True if triggered by scrollToIndex/Offset. |
range | { start, end } | Visible row range (inclusive start, exclusive end). |
columnRange | ColumnRange | Visible column range (grid). |
RenderedItem<T>
| Property | Type | Description |
|---|---|---|
item | T | The source data item. |
index | number | Item's position in the array. |
offset | { x, y } | Absolute pixel position within the wrapper (DU). |
size | { width, height } | Current dimensions (VU). |
originalX / originalY | number | Offsets before any sticky adjustments (VU). |
isSticky | boolean | Is configured as sticky. |
isStickyActive | boolean | Currently stuck to the edge. |
stickyOffset | { x, y } | Translation applied for sticky pushing effect (DU). |
ColumnRange
| Property | Type | Description |
|---|---|---|
start | number | Index of first rendered column. |
end | number | Index of last rendered column (exclusive). |
padStart | number | Pixel space to maintain before columns (VU). |
padEnd | number | Pixel space to maintain after columns (VU). |
VirtualScrollProps<T>
Full property configuration shared between the component and composable.
| Property | Type | Description |
|---|---|---|
items | T[] | Data source. Required. |
itemSize | num | fn | null | Sizing logic. Default: 40px. |
direction | ScrollDirection | 'vertical' | 'horizontal' | 'both'. |
bufferBefore / bufferAfter | number | Items outside viewport. Default: 5. |
container | HTMLElement | Window | Scroll container. Defaults to component root. |
hostElement | HTMLElement | Reference for offset calculation (DU). |
ssrRange | SSRRange | Pre-rendered range for SSR. |
columnCount | number | Total columns for grid mode. |
columnWidth | num | arr | fn | null | Column sizing. Default: 100px. |
scrollPaddingStart / End | num | {x, y} | Pixel offsets for scroll limits. |
gap / columnGap | number | Pixel space between items/cols. |
restoreScrollOnPrepend | boolean | Maintain chat scroll position. |
initialScrollIndex | number | Mount-time jump index. |
initialScrollAlign | ScrollAlignment | Options | Alignment for initial jump. |
defaultItemSize | number | Estimate for dynamic items. |
defaultColumnWidth | number | Estimate for dynamic columns. |
debug | boolean | Enable visualization. |
UseVirtualScrollbarProps
| Property | Type | Description |
|---|---|---|
axis | 'vertical' | 'horizontal' | Axis of the scrollbar. |
totalSize | number | Total size of content in pixels. |
position | number | Current scroll position in pixels. |
viewportSize | number | Visible area size in pixels. |
scrollToOffset | (offset: number) => void | Callback to update position. |
containerId | string | ID for accessibility. |
isRtl | boolean | Enable RTL mapping. |
ariaLabel | string | Accessible label for the scrollbar. |
ScrollToIndexOptions
Full configuration for index-based scrolling.
| Property | Type | Description |
|---|---|---|
align | ScrollAlignment | Options | Where to align the item (default: 'auto'). |
behavior | 'auto' | 'smooth' | Scroll behavior (default: 'smooth'). |
ScrollAlignmentOptions
Allows axis-specific alignment in scrollToIndex.
| Property | Type | Description |
|---|---|---|
x | ScrollAlignment | Alignment on the horizontal axis. |
y | ScrollAlignment | Alignment on the vertical axis. |
ScrollAlignment
Controls the item's final position in the viewport during scrollToIndex.
| Value | Behavior |
|---|---|
'start' | Aligns to top (vertical) or left (horizontal) edge. |
'center' | Aligns to viewport center. |
'end' | Aligns to bottom (vertical) or right (horizontal) edge. |
'auto' Default | Smart: If the item is already fully visible, no scroll occurs. Otherwise, aligns to 'start' or 'end' to bring it into view. |
Methods
Method scrollToIndex()
scrollToIndex(
rowIndex: number | null,
colIndex: number | null,
options?: ScrollAlignment | ScrollAlignmentOptions | ScrollToIndexOptions
): voidEnsures a specific item is visible within the viewport. If the item's size is dynamic and not yet measured, the scroll position will be automatically corrected after rendering.
| Parameter | Type | Description |
|---|---|---|
rowIndex | number | null | Target row. null to keep current Y. |
colIndex | number | null | Target column. null to keep current X. |
options | Options | Alignment and behavior settings. |
Method scrollToOffset()
scrollToOffset(
x: number | null,
y: number | null,
options?: { behavior?: 'auto' | 'smooth' } // behavior default: 'auto'
): voidScrolls the container to an absolute pixel position. Clamped between 0 and the calculated total size.
Method refresh()
Invalidates all cached measurements and triggers a full re-initialization. Use this if your item source data changes in a way that affects sizes without changing the items array reference.
Method updateItemSize()
updateItemSize(
index: number,
width: number,
height: number,
element?: HTMLElement
): voidManually registers a new measurement for a single item. The element parameter allows the virtualizer to detect columns from any internal structure using data-col-index attributes.
Method updateItemSizes()
updateItemSizes(updates: Array<{ index: number; inlineSize: number; blockSize: number; element?: HTMLElement }>): voidBatched version of updateItemSize. More efficient when many items are measured simultaneously.
Method updateHostOffset()
Forces a recalculation of the host element's position relative to the scroll container. Call this if the layout changes in a way that shifts the component without triggering a resize event.
Method updateDirection()
Manually triggers the detection of the scroll direction (LTR or RTL). The component also performs this automatically on mount and whenever the container prop changes.
Method getColumnWidth()
getColumnWidth(index: number): numberReturns the currently calculated width for a specific column index, taking measurements and gaps into account.
Method getRowHeight()
getRowHeight(index: number): numberReturns the currently calculated height for a specific row index, taking measurements and gaps into account.
Method getRowOffset()
getRowOffset(index: number): numberReturns the virtual vertical offset (top) of a row in virtual units (VU).
Method getColumnOffset()
getColumnOffset(index: number): numberReturns the virtual horizontal offset (left) of a column in virtual units (VU).
Method getItemOffset()
getItemOffset(index: number): numberReturns the virtual offset of an item along the scroll axis in virtual units (VU).
Method getItemSize()
getItemSize(index: number): numberReturns the size of an item along the scroll axis in virtual units (VU).
Method getItemAriaProps()
getItemAriaProps(index: number): Record<string, string | number | undefined>Returns the ARIA attributes for an item at the given index. Includes role, aria-setsize, and aria-posinset (or aria-rowindex for grids).
Method getCellAriaProps()
getCellAriaProps(colIndex: number): Record<string, string | number | undefined>Returns the ARIA attributes for a cell at the given column index. Only relevant for direction="both" or role="grid". Includes role="gridcell" and aria-colindex.
Method stopProgrammaticScroll()
Immediately halts any active smooth scroll animation and clears pending scroll requests.
Utility Functions
Type Guards
isElement(val): Checks if a value is a standard HTMLElement (explicitly excluding window).
isWindow(val): Checks for global window object.
isBody(val): Checks for document.body.
isWindowLike(val): Matches window or body.
isScrollableElement(val): Checks if a value is an HTMLElement or Window that exposes native scroll properties like scrollLeft.
isScrollToIndexOptions(val): Type guard for ScrollToIndexOptions object.
getPaddingX / getPaddingY
(p: number | object, dir: string): number
Extracts effective pixel padding from scrollPadding props, taking the current direction into account.
Coordinate Mapping
displayToVirtual(displayPos, hostOffset, scale): Maps display pixels (DU) to virtual content position (VU).
virtualToDisplay(virtualPos, hostOffset, scale): Maps virtual content position (VU) to display pixels (DU).
isItemVisible
(pos, size, scroll, view, sticky?): boolean
Highly accurate visibility check (VU) used for auto-alignment and rendering ranges.
FenwickTree
class FenwickTree(size: number)
Highly optimized data structure for O(log n) prefix sum calculations and point updates. Used internally for all position tracking.
Default Values & Constants
DEFAULT_ITEM_SIZE40pxDEFAULT_COLUMN_WIDTH100pxDEFAULT_BUFFER5 itemsBROWSER_MAX_SIZE10,000,000px Values applied when props are omitted or dynamic estimates are needed. BROWSER_MAX_SIZE defines the scaling threshold.
SSR & Hydration
The library supports Server-Side Rendering via the ssrRange prop. When provided, the specified items are rendered "in-flow" on the server.
Hydration Logic
- Server: Renders a static block of items at
ssrRange. - Client (Pre-mount): Renders the same items to match server HTML.
- Client (Mounted): Calculates total dimensions, scrolls to exactly match the pre-rendered range, and then transitions to absolute positioning for virtualization.