svelte-infinite 0.3.0 → 0.3.1
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.
|
@@ -7,11 +7,11 @@ const {
|
|
|
7
7
|
loopMaxCalls = 5,
|
|
8
8
|
intersectionOptions = {},
|
|
9
9
|
children,
|
|
10
|
-
loading,
|
|
11
|
-
noResults,
|
|
12
|
-
noData,
|
|
13
|
-
coolingOff,
|
|
14
|
-
error
|
|
10
|
+
loading: loadingSnippet,
|
|
11
|
+
noResults: noResultsSnippet,
|
|
12
|
+
noData: noDataSnippet,
|
|
13
|
+
coolingOff: coolingOffSnippet,
|
|
14
|
+
error: errorSnippet
|
|
15
15
|
} = $props();
|
|
16
16
|
const ERROR_INFINITE_LOOP = `Attempted to execute load function ${loopMaxCalls} or more times within a short period. Please wait before trying again..`;
|
|
17
17
|
class LoopTracker {
|
|
@@ -19,6 +19,7 @@ class LoopTracker {
|
|
|
19
19
|
#coolingOffTimer = null;
|
|
20
20
|
#timer = null;
|
|
21
21
|
#count = 0;
|
|
22
|
+
// On each call, increment the count and reset the timer
|
|
22
23
|
track() {
|
|
23
24
|
this.#count += 1;
|
|
24
25
|
clearTimeout(this.#timer);
|
|
@@ -34,6 +35,10 @@ class LoopTracker {
|
|
|
34
35
|
}, loopTimeout);
|
|
35
36
|
}
|
|
36
37
|
}
|
|
38
|
+
destroy() {
|
|
39
|
+
this.#timer && clearTimeout(this.#timer);
|
|
40
|
+
this.#coolingOffTimer && clearTimeout(this.#coolingOffTimer);
|
|
41
|
+
}
|
|
37
42
|
}
|
|
38
43
|
const loopTracker = new LoopTracker();
|
|
39
44
|
let intersectionTarget = $state();
|
|
@@ -74,56 +79,56 @@ onMount(() => {
|
|
|
74
79
|
observer.observe(intersectionTarget);
|
|
75
80
|
});
|
|
76
81
|
onDestroy(() => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
82
|
+
observer && observer.disconnect();
|
|
83
|
+
loopTracker && loopTracker.destroy();
|
|
80
84
|
});
|
|
81
85
|
</script>
|
|
82
86
|
|
|
83
87
|
<div class="infinite-loader-wrapper">
|
|
88
|
+
<!-- Render the users list items -->
|
|
84
89
|
{@render children()}
|
|
85
90
|
|
|
86
91
|
<div class="infinite-intersection-target" bind:this={intersectionTarget}>
|
|
87
92
|
{#if showLoading}
|
|
88
|
-
{#if
|
|
89
|
-
{@render
|
|
93
|
+
{#if loadingSnippet}
|
|
94
|
+
{@render loadingSnippet()}
|
|
90
95
|
{:else}
|
|
91
96
|
<div class="infinite-loading">Loading...</div>
|
|
92
97
|
{/if}
|
|
93
98
|
{/if}
|
|
94
99
|
|
|
95
100
|
{#if showNoResults}
|
|
96
|
-
{#if
|
|
97
|
-
{@render
|
|
101
|
+
{#if noResultsSnippet}
|
|
102
|
+
{@render noResultsSnippet()}
|
|
98
103
|
{:else}
|
|
99
104
|
<div class="infinite-no-results">No results</div>
|
|
100
105
|
{/if}
|
|
101
106
|
{/if}
|
|
102
107
|
|
|
103
108
|
{#if showNoData}
|
|
104
|
-
{#if
|
|
105
|
-
{@render
|
|
109
|
+
{#if noDataSnippet}
|
|
110
|
+
{@render noDataSnippet()}
|
|
106
111
|
{:else}
|
|
107
112
|
<div class="infinite-no-data">No more data</div>
|
|
108
113
|
{/if}
|
|
109
114
|
{/if}
|
|
110
115
|
|
|
111
116
|
{#if showCoolingOff}
|
|
112
|
-
{#if
|
|
113
|
-
{@render
|
|
117
|
+
{#if coolingOffSnippet}
|
|
118
|
+
{@render coolingOffSnippet()}
|
|
114
119
|
{:else}
|
|
115
120
|
<div class="infinite-cooling-off">Potential loop detected, please wait and try again..</div>
|
|
116
121
|
{/if}
|
|
117
122
|
{/if}
|
|
118
123
|
|
|
119
124
|
{#if showError}
|
|
120
|
-
{#if
|
|
121
|
-
{@render
|
|
125
|
+
{#if errorSnippet}
|
|
126
|
+
{@render errorSnippet(attemptLoad)}
|
|
122
127
|
{:else}
|
|
123
128
|
<div class="infinite-error">
|
|
124
|
-
<div class="infinite-
|
|
129
|
+
<div class="infinite-error__label">Oops, something went wrong</div>
|
|
125
130
|
<button
|
|
126
|
-
class="infinite-
|
|
131
|
+
class="infinite-error__btn"
|
|
127
132
|
disabled={loaderState.status === STATUS.COMPLETE}
|
|
128
133
|
onclick={attemptLoad}
|
|
129
134
|
>
|
|
@@ -162,11 +167,11 @@ onDestroy(() => {
|
|
|
162
167
|
font-size: 1.5rem;
|
|
163
168
|
margin-block: 1rem;
|
|
164
169
|
|
|
165
|
-
.infinite-
|
|
170
|
+
.infinite-error__label {
|
|
166
171
|
color: crimson;
|
|
167
172
|
}
|
|
168
173
|
|
|
169
|
-
.infinite-
|
|
174
|
+
.infinite-error__btn {
|
|
170
175
|
color: white;
|
|
171
176
|
background-color: #333;
|
|
172
177
|
padding-inline: 1.5rem;
|
|
@@ -176,7 +181,7 @@ onDestroy(() => {
|
|
|
176
181
|
transition: background-color 0.3s;
|
|
177
182
|
line-height: normal;
|
|
178
183
|
}
|
|
179
|
-
.infinite-
|
|
184
|
+
.infinite-error__btn:hover {
|
|
180
185
|
cursor: pointer;
|
|
181
186
|
background-color: #222;
|
|
182
187
|
}
|
|
@@ -20,9 +20,7 @@ declare const __propDef: {
|
|
|
20
20
|
coolingOff?: ((this: void) => typeof import("svelte").SnippetReturn & {
|
|
21
21
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
22
22
|
}) | undefined;
|
|
23
|
-
error?: ((this: void, args_0: {
|
|
24
|
-
attemptLoad: Promise<() => void>;
|
|
25
|
-
}) => typeof import("svelte").SnippetReturn & {
|
|
23
|
+
error?: ((this: void, args_0: () => Promise<void>) => typeof import("svelte").SnippetReturn & {
|
|
26
24
|
_: "functions passed to {@render ...} tags must use the `Snippet` type imported from \"svelte\"";
|
|
27
25
|
}) | undefined;
|
|
28
26
|
};
|