Scroll Restoration
Maintain scroll position when prepending items
Demonstrates the restoreScrollOnPrepend prop. Currently showing 50 items. When items are added to the beginning of the list, the scroll position is adjusted to keep the current view stable.
#0Original Item 0
#1Original Item 1
#2Original Item 2
#3Original Item 3
#4Original Item 4
<script setup lang="ts">
import type { Ref } from 'vue';
import { VirtualScroll } from '@pdanpdan/virtual-scroll';
import { inject, ref } from 'vue';
import ExampleContainer from '#/components/ExampleContainer.vue';
import ScrollStatus from '#/components/ScrollStatus.vue';
import { useExampleScroll } from '#/lib/useExampleScroll';
import { html as highlightedCode } from './+Page.vue?highlight';
const items = ref(Array.from({ length: 50 }, (_, i) => ({ id: `orig-${ i }`, label: `Original Item ${ i }` })));
const prependCount = ref(0);
const restoreScrollOnPrepend = ref(true);
const {
scrollDetails,
onScroll,
} = useExampleScroll();
const debugMode = inject<Ref<boolean>>('debugMode', ref(false));
function prependItems() {
const count = 5;
const newItems = Array.from({ length: count }, (_, i) => ({
id: `prepended-${ prependCount.value + i }`,
label: `Prepended Item ${ prependCount.value + i }`,
}));
items.value = [ ...newItems, ...items.value ];
prependCount.value += count;
}
const appendCount = ref(0);
function appendItems() {
const count = 5;
const newItems = Array.from({ length: count }, (_, i) => ({
id: `appended-${ appendCount.value + i }`,
label: `Appended Item ${ appendCount.value + i }`,
}));
items.value = [ ...items.value, ...newItems ];
appendCount.value += count;
}
</script>
<template>
<ExampleContainer :code="highlightedCode">
<template #title>
<span class="example-title example-title--group-2">Scroll Restoration</span>
</template>
<template #description>
Demonstrates the <strong>restoreScrollOnPrepend</strong> prop. Currently showing {{ items.length.toLocaleString() }} items. When items are added to the beginning of the list, the scroll position is adjusted to keep the current view stable.
</template>
<template #icon>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="example-icon example-icon--group-2"
>
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99" class="rotate-180 origin-center" />
</svg>
</template>
<template #subtitle>
Maintain scroll position when prepending items
</template>
<template #controls>
<ScrollStatus :scroll-details="scrollDetails" direction="vertical" />
</template>
<template #example-controls>
<div class="flex flex-wrap gap-4 items-center">
<label class="settings-item group">
<span class="settings-label pe-4">Restore on Prepend</span>
<input v-model="restoreScrollOnPrepend" type="checkbox" class="toggle toggle-primary toggle-sm" />
</label>
<button class="btn btn-sm btn-soft btn-primary" @click="prependItems">Prepend 5</button>
<button class="btn btn-sm btn-soft btn-primary" @click="appendItems">Append 5</button>
<button class="btn btn-sm btn-soft btn-error" @click="items = []">Clear Items</button>
</div>
</template>
<VirtualScroll
:debug="debugMode"
class="example-container"
:items="items"
:item-size="60"
:restore-scroll-on-prepend="restoreScrollOnPrepend"
aria-label="Scroll restoration list"
@scroll="onScroll"
>
<template #item="{ item, index }">
<div class="example-vertical-item example-vertical-item--fixed">
<span class="example-badge me-4">#{{ index }}</span>
<span class="font-medium">{{ item.label }}</span>
</div>
</template>
</VirtualScroll>
</ExampleContainer>
</template>
- Scroll Status
- Directionvertical
- Current Item #-
- Rendered Range #0:0
- Total Size (px)0h
- Viewport Size (px)0h
- Scroll Offset (px)0y