diff --git a/src/shared/lib/helpers/createVirtualizer/createVirtualizer.svelte.ts b/src/shared/lib/helpers/createVirtualizer/createVirtualizer.svelte.ts
index 5d0fcec..3482292 100644
--- a/src/shared/lib/helpers/createVirtualizer/createVirtualizer.svelte.ts
+++ b/src/shared/lib/helpers/createVirtualizer/createVirtualizer.svelte.ts
@@ -1,3 +1,84 @@
+/**
+ * Represents a virtualized list item with layout information.
+ *
+ * Used to render visible items with absolute positioning based on computed offsets.
+ */
+export interface VirtualItem {
+ /** Index of the item in the data array */
+ index: number;
+ /** Offset from the top of the list in pixels */
+ start: number;
+ /** Height/size of the item in pixels */
+ size: number;
+ /** End position in pixels (start + size) */
+ end: number;
+ /** Unique key for the item (for Svelte's {#each} keying) */
+ key: string | number;
+}
+
+/**
+ * Configuration options for {@link createVirtualizer}.
+ *
+ * Options are reactive - pass them through a function getter to enable updates.
+ */
+export interface VirtualizerOptions {
+ /** Total number of items in the data array */
+ count: number;
+ /**
+ * Function to estimate the size of an item at a given index.
+ * Used for initial layout before actual measurements are available.
+ */
+ estimateSize: (index: number) => number;
+ /** Number of extra items to render outside viewport for smoother scrolling (default: 5) */
+ overscan?: number;
+ /**
+ * Function to get the key of an item at a given index.
+ * Defaults to using the index directly. Useful for stable keys when items reorder.
+ */
+ getItemKey?: (index: number) => string | number;
+ /**
+ * Optional margin in pixels for scroll calculations.
+ * Can be useful for handling sticky headers or other UI elements.
+ */
+ scrollMargin?: number;
+}
+
+/**
+ * Creates a reactive virtualizer for efficiently rendering large lists by only rendering visible items.
+ *
+ * Uses Svelte 5 runes ($state, $derived) for reactive state management and optimizes rendering
+ * through scroll position tracking and item height measurement. Supports dynamic item heights
+ * and programmatic scrolling.
+ *
+ * @param optionsGetter - Function that returns reactive virtualizer options
+ * @returns Virtualizer instance with computed properties and action functions
+ *
+ * @example
+ * ```svelte
+ *
+ *
+ *
+ *
+ * {#each virtualizer.items as item (item.key)}
+ *
+ * Item {item.index}
+ *
+ * {/each}
+ *
+ *
+ * ```
+ */
export function createVirtualizer(optionsGetter: () => VirtualizerOptions) {
// Reactive State
let scrollOffset = $state(0);
@@ -71,6 +152,15 @@ export function createVirtualizer(optionsGetter: () => VirtualizerOptions) {
});
// Svelte Actions (The DOM Interface)
+
+ /**
+ * Svelte action to attach to the scrollable container element.
+ *
+ * Sets up scroll tracking, container height monitoring, and cleanup on destroy.
+ *
+ * @param node - The DOM element to attach to (should be the scrollable container)
+ * @returns Object with destroy method for cleanup
+ */
function container(node: HTMLElement) {
elementRef = node;
containerHeight = node.offsetHeight;
@@ -95,6 +185,15 @@ export function createVirtualizer(optionsGetter: () => VirtualizerOptions) {
};
}
+ /**
+ * Svelte action to measure individual item elements for dynamic height support.
+ *
+ * Attaches a ResizeObserver to track actual element height and updates
+ * measured sizes when dimensions change. Requires `data-index` attribute on the element.
+ *
+ * @param node - The DOM element to measure (should have `data-index` attribute)
+ * @returns Object with destroy method for cleanup
+ */
function measureElement(node: HTMLElement) {
// Use a ResizeObserver on individual items for dynamic height support
const resizeObserver = new ResizeObserver(([entry]) => {
@@ -116,6 +215,18 @@ export function createVirtualizer(optionsGetter: () => VirtualizerOptions) {
}
// Programmatic Scroll
+
+ /**
+ * Scrolls the container to bring the specified item into view.
+ *
+ * @param index - Index of the item to scroll to
+ * @param align - Scroll alignment: 'start', 'center', 'end', or 'auto' (default)
+ *
+ * @example
+ * ```ts
+ * virtualizer.scrollToIndex(50, 'center'); // Scroll to item 50 and center it
+ * ```
+ */
function scrollToIndex(index: number, align: 'start' | 'center' | 'end' | 'auto' = 'auto') {
if (!elementRef || index < 0 || index >= options.count) return;
@@ -130,42 +241,27 @@ export function createVirtualizer(optionsGetter: () => VirtualizerOptions) {
}
return {
+ /** Computed array of visible items to render (reactive) */
get items() {
return items;
},
+ /** Total height of all items in pixels (reactive) */
get totalSize() {
return totalSize;
},
+ /** Svelte action for the scrollable container element */
container,
+ /** Svelte action for measuring individual item elements */
measureElement,
+ /** Programmatic scroll method to scroll to a specific item */
scrollToIndex,
};
}
-export interface VirtualItem {
- /** Index of the item in the data array */
- index: number;
- /** Offset from the top of the list */
- start: number;
- /** Height of the item */
- size: number;
- /** End position (start + size) */
- end: number;
- /** Unique key for the item (for Svelte's {#each} keying) */
- key: string | number;
-}
-
-export interface VirtualizerOptions {
- /** Total number of items in the data array */
- count: number;
- /** Function to estimate the size of an item at a given index */
- estimateSize: (index: number) => number;
- /** Number of extra items to render outside viewport (default: 5) */
- overscan?: number;
- /** Function to get the key of an item at a given index (defaults to index) */
- getItemKey?: (index: number) => string | number;
- /** Optional margin in pixels for scroll calculations */
- scrollMargin?: number;
-}
-
+/**
+ * Virtualizer instance returned by {@link createVirtualizer}.
+ *
+ * Provides reactive computed properties for visible items and total size,
+ * along with action functions for DOM integration and element measurement.
+ */
export type Virtualizer = ReturnType;