@fluid-topics/ft-infinite-scroll 2.0.13 → 2.0.14
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.
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { PropertyValues, TemplateResult } from "lit";
|
|
2
3
|
import { KeyFn } from "lit/directives/repeat.js";
|
|
3
4
|
import { CancelablePromise, Debouncer, FtLitElement, Optional } from "@fluid-topics/ft-wc-utils";
|
|
@@ -32,12 +33,13 @@ export declare class FtInfiniteScroll<T> extends FtLitElement implements FtInfin
|
|
|
32
33
|
renderBeforeFirst: number;
|
|
33
34
|
renderAfterLast: number;
|
|
34
35
|
ensureScrollToTarget: boolean;
|
|
36
|
+
disableScrollManagement: boolean;
|
|
35
37
|
visibleItems: Array<number>;
|
|
36
38
|
internalScrollable?: HTMLDivElement;
|
|
37
39
|
itemsContainer: HTMLDivElement;
|
|
38
40
|
scrolledToTarget: boolean;
|
|
39
41
|
scrolling: boolean;
|
|
40
|
-
protected renderApprovalTimeouts: Array<
|
|
42
|
+
protected renderApprovalTimeouts: Array<NodeJS.Timeout | undefined>;
|
|
41
43
|
renderedIndexes: Set<number>;
|
|
42
44
|
protected _scrollable?: HTMLElement;
|
|
43
45
|
protected initialOverflowAnchorValue?: string;
|
|
@@ -52,6 +54,8 @@ export declare class FtInfiniteScroll<T> extends FtLitElement implements FtInfin
|
|
|
52
54
|
protected scrollDebouncer: Debouncer;
|
|
53
55
|
protected scrollDoneDebouncer: Debouncer;
|
|
54
56
|
resetScroll(findScrollableParent?: boolean): void;
|
|
57
|
+
protected updateScrollableParent(findScrollableParent: boolean): void;
|
|
58
|
+
protected ensureScrollPosition(targetIndex: number): void;
|
|
55
59
|
protected resolveScrollToIndex(): number;
|
|
56
60
|
protected getItem(index: number): HTMLElement;
|
|
57
61
|
protected scrollToTarget(index: number): void;
|
|
@@ -84,9 +88,9 @@ export declare class FtInfiniteScroll<T> extends FtLitElement implements FtInfin
|
|
|
84
88
|
protected lastRenderedItemsLength: number;
|
|
85
89
|
protected contentAvailableCallback(props: PropertyValues): void;
|
|
86
90
|
dispatchRenderedItemsChangeEvent(renderedItemIndexes?: number[]): void;
|
|
87
|
-
protected
|
|
91
|
+
protected resetVisibleItemsAttempted: boolean;
|
|
88
92
|
protected resetVisibleItemsDebouncer: Debouncer;
|
|
89
93
|
protected onVisibleItemsChange(): void;
|
|
90
|
-
protected cancelableDispatchEvent?: CancelablePromise<
|
|
94
|
+
protected cancelableDispatchEvent?: CancelablePromise<unknown>;
|
|
91
95
|
dispatchVisibleItemsEvent(): void;
|
|
92
96
|
}
|
|
@@ -4,10 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { html, nothing } from "lit";
|
|
8
|
-
import { property, query, state } from "lit/decorators.js";
|
|
9
|
-
import { repeat } from "lit/directives/repeat.js";
|
|
10
|
-
import { cancelable, Debouncer,
|
|
7
|
+
import { html, nothing, } from "lit";
|
|
8
|
+
import { property, query, state, } from "lit/decorators.js";
|
|
9
|
+
import { repeat, } from "lit/directives/repeat.js";
|
|
10
|
+
import { cancelable, Debouncer, FtLitElement, hasChanged, minmax, numberProperty, scrollHelper, waitFor, waitUntil, } from "@fluid-topics/ft-wc-utils";
|
|
11
11
|
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
12
12
|
import { styles } from "./ft-infinite-scroll.styles";
|
|
13
13
|
export class VisibleItemsChangeEvent extends CustomEvent {
|
|
@@ -17,8 +17,8 @@ export class VisibleItemsChangeEvent extends CustomEvent {
|
|
|
17
17
|
indexes,
|
|
18
18
|
items,
|
|
19
19
|
visibleIndexes: indexes,
|
|
20
|
-
visibleItems: items
|
|
21
|
-
}
|
|
20
|
+
visibleItems: items,
|
|
21
|
+
},
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
}
|
|
@@ -43,6 +43,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
43
43
|
this.renderBeforeFirst = 1;
|
|
44
44
|
this.renderAfterLast = 1;
|
|
45
45
|
this.ensureScrollToTarget = false;
|
|
46
|
+
this.disableScrollManagement = false;
|
|
46
47
|
this.visibleItems = [];
|
|
47
48
|
this.scrolledToTarget = false;
|
|
48
49
|
this.scrolling = false;
|
|
@@ -51,10 +52,10 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
51
52
|
this.scrollDebouncer = new Debouncer(5);
|
|
52
53
|
this.scrollDoneDebouncer = new Debouncer(10);
|
|
53
54
|
this.onVisibilityChange = (items) => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
for (
|
|
57
|
-
|
|
55
|
+
const visibleItems = new Set(this.visibleItems);
|
|
56
|
+
const newItems = new Set();
|
|
57
|
+
for (const item of items) {
|
|
58
|
+
const index = +item.target.getAttribute("data-item-index");
|
|
58
59
|
if (item.intersectionRect.height > 0) {
|
|
59
60
|
visibleItems.add(index);
|
|
60
61
|
newItems.add(index);
|
|
@@ -70,6 +71,9 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
70
71
|
this.ignoreNextScrollEvent = false;
|
|
71
72
|
this.scrollListener = () => {
|
|
72
73
|
var _a;
|
|
74
|
+
if (this.disableScrollManagement) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
73
77
|
const ignoreThisScrollEvent = this.ignoreNextScrollEvent;
|
|
74
78
|
this.ignoreNextScrollEvent = false;
|
|
75
79
|
if (!ignoreThisScrollEvent) {
|
|
@@ -115,12 +119,13 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
115
119
|
}
|
|
116
120
|
};
|
|
117
121
|
this.onMutation = () => {
|
|
118
|
-
for (
|
|
122
|
+
for (const item of this.itemsContainer.children) {
|
|
119
123
|
this.intersectionObserver.observe(item);
|
|
120
124
|
}
|
|
121
125
|
};
|
|
122
126
|
this.mutationObserver = new MutationObserver(this.onMutation);
|
|
123
127
|
this.lastRenderedItemsLength = 0;
|
|
128
|
+
this.resetVisibleItemsAttempted = false;
|
|
124
129
|
this.resetVisibleItemsDebouncer = new Debouncer(10);
|
|
125
130
|
}
|
|
126
131
|
get scrollable() {
|
|
@@ -152,7 +157,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
152
157
|
}
|
|
153
158
|
render() {
|
|
154
159
|
return html `
|
|
155
|
-
<div @scroll-into-view
|
|
160
|
+
<div @scroll-into-view=${this.onScrollIntoView} class="items-container ${this.internalScroll ? "scrollable" : ""}" tabindex="-1">
|
|
156
161
|
${repeat(this.items, (item, index) => this.getItemKey(item, index), (item, index) => this.renderItemContainer(item, index))}
|
|
157
162
|
</div>
|
|
158
163
|
`;
|
|
@@ -179,11 +184,11 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
179
184
|
this.renderApprovalTimeouts[index] = setTimeout(() => {
|
|
180
185
|
if (this.inRenderRange(index)) { // Still in render range after timeout
|
|
181
186
|
this.addRenderedIndex(index);
|
|
187
|
+
this.requestUpdate();
|
|
182
188
|
}
|
|
183
189
|
else {
|
|
184
190
|
this.renderApprovalTimeouts[index] = undefined;
|
|
185
191
|
}
|
|
186
|
-
this.requestUpdate();
|
|
187
192
|
}, 300);
|
|
188
193
|
}
|
|
189
194
|
}
|
|
@@ -199,41 +204,51 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
199
204
|
return this.renderedIndexes.has(this.items.indexOf(item));
|
|
200
205
|
}
|
|
201
206
|
resetScroll(findScrollableParent = true) {
|
|
207
|
+
if (this.disableScrollManagement) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
202
210
|
this.shouldRestoreScroll = false;
|
|
203
211
|
this.intersectionObserver.disconnect();
|
|
204
212
|
this.visibleItems = [];
|
|
205
213
|
this.scrolledToTarget = false;
|
|
206
|
-
|
|
207
|
-
this.scrollable = this.internalScrollable;
|
|
208
|
-
}
|
|
209
|
-
else if (!this.internalScroll && findScrollableParent) {
|
|
210
|
-
this.scrollable = scrollHelper.findFirstScrollableParent(this.itemsContainer);
|
|
211
|
-
}
|
|
214
|
+
this.updateScrollableParent(findScrollableParent);
|
|
212
215
|
const targetIndex = this.resolveScrollToIndex();
|
|
213
216
|
this.addRenderedIndex(targetIndex);
|
|
214
217
|
this.scrollToTarget(targetIndex);
|
|
215
218
|
this.scrollDoneDebouncer.run(() => {
|
|
216
|
-
if (this.ensureScrollToTarget && targetIndex >= 0) {
|
|
217
|
-
this.scrollDebouncer.run(() => {
|
|
218
|
-
if (Math.abs(this.scrollable.scrollTop - this.getOffset(targetIndex)) > 5) {
|
|
219
|
-
this.scrollToTarget(targetIndex);
|
|
220
|
-
}
|
|
221
|
-
}, 500);
|
|
222
|
-
}
|
|
223
219
|
this.scrollToTarget(targetIndex);
|
|
224
220
|
this.scrolledToTarget = true;
|
|
225
221
|
this.shouldRestoreScroll = true;
|
|
226
222
|
this.resetIntersectionObserver();
|
|
223
|
+
this.ensureScrollPosition(targetIndex);
|
|
227
224
|
});
|
|
228
225
|
}
|
|
226
|
+
updateScrollableParent(findScrollableParent) {
|
|
227
|
+
if (this.internalScroll && this.scrollable !== this.internalScrollable) {
|
|
228
|
+
this.scrollable = this.internalScrollable;
|
|
229
|
+
}
|
|
230
|
+
else if (!this.internalScroll && findScrollableParent) {
|
|
231
|
+
this.scrollable = scrollHelper.findFirstScrollableParent(this.itemsContainer);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
ensureScrollPosition(targetIndex) {
|
|
235
|
+
if (!this.ensureScrollToTarget || targetIndex < 0) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
this.scrollDebouncer.run(() => {
|
|
239
|
+
if (Math.abs(this.scrollable.scrollTop - this.getOffset(targetIndex)) > 5) {
|
|
240
|
+
this.scrollToTarget(targetIndex);
|
|
241
|
+
}
|
|
242
|
+
}, 500);
|
|
243
|
+
}
|
|
229
244
|
resolveScrollToIndex() {
|
|
230
245
|
var _a;
|
|
231
|
-
|
|
246
|
+
const index = (_a = this.scrollToIndex) !== null && _a !== void 0 ? _a : (this.scrollToItem ? this.items.indexOf(this.scrollToItem) : -1);
|
|
232
247
|
return index >= this.items.length ? -1 : index;
|
|
233
248
|
}
|
|
234
249
|
getItem(index) {
|
|
235
|
-
var _a, _b
|
|
236
|
-
return (
|
|
250
|
+
var _a, _b;
|
|
251
|
+
return (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(`#item-${index}`)) !== null && _b !== void 0 ? _b : this.shadowRoot.querySelector(`#item-0`);
|
|
237
252
|
}
|
|
238
253
|
scrollToTarget(index) {
|
|
239
254
|
if (index <= 0) {
|
|
@@ -248,6 +263,9 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
248
263
|
}
|
|
249
264
|
onScrollIntoView(e) {
|
|
250
265
|
var _a;
|
|
266
|
+
if (this.disableScrollManagement) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
251
269
|
this.scrollDebouncer.cancel();
|
|
252
270
|
const target = e.composedPath()[0];
|
|
253
271
|
const targetOffset = this.getOffset(target);
|
|
@@ -259,7 +277,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
259
277
|
this.scrollable.scrollTop = targetOffset;
|
|
260
278
|
}
|
|
261
279
|
getOffset(target) {
|
|
262
|
-
|
|
280
|
+
const el = typeof target === "number" ? this.getItem(target) : target;
|
|
263
281
|
return el ? scrollHelper.getAbsoluteScrollOffset(this.scrollable, el) : 0;
|
|
264
282
|
}
|
|
265
283
|
appendItems(...items) {
|
|
@@ -288,7 +306,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
288
306
|
this.intersectionObserver = new IntersectionObserver(this.onVisibilityChange, {
|
|
289
307
|
root: this.scrollable,
|
|
290
308
|
rootMargin: "-8px",
|
|
291
|
-
threshold: [0, 0.01, 0.1, 1]
|
|
309
|
+
threshold: [0, 0.01, 0.1, 1],
|
|
292
310
|
});
|
|
293
311
|
this.onMutation();
|
|
294
312
|
}
|
|
@@ -300,7 +318,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
300
318
|
}
|
|
301
319
|
const middle = Math.floor((to - from) / 2) + from;
|
|
302
320
|
const middleItem = items[middle];
|
|
303
|
-
|
|
321
|
+
const middleItemOffset = this.getOffset(middleItem);
|
|
304
322
|
if (middleItemOffset > currentScrollTop) {
|
|
305
323
|
return this.searchFirstVisibleItem(currentScrollTop, items, from, middle - 1);
|
|
306
324
|
}
|
|
@@ -313,7 +331,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
313
331
|
return this._shouldRestoreScroll;
|
|
314
332
|
}
|
|
315
333
|
set shouldRestoreScroll(value) {
|
|
316
|
-
|
|
334
|
+
const switchedOn = value && !this._shouldRestoreScroll;
|
|
317
335
|
this._shouldRestoreScroll = value;
|
|
318
336
|
if (switchedOn) {
|
|
319
337
|
requestAnimationFrame(this.scrollAdjustment);
|
|
@@ -322,11 +340,12 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
322
340
|
willUpdate(props) {
|
|
323
341
|
super.willUpdate(props);
|
|
324
342
|
if (props.has("items")) {
|
|
343
|
+
this.renderApprovalTimeouts.forEach((id) => clearTimeout(id));
|
|
344
|
+
this.renderApprovalTimeouts = [];
|
|
325
345
|
this.renderedIndexes = new Set();
|
|
326
346
|
this.lastRenderedItemsLength = 0;
|
|
327
|
-
this.renderApprovalTimeouts = [];
|
|
328
347
|
}
|
|
329
|
-
|
|
348
|
+
const scrollTargetUpdated = (props.has("scrollToItem") || props.has("scrollToIndex")) && (this.scrollToItem != null || this.scrollToIndex != null);
|
|
330
349
|
if (scrollTargetUpdated || props.has("internalScroll")) {
|
|
331
350
|
waitFor(() => this.itemsContainer).then(() => this.resetScroll());
|
|
332
351
|
}
|
|
@@ -344,7 +363,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
344
363
|
var _a, _b;
|
|
345
364
|
super.contentAvailableCallback(props);
|
|
346
365
|
const renderedItemIndexes = [...(_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll(".item-container.rendered")) !== null && _b !== void 0 ? _b : []]
|
|
347
|
-
.map(e => +e.getAttribute("data-item-index"));
|
|
366
|
+
.map((e) => +e.getAttribute("data-item-index"));
|
|
348
367
|
if (this.lastRenderedItemsLength !== renderedItemIndexes.length) {
|
|
349
368
|
this.dispatchRenderedItemsChangeEvent(renderedItemIndexes);
|
|
350
369
|
this.lastRenderedItemsLength = renderedItemIndexes.length;
|
|
@@ -352,17 +371,18 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
352
371
|
}
|
|
353
372
|
dispatchRenderedItemsChangeEvent(renderedItemIndexes) {
|
|
354
373
|
const indexes = renderedItemIndexes !== null && renderedItemIndexes !== void 0 ? renderedItemIndexes : [...this.renderedIndexes].sort((a, b) => a - b);
|
|
355
|
-
this.dispatchEvent(new RenderedItemsChangeEvent(indexes, indexes.map(i => this.items[i])));
|
|
374
|
+
this.dispatchEvent(new RenderedItemsChangeEvent(indexes, indexes.map((i) => this.items[i])));
|
|
356
375
|
}
|
|
357
376
|
onVisibleItemsChange() {
|
|
358
377
|
const isVisibleItemsOk = this.visibleItems.every((v, i) => this.visibleItems[i + 1] == null || v + 1 === this.visibleItems[i + 1]);
|
|
359
|
-
if (isVisibleItemsOk ||
|
|
378
|
+
if (isVisibleItemsOk || this.resetVisibleItemsAttempted) {
|
|
379
|
+
this.resetVisibleItemsAttempted = false;
|
|
360
380
|
this.resetVisibleItemsDebouncer.cancel();
|
|
361
381
|
this.dispatchVisibleItemsEvent();
|
|
362
382
|
}
|
|
363
383
|
else {
|
|
364
384
|
this.resetVisibleItemsDebouncer.run(() => {
|
|
365
|
-
this.
|
|
385
|
+
this.resetVisibleItemsAttempted = true;
|
|
366
386
|
this.visibleItems = [];
|
|
367
387
|
this.resetIntersectionObserver();
|
|
368
388
|
});
|
|
@@ -373,7 +393,7 @@ class FtInfiniteScroll extends FtLitElement {
|
|
|
373
393
|
(_a = this.cancelableDispatchEvent) === null || _a === void 0 ? void 0 : _a.cancel();
|
|
374
394
|
this.cancelableDispatchEvent = cancelable(waitUntil(() => this.scrolledToTarget && !this.scrolling));
|
|
375
395
|
this.cancelableDispatchEvent
|
|
376
|
-
.then(() => this.dispatchEvent(new VisibleItemsChangeEvent(this.visibleItems, this.visibleItems.map(index => this.items[index]))))
|
|
396
|
+
.then(() => this.dispatchEvent(new VisibleItemsChangeEvent(this.visibleItems, this.visibleItems.map((index) => this.items[index]))))
|
|
377
397
|
.catch(() => null);
|
|
378
398
|
}
|
|
379
399
|
}
|
|
@@ -392,27 +412,30 @@ __decorate([
|
|
|
392
412
|
property({ type: Object })
|
|
393
413
|
], FtInfiniteScroll.prototype, "scrollToItem", void 0);
|
|
394
414
|
__decorate([
|
|
395
|
-
|
|
415
|
+
numberProperty()
|
|
396
416
|
], FtInfiniteScroll.prototype, "scrollToIndex", void 0);
|
|
397
417
|
__decorate([
|
|
398
418
|
property({ type: Boolean })
|
|
399
419
|
], FtInfiniteScroll.prototype, "internalScroll", void 0);
|
|
400
420
|
__decorate([
|
|
401
|
-
|
|
421
|
+
numberProperty()
|
|
402
422
|
], FtInfiniteScroll.prototype, "renderBeforeFirst", void 0);
|
|
403
423
|
__decorate([
|
|
404
|
-
|
|
424
|
+
numberProperty()
|
|
405
425
|
], FtInfiniteScroll.prototype, "renderAfterLast", void 0);
|
|
406
426
|
__decorate([
|
|
407
427
|
property({ type: Boolean })
|
|
408
428
|
], FtInfiniteScroll.prototype, "ensureScrollToTarget", void 0);
|
|
429
|
+
__decorate([
|
|
430
|
+
property({ type: Boolean })
|
|
431
|
+
], FtInfiniteScroll.prototype, "disableScrollManagement", void 0);
|
|
409
432
|
__decorate([
|
|
410
433
|
state({
|
|
411
434
|
hasChanged(value, oldValue) {
|
|
412
435
|
return (value != null && oldValue == null)
|
|
413
436
|
|| value.length !== oldValue.length
|
|
414
437
|
|| value[0] !== oldValue[0];
|
|
415
|
-
}
|
|
438
|
+
},
|
|
416
439
|
})
|
|
417
440
|
], FtInfiniteScroll.prototype, "visibleItems", void 0);
|
|
418
441
|
__decorate([
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(()=>{var H=Object.create;var y=Object.defineProperty;var
|
|
1
|
+
"use strict";(()=>{var H=Object.create;var y=Object.defineProperty;var N=Object.getOwnPropertyDescriptor;var P=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var u=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports);var k=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of P(e))!j.call(r,i)&&i!==t&&y(r,i,{get:()=>e[i],enumerable:!(s=N(e,i))||s.enumerable});return r};var m=(r,e,t)=>(t=r!=null?H(U(r)):{},k(e||!r||!r.__esModule?y(t,"default",{value:r,enumerable:!0}):t,r));var b=u((G,O)=>{O.exports=ftGlobals.wcUtils});var g=u((K,w)=>{w.exports=ftGlobals.lit});var _=u((Z,x)=>{x.exports=ftGlobals.litDecorators});var C=u((W,A)=>{A.exports=ftGlobals.litRepeat});var V=u((z,E)=>{E.exports=ftGlobals.litUnsafeHTML});var $=m(b());var f=m(g()),h=m(_()),L=m(C()),o=m(b()),F=m(V());var D=m(g()),p=m(b()),I={padding:p.FtCssVariableFactory.create("--ft-infinite-scroll-padding","","SIZE","0"),itemsGap:p.FtCssVariableFactory.create("--ft-infinite-scroll-items-gap","","SIZE","4px"),itemContainerMinHeight:p.FtCssVariableFactory.create("--ft-infinite-scroll-item-container-min-height","","SIZE",".1px")},M=D.css`
|
|
2
2
|
.items-container {
|
|
3
3
|
padding: ${I.padding};
|
|
4
4
|
outline: none;
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
display: flow-root;
|
|
29
29
|
min-height: ${I.itemContainerMinHeight};
|
|
30
30
|
}
|
|
31
|
-
`;var c=function(r,e,t,s){var i=arguments.length,l=i<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,
|
|
32
|
-
<div @scroll-into-view
|
|
33
|
-
${(0,
|
|
31
|
+
`;var c=function(r,e,t,s){var i=arguments.length,l=i<3?e:s===null?s=Object.getOwnPropertyDescriptor(e,t):s,a;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")l=Reflect.decorate(r,e,t,s);else for(var d=r.length-1;d>=0;d--)(a=r[d])&&(l=(i<3?a(l):i>3?a(e,t,l):a(e,t))||l);return i>3&&l&&Object.defineProperty(e,t,l),l},T=class extends CustomEvent{constructor(e,t){super("visible-items-change",{detail:{indexes:e,items:t,visibleIndexes:e,visibleItems:t}})}},S=class extends CustomEvent{constructor(e,t){super("rendered-items-change",{detail:{indexes:e,items:t}})}},R=class extends Event{constructor(){super("scrolled-to-target")}},q=r=>(r??[])[(r??[]).length-1],n=class extends o.FtLitElement{constructor(){super(...arguments),this.items=[],this.renderItem=()=>f.html``,this.getItemKey=(e,t)=>`${t} - ${JSON.stringify(e)}`,this.internalScroll=!1,this.renderBeforeFirst=1,this.renderAfterLast=1,this.ensureScrollToTarget=!1,this.disableScrollManagement=!1,this.visibleItems=[],this.scrolledToTarget=!1,this.scrolling=!1,this.renderApprovalTimeouts=[],this.renderedIndexes=new Set,this.scrollDebouncer=new o.Debouncer(5),this.scrollDoneDebouncer=new o.Debouncer(10),this.onVisibilityChange=e=>{let t=new Set(this.visibleItems),s=new Set;for(let i of e){let l=+i.target.getAttribute("data-item-index");i.intersectionRect.height>0?(t.add(l),s.add(l)):s.has(l)||t.delete(l)}this.visibleItems=[...t].sort((i,l)=>i-l)},this.intersectionObserver=new IntersectionObserver(this.onVisibilityChange),this.scrollingDebouncer=new o.Debouncer(50),this.ignoreNextScrollEvent=!1,this.scrollListener=()=>{var e;if(this.disableScrollManagement)return;let t=this.ignoreNextScrollEvent;this.ignoreNextScrollEvent=!1,t||(this.scrolling=!0,this.scrollingDebouncer.run(()=>this.scrolling=!1));let s=this.scrollable.scrollTop,i=s-((e=this.lastScrollTop)!==null&&e!==void 0?e:0);if(this.lastScrollTop=s,this.scrolledToTarget&&(this.restoreScrollIfNeeded(t?0:i),!t||this.scrollRestorationItem==null)){let l=this.searchFirstVisibleItem(s,this.itemsContainer.children);this.scrollRestorationItem=l?+l.getAttribute("data-item-index"):void 0,this.scrollRestorationOffset=s-this.getOffset(l)}},this.restoreScrollIfNeeded=(e=0)=>{var t;let s=this.scrollable.scrollHeight,i=s-((t=this.lastScrollHeight)!==null&&t!==void 0?t:s);if(this.lastScrollHeight=s,i!==0&&this.scrolledToTarget&&this.scrollRestorationItem!=null&&this.scrollRestorationOffset!=null&&!(this.scrollRestorationItem===0&&this.scrollRestorationOffset<0)){let l=this.getItem(this.scrollRestorationItem),a=this.getOffset(l),d=(0,o.minmax)(this.scrollRestorationItem===0?-a:1,this.scrollRestorationOffset,l.clientHeight-1),v=a+d+e-this.scrollable.scrollTop;(Math.abs(i-v)<4||Math.abs(v)>5)&&(this.ignoreNextScrollEvent=!0,this.scrollable.scrollTop+=v)}},this._shouldRestoreScroll=!1,this.scrollAdjustment=()=>{this.restoreScrollIfNeeded(),this.shouldRestoreScroll&&requestAnimationFrame(this.scrollAdjustment)},this.onMutation=()=>{for(let e of this.itemsContainer.children)this.intersectionObserver.observe(e)},this.mutationObserver=new MutationObserver(this.onMutation),this.lastRenderedItemsLength=0,this.resetVisibleItemsAttempted=!1,this.resetVisibleItemsDebouncer=new o.Debouncer(10)}get scrollable(){var e;return(e=this._scrollable)!==null&&e!==void 0?e:document.body}set scrollable(e){var t,s,i;this._scrollable!==e&&(this._scrollable&&(this._scrollable.removeEventListener("scroll",this.scrollListener),this.initialOverflowAnchorValue&&(this._scrollable.style.overflowAnchor=this.initialOverflowAnchorValue),o.scrollHelper.release(this,this._scrollable)),this._scrollable=o.scrollHelper.lock(this,e),e&&!this._scrollable&&console.error("Scrollable parent is already locked",this,e),(t=this._scrollable)===null||t===void 0||t.addEventListener("scroll",this.scrollListener),this.lastScrollTop=(s=this._scrollable)===null||s===void 0?void 0:s.scrollTop,this.lastScrollHeight=(i=this._scrollable)===null||i===void 0?void 0:i.scrollHeight,this._scrollable&&(this.initialOverflowAnchorValue=getComputedStyle(this._scrollable).overflowAnchor,this._scrollable.style.overflowAnchor="none"))}render(){return f.html`
|
|
32
|
+
<div @scroll-into-view=${this.onScrollIntoView} class="items-container ${this.internalScroll?"scrollable":""}" tabindex="-1">
|
|
33
|
+
${(0,L.repeat)(this.items,(e,t)=>this.getItemKey(e,t),(e,t)=>this.renderItemContainer(e,t))}
|
|
34
34
|
</div>
|
|
35
35
|
`}renderItemContainer(e,t){this.prepareRenderIfNeeded(t);let s=this.scrolledToTarget&&this.visibleItems.includes(t),i=this.renderedIndexes.has(t);return f.html`
|
|
36
36
|
<div id="item-${t}"
|
|
37
37
|
class="item-container ${i?"rendered":""} ${s?"visible":""}"
|
|
38
38
|
data-item-index="${t}">
|
|
39
|
-
${i?(()=>{let
|
|
39
|
+
${i?(()=>{let a=this.renderItem(e,t);return typeof a=="string"?(0,F.unsafeHTML)(a):a})():f.nothing}
|
|
40
40
|
</div>
|
|
41
|
-
`}prepareRenderIfNeeded(e){let t=this.renderApprovalTimeouts[e]!=null;this.inRenderRange(e)&&!t&&(this.renderApprovalTimeouts[e]=setTimeout(()=>{this.inRenderRange(e)?this.addRenderedIndex(e):this.renderApprovalTimeouts[e]=void 0
|
|
41
|
+
`}prepareRenderIfNeeded(e){let t=this.renderApprovalTimeouts[e]!=null;this.inRenderRange(e)&&!t&&(this.renderApprovalTimeouts[e]=setTimeout(()=>{this.inRenderRange(e)?(this.addRenderedIndex(e),this.requestUpdate()):this.renderApprovalTimeouts[e]=void 0},300))}addRenderedIndex(e){e>=0&&!this.renderedIndexes.has(e)&&this.renderedIndexes.add(e)}inRenderRange(e){return e>=this.visibleItems[0]-this.renderBeforeFirst&&e<=q(this.visibleItems)+this.renderAfterLast}isRendered(e){return this.renderedIndexes.has(this.items.indexOf(e))}resetScroll(e=!0){if(this.disableScrollManagement)return;this.shouldRestoreScroll=!1,this.intersectionObserver.disconnect(),this.visibleItems=[],this.scrolledToTarget=!1,this.updateScrollableParent(e);let t=this.resolveScrollToIndex();this.addRenderedIndex(t),this.scrollToTarget(t),this.scrollDoneDebouncer.run(()=>{this.scrollToTarget(t),this.scrolledToTarget=!0,this.shouldRestoreScroll=!0,this.resetIntersectionObserver(),this.ensureScrollPosition(t)})}updateScrollableParent(e){this.internalScroll&&this.scrollable!==this.internalScrollable?this.scrollable=this.internalScrollable:!this.internalScroll&&e&&(this.scrollable=o.scrollHelper.findFirstScrollableParent(this.itemsContainer))}ensureScrollPosition(e){!this.ensureScrollToTarget||e<0||this.scrollDebouncer.run(()=>{Math.abs(this.scrollable.scrollTop-this.getOffset(e))>5&&this.scrollToTarget(e)},500)}resolveScrollToIndex(){var e;let t=(e=this.scrollToIndex)!==null&&e!==void 0?e:this.scrollToItem?this.items.indexOf(this.scrollToItem):-1;return t>=this.items.length?-1:t}getItem(e){var t,s;return(s=(t=this.shadowRoot)===null||t===void 0?void 0:t.querySelector(`#item-${e}`))!==null&&s!==void 0?s:this.shadowRoot.querySelector("#item-0")}scrollToTarget(e){e<=0?(this.scrollable.scrollTop=0,this.scrollRestorationOffset=-this.getOffset(e)):(this.scrollable.scrollTop=this.getOffset(e),this.scrollRestorationOffset=0),this.scrollRestorationItem=e>=0?e:void 0}onScrollIntoView(e){var t;if(this.disableScrollManagement)return;this.scrollDebouncer.cancel();let s=e.composedPath()[0],i=this.getOffset(s),l=(t=e.composedPath().find(a=>typeof a.matches=="function"&&a.matches(".item-container")))===null||t===void 0?void 0:t.getAttribute("data-item-index");this.scrollRestorationItem=l==null?this.scrollRestorationItem:+l,this.scrollRestorationOffset=i-this.getOffset(this.scrollRestorationItem),this.ignoreNextScrollEvent=!0,this.scrollable.scrollTop=i}getOffset(e){let t=typeof e=="number"?this.getItem(e):e;return t?o.scrollHelper.getAbsoluteScrollOffset(this.scrollable,t):0}appendItems(...e){this.items=[...this.items,...e]}prependItems(...e){this.items=[...e,...this.items]}connectedCallback(){super.connectedCallback(),setTimeout(()=>{this.mutationObserver.disconnect(),this.mutationObserver.observe(this.itemsContainer,{childList:!0}),this.resetScroll()},0)}disconnectedCallback(){super.disconnectedCallback(),this.scrollable=void 0,this.intersectionObserver.disconnect(),this.mutationObserver.disconnect(),this.shouldRestoreScroll=!1}resetIntersectionObserver(){this.intersectionObserver.disconnect(),this.intersectionObserver=new IntersectionObserver(this.onVisibilityChange,{root:this.scrollable,rootMargin:"-8px",threshold:[0,.01,.1,1]}),this.onMutation()}searchFirstVisibleItem(e,t,s,i){if(s=s??0,i=i??t.length-1,i<=s)return t[s];let l=Math.floor((i-s)/2)+s,a=t[l],d=this.getOffset(a);return d>e?this.searchFirstVisibleItem(e,t,s,l-1):d+a.clientHeight<e?this.searchFirstVisibleItem(e,t,l+1,i):a}get shouldRestoreScroll(){return this._shouldRestoreScroll}set shouldRestoreScroll(e){let t=e&&!this._shouldRestoreScroll;this._shouldRestoreScroll=e,t&&requestAnimationFrame(this.scrollAdjustment)}willUpdate(e){super.willUpdate(e),e.has("items")&&(this.renderApprovalTimeouts.forEach(s=>clearTimeout(s)),this.renderApprovalTimeouts=[],this.renderedIndexes=new Set,this.lastRenderedItemsLength=0),((e.has("scrollToItem")||e.has("scrollToIndex"))&&(this.scrollToItem!=null||this.scrollToIndex!=null)||e.has("internalScroll"))&&(0,o.waitFor)(()=>this.itemsContainer).then(()=>this.resetScroll())}updated(e){super.updated(e),(e.has("visibleItems")||e.has("items"))&&this.onVisibleItemsChange(),e.has("scrolledToTarget")&&this.scrolledToTarget&&(this.scrollToItem!=null||this.scrollToIndex!=null)&&this.dispatchEvent(new R)}contentAvailableCallback(e){var t,s;super.contentAvailableCallback(e);let i=[...(s=(t=this.shadowRoot)===null||t===void 0?void 0:t.querySelectorAll(".item-container.rendered"))!==null&&s!==void 0?s:[]].map(l=>+l.getAttribute("data-item-index"));this.lastRenderedItemsLength!==i.length&&(this.dispatchRenderedItemsChangeEvent(i),this.lastRenderedItemsLength=i.length)}dispatchRenderedItemsChangeEvent(e){let t=e??[...this.renderedIndexes].sort((s,i)=>s-i);this.dispatchEvent(new S(t,t.map(s=>this.items[s])))}onVisibleItemsChange(){this.visibleItems.every((t,s)=>this.visibleItems[s+1]==null||t+1===this.visibleItems[s+1])||this.resetVisibleItemsAttempted?(this.resetVisibleItemsAttempted=!1,this.resetVisibleItemsDebouncer.cancel(),this.dispatchVisibleItemsEvent()):this.resetVisibleItemsDebouncer.run(()=>{this.resetVisibleItemsAttempted=!0,this.visibleItems=[],this.resetIntersectionObserver()})}dispatchVisibleItemsEvent(){var e;(e=this.cancelableDispatchEvent)===null||e===void 0||e.cancel(),this.cancelableDispatchEvent=(0,o.cancelable)((0,o.waitUntil)(()=>this.scrolledToTarget&&!this.scrolling)),this.cancelableDispatchEvent.then(()=>this.dispatchEvent(new T(this.visibleItems,this.visibleItems.map(t=>this.items[t])))).catch(()=>null)}};n.styles=M;c([(0,h.property)({attribute:!1,hasChanged:o.hasChanged})],n.prototype,"items",void 0);c([(0,h.property)({attribute:!1})],n.prototype,"renderItem",void 0);c([(0,h.property)({attribute:!1})],n.prototype,"getItemKey",void 0);c([(0,h.property)({type:Object})],n.prototype,"scrollToItem",void 0);c([(0,o.numberProperty)()],n.prototype,"scrollToIndex",void 0);c([(0,h.property)({type:Boolean})],n.prototype,"internalScroll",void 0);c([(0,o.numberProperty)()],n.prototype,"renderBeforeFirst",void 0);c([(0,o.numberProperty)()],n.prototype,"renderAfterLast",void 0);c([(0,h.property)({type:Boolean})],n.prototype,"ensureScrollToTarget",void 0);c([(0,h.property)({type:Boolean})],n.prototype,"disableScrollManagement",void 0);c([(0,h.state)({hasChanged(r,e){return r!=null&&e==null||r.length!==e.length||r[0]!==e[0]}})],n.prototype,"visibleItems",void 0);c([(0,h.query)(".scrollable")],n.prototype,"internalScrollable",void 0);c([(0,h.query)(".items-container")],n.prototype,"itemsContainer",void 0);c([(0,h.state)()],n.prototype,"scrolledToTarget",void 0);c([(0,h.state)()],n.prototype,"scrolling",void 0);(0,$.customElement)("ft-infinite-scroll")(n);})();
|