Socket
Socket
Sign inDemoInstall

svelte-infinite

Package Overview
Dependencies
0
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.1 to 0.1.2

1

dist/InfiniteLoader.svelte.d.ts

@@ -13,2 +13,3 @@ import { SvelteComponent } from "svelte";

loopMaxCalls?: number | undefined;
intersectionOptions?: IntersectionObserverInit | undefined;
} & {

@@ -15,0 +16,0 @@ children?: ((this: void) => typeof import("svelte").SnippetReturn & {

51

package.json
{
"name": "svelte-infinite",
"description": "Infinite scroll for Svelte 5 with Runes",
"author": "ndom91 <yo@ndo.dev>",
"version": "0.1.1",
"author": {
"name": "Nico Domino",
"email": "yo@ndo.dev",
"url": "https://ndo.dev"
},
"version": "0.1.2",
"license": "MIT",
"homepage": "https://svelte-5-infinite.vercel.app",
"keywords": [
"infinite-loader",
"svelte",
"svelte5",
"sveltekit"
],
"repository": {

@@ -15,20 +25,5 @@ "type": "git",

},
"scripts": {
"dev": "vite dev",
"build": "vite build && npm run package",
"preview": "vite preview",
"package": "svelte-kit sync && svelte-package && publint",
"prepublishOnly": "npm run package",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
},
"keywords": [
"infinite-loader",
"svelte",
"svelte5",
"sveltekit"
],
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"exports": {

@@ -69,5 +64,13 @@ ".": {

},
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module"
}
"scripts": {
"dev": "vite dev",
"build": "vite build && npm run package",
"preview": "vite preview",
"package": "svelte-kit sync && svelte-package && publint",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test": "vitest",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
}
}

@@ -1,14 +0,23 @@

<img align="right" src="https://raw.githubusercontent.com/ndom91/svelte-infinite/51683d459ae954a99e7c5c25817ed667678a0840/src/assets/SvelteLogo.svg" alt="Svelte Logo" width="128px" />
<p align="center">
<img align="center" src="https://raw.githubusercontent.com/ndom91/svelte-infinite/51683d459ae954a99e7c5c25817ed667678a0840/src/assets/SvelteLogo.svg" height="96" />
<h1 align="center">
Svelte Infinite
</h1>
</p>
# Svelte Infinite
![](https://img.shields.io/badge/typescript-black?style=for-the-badge&logo=typescript&logoColor=white)
![](https://img.shields.io/badge/only-svelte5?style=for-the-badge&logo=svelte&logoColor=white&label=svelte5&labelColor=black&color=black)
[![](https://img.shields.io/npm/v/svelte-infinite?style=for-the-badge&labelColor=black&color=black)](https://npmjs.org/packages/svelte-infinite)
[![](https://img.shields.io/badge/13kb-size?style=for-the-badge&label=size&labelColor=black&color=black)](https://npmjs.org/packages/svelte-infinite)
[![](https://img.shields.io/npm/dm/svelte-infinite?style=for-the-badge&labelColor=black&color=black)](https://npmjs.org/packages/svelte-infinite)
[![](https://img.shields.io/badge/demo-black?style=for-the-badge&logo=&logoColor=white&labelColor=black&color=black)](https://svelte-5-infinite.vercel.app)
Svelte Infinite Scroller designed for use in **Svelte 5** with runes
> Svelte Infinite Loader designed and rebuilt specifically for use in **Svelte 5** with runes
- ⏰ Infinite Loop Detection
- 📣 Control Loader State
- 🔎 `IntersectionObservor` based
- ✨ Flexible
✨ Flexible
⏰ Infinite Loop Detection
📣 Control Loader State
🔎 `IntersectionObserver` based
🧑‍🔧 **Demo**: [svelte-5-infinite.vercel.app](https://svelte-5-infinite.vercel.app)
**Demo**: [svelte-5-infinite.vercel.app](https://svelte-5-infinite.vercel.app)
## 🏗️ Getting Started

@@ -19,3 +28,5 @@

```bash
npm install svelte-infinite
pnpm install svelte-infinite
yarn add svelte-infinite
```

@@ -25,4 +36,27 @@

3. The component should wrap your list of items, and `stateChanger` should be used in your `triggerLoad` function to interact with the internal state of the component, telling it whether you're out of data, ran into an error, etc. See the example below and [in this repository](https://github.com/ndom91/svelte-infinite/blob/main/src/routes/%2Bpage.svelte#L12-L50) for more details.
```svelte
<script lang="ts">
import { InfiniteLoader, stateChanger } from "svelte-infinite"
const allItems = $state([])
const loadMore = async () => {
const res = fetch("...")
const data = await jes.json()
allItems.push(...data)
stateChanger.loaded()
}
</script>
<InfiniteLoader triggerLoad={loadMore}>
{#each allItems as user (user.id)}
<div>{user.name}</div>
{/each}
</InfiniteLoader>
```
The component should wrap your list of items, and `stateChanger` should be used in your `triggerLoad` function (and/or elsewhere) to interact with the internal state of the Loader component. You tell it whether you're out of data, ran into an error, etc.
See the example below and [in this repository](https://github.com/ndom91/svelte-infinite/blob/main/src/routes/%2Bpage.svelte#L12-L50) for more details.
## 🍍 Example

@@ -33,5 +67,6 @@

import { InfiniteLoader, stateChanger } from "svelte-infinite"
import UserCard from "$components/UserCard.svelte"
const LOAD_LIMIT = 20
const allItems = $state<number[]>($page.data.items)
const allItems = $state<{ id: number, body: string }[]>($page.data.items)
let pageNumber = $state(1)

@@ -42,9 +77,10 @@

const loadMore = async () => {
// This is a relatively straight-forward load function with support for pagination
try {
pageNumber += 1
const limit = LOAD_LIMIT
const skip = LOAD_LIMIT * (pageNumber - 1)
const limit = String(LOAD_LIMIT)
const skip = String(LOAD_LIMIT * (pageNumber - 1))
// If there are less results on the first page than the limit,
// don't keep trying to fetch more. We're done.
// If there are less results on the first page (page.server loaded data)
// than the limit, don't keep trying to fetch more. We're done.
if (allItems.length < LOAD_LIMIT) {

@@ -57,6 +93,12 @@ stateChanger.complete()

// Execute the API call to grab more data
const dataResponse = await fetch(`/api/data?${searchParams}`)
// Ideally, like most paginated endpoints, this should return the data
// you've requested for your page, as well as the total amount of data
// available to page through
if (!dataResponse.ok) {
stateChanger.error()
pageNumber -= 1
return

@@ -66,2 +108,4 @@ }

// If we've received data, push it to the reactive state variable
// rendering our items inside the `<InfiniteLoader />` below.
if (data.items.length) {

@@ -71,4 +115,4 @@ allItems.push(...data.items)

// There are less items available than fit on one page,
// don't keep trying to fetch more. We're done.
// If there are more (or equal) number of items loaded as are totally available
// from the API, don't keep trying to fetch more. We're done.
if (allItems.length >= data.totalCount) {

@@ -82,2 +126,3 @@ stateChanger.complete()

stateChanger.error()
pageNumber -= 1
}

@@ -95,2 +140,7 @@ }

{/each}
<!-- There are a few optional slots for customizing what is shown at the bottom
of the scroller in various states, see README.md for more details -->
<div slot="loading">Loading...</div>
<div slot="no-data">Thats it, no more users left!</div>
</InfiniteLoader>

@@ -112,19 +162,33 @@ </main>

1. `stateChanger.loaded()` - Designed to be called after a successful fetch.
2. `stateChanger.error()` - Designed to be called after a failed fetch or any other error. This will cause the `InfiniteLoader` to render a "Retry" button.
3. `stateChanger.complete()` - Designed to be called when you've reached the end of your list and there are no more items to fetch.
4. `stateChanger.reset()` - Designed to be called when you want to reset the state of the `InfiniteLoader` to its initial state, for example if there is a search input tied to your infinite list and the user enters a new query.
- `stateChanger.loaded()`
- Designed to be called after a successful fetch.
- `stateChanger.error()`
- Designed to be called after a failed fetch or any other error. This will cause the `InfiniteLoader` to render a "Retry" button by default, or the `error` slot.
- `stateChanger.complete()`
- Designed to be called when you've reached the end of your list and there are no more items to fetch. This will render a "No more data" string, or the `no-data` slot.
- `stateChanger.reset()`
- Designed to be called when you want to reset the state of the `InfiniteLoader` to its initial state, for example if there is a search input tied to your infinite list and the user enters a new query.
### Props
- `triggerLoad: () => Promise<void>` - **required** - The function to call when the user scrolls to the bottom of the list.
- `loopTimeout: number = 1000` - optional - If the `loopMaxCalls` is reached within this duration (in milliseconds), a cool down period is triggered.
- `loopMaxCalls: number = 5` - optional - The number of calls to the `triggerLoad` function within timeout which should trigger cool down period.
- `triggerLoad: () => Promise<void>` - **required**
- The async function to call when we should attempt to load more data to show.
- `intersectionOptions` - optional
- The options to pass to the `IntersectionObserver` instance. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#options) for more details. Default is `{ rootMargin: "0px 0px 200px 0px" }`, making it trigger the `loadMore` function 200px before it actually intersects with the root element (window by default). This has the effect of beginning to load the next page of data before the user has actually reached the bottom of the list, making the experience feel more smooth.
- It may also be required to pass in a reference to your scroll container as the `root` option, if your scroll container is not the window.
- `loopTimeout: number = 1000` - optional
- If the `loopMaxCalls` is reached within this duration (in milliseconds), a cool down period is triggered.
- `loopMaxCalls: number = 5` - optional
- The number of calls to the `triggerLoad` function within timeout which should trigger cool down period.
### Slots
- `loading` - Shown while calling `triggerLoad` and waiting on a response.
- `no-results` - Shown when there are no results to display.
- `no-data` - Shown when `stateChanger.complete()` is called, indicating the end of scroll.
- `error` - Shown when there is an error. Slot has an `attemptLoad` prop passed to it which is the `triggerLoad` function, designed for a "Retry" button or similar.
- `loading`
- Shown while calling `triggerLoad` and waiting on a response.
- `no-results`
- Shown when there are no more results to display and we haven't fetched any data yet (i.e. data is less than count of items to be shown on first "page").
- `no-data`
- Shown when `stateChanger.complete()` is called, indicating we've fetched and displayed all available data.
- `error`
- Shown when there is an error or `stateChanger.error()` has been called. The slot has an `attemptLoad` prop passed to it which is just the internal `triggerLoad` function, designed for a "Retry" button or similar.

@@ -134,3 +198,3 @@ ## 📦 Contributing

- Initially inspired by [jonasgeiler/svelte-infinite-loading](https://github.com/jonasgeiler/svelte-infinite-loading)
- Open to contributions, issues, and feedback.
- Open to contributions, issues, and feedback 🙏

@@ -137,0 +201,0 @@ ## 📝 License

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc