diff --git a/src/shared/ui/VirtualList/VirtualList.svelte b/src/shared/ui/VirtualList/VirtualList.svelte index 2ce1070..d4e2f05 100644 --- a/src/shared/ui/VirtualList/VirtualList.svelte +++ b/src/shared/ui/VirtualList/VirtualList.svelte @@ -76,6 +76,18 @@ interface Props { * ``` */ onNearBottom?: (lastVisibleIndex: number) => void; + /** + * Snippet for rendering individual list items. + * + * The snippet receives an object containing: + * - `item`: The item from the items array (type T) + * - `index`: The current item's index in the array + * + * This pattern provides type safety and flexibility for + * rendering different item types without prop drilling. + * + * @template T - The type of items in the list + */ /** * Snippet for rendering individual list items. * @@ -89,8 +101,13 @@ interface Props { * @template T - The type of items in the list */ children: Snippet< - [{ item: T; index: number; isVisible: boolean; proximity: number }] + [{ item: T; index: number; isFullyVisible: boolean; isPartiallyVisible: boolean; proximity: number }] >; + /** + * Whether to use the window as the scroll container. + * @default false + */ + useWindowScroll?: boolean; } let { @@ -102,6 +119,7 @@ let { onVisibleItemsChange, onNearBottom, children, + useWindowScroll = false, }: Props = $props(); // Reference to the ScrollArea viewport element for attaching the virtualizer @@ -112,6 +130,7 @@ const virtualizer = createVirtualizer(() => ({ data: items, estimateSize: typeof itemHeight === 'function' ? itemHeight : () => itemHeight, overscan, + useWindowScroll, })); // Attach virtualizer.container action to the viewport when it becomes available @@ -139,30 +158,61 @@ $effect(() => { }); - -
- {#each virtualizer.items as item (item.key)} -
- {#if item.index < items.length} - {@render children({ +{#if useWindowScroll} +
+
+ {#each virtualizer.items as item (item.key)} +
+ {#if item.index < items.length} + {@render children({ // TODO: Fix indenation rule for this case item: items[item.index], index: item.index, - isVisible: item.isVisible, + isFullyVisible: item.isFullyVisible, + isPartiallyVisible: item.isPartiallyVisible, proximity: item.proximity, })} - {/if} -
- {/each} + {/if} +
+ {/each} +
- +{:else} + +
+ {#each virtualizer.items as item (item.key)} +
+ {#if item.index < items.length} + {@render children({ + // TODO: Fix indenation rule for this case + item: items[item.index], + index: item.index, + isFullyVisible: item.isFullyVisible, + isPartiallyVisible: item.isPartiallyVisible, + proximity: item.proximity, +})} + {/if} +
+ {/each} +
+
+{/if}