A long list where only the rows near the viewport are in the DOM.
Import it from rei-kit:
import { VirtualList } from 'rei-kit'
Open VirtualList in the live documentation, where every prop below is a control you can change, in four materials and ten palettes.
<script setup lang="ts">
import { VirtualList } from 'rei-kit'
/** Long enough that rendering all of it would be the reason to reach for this. */
const ROWS = Array.from({ length: 5000 }, (_, index) => ({
id: index,
name: `Row ${index + 1}`,
}))
</script>
<template>
<VirtualList
:items="ROWS"
:row-height="36"
label="Five thousand rows"
class="border-hair max-h-56 rounded-xl border"
>
<template #default="{ item }">
<span class="text-ink flex h-full items-center px-3 text-sm">{{ item.name }}</span>
</template>
</VirtualList>
</template>
| Prop | Type | Required or default | What it is for |
|---|---|---|---|
items | readonly T[] | yes | The whole list. Only the rows near the viewport are rendered. |
rowHeight | number | yes | Every row is this tall, in pixels. |
label | string | yes | Names the list, e.g. "Bütün kayıtlar". Already translated. |
virtualizeAfter | number | 50 | Below this many rows the list is not windowed at all. |
scrollbar | 'auto' | 'hidden' | 'auto' | Passed to the scroll area: `hidden` takes the native bar away. |
rei-kit is an accessible Vue 3 and Tailwind CSS 4 component library: 106 components, themed by role rather than by colour on three independent axes — ten WCAG-checked palettes, four materials and light or dark, each switched with one attribute. Typed, tested, SSR-safe, no runtime dependencies, MIT.