svelte-infinite-loading
An infinite scroll component for Svelte apps
About • Features • Installation • Usage • API • Examples • Development • License
About
An infinite scroll component for Svelte, to help you implement an infinite scroll list more easily.
This is heavily inspired by vue-infinite-loading and uses most of its code and functionality!
Features
- Mobile friendly
- Built-in spinners
- 2-directional support
- Load result message display
Installation
With npm:
$ npm install svelte-infinite-loading
With yarn:
$ yarn add svelte-infinite-loading
With pnpm:
$ pnpm install svelte-infinite-loading
Usage
<script lang="ts">
import InfiniteLoading, { type StateChanger } from 'svelte-infinite-loading';
type Post = { id: number; title: string };
let page = 0;
const pageSize = 20;
let items: Post[] = $state([]);
async function loadMore(stateChanger: StateChanger) {
try {
const res = await fetch(`/api/posts?page=${page}&limit=${pageSize}`);
const data = (await res.json()) as Post[];
if (data.length === 0) {
stateChanger.complete();
return;
}
items = [...items, ...data];
page += 1;
stateChanger.loaded();
} catch {
stateChanger.error();
}
}
</script>
<ul>
{#each items as item (item.id)}
<li>{item.title}</li>
{/each}
</ul>
<InfiniteLoading onInfinite={loadMore} />
API
Props
| Prop | Type | Default | Description |
|---|---|---|---|
distance |
number |
100 |
Triggers onInfinite when the remaining scroll distance reaches this threshold (top or bottom depending on direction). |
spinnerType |
'default' | 'bubbles' | 'circles' | 'spiral' | 'wavedots' |
'default' |
Selects a built-in spinner. You can also override with the spinner snippet. |
direction |
'top' | 'bottom' |
'bottom' |
Sets the loading direction. |
forceUseInfiniteWrapper |
boolean | string |
false |
Controls which scroll container is used: true for nearest infinite-wrapper / data-infinite-wrapper, string for CSS selector, fallback to window. |
identifier |
any |
Date.now() |
Resets the component when the value changes (useful for filters/tabs). |
Event
onInfinite(stateChanger: StateChanger) => Promise<void> | void
Fires when the threshold (distance) is reached. Use stateChanger methods to drive state:
stateChanger.loaded()marks a successful load and keeps listening.stateChanger.complete()ends loading and shows eithernoResults(if nothing loaded yet) ornoMore.stateChanger.error()shows the error snippet.stateChanger.reset()resets the component (equivalent to changingidentifier).
Snippets
| Snippet | Signature | Default behavior |
|---|---|---|
noResults |
Snippet |
Shown when complete() is called before any loaded(). |
noMore |
Snippet |
Shown when complete() is called after at least one loaded(). |
error |
Snippet<[() => void]> |
Shown when error() is called. Receives attemptLoad retry callback. |
spinner |
Snippet<[boolean]> |
Shown while loading. Receives isFirstLoad flag. |
Examples / Demo
- Hacker News
- Hacker News with Filter
- Hacker News with Top Direction
- Hacker News using svelte-tiny-virtual-list
Development
Developing
npm run dev
npm run dev -- --open
Everything inside src/lib is part of the library. Everything inside src/routes can be used as a showcase or preview app.
Building
npm pack
npm run build
Preview production build:
npm run preview
Publishing
pnpm version <major|minor|patch|premajor|preminor|prepatch|prerelease>
git push --follow-tags