svelte-infinite 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,17 +14,13 @@
14
14
 
15
15
  > Svelte Infinite Loader designed and rebuilt specifically for use with **Svelte 5**
16
16
 
17
- ✨ Flexible
18
- ⏰ Infinite Loop Detection
19
- 📣 Control Loader State
20
- 🔎 `IntersectionObserver` based
21
- 🔥 Using Runes and Snippets
17
+ ✨ Flexible
18
+ ⏰ Infinite Loop Detection
19
+ 📣 Control Loader State
20
+ 🔎 `IntersectionObserver` based
21
+ 🔥 Using Runes and Snippets
22
22
  🧑‍🔧 **Demo**: [svelte-5-infinite.vercel.app](https://svelte-5-infinite.vercel.app)
23
23
 
24
- Svelte 5 is still early days, but I couldn't find an infinite loader-type component that was maintained for the last few years of Svelte 4 even. So I had recently built this for a Svelte 5-based application I'm working on and was pretty happy with it, so I decided to share it with the world!
25
-
26
- As Svelte 5 inevitably changes over the next weeks and months, I plan to keep this package updated and working with the latest available version of Svelte 5. Don't hesitate to open an issue if something has changed in the latest Svelte releases or you come across a bug!
27
-
28
24
  ## 🏗️ Getting Started
29
25
 
30
26
  1. Install `svelte-infinite`
@@ -35,23 +31,24 @@ pnpm install svelte-infinite
35
31
  yarn add svelte-infinite
36
32
  ```
37
33
 
38
- 2. Import both `InfiniteLoader` and `loaderState` from `svelte-infinite`
34
+ 2. Import both `InfiniteLoader` and `LoaderState` from `svelte-infinite`
39
35
 
40
36
  ```svelte
41
37
  <script lang="ts">
42
- import { InfiniteLoader, loaderState } from "svelte-infinite"
38
+ import { InfiniteLoader, LoaderState } from "svelte-infinite"
43
39
 
40
+ const loaderState = new LoaderState()
44
41
  const allItems = $state([])
45
42
 
46
43
  const loadMore = async () => {
47
44
  const res = fetch("...")
48
- const data = await jes.json()
45
+ const data = await res.json()
49
46
  allItems.push(...data)
50
47
  loaderState.loaded()
51
48
  }
52
49
  </script>
53
50
 
54
- <InfiniteLoader triggerLoad={loadMore}>
51
+ <InfiniteLoader {loaderState} triggerLoad={loadMore}>
55
52
  {#each allItems as user (user.id)}
56
53
  <div>{user.name}</div>
57
54
  {/each}
@@ -65,10 +62,10 @@ This is a more realistic example use-case which includes a paginated data endpoi
65
62
  ```svelte
66
63
  <script lang="ts">
67
64
  // +page.svelte
68
-
69
- import { InfiniteLoader, loaderState } from "svelte-infinite"
65
+ import { InfiniteLoader, LoaderState } from "svelte-infinite"
70
66
  import UserCard from "$components/UserCard.svelte"
71
67
 
68
+ const loaderState = new LoaderState()
72
69
  const LOAD_LIMIT = 20
73
70
  // Assume `$page.data.items` is the `+page.server.ts` server-side loaded
74
71
  // and rendered initial 20 items of the list
@@ -132,8 +129,7 @@ This is a more realistic example use-case which includes a paginated data endpoi
132
129
  <main class="container">
133
130
 
134
131
  <!-- 2. Here you wrap your items with the InfiniteLoader component -->
135
-
136
- <InfiniteLoader triggerLoad={loadMore}>
132
+ <InfiniteLoader {loaderState} triggerLoad={loadMore}>
137
133
  {#each allItems as user (user.id)}
138
134
  <UserCard {user} />
139
135
  {/each}
@@ -157,7 +153,10 @@ This is a more realistic example use-case which includes a paginated data endpoi
157
153
 
158
154
  This package consists of two parts, first the `InfiniteLoader` component which is a wrapper around your items. It will trigger whichever async function you've passed to the `triggerLoad` prop when the user scrolls to the bottom of the list.
159
155
 
160
- Second, there is also a `loaderState` import which you should use to interact with the internal state of the loader. For example, if your `fetch` call errored, or you've reached the maximum number of items, etc. you can communicate that to the loader. The most basic usage example can be seen in the 'Getting Started' section above. A more complex example can be seen in the 'Example' section, and of course the application in `/src/routes/+page.svelte` in this repository also has a "real-world" usage example.
156
+ Second, there is also a `LoaderState` class which you should use to interact with the internal state of the loader. For example, if your `fetch` call errored, or you've reached the maximum number of items, etc. you can communicate that to the loader. The most basic usage example can be seen in the 'Getting Started' section above. A more complex example can be seen in the 'Example' section, and of course the application in `/src/routes/+page.svelte` in this repository also has a "real world" usage example.
157
+
158
+ > [!WARNING]
159
+ > As of `0.5.0` the `LoaderState` import is not an instance of the class, but the class itself. Meaning you'll need to instantiate it yourself with `new LoaderState()` per component instance. This gives the user more flexibility when trying to use multiple `svelte-infinite` instances per page, as well as resetting the state.
161
160
 
162
161
  ### `loaderState` Controller
163
162
 
@@ -174,6 +173,8 @@ The `loaderState` controller has 4 methods on it. You should call these at the a
174
173
 
175
174
  ### `InfiniteLoader` Props
176
175
 
176
+ - `loaderState: LoaderState`
177
+ - An instance of the `LoaderState` class.
177
178
  - `triggerLoad: () => Promise<void>` - **required**
178
179
  - The async function to call when we should attempt to load more data to show.
179
180
  - `intersectionOptions: `[`IntersectionObserverInit`](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#options)` = { rootMargin: "0px 0px 200px 0px" }` - optional
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { onMount, onDestroy, type Snippet } from "svelte"
3
- import { STATUS, loaderState } from "./loaderState.svelte"
3
+ import { STATUS, LoaderState } from "./loaderState.svelte"
4
4
 
5
5
  type InfiniteLoaderProps = {
6
6
  triggerLoad: () => Promise<void>
@@ -8,6 +8,7 @@
8
8
  loopDetectionTimeout?: number
9
9
  loopMaxCalls?: number
10
10
  intersectionOptions?: Partial<IntersectionObserver>
11
+ loaderState: LoaderState
11
12
  children: Snippet
12
13
  loading?: Snippet
13
14
  noResults?: Snippet
@@ -22,6 +23,7 @@
22
23
  loopDetectionTimeout = 2000,
23
24
  loopMaxCalls = 5,
24
25
  intersectionOptions = {},
26
+ loaderState,
25
27
  children,
26
28
  loading: loadingSnippet,
27
29
  noResults: noResultsSnippet,
@@ -1,10 +1,12 @@
1
1
  import { type Snippet } from "svelte";
2
+ import { LoaderState } from "./loaderState.svelte";
2
3
  declare const InfiniteLoader: import("svelte").Component<{
3
4
  triggerLoad: () => Promise<void>;
4
5
  loopTimeout?: number;
5
6
  loopDetectionTimeout?: number;
6
7
  loopMaxCalls?: number;
7
8
  intersectionOptions?: Partial<IntersectionObserver>;
9
+ loaderState: LoaderState;
8
10
  children: Snippet;
9
11
  loading?: Snippet;
10
12
  noResults?: Snippet;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  import InfiniteLoader from "./InfiniteLoader.svelte";
2
- import { loaderState } from "./loaderState.svelte";
3
- export { InfiniteLoader, loaderState };
2
+ import { LoaderState } from "./loaderState.svelte";
3
+ export { InfiniteLoader, LoaderState };
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import InfiniteLoader from "./InfiniteLoader.svelte";
2
- import { loaderState } from "./loaderState.svelte";
3
- export { InfiniteLoader, loaderState };
2
+ import { LoaderState } from "./loaderState.svelte";
3
+ export { InfiniteLoader, LoaderState };
@@ -4,7 +4,7 @@ export declare const STATUS: {
4
4
  readonly COMPLETE: "COMPLETE";
5
5
  readonly ERROR: "ERROR";
6
6
  };
7
- declare class LoaderState {
7
+ export declare class LoaderState {
8
8
  isFirstLoad: boolean;
9
9
  status: "READY" | "LOADING" | "COMPLETE" | "ERROR";
10
10
  mounted: boolean;
@@ -13,5 +13,3 @@ declare class LoaderState {
13
13
  reset: () => void;
14
14
  error: () => void;
15
15
  }
16
- export declare const loaderState: LoaderState;
17
- export {};
@@ -4,7 +4,7 @@ export const STATUS = {
4
4
  COMPLETE: "COMPLETE",
5
5
  ERROR: "ERROR"
6
6
  };
7
- class LoaderState {
7
+ export class LoaderState {
8
8
  isFirstLoad = $state(true);
9
9
  status = $state(STATUS.READY);
10
10
  mounted = $state(false);
@@ -26,4 +26,3 @@ class LoaderState {
26
26
  this.status = STATUS.ERROR;
27
27
  };
28
28
  }
29
- export const loaderState = new LoaderState();
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "email": "yo@ndo.dev",
7
7
  "url": "https://ndo.dev"
8
8
  },
9
- "version": "0.4.0",
9
+ "version": "0.5.0",
10
10
  "license": "MIT",
11
11
  "homepage": "https://svelte-5-infinite.vercel.app",
12
12
  "keywords": [
@@ -22,6 +22,18 @@
22
22
  "bugs": {
23
23
  "url": "https://github.com/ndom91/svelte-infinite/issues"
24
24
  },
25
+ "scripts": {
26
+ "dev": "vite dev",
27
+ "build": "vite build && npm run package",
28
+ "preview": "vite preview",
29
+ "package": "svelte-kit sync && svelte-package && publint",
30
+ "prepublishOnly": "npm run package",
31
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
32
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
33
+ "test": "vitest",
34
+ "lint": "prettier --check . && eslint .",
35
+ "format": "prettier --write ."
36
+ },
25
37
  "svelte": "./dist/index.js",
26
38
  "types": "./dist/index.d.ts",
27
39
  "type": "module",
@@ -65,15 +77,5 @@
65
77
  "vite": "^5.4.11",
66
78
  "vitest": "^2.1.5"
67
79
  },
68
- "scripts": {
69
- "dev": "vite dev",
70
- "build": "vite build && npm run package",
71
- "preview": "vite preview",
72
- "package": "svelte-kit sync && svelte-package && publint",
73
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
74
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
75
- "test": "vitest",
76
- "lint": "prettier --check . && eslint .",
77
- "format": "prettier --write ."
78
- }
79
- }
80
+ "packageManager": "pnpm@9.0.6+sha256.0624e30eff866cdeb363b15061bdb7fd9425b17bc1bb42c22f5f4efdea21f6b3"
81
+ }