Positioning
The component provides properties to position the list either on an element, or at a pixel offset.
Scroll to row index
Scroll to pixel offset
Alignment
Behaviour
Visible Area: start 0 - end 0
#0
3694
#1
8736
#2
9774
#3
7001
#4
3554
#5
1320
<script lang="ts">
import { ALIGNMENT, SCROLL_BEHAVIOR, type VLRangeEvent, type VLSlotSignature } from '$lib';
import { VirtualList } from 'svelte-virtuallists';
const myModel = $state(new Array(10000));
// used for the positioning pointers
let start = $state(0);
let end = $state(0);
// on the UI
let theScrollToIndex: number | undefined = $state();
let theScrollOffet: number | undefined = $state();
// on the component
let scrollToIndex: number | undefined = $state();
let scrollToOffet: number | undefined = $state();
let scrollToAlignment: ALIGNMENT = $state(ALIGNMENT.AUTO);
let scrollToBehaviour: SCROLL_BEHAVIOR = $state(SCROLL_BEHAVIOR.SMOOTH);
let szCalculator: ((index: number, item: unknown) => number) | undefined = $state();
// holds randomized sizes
let randSizes: Array<number>;
function handleVisualRangeChange(event: VLRangeEvent) {
start = event.start;
end = event.end;
}
// The two effects below are an elegant VLRangeEventensure only one fo the value is defined
$effect(() => {
// scrollToIndex and scrollOffset shall not be used together.
scrollToIndex = undefined;
scrollToOffet = theScrollOffet;
});
$effect(() => {
// scrollToIndex and scrollOffset shall not be used together.
scrollToOffet = undefined;
scrollToIndex = theScrollToIndex;
});
function randomizeSize() {
randSizes = new Array(myModel.length);
for (let i = 0; i < randSizes.length; i++) {
randSizes[i] = Math.round(Math.random() * 65 + 30);
}
szCalculator = (_index: number, _item: any) => randSizes[_index];
}
function sameSize() {
szCalculator = () => 25;
}
function randomizeContent() {
for (let i = 0; i < myModel.length; i++) {
myModel[i] = { text: Math.floor(Math.random() * myModel.length) }; // Random number between 0 and 9999
}
}
function stripItemsBy10() {
for (let i = 0; i < 10; i++) myModel.pop();
}
randomizeContent();
sameSize();
</script>
<div class="actions">
<div class="select">
<span>
Scroll to row index
<input
id="index"
type="number"
placeholder="pick an index..."
class="input"
bind:value={theScrollToIndex} />
</span>
</div>
<div class="select">
<span>
Scroll to pixel offset
<input
id="offset"
type="number"
placeholder="pick an offset..."
class="input"
bind:value={theScrollOffet} />
</span>
</div>
<div class="select">
<span>
Alignment
<select id="alignment" bind:value={scrollToAlignment}>
<option value="auto">auto</option>
<option value="start">start</option>
<option value="center">center</option>
<option value="end">end</option>
</select>
</span>
</div>
<div class="select">
<span>
Behaviour
<select id="behaviour" bind:value={scrollToBehaviour}>
<option value="auto">auto</option>
<option value="smooth">smooth</option>
<option value="instant">instant</option>
</select>
</span>
</div>
</div>
<div style="font-weight: bold">
<span>Visible Area: start</span>
<span>{start}</span>
-
<span>end</span>
<span>{end}</span>
</div>
<VirtualList
items={myModel}
style="height:500px"
{scrollToIndex}
scrollToOffset={scrollToOffet}
{scrollToAlignment}
{scrollToBehaviour}
sizingCalculator={szCalculator}
onVisibleRangeUpdate={handleVisualRangeChange}>
{#snippet vl_slot({ index, item, size }: VLSlotSignature<(typeof myModel)[0]>)}
<div
style="border: 1px solid rgb(204, 204, 204); line-height: {size}px;"
class:highlighted={index === scrollToIndex}>
#{index}
{item.text}
</div>
{/snippet}
</VirtualList>
<div class="actions">
<button onclick={randomizeSize} class="button">Randomize row heights</button>
<button onclick={sameSize} class="button">Same row heights</button>
<button onclick={randomizeContent} class="button">Randomize content</button>
<button onclick={stripItemsBy10} class="button">array size -10</button>
</div>
<style>
.highlighted {
background: #efefef;
}
</style>
previous Variable Sizing
next Events