Display
Virtual List
A windowed list with load-older at the top that keeps the scroll position, for long chat histories.
<script>
import { VirtualList } from "@codeatlasdev/ui";
</script>
<VirtualList {items} getKey={(m) => m.id} label="Conversation" {hasMore} loadingMore={loading} onloadmore={loadOlder}>
{#snippet item(m)}<Message {m} />{/snippet}
</VirtualList>
Only the rows in view (plus overscan) are in the DOM; row heights are measured, so they can vary. Prepending older rows keeps the row you were reading in the same place: the list finds the previous first row by getKey and corrects scrollTop. LiveList follows the bottom but cannot prepend history without a jump; this one can, and also follows new rows while you are at the bottom. A visible “Load older messages” button gives keyboard and screen reader users the same trigger as scrolling.
Chat history
Scroll to the top to load older messages; the view does not jump.
- Message 5000
- Message 5001
- Message 5002
- Message 5003
- Message 5004
- Message 5005
- Message 5006
- Message 5007
- Message 5008
- Message 5009
- Message 5010
- Message 5011
- Message 5012
- Message 5013
- Message 5014
- Message 5015
- Message 5016
Reference #254 · Pick in the gallery
Code
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | readonly T[] | – | Rows, oldest first. |
item | Snippet<[T, number]> | – | One row, rendered inside an li. |
getKey | (item: T, index: number) => string | number | – | Stable key per row; required to keep position on prepend. |
label | string | – | Accessible name of the scrolling region. |
estimateSize | number | 56 | Row height guess in px until measured. |
overscan | number | 6 | Extra rows rendered above and below the view. |
height | string | '24rem' | Height of the scrolling area. |
follow | boolean | true | Stay at the bottom while new rows arrive and you are there. |
hasMore | boolean | false | More older rows exist. |
loadingMore | boolean | false | A page is loading. |
loadThreshold | number | 120 | Distance from the top in px that triggers onloadmore. |
onloadmore | () => void | Promise<void> | – | Load the next older page. |
empty | Snippet | – | Shown when there are no rows. |