vue-virtual-flow 0.0.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.
@@ -0,0 +1,1628 @@
1
+ import { watch as ae, defineComponent as ge, ref as A, computed as i, nextTick as $, onMounted as pe, onUpdated as ze, onBeforeUnmount as ye, openBlock as w, createElementBlock as b, normalizeStyle as C, createElementVNode as Be, renderSlot as X, createTextVNode as me, createCommentVNode as he, Fragment as ve, renderList as Me, unref as m, normalizeClass as $e, toDisplayString as ke } from "vue";
2
+ function Ve(n) {
3
+ return typeof n == "string" || typeof n == "number" || typeof n == "symbol";
4
+ }
5
+ function Ie(n, W) {
6
+ const k = n[W];
7
+ return Ve(k) ? k : void 0;
8
+ }
9
+ function Ee(n) {
10
+ return Ie(n, "id") ?? Ie(n, "key");
11
+ }
12
+ function xe(n) {
13
+ function W(e, S) {
14
+ const g = n.itemKey();
15
+ if (typeof g == "function")
16
+ return g(e, S);
17
+ if (e !== null && typeof e == "object") {
18
+ if (g !== void 0) {
19
+ const u = Ie(e, g);
20
+ if (u !== void 0) return u;
21
+ }
22
+ const x = Ee(e);
23
+ if (x !== void 0) return x;
24
+ }
25
+ return S;
26
+ }
27
+ function k() {
28
+ }
29
+ return ae(
30
+ () => [n.itemKey(), n.items()],
31
+ k,
32
+ { immediate: !0 }
33
+ ), { getItemKey: W };
34
+ }
35
+ function we(n) {
36
+ return n === "fill" ? "100%" : typeof n == "number" ? `${n}px` : n;
37
+ }
38
+ function be(n) {
39
+ return (W, k) => {
40
+ typeof k == "string" && (k === "fill" || k.trim().endsWith("%"));
41
+ };
42
+ }
43
+ const Ke = ["aria-label"], Ce = {
44
+ key: 0,
45
+ class: "vue-chat-virtual-scroll__loading-older",
46
+ role: "status",
47
+ "aria-live": "polite"
48
+ }, De = ["aria-posinset", "aria-setsize"], Re = /* @__PURE__ */ ge({
49
+ name: "ChatVirtualScroll",
50
+ __name: "ChatVirtualScroll",
51
+ props: {
52
+ items: {},
53
+ estimatedItemSize: { default: 48 },
54
+ height: { default: 400 },
55
+ overscan: { default: 5 },
56
+ itemKey: { default: void 0 },
57
+ ariaLabel: { default: "Chat messages" },
58
+ stickToBottom: { type: Boolean, default: !0 },
59
+ bottomThreshold: { default: 80 },
60
+ initialScroll: { default: "bottom" },
61
+ hasOlder: { type: Boolean, default: !1 },
62
+ loadingOlder: { type: Boolean, default: !1 },
63
+ loadOlderThreshold: { default: 120 }
64
+ },
65
+ emits: ["scroll", "loadOlder", "bottomChange"],
66
+ setup(n, { expose: W, emit: k }) {
67
+ const e = n, S = k, g = A(), x = A(0), u = A(0), V = A(0), P = A(!0), O = /* @__PURE__ */ new Map(), E = /* @__PURE__ */ new Map();
68
+ let N, p, H = -1, T = !1;
69
+ const B = be(), { getItemKey: F } = xe({
70
+ componentName: "ChatVirtualScroll",
71
+ items: () => e.items,
72
+ itemKey: () => e.itemKey
73
+ }), I = i(
74
+ () => Math.max(1, e.estimatedItemSize)
75
+ ), U = i(() => Math.max(0, Math.floor(e.overscan))), ee = i(() => u.value > 0 ? u.value : typeof e.height == "number" ? Math.max(0, e.height) : I.value), K = i(() => {
76
+ V.value;
77
+ const a = new Array(e.items.length + 1), f = new Array(e.items.length);
78
+ a[0] = 0;
79
+ for (let r = 0; r < e.items.length; r += 1) {
80
+ const D = F(e.items[r], r), R = O.get(D) ?? I.value;
81
+ f[r] = R, a[r + 1] = a[r] + R;
82
+ }
83
+ return {
84
+ offsets: a,
85
+ sizes: f,
86
+ total: a[e.items.length] ?? 0
87
+ };
88
+ }), z = i(() => {
89
+ const a = /* @__PURE__ */ new Map();
90
+ return e.items.forEach((f, r) => {
91
+ a.set(F(f, r), r);
92
+ }), a;
93
+ });
94
+ function te(a) {
95
+ if (e.items.length === 0) return 0;
96
+ const f = K.value.offsets;
97
+ let r = 0, D = e.items.length;
98
+ for (; r < D; ) {
99
+ const R = Math.floor((r + D) / 2);
100
+ f[R + 1] <= a ? r = R + 1 : D = R;
101
+ }
102
+ return Math.min(r, e.items.length - 1);
103
+ }
104
+ const G = i(
105
+ () => Math.max(
106
+ 0,
107
+ te(x.value) - U.value
108
+ )
109
+ ), J = i(() => {
110
+ if (e.items.length === 0) return 0;
111
+ const a = te(x.value + ee.value) + 1;
112
+ return Math.min(
113
+ e.items.length,
114
+ a + U.value
115
+ );
116
+ }), _ = i(
117
+ () => e.items.slice(G.value, J.value).map((a, f) => {
118
+ const r = G.value + f;
119
+ return {
120
+ item: a,
121
+ index: r,
122
+ key: F(a, r),
123
+ top: K.value.offsets[r]
124
+ };
125
+ })
126
+ ), oe = i(() => ({
127
+ height: we(e.height)
128
+ }));
129
+ function Y() {
130
+ const a = g.value;
131
+ if (!a) return;
132
+ const r = Math.max(
133
+ 0,
134
+ K.value.total - a.scrollTop - a.clientHeight
135
+ ) <= Math.max(0, e.bottomThreshold);
136
+ r !== P.value && (P.value = r, T && S("bottomChange", r));
137
+ }
138
+ function c() {
139
+ var a;
140
+ u.value = ((a = g.value) == null ? void 0 : a.clientHeight) ?? 0, B(g.value, e.height), $(() => {
141
+ Y(), L();
142
+ });
143
+ }
144
+ function v(a) {
145
+ x.value = a.currentTarget.scrollTop, Y(), S("scroll", {
146
+ scrollTop: x.value,
147
+ startIndex: G.value,
148
+ endIndex: J.value
149
+ }), L();
150
+ }
151
+ function L() {
152
+ const a = g.value;
153
+ !T || !a || !e.hasOlder || e.loadingOlder || H === e.items.length || a.scrollTop <= Math.max(0, e.loadOlderThreshold) && (H = e.items.length, S("loadOlder"));
154
+ }
155
+ function j(a) {
156
+ const f = a.borderBoxSize;
157
+ if (f) {
158
+ const r = Array.isArray(f) ? f[0] : f;
159
+ if (r != null && r.blockSize) return r.blockSize;
160
+ }
161
+ return a.contentRect.height;
162
+ }
163
+ function re(a) {
164
+ const f = K.value, r = P.value && e.stickToBottom;
165
+ let D = 0, R = !1;
166
+ for (const Z of a) {
167
+ const ue = Z.target, t = E.get(ue), o = j(Z);
168
+ if (t === void 0 || o <= 0) continue;
169
+ const l = O.get(t) ?? I.value;
170
+ if (Math.abs(l - o) < 0.5) continue;
171
+ const M = z.value.get(t);
172
+ M !== void 0 && f.offsets[M + 1] <= x.value && (D += o - l), O.set(t, o), R = !0;
173
+ }
174
+ R && (V.value += 1, $(() => {
175
+ const Z = g.value;
176
+ Z && (r ? s("auto") : D !== 0 && (Z.scrollTop += D, x.value = Z.scrollTop, Y()));
177
+ }));
178
+ }
179
+ function se(a, f) {
180
+ a instanceof HTMLElement && (E.set(a, f), p == null || p.observe(a));
181
+ }
182
+ function ne() {
183
+ for (const [a] of E)
184
+ a.isConnected || (p == null || p.unobserve(a), E.delete(a));
185
+ }
186
+ function fe(a, f = {}) {
187
+ const r = g.value;
188
+ if (!r) return;
189
+ const D = Math.max(0, K.value.total - r.clientHeight), R = Math.min(
190
+ Math.max(0, Number.isFinite(a) ? a : 0),
191
+ D
192
+ ), Z = f.behavior ?? "auto";
193
+ Z === "auto" && (x.value = R), r.scrollTo({ ...f, top: R, behavior: Z }), $(Y);
194
+ }
195
+ function le(a, f = {}) {
196
+ const r = g.value;
197
+ if (!r || e.items.length === 0) return;
198
+ const D = Math.min(
199
+ e.items.length - 1,
200
+ Math.max(0, Math.floor(a))
201
+ ), { align: R = "start", ...Z } = f, ue = K.value.sizes[D];
202
+ let t = K.value.offsets[D];
203
+ R === "center" ? t -= (r.clientHeight - ue) / 2 : R === "end" && (t -= r.clientHeight - ue);
204
+ const o = Math.max(
205
+ 0,
206
+ Math.min(t, K.value.total - r.clientHeight)
207
+ ), l = Z.behavior ?? "auto", M = Math.max(
208
+ r.clientHeight * 3,
209
+ I.value * 10
210
+ ), y = l === "smooth" && Math.abs(o - r.scrollTop) > M ? "auto" : l;
211
+ y === "auto" && (x.value = o), r.scrollTo({
212
+ ...Z,
213
+ top: o,
214
+ behavior: y
215
+ }), $(Y);
216
+ }
217
+ function d(a = "auto") {
218
+ const f = g.value;
219
+ f && (a === "auto" && (x.value = 0), f.scrollTo({ top: 0, behavior: a }), $(Y));
220
+ }
221
+ function s(a = "auto") {
222
+ const f = g.value;
223
+ if (!f) return;
224
+ const r = Math.max(0, K.value.total - f.clientHeight);
225
+ a === "auto" ? (f.scrollTop = r, x.value = r) : f.scrollTo({ top: r, behavior: a }), $(Y);
226
+ }
227
+ let h = e.items.map((a, f) => F(a, f));
228
+ return ae(
229
+ () => e.items.map((a, f) => F(a, f)),
230
+ async (a) => {
231
+ const f = h;
232
+ h = a;
233
+ const r = g.value, D = (r == null ? void 0 : r.scrollTop) ?? 0, R = P.value && e.stickToBottom, Z = f[0], ue = Z === void 0 ? 0 : a.indexOf(Z), t = ue > 0 ? a.slice(0, ue).reduce(
234
+ (l, M) => l + (O.get(M) ?? I.value),
235
+ 0
236
+ ) : 0, o = new Set(a);
237
+ for (const l of O.keys())
238
+ o.has(l) || O.delete(l);
239
+ V.value += 1, await $(), r && (t > 0 ? (r.scrollTop = D + t, x.value = r.scrollTop) : a.length > f.length && R && s("auto"), Y(), L());
240
+ }
241
+ ), ae(
242
+ () => [e.hasOlder, e.loadingOlder],
243
+ async ([a]) => {
244
+ a || (H = -1), await $(), L();
245
+ }
246
+ ), pe(() => {
247
+ if (c(), typeof ResizeObserver < "u") {
248
+ N = new ResizeObserver(c), p = new ResizeObserver(re), g.value && N.observe(g.value);
249
+ for (const [a] of E)
250
+ p.observe(a);
251
+ }
252
+ $(() => {
253
+ e.initialScroll === "bottom" && s("auto"), T = !0, Y(), L();
254
+ });
255
+ }), ze(ne), ye(() => {
256
+ N == null || N.disconnect(), p == null || p.disconnect(), E.clear();
257
+ }), W({
258
+ isAtBottom: P,
259
+ scrollTo: fe,
260
+ scrollToIndex: le,
261
+ scrollToTop: d,
262
+ scrollToBottom: s
263
+ }), (a, f) => (w(), b("div", {
264
+ ref_key: "viewport",
265
+ ref: g,
266
+ class: "vue-chat-virtual-scroll",
267
+ style: C(oe.value),
268
+ role: "log",
269
+ "aria-label": n.ariaLabel,
270
+ "aria-live": "polite",
271
+ tabindex: "0",
272
+ onScrollPassive: v
273
+ }, [
274
+ n.loadingOlder ? (w(), b("div", Ce, [
275
+ Be("div", null, [
276
+ X(a.$slots, "loadingOlder", {}, () => [
277
+ f[0] || (f[0] = me("Loading older messages…", -1))
278
+ ])
279
+ ])
280
+ ])) : he("", !0),
281
+ n.items.length ? (w(), b("div", {
282
+ key: 1,
283
+ class: "vue-chat-virtual-scroll__spacer",
284
+ style: C({ height: `${K.value.total}px` })
285
+ }, [
286
+ (w(!0), b(ve, null, Me(_.value, ({ item: r, index: D, key: R, top: Z }) => (w(), b("div", {
287
+ key: R,
288
+ ref_for: !0,
289
+ ref: (ue) => se(ue, R),
290
+ class: "vue-chat-virtual-scroll__item",
291
+ style: C({ transform: `translateY(${Z}px)` }),
292
+ role: "article",
293
+ "aria-posinset": D + 1,
294
+ "aria-setsize": n.items.length
295
+ }, [
296
+ X(a.$slots, "default", {
297
+ item: r,
298
+ index: D
299
+ })
300
+ ], 12, De))), 128))
301
+ ], 4)) : X(a.$slots, "empty", {}, void 0, void 0, 2)
302
+ ], 44, Ke));
303
+ }
304
+ });
305
+ function He(n) {
306
+ const W = A(), k = A(0), e = A(!1), S = A(!1), g = i(() => Math.max(1, n.threshold())), x = i(
307
+ () => n.refreshing() || S.value ? g.value : k.value
308
+ ), u = i(
309
+ () => Math.min(1, k.value / g.value)
310
+ ), V = i(() => n.refreshing() || S.value ? "Refreshing…" : u.value >= 1 ? "Release to refresh" : "Pull to refresh");
311
+ function P() {
312
+ W.value = void 0, e.value = !1, k.value = 0;
313
+ }
314
+ function O(p) {
315
+ var B;
316
+ const H = p.currentTarget, T = ((B = n.scrollTop) == null ? void 0 : B.call(n)) ?? H.scrollTop;
317
+ !n.enabled() || n.refreshing() || T > 0 || p.touches.length !== 1 || (W.value = p.touches[0].clientY, e.value = !0);
318
+ }
319
+ function E(p) {
320
+ var F;
321
+ if (W.value === void 0 || !e.value) return;
322
+ const H = p.currentTarget;
323
+ if ((((F = n.scrollTop) == null ? void 0 : F.call(n)) ?? H.scrollTop) > 0 || p.touches.length !== 1) {
324
+ P();
325
+ return;
326
+ }
327
+ const B = p.touches[0].clientY - W.value;
328
+ if (B <= 0) {
329
+ k.value = 0;
330
+ return;
331
+ }
332
+ p.preventDefault(), k.value = Math.min(B * 0.5, g.value * 2);
333
+ }
334
+ function N() {
335
+ if (W.value === void 0) return;
336
+ const p = k.value >= g.value && n.enabled() && !n.refreshing();
337
+ if (W.value = void 0, e.value = !1, !p) {
338
+ k.value = 0;
339
+ return;
340
+ }
341
+ k.value = g.value, S.value = !0, n.onRefresh(), $(() => {
342
+ n.refreshing() || (S.value = !1, k.value = 0);
343
+ });
344
+ }
345
+ return ae(
346
+ () => n.refreshing(),
347
+ (p, H) => {
348
+ p ? (S.value = !1, k.value = g.value) : H && (S.value = !1, k.value = 0);
349
+ }
350
+ ), {
351
+ pulling: e,
352
+ pullDistance: k,
353
+ pullOffset: x,
354
+ pullProgress: u,
355
+ refreshMessage: V,
356
+ refreshThreshold: g,
357
+ handleTouchStart: O,
358
+ handleTouchMove: E,
359
+ handleTouchEnd: N,
360
+ handleTouchCancel: P
361
+ };
362
+ }
363
+ const Ae = ["aria-label"], Pe = ["aria-posinset", "aria-setsize"], Le = /* @__PURE__ */ ge({
364
+ name: "DynamicVirtualScroll",
365
+ __name: "DynamicVirtualScroll",
366
+ props: {
367
+ items: {},
368
+ estimatedItemSize: { default: 48 },
369
+ height: { default: 400 },
370
+ overscan: { default: 3 },
371
+ itemKey: { default: void 0 },
372
+ ariaLabel: { default: "Dynamic virtual list" },
373
+ hasMore: { type: Boolean, default: !1 },
374
+ loading: { type: Boolean, default: !1 },
375
+ loadingItemSize: { default: void 0 },
376
+ loadMoreThreshold: { default: 200 },
377
+ pullToRefresh: { type: Boolean, default: !1 },
378
+ refreshing: { type: Boolean, default: !1 },
379
+ pullRefreshThreshold: { default: 64 }
380
+ },
381
+ emits: ["scroll", "loadMore", "refresh"],
382
+ setup(n, { expose: W, emit: k }) {
383
+ const e = n, S = k, {
384
+ pulling: g,
385
+ pullDistance: x,
386
+ pullOffset: u,
387
+ pullProgress: V,
388
+ refreshMessage: P,
389
+ refreshThreshold: O,
390
+ handleTouchStart: E,
391
+ handleTouchMove: N,
392
+ handleTouchEnd: p,
393
+ handleTouchCancel: H
394
+ } = He({
395
+ enabled: () => e.pullToRefresh,
396
+ refreshing: () => e.refreshing,
397
+ threshold: () => e.pullRefreshThreshold,
398
+ onRefresh: () => S("refresh")
399
+ }), T = A(), B = A(0), F = A(0), I = A(0), U = /* @__PURE__ */ new Map(), ee = /* @__PURE__ */ new Map();
400
+ let K, z, te = -1;
401
+ const G = be(), { getItemKey: J } = xe({
402
+ componentName: "DynamicVirtualScroll",
403
+ items: () => e.items,
404
+ itemKey: () => e.itemKey
405
+ }), _ = i(
406
+ () => Math.max(1, e.estimatedItemSize)
407
+ ), oe = i(
408
+ () => Math.max(1, e.loadingItemSize ?? _.value)
409
+ ), Y = i(() => Math.max(0, Math.floor(e.overscan))), c = i(() => F.value > 0 ? F.value : typeof e.height == "number" ? Math.max(0, e.height) : _.value), v = i(() => {
410
+ I.value;
411
+ const t = new Array(e.items.length + 1), o = new Array(e.items.length);
412
+ t[0] = 0;
413
+ for (let l = 0; l < e.items.length; l += 1) {
414
+ const M = J(e.items[l], l), y = U.get(M) ?? _.value;
415
+ o[l] = y, t[l + 1] = t[l] + y;
416
+ }
417
+ return {
418
+ offsets: t,
419
+ sizes: o,
420
+ total: t[e.items.length] ?? 0
421
+ };
422
+ }), L = i(
423
+ () => v.value.total + (e.loading ? oe.value : 0)
424
+ ), j = i(() => {
425
+ const t = /* @__PURE__ */ new Map();
426
+ return e.items.forEach((o, l) => {
427
+ t.set(J(o, l), l);
428
+ }), t;
429
+ });
430
+ function re(t) {
431
+ if (e.items.length === 0) return 0;
432
+ const o = v.value.offsets;
433
+ let l = 0, M = e.items.length;
434
+ for (; l < M; ) {
435
+ const y = Math.floor((l + M) / 2);
436
+ o[y + 1] <= t ? l = y + 1 : M = y;
437
+ }
438
+ return Math.min(l, e.items.length - 1);
439
+ }
440
+ const se = i(
441
+ () => Math.max(
442
+ 0,
443
+ re(B.value) - Y.value
444
+ )
445
+ ), ne = i(() => {
446
+ if (e.items.length === 0) return 0;
447
+ const t = re(B.value + c.value) + 1;
448
+ return Math.min(
449
+ e.items.length,
450
+ t + Y.value
451
+ );
452
+ }), fe = i(
453
+ () => e.items.slice(se.value, ne.value).map((t, o) => {
454
+ const l = se.value + o;
455
+ return {
456
+ item: t,
457
+ index: l,
458
+ key: J(t, l),
459
+ top: v.value.offsets[l]
460
+ };
461
+ })
462
+ ), le = i(() => ({
463
+ height: we(e.height)
464
+ }));
465
+ function d() {
466
+ var t;
467
+ F.value = ((t = T.value) == null ? void 0 : t.clientHeight) ?? 0, G(T.value, e.height), $(h);
468
+ }
469
+ function s(t) {
470
+ B.value = t.currentTarget.scrollTop, S("scroll", {
471
+ scrollTop: B.value,
472
+ startIndex: se.value,
473
+ endIndex: ne.value
474
+ }), h();
475
+ }
476
+ function h() {
477
+ const t = T.value;
478
+ if (!t || !e.hasMore || e.loading || te === e.items.length)
479
+ return;
480
+ const o = Math.max(0, e.loadMoreThreshold);
481
+ L.value - t.scrollTop - t.clientHeight <= o && (te = e.items.length, S("loadMore"));
482
+ }
483
+ function a(t) {
484
+ const o = t.borderBoxSize;
485
+ if (o) {
486
+ const l = Array.isArray(o) ? o[0] : o;
487
+ if (l != null && l.blockSize) return l.blockSize;
488
+ }
489
+ return t.contentRect.height;
490
+ }
491
+ function f(t) {
492
+ const o = v.value;
493
+ let l = 0, M = !1;
494
+ for (const y of t) {
495
+ const Q = y.target, q = ee.get(Q), ie = a(y);
496
+ if (q === void 0 || ie <= 0) continue;
497
+ const ce = U.get(q) ?? _.value;
498
+ if (Math.abs(ce - ie) < 0.5) continue;
499
+ const de = j.value.get(q);
500
+ de !== void 0 && o.offsets[de + 1] <= B.value && (l += ie - ce), U.set(q, ie), M = !0;
501
+ }
502
+ M && (I.value += 1, $(h), l !== 0 && $(() => {
503
+ const y = T.value;
504
+ y && (y.scrollTop += l, B.value = y.scrollTop);
505
+ }));
506
+ }
507
+ function r(t, o) {
508
+ t instanceof HTMLElement && (ee.set(t, o), z == null || z.observe(t));
509
+ }
510
+ function D() {
511
+ for (const [t] of ee)
512
+ t.isConnected || (z == null || z.unobserve(t), ee.delete(t));
513
+ }
514
+ function R(t, o = {}) {
515
+ const l = T.value;
516
+ if (!l) return;
517
+ const M = Math.max(0, L.value - l.clientHeight), y = Math.min(
518
+ Math.max(0, Number.isFinite(t) ? t : 0),
519
+ M
520
+ ), Q = o.behavior ?? "auto";
521
+ Q === "auto" && (B.value = y), l.scrollTo({ ...o, top: y, behavior: Q });
522
+ }
523
+ function Z(t, o = {}) {
524
+ const l = T.value;
525
+ if (!l || e.items.length === 0) return;
526
+ const M = Math.min(
527
+ e.items.length - 1,
528
+ Math.max(0, Math.floor(t))
529
+ ), { align: y = "start", ...Q } = o;
530
+ let q = v.value.offsets[M];
531
+ const ie = v.value.sizes[M];
532
+ y === "center" ? q -= (l.clientHeight - ie) / 2 : y === "end" && (q -= l.clientHeight - ie);
533
+ const ce = Math.max(
534
+ 0,
535
+ Math.min(q, L.value - l.clientHeight)
536
+ ), de = Q.behavior ?? "auto", Se = Math.max(
537
+ l.clientHeight * 3,
538
+ _.value * 10
539
+ ), Te = de === "smooth" && Math.abs(ce - l.scrollTop) > Se ? "auto" : de;
540
+ Te === "auto" && (B.value = ce), l.scrollTo({
541
+ ...Q,
542
+ top: ce,
543
+ behavior: Te
544
+ });
545
+ }
546
+ function ue(t = "auto") {
547
+ var o;
548
+ (o = T.value) == null || o.scrollTo({ top: 0, behavior: t });
549
+ }
550
+ return ae(
551
+ () => e.itemKey,
552
+ () => {
553
+ U.clear(), I.value += 1;
554
+ }
555
+ ), ae(
556
+ () => e.items.length,
557
+ async () => {
558
+ const t = new Set(
559
+ e.items.map((M, y) => J(M, y))
560
+ );
561
+ for (const M of U.keys())
562
+ t.has(M) || U.delete(M);
563
+ I.value += 1, await $();
564
+ const o = T.value;
565
+ if (!o) return;
566
+ const l = Math.max(0, L.value - o.clientHeight);
567
+ o.scrollTop > l && (o.scrollTop = l, B.value = l), h();
568
+ }
569
+ ), ae(
570
+ () => [e.hasMore, e.loading],
571
+ async ([t]) => {
572
+ t || (te = -1), await $(), h();
573
+ }
574
+ ), pe(() => {
575
+ if (d(), typeof ResizeObserver < "u") {
576
+ K = new ResizeObserver(d), z = new ResizeObserver(f), T.value && K.observe(T.value);
577
+ for (const [t] of ee)
578
+ z.observe(t);
579
+ }
580
+ $(h);
581
+ }), ze(D), ye(() => {
582
+ K == null || K.disconnect(), z == null || z.disconnect(), ee.clear();
583
+ }), W({
584
+ scrollTo: R,
585
+ scrollToIndex: Z,
586
+ scrollToTop: ue
587
+ }), (t, o) => (w(), b("div", {
588
+ ref_key: "viewport",
589
+ ref: T,
590
+ class: $e(["vue-dynamic-virtual-scroll", { "vue-dynamic-virtual-scroll--pulling": m(g) }]),
591
+ style: C(le.value),
592
+ role: "list",
593
+ "aria-label": n.ariaLabel,
594
+ tabindex: "0",
595
+ onScrollPassive: s,
596
+ onTouchstartPassive: o[0] || (o[0] = //@ts-ignore
597
+ (...l) => m(E) && m(E)(...l)),
598
+ onTouchmove: o[1] || (o[1] = //@ts-ignore
599
+ (...l) => m(N) && m(N)(...l)),
600
+ onTouchend: o[2] || (o[2] = //@ts-ignore
601
+ (...l) => m(p) && m(p)(...l)),
602
+ onTouchcancel: o[3] || (o[3] = //@ts-ignore
603
+ (...l) => m(H) && m(H)(...l))
604
+ }, [
605
+ n.pullToRefresh || n.refreshing ? (w(), b("div", {
606
+ key: 0,
607
+ class: "vue-dynamic-virtual-scroll__refresh",
608
+ style: C({
609
+ height: `${m(O)}px`,
610
+ transform: `translateY(${m(u) - m(O)}px)`
611
+ }),
612
+ role: "status",
613
+ "aria-live": "polite"
614
+ }, [
615
+ X(t.$slots, "refresh", {
616
+ pullDistance: m(x),
617
+ progress: m(V),
618
+ refreshing: n.refreshing
619
+ }, () => [
620
+ me(ke(m(P)), 1)
621
+ ])
622
+ ], 4)) : he("", !0),
623
+ n.items.length || n.loading ? (w(), b("div", {
624
+ key: 1,
625
+ class: "vue-dynamic-virtual-scroll__spacer",
626
+ style: C({
627
+ height: `${L.value}px`,
628
+ transform: `translateY(${m(u)}px)`
629
+ })
630
+ }, [
631
+ (w(!0), b(ve, null, Me(fe.value, ({ item: l, index: M, key: y, top: Q }) => (w(), b("div", {
632
+ key: y,
633
+ ref_for: !0,
634
+ ref: (q) => r(q, y),
635
+ class: "vue-dynamic-virtual-scroll__item",
636
+ style: C({ transform: `translateY(${Q}px)` }),
637
+ role: "listitem",
638
+ "aria-posinset": M + 1,
639
+ "aria-setsize": n.items.length
640
+ }, [
641
+ X(t.$slots, "default", {
642
+ item: l,
643
+ index: M
644
+ })
645
+ ], 12, Pe))), 128)),
646
+ n.loading ? (w(), b("div", {
647
+ key: 0,
648
+ class: "vue-dynamic-virtual-scroll__loading",
649
+ style: C({
650
+ height: `${oe.value}px`,
651
+ transform: `translateY(${v.value.total}px)`
652
+ }),
653
+ role: "status",
654
+ "aria-live": "polite"
655
+ }, [
656
+ X(t.$slots, "loading", {}, () => [
657
+ o[4] || (o[4] = me("Loading more…", -1))
658
+ ])
659
+ ], 4)) : he("", !0)
660
+ ], 4)) : (w(), b("div", {
661
+ key: 2,
662
+ class: "vue-dynamic-virtual-scroll__empty",
663
+ style: C({ transform: `translateY(${m(u)}px)` })
664
+ }, [
665
+ X(t.$slots, "empty")
666
+ ], 4))
667
+ ], 46, Ae));
668
+ }
669
+ }), Oe = ["aria-label"], Ne = ["aria-current", "aria-posinset", "aria-setsize"], Ye = {
670
+ key: 1,
671
+ class: "vue-short-media-feed__empty"
672
+ }, Fe = /* @__PURE__ */ ge({
673
+ name: "ShortMediaFeed",
674
+ __name: "ShortMediaFeed",
675
+ props: {
676
+ items: {},
677
+ activeIndex: { default: 0 },
678
+ buffer: { default: 1 },
679
+ height: { default: "100dvh" },
680
+ itemKey: { default: void 0 },
681
+ ariaLabel: { default: "Short media feed" },
682
+ hasMore: { type: Boolean, default: !1 },
683
+ loading: { type: Boolean, default: !1 },
684
+ loadMoreThreshold: { default: 2 }
685
+ },
686
+ emits: ["update:activeIndex", "change", "reachStart", "reachEnd", "loadMore"],
687
+ setup(n, { expose: W, emit: k }) {
688
+ const e = n, S = k, g = A(), x = A(0), u = A(K(e.activeIndex));
689
+ let V, P = -1;
690
+ const O = be(), { getItemKey: E } = xe({
691
+ componentName: "ShortMediaFeed",
692
+ items: () => e.items,
693
+ itemKey: () => e.itemKey
694
+ }), N = i(
695
+ () => Math.max(0, Math.floor(e.buffer))
696
+ ), p = i(
697
+ () => Math.max(
698
+ 0,
699
+ Math.floor(
700
+ Number.isFinite(e.loadMoreThreshold) ? e.loadMoreThreshold : 0
701
+ )
702
+ )
703
+ ), H = i(() => x.value > 0 ? x.value : typeof e.height == "number" ? Math.max(1, e.height) : 0), T = i(
704
+ () => Math.max(0, u.value - N.value)
705
+ ), B = i(
706
+ () => Math.min(
707
+ e.items.length,
708
+ u.value + N.value + 1
709
+ )
710
+ ), F = i(
711
+ () => e.items.slice(T.value, B.value).map((c, v) => ({
712
+ item: c,
713
+ index: T.value + v
714
+ }))
715
+ ), I = i(() => T.value * H.value), U = i(
716
+ () => (e.items.length - B.value) * H.value
717
+ ), ee = i(() => ({
718
+ height: we(e.height)
719
+ }));
720
+ function K(c) {
721
+ return e.items.length === 0 ? 0 : Math.min(
722
+ e.items.length - 1,
723
+ Math.max(0, Math.floor(Number.isFinite(c) ? c : 0))
724
+ );
725
+ }
726
+ function z() {
727
+ if (!e.hasMore || e.loading || P === e.items.length)
728
+ return;
729
+ (e.items.length === 0 ? 0 : e.items.length - 1 - u.value) <= p.value && (P = e.items.length, S("loadMore"));
730
+ }
731
+ function te(c) {
732
+ const v = K(c);
733
+ v === u.value || e.items.length === 0 || (u.value = v, S("update:activeIndex", v), S("change", {
734
+ index: v,
735
+ item: e.items[v]
736
+ }), v === 0 && S("reachStart"), v === e.items.length - 1 && S("reachEnd"), z());
737
+ }
738
+ function G(c, v = {}) {
739
+ const L = g.value;
740
+ L && (typeof L.scrollTo == "function" ? L.scrollTo({ ...v, top: c }) : L.scrollTop = c);
741
+ }
742
+ function J(c, v = {}) {
743
+ if (e.items.length === 0) return;
744
+ const L = K(c);
745
+ te(L), G(L * H.value, v);
746
+ }
747
+ function _(c) {
748
+ if (H.value <= 0) return;
749
+ const v = c.currentTarget.scrollTop;
750
+ te(Math.round(v / H.value));
751
+ }
752
+ function oe(c) {
753
+ let v;
754
+ c.key === "ArrowDown" || c.key === "PageDown" ? v = u.value + 1 : c.key === "ArrowUp" || c.key === "PageUp" ? v = u.value - 1 : c.key === "Home" ? v = 0 : c.key === "End" && (v = e.items.length - 1), v !== void 0 && (c.preventDefault(), J(v, { behavior: "smooth" }));
755
+ }
756
+ function Y() {
757
+ var v;
758
+ const c = ((v = g.value) == null ? void 0 : v.clientHeight) ?? 0;
759
+ O(g.value, e.height), !(c <= 0 || c === x.value) && (x.value = c, $(() => {
760
+ G(u.value * c);
761
+ }));
762
+ }
763
+ return ae(
764
+ () => e.activeIndex,
765
+ async (c) => {
766
+ const v = K(c);
767
+ v !== u.value && (u.value = v, await $(), G(v * H.value), z());
768
+ }
769
+ ), ae(
770
+ () => [
771
+ e.hasMore,
772
+ e.loading,
773
+ e.loadMoreThreshold
774
+ ],
775
+ async ([c]) => {
776
+ c || (P = -1), await $(), z();
777
+ }
778
+ ), ae(
779
+ () => e.items.length,
780
+ async () => {
781
+ const c = K(u.value);
782
+ e.items.length === 0 ? u.value !== 0 && (u.value = 0, S("update:activeIndex", 0)) : te(c), await $(), G(c * H.value), z();
783
+ }
784
+ ), pe(async () => {
785
+ Y(), typeof ResizeObserver < "u" && g.value && (V = new ResizeObserver(Y), V.observe(g.value)), await $(), G(u.value * H.value), z();
786
+ }), ye(() => {
787
+ V == null || V.disconnect();
788
+ }), W({
789
+ scrollToIndex: J
790
+ }), (c, v) => (w(), b("div", {
791
+ ref_key: "viewport",
792
+ ref: g,
793
+ class: "vue-short-media-feed",
794
+ style: C(ee.value),
795
+ role: "list",
796
+ "aria-orientation": "vertical",
797
+ "aria-label": n.ariaLabel,
798
+ tabindex: "0",
799
+ onScrollPassive: _,
800
+ onKeydown: oe
801
+ }, [
802
+ n.items.length ? (w(), b(ve, { key: 0 }, [
803
+ I.value > 0 ? (w(), b("div", {
804
+ key: 0,
805
+ class: "vue-short-media-feed__spacer",
806
+ style: C({ height: `${I.value}px` }),
807
+ "aria-hidden": "true"
808
+ }, null, 4)) : he("", !0),
809
+ (w(!0), b(ve, null, Me(F.value, ({ item: L, index: j }) => (w(), b("div", {
810
+ key: m(E)(L, j),
811
+ class: "vue-short-media-feed__item",
812
+ style: C({ height: `${H.value}px` }),
813
+ role: "listitem",
814
+ "aria-current": j === u.value ? "true" : void 0,
815
+ "aria-posinset": j + 1,
816
+ "aria-setsize": n.items.length
817
+ }, [
818
+ X(c.$slots, "default", {
819
+ item: L,
820
+ index: j,
821
+ active: j === u.value
822
+ })
823
+ ], 12, Ne))), 128)),
824
+ U.value > 0 ? (w(), b("div", {
825
+ key: 1,
826
+ class: "vue-short-media-feed__spacer",
827
+ style: C({ height: `${U.value}px` }),
828
+ "aria-hidden": "true"
829
+ }, null, 4)) : he("", !0)
830
+ ], 64)) : (w(), b("div", Ye, [
831
+ X(c.$slots, "empty")
832
+ ]))
833
+ ], 44, Oe));
834
+ }
835
+ }), We = ["aria-label"], _e = {
836
+ key: 0,
837
+ class: "vue-virtual-carousel__track",
838
+ role: "list"
839
+ }, Ue = ["aria-label", "aria-current"], je = {
840
+ key: 1,
841
+ class: "vue-virtual-carousel__empty"
842
+ }, Ze = /* @__PURE__ */ ge({
843
+ name: "VirtualCarousel",
844
+ __name: "VirtualCarousel",
845
+ props: {
846
+ items: {},
847
+ activeIndex: { default: 0 },
848
+ slidesPerView: { default: 1 },
849
+ slidesToScroll: { default: 1 },
850
+ gap: { default: 0 },
851
+ buffer: { default: 1 },
852
+ height: { default: "auto" },
853
+ itemKey: { default: void 0 },
854
+ ariaLabel: { default: "Carousel" },
855
+ hasMore: { type: Boolean, default: !1 },
856
+ loading: { type: Boolean, default: !1 },
857
+ loadMoreThreshold: { default: 2 }
858
+ },
859
+ emits: ["update:activeIndex", "change", "reachStart", "reachEnd", "loadMore"],
860
+ setup(n, { expose: W, emit: k }) {
861
+ const e = n, S = k, g = A(), x = A(0), u = A(0);
862
+ let V, P = -1;
863
+ const { getItemKey: O } = xe({
864
+ componentName: "VirtualCarousel",
865
+ items: () => e.items,
866
+ itemKey: () => e.itemKey
867
+ }), E = i(
868
+ () => Math.max(
869
+ 1,
870
+ Math.floor(
871
+ Number.isFinite(e.slidesPerView) ? e.slidesPerView : 1
872
+ )
873
+ )
874
+ ), N = i(
875
+ () => Math.max(
876
+ 1,
877
+ Math.floor(
878
+ Number.isFinite(e.slidesToScroll) ? e.slidesToScroll : 1
879
+ )
880
+ )
881
+ ), p = i(
882
+ () => Math.max(0, Number.isFinite(e.gap) ? e.gap : 0)
883
+ ), H = i(
884
+ () => Math.max(
885
+ 0,
886
+ Math.floor(Number.isFinite(e.buffer) ? e.buffer : 0)
887
+ )
888
+ ), T = i(
889
+ () => Math.max(
890
+ 0,
891
+ Math.floor(
892
+ Number.isFinite(e.loadMoreThreshold) ? e.loadMoreThreshold : 0
893
+ )
894
+ )
895
+ ), B = i(() => Math.max(0, x.value)), F = i(() => {
896
+ if (B.value <= 0) return 0;
897
+ const d = (E.value - 1) * p.value;
898
+ return Math.max(
899
+ 1,
900
+ (B.value - d) / E.value
901
+ );
902
+ }), I = i(() => F.value + p.value), U = i(
903
+ () => Math.max(
904
+ 0,
905
+ e.items.length - E.value
906
+ )
907
+ ), ee = i(
908
+ () => Math.max(0, u.value - H.value)
909
+ ), K = i(
910
+ () => Math.min(
911
+ e.items.length,
912
+ u.value + E.value + H.value
913
+ )
914
+ ), z = i(
915
+ () => e.items.slice(ee.value, K.value).map((d, s) => ({
916
+ item: d,
917
+ index: ee.value + s
918
+ }))
919
+ ), te = i(() => e.items.length === 0 ? 0 : e.items.length * F.value + (e.items.length - 1) * p.value), G = i(
920
+ () => ee.value * I.value
921
+ ), J = i(
922
+ () => Math.max(
923
+ 0,
924
+ te.value - K.value * I.value
925
+ )
926
+ ), _ = i(() => ({
927
+ height: we(e.height)
928
+ }));
929
+ function oe(d) {
930
+ return Math.min(
931
+ U.value,
932
+ Math.max(0, Math.floor(Number.isFinite(d) ? d : 0))
933
+ );
934
+ }
935
+ u.value = oe(e.activeIndex);
936
+ function Y(d) {
937
+ return d >= u.value && d < Math.min(
938
+ e.items.length,
939
+ u.value + E.value
940
+ );
941
+ }
942
+ function c() {
943
+ if (!e.hasMore || e.loading || P === e.items.length)
944
+ return;
945
+ const d = e.items.length === 0 ? -1 : Math.min(
946
+ e.items.length - 1,
947
+ u.value + E.value - 1
948
+ );
949
+ e.items.length - 1 - d <= T.value && (P = e.items.length, S("loadMore"));
950
+ }
951
+ function v(d) {
952
+ const s = oe(d);
953
+ s === u.value || e.items.length === 0 || (u.value = s, S("update:activeIndex", s), S("change", {
954
+ index: s,
955
+ item: e.items[s]
956
+ }), s === 0 && S("reachStart"), s === U.value && S("reachEnd"), c());
957
+ }
958
+ function L(d, s = {}) {
959
+ const h = g.value;
960
+ h && (typeof h.scrollTo == "function" ? h.scrollTo({ ...s, left: d }) : h.scrollLeft = d);
961
+ }
962
+ function j(d, s = {}) {
963
+ if (e.items.length === 0 || I.value <= 0) return;
964
+ const h = oe(d), a = Math.abs(h - u.value), f = s.behavior === "smooth" && a > H.value ? "auto" : s.behavior;
965
+ v(h), L(h * I.value, {
966
+ ...s,
967
+ behavior: f
968
+ });
969
+ }
970
+ function re(d = "smooth") {
971
+ j(
972
+ u.value + N.value,
973
+ { behavior: d }
974
+ );
975
+ }
976
+ function se(d = "smooth") {
977
+ j(
978
+ u.value - N.value,
979
+ { behavior: d }
980
+ );
981
+ }
982
+ function ne(d) {
983
+ if (I.value <= 0) return;
984
+ const s = d.currentTarget.scrollLeft;
985
+ v(Math.round(s / I.value));
986
+ }
987
+ function fe(d) {
988
+ d.key === "ArrowRight" || d.key === "PageDown" ? (d.preventDefault(), re()) : d.key === "ArrowLeft" || d.key === "PageUp" ? (d.preventDefault(), se()) : d.key === "Home" ? (d.preventDefault(), j(0, { behavior: "smooth" })) : d.key === "End" && (d.preventDefault(), j(U.value, { behavior: "auto" }));
989
+ }
990
+ function le() {
991
+ var s;
992
+ const d = ((s = g.value) == null ? void 0 : s.clientWidth) ?? 0;
993
+ d <= 0 || d === x.value || (x.value = d, $(() => {
994
+ L(u.value * I.value);
995
+ }));
996
+ }
997
+ return ae(
998
+ () => e.activeIndex,
999
+ async (d) => {
1000
+ const s = oe(d);
1001
+ s !== u.value && (u.value = s, await $(), L(s * I.value), c());
1002
+ }
1003
+ ), ae(
1004
+ () => [
1005
+ e.items.length,
1006
+ e.slidesPerView,
1007
+ e.gap
1008
+ ],
1009
+ async () => {
1010
+ const d = oe(u.value);
1011
+ e.items.length === 0 ? u.value !== 0 && (u.value = 0, S("update:activeIndex", 0)) : v(d), await $(), L(d * I.value), c();
1012
+ }
1013
+ ), ae(
1014
+ () => [
1015
+ e.hasMore,
1016
+ e.loading,
1017
+ e.loadMoreThreshold
1018
+ ],
1019
+ async ([d]) => {
1020
+ d || (P = -1), await $(), c();
1021
+ }
1022
+ ), pe(async () => {
1023
+ le(), typeof ResizeObserver < "u" && g.value && (V = new ResizeObserver(le), V.observe(g.value)), await $(), L(u.value * I.value), c();
1024
+ }), ye(() => {
1025
+ V == null || V.disconnect();
1026
+ }), W({
1027
+ next: re,
1028
+ previous: se,
1029
+ scrollToIndex: j
1030
+ }), (d, s) => (w(), b("div", {
1031
+ ref_key: "viewport",
1032
+ ref: g,
1033
+ class: "vue-virtual-carousel",
1034
+ style: C(_.value),
1035
+ role: "region",
1036
+ "aria-roledescription": "carousel",
1037
+ "aria-label": n.ariaLabel,
1038
+ tabindex: "0",
1039
+ onScrollPassive: ne,
1040
+ onKeydown: fe
1041
+ }, [
1042
+ n.items.length ? (w(), b("div", _e, [
1043
+ G.value > 0 ? (w(), b("div", {
1044
+ key: 0,
1045
+ class: "vue-virtual-carousel__spacer",
1046
+ style: C({ flexBasis: `${G.value}px` }),
1047
+ "aria-hidden": "true"
1048
+ }, null, 4)) : he("", !0),
1049
+ (w(!0), b(ve, null, Me(z.value, ({ item: h, index: a }) => (w(), b("div", {
1050
+ key: m(O)(h, a),
1051
+ class: "vue-virtual-carousel__item",
1052
+ style: C({
1053
+ flexBasis: `${F.value}px`,
1054
+ marginRight: a < n.items.length - 1 ? `${p.value}px` : "0px"
1055
+ }),
1056
+ role: "listitem",
1057
+ "aria-roledescription": "slide",
1058
+ "aria-label": `${a + 1} of ${n.items.length}`,
1059
+ "aria-current": a === u.value ? "true" : void 0
1060
+ }, [
1061
+ X(d.$slots, "default", {
1062
+ item: h,
1063
+ index: a,
1064
+ active: a === u.value,
1065
+ visible: Y(a)
1066
+ })
1067
+ ], 12, Ue))), 128)),
1068
+ J.value > 0 ? (w(), b("div", {
1069
+ key: 1,
1070
+ class: "vue-virtual-carousel__spacer",
1071
+ style: C({ flexBasis: `${J.value}px` }),
1072
+ "aria-hidden": "true"
1073
+ }, null, 4)) : he("", !0)
1074
+ ])) : (w(), b("div", je, [
1075
+ X(d.$slots, "empty")
1076
+ ]))
1077
+ ], 44, We));
1078
+ }
1079
+ }), qe = ["aria-label"], Ge = ["aria-posinset", "aria-setsize"], Je = /* @__PURE__ */ ge({
1080
+ name: "VirtualScroll",
1081
+ __name: "VirtualScroll",
1082
+ props: {
1083
+ items: {},
1084
+ itemSize: {},
1085
+ height: { default: 400 },
1086
+ overscan: { default: 3 },
1087
+ itemKey: { default: void 0 },
1088
+ ariaLabel: { default: "Virtual list" },
1089
+ hasMore: { type: Boolean, default: !1 },
1090
+ loading: { type: Boolean, default: !1 },
1091
+ loadingItemSize: { default: void 0 },
1092
+ loadMoreThreshold: { default: 200 },
1093
+ pullToRefresh: { type: Boolean, default: !1 },
1094
+ refreshing: { type: Boolean, default: !1 },
1095
+ pullRefreshThreshold: { default: 64 }
1096
+ },
1097
+ emits: ["scroll", "loadMore", "refresh"],
1098
+ setup(n, { expose: W, emit: k }) {
1099
+ const e = n, S = k, {
1100
+ pulling: g,
1101
+ pullDistance: x,
1102
+ pullOffset: u,
1103
+ pullProgress: V,
1104
+ refreshMessage: P,
1105
+ refreshThreshold: O,
1106
+ handleTouchStart: E,
1107
+ handleTouchMove: N,
1108
+ handleTouchEnd: p,
1109
+ handleTouchCancel: H
1110
+ } = He({
1111
+ enabled: () => e.pullToRefresh,
1112
+ refreshing: () => e.refreshing,
1113
+ threshold: () => e.pullRefreshThreshold,
1114
+ onRefresh: () => S("refresh")
1115
+ }), T = A(), B = A(0), F = A(0);
1116
+ let I, U = -1;
1117
+ const ee = be(), { getItemKey: K } = xe({
1118
+ componentName: "VirtualScroll",
1119
+ items: () => e.items,
1120
+ itemKey: () => e.itemKey
1121
+ }), z = i(() => Math.max(1, e.itemSize)), te = i(() => Math.max(0, Math.floor(e.overscan))), G = i(
1122
+ () => e.items.length * z.value
1123
+ ), J = i(
1124
+ () => Math.max(1, e.loadingItemSize ?? z.value)
1125
+ ), _ = i(
1126
+ () => G.value + (e.loading ? J.value : 0)
1127
+ ), oe = i(() => F.value > 0 ? F.value : typeof e.height == "number" ? e.height : 0), Y = i(
1128
+ () => Math.max(
1129
+ 0,
1130
+ Math.floor(B.value / z.value) - te.value
1131
+ )
1132
+ ), c = i(() => {
1133
+ const s = Math.ceil(
1134
+ (B.value + oe.value) / z.value
1135
+ );
1136
+ return Math.min(
1137
+ e.items.length,
1138
+ s + te.value
1139
+ );
1140
+ }), v = i(
1141
+ () => e.items.slice(Y.value, c.value).map((s, h) => ({
1142
+ item: s,
1143
+ index: Y.value + h
1144
+ }))
1145
+ ), L = i(() => ({
1146
+ height: we(e.height)
1147
+ })), j = i(() => ({
1148
+ transform: `translateY(${Y.value * z.value}px)`
1149
+ }));
1150
+ function re() {
1151
+ var s;
1152
+ F.value = ((s = T.value) == null ? void 0 : s.clientHeight) ?? 0, ee(T.value, e.height), $(ne);
1153
+ }
1154
+ function se(s) {
1155
+ B.value = s.currentTarget.scrollTop, S("scroll", {
1156
+ scrollTop: B.value,
1157
+ startIndex: Y.value,
1158
+ endIndex: c.value
1159
+ }), ne();
1160
+ }
1161
+ function ne() {
1162
+ const s = T.value;
1163
+ if (!s || !e.hasMore || e.loading || U === e.items.length)
1164
+ return;
1165
+ const h = Math.max(0, e.loadMoreThreshold);
1166
+ _.value - s.scrollTop - s.clientHeight <= h && (U = e.items.length, S("loadMore"));
1167
+ }
1168
+ function fe(s, h = {}) {
1169
+ const a = T.value;
1170
+ if (!a) return;
1171
+ const f = Math.max(0, _.value - a.clientHeight), r = Math.min(
1172
+ Math.max(0, Number.isFinite(s) ? s : 0),
1173
+ f
1174
+ ), D = h.behavior ?? "auto";
1175
+ D === "auto" && (B.value = r), a.scrollTo({ ...h, top: r, behavior: D });
1176
+ }
1177
+ function le(s, h = {}) {
1178
+ const a = T.value;
1179
+ if (!a || e.items.length === 0) return;
1180
+ const f = Math.min(
1181
+ e.items.length - 1,
1182
+ Math.max(0, Math.floor(s))
1183
+ ), { align: r = "start", ...D } = h;
1184
+ let R = f * z.value;
1185
+ r === "center" ? R -= (a.clientHeight - z.value) / 2 : r === "end" && (R -= a.clientHeight - z.value), a.scrollTo({
1186
+ ...D,
1187
+ top: Math.max(0, Math.min(R, _.value - a.clientHeight))
1188
+ });
1189
+ }
1190
+ function d(s = "auto") {
1191
+ var h;
1192
+ (h = T.value) == null || h.scrollTo({ top: 0, behavior: s });
1193
+ }
1194
+ return ae(
1195
+ () => [e.items.length, e.itemSize],
1196
+ async () => {
1197
+ await $();
1198
+ const s = T.value;
1199
+ if (!s) return;
1200
+ const h = Math.max(0, _.value - s.clientHeight);
1201
+ s.scrollTop > h && (s.scrollTop = h, B.value = h), ne();
1202
+ }
1203
+ ), ae(
1204
+ () => [e.hasMore, e.loading],
1205
+ async ([s]) => {
1206
+ s || (U = -1), await $(), ne();
1207
+ }
1208
+ ), pe(() => {
1209
+ re(), typeof ResizeObserver < "u" && T.value && (I = new ResizeObserver(re), I.observe(T.value)), $(ne);
1210
+ }), ye(() => {
1211
+ I == null || I.disconnect();
1212
+ }), W({
1213
+ scrollTo: fe,
1214
+ scrollToIndex: le,
1215
+ scrollToTop: d
1216
+ }), (s, h) => (w(), b("div", {
1217
+ ref_key: "viewport",
1218
+ ref: T,
1219
+ class: $e(["vue-virtual-scroll", { "vue-virtual-scroll--pulling": m(g) }]),
1220
+ style: C(L.value),
1221
+ role: "list",
1222
+ "aria-label": n.ariaLabel,
1223
+ tabindex: "0",
1224
+ onScrollPassive: se,
1225
+ onTouchstartPassive: h[0] || (h[0] = //@ts-ignore
1226
+ (...a) => m(E) && m(E)(...a)),
1227
+ onTouchmove: h[1] || (h[1] = //@ts-ignore
1228
+ (...a) => m(N) && m(N)(...a)),
1229
+ onTouchend: h[2] || (h[2] = //@ts-ignore
1230
+ (...a) => m(p) && m(p)(...a)),
1231
+ onTouchcancel: h[3] || (h[3] = //@ts-ignore
1232
+ (...a) => m(H) && m(H)(...a))
1233
+ }, [
1234
+ n.pullToRefresh || n.refreshing ? (w(), b("div", {
1235
+ key: 0,
1236
+ class: "vue-virtual-scroll__refresh",
1237
+ style: C({
1238
+ height: `${m(O)}px`,
1239
+ transform: `translateY(${m(u) - m(O)}px)`
1240
+ }),
1241
+ role: "status",
1242
+ "aria-live": "polite"
1243
+ }, [
1244
+ X(s.$slots, "refresh", {
1245
+ pullDistance: m(x),
1246
+ progress: m(V),
1247
+ refreshing: n.refreshing
1248
+ }, () => [
1249
+ me(ke(m(P)), 1)
1250
+ ])
1251
+ ], 4)) : he("", !0),
1252
+ n.items.length || n.loading ? (w(), b("div", {
1253
+ key: 1,
1254
+ class: "vue-virtual-scroll__spacer",
1255
+ style: C({
1256
+ height: `${_.value}px`,
1257
+ transform: `translateY(${m(u)}px)`
1258
+ })
1259
+ }, [
1260
+ Be("div", {
1261
+ class: "vue-virtual-scroll__content",
1262
+ style: C(j.value)
1263
+ }, [
1264
+ (w(!0), b(ve, null, Me(v.value, ({ item: a, index: f }) => (w(), b("div", {
1265
+ key: m(K)(a, f),
1266
+ class: "vue-virtual-scroll__item",
1267
+ style: C({ height: `${z.value}px` }),
1268
+ role: "listitem",
1269
+ "aria-posinset": f + 1,
1270
+ "aria-setsize": n.items.length
1271
+ }, [
1272
+ X(s.$slots, "default", {
1273
+ item: a,
1274
+ index: f
1275
+ })
1276
+ ], 12, Ge))), 128))
1277
+ ], 4),
1278
+ n.loading ? (w(), b("div", {
1279
+ key: 0,
1280
+ class: "vue-virtual-scroll__loading",
1281
+ style: C({
1282
+ height: `${J.value}px`,
1283
+ transform: `translateY(${G.value}px)`
1284
+ }),
1285
+ role: "status",
1286
+ "aria-live": "polite"
1287
+ }, [
1288
+ X(s.$slots, "loading", {}, () => [
1289
+ h[4] || (h[4] = me("Loading more…", -1))
1290
+ ])
1291
+ ], 4)) : he("", !0)
1292
+ ], 4)) : (w(), b("div", {
1293
+ key: 2,
1294
+ class: "vue-virtual-scroll__empty",
1295
+ style: C({ transform: `translateY(${m(u)}px)` })
1296
+ }, [
1297
+ X(s.$slots, "empty")
1298
+ ], 4))
1299
+ ], 46, qe));
1300
+ }
1301
+ }), Qe = ["aria-label"], Xe = ["aria-posinset", "aria-setsize"], et = /* @__PURE__ */ ge({
1302
+ name: "WindowDynamicVirtualScroll",
1303
+ __name: "WindowDynamicVirtualScroll",
1304
+ props: {
1305
+ items: {},
1306
+ estimatedItemSize: { default: 48 },
1307
+ overscan: { default: 3 },
1308
+ itemKey: { default: void 0 },
1309
+ ariaLabel: { default: "Window dynamic virtual list" },
1310
+ hasMore: { type: Boolean, default: !1 },
1311
+ loading: { type: Boolean, default: !1 },
1312
+ loadingItemSize: { default: void 0 },
1313
+ loadMoreThreshold: { default: 200 },
1314
+ pullToRefresh: { type: Boolean, default: !1 },
1315
+ refreshing: { type: Boolean, default: !1 },
1316
+ pullRefreshThreshold: { default: 64 }
1317
+ },
1318
+ emits: ["scroll", "loadMore", "refresh"],
1319
+ setup(n, { expose: W, emit: k }) {
1320
+ const e = n, S = k, g = A(), x = A(0), u = A(0), V = A(0), P = A(0), O = /* @__PURE__ */ new Map(), E = /* @__PURE__ */ new Map();
1321
+ let N, p, H = -1;
1322
+ const { getItemKey: T } = xe({
1323
+ componentName: "WindowDynamicVirtualScroll",
1324
+ items: () => e.items,
1325
+ itemKey: () => e.itemKey
1326
+ }), {
1327
+ pulling: B,
1328
+ pullDistance: F,
1329
+ pullOffset: I,
1330
+ pullProgress: U,
1331
+ refreshMessage: ee,
1332
+ refreshThreshold: K,
1333
+ handleTouchStart: z,
1334
+ handleTouchMove: te,
1335
+ handleTouchEnd: G,
1336
+ handleTouchCancel: J
1337
+ } = He({
1338
+ enabled: () => e.pullToRefresh,
1339
+ refreshing: () => e.refreshing,
1340
+ threshold: () => e.pullRefreshThreshold,
1341
+ onRefresh: () => S("refresh"),
1342
+ scrollTop: () => typeof window > "u" ? 0 : Math.max(0, window.scrollY)
1343
+ }), _ = i(
1344
+ () => Math.max(1, e.estimatedItemSize)
1345
+ ), oe = i(
1346
+ () => Math.max(1, e.loadingItemSize ?? _.value)
1347
+ ), Y = i(() => Math.max(0, Math.floor(e.overscan))), c = i(() => {
1348
+ P.value;
1349
+ const t = new Array(e.items.length + 1), o = new Array(e.items.length);
1350
+ t[0] = 0;
1351
+ for (let l = 0; l < e.items.length; l += 1) {
1352
+ const M = T(e.items[l], l), y = O.get(M) ?? _.value;
1353
+ o[l] = y, t[l + 1] = t[l] + y;
1354
+ }
1355
+ return {
1356
+ offsets: t,
1357
+ sizes: o,
1358
+ total: t[e.items.length] ?? 0
1359
+ };
1360
+ }), v = i(
1361
+ () => c.value.total + (e.loading ? oe.value : 0)
1362
+ ), L = i(() => {
1363
+ const t = /* @__PURE__ */ new Map();
1364
+ return e.items.forEach((o, l) => {
1365
+ t.set(T(o, l), l);
1366
+ }), t;
1367
+ }), j = i(
1368
+ () => Math.max(0, x.value - V.value)
1369
+ );
1370
+ function re(t) {
1371
+ if (e.items.length === 0) return 0;
1372
+ const o = c.value.offsets;
1373
+ let l = 0, M = e.items.length;
1374
+ for (; l < M; ) {
1375
+ const y = Math.floor((l + M) / 2);
1376
+ o[y + 1] <= t ? l = y + 1 : M = y;
1377
+ }
1378
+ return Math.min(l, e.items.length - 1);
1379
+ }
1380
+ const se = i(
1381
+ () => Math.max(
1382
+ 0,
1383
+ re(j.value) - Y.value
1384
+ )
1385
+ ), ne = i(() => {
1386
+ if (e.items.length === 0) return 0;
1387
+ const t = x.value + u.value - V.value, o = Math.max(
1388
+ _.value,
1389
+ t
1390
+ ), l = re(o) + 1;
1391
+ return Math.min(
1392
+ e.items.length,
1393
+ l + Y.value
1394
+ );
1395
+ }), fe = i(
1396
+ () => e.items.slice(se.value, ne.value).map((t, o) => {
1397
+ const l = se.value + o;
1398
+ return {
1399
+ item: t,
1400
+ index: l,
1401
+ key: T(t, l),
1402
+ top: c.value.offsets[l]
1403
+ };
1404
+ })
1405
+ );
1406
+ function le() {
1407
+ typeof window > "u" || (x.value = Math.max(0, window.scrollY), u.value = window.innerHeight, g.value && (V.value = g.value.getBoundingClientRect().top + x.value));
1408
+ }
1409
+ function d() {
1410
+ S("scroll", {
1411
+ scrollTop: j.value,
1412
+ startIndex: se.value,
1413
+ endIndex: ne.value
1414
+ });
1415
+ }
1416
+ function s() {
1417
+ le(), d(), h();
1418
+ }
1419
+ function h() {
1420
+ if (typeof window > "u" || !e.hasMore || e.loading || H === e.items.length)
1421
+ return;
1422
+ const t = Math.max(0, e.loadMoreThreshold), o = V.value + v.value, l = x.value + u.value;
1423
+ o - l <= t && (H = e.items.length, S("loadMore"));
1424
+ }
1425
+ function a(t) {
1426
+ const o = t.borderBoxSize;
1427
+ if (o) {
1428
+ const l = Array.isArray(o) ? o[0] : o;
1429
+ if (l != null && l.blockSize) return l.blockSize;
1430
+ }
1431
+ return t.contentRect.height;
1432
+ }
1433
+ function f(t) {
1434
+ const o = c.value;
1435
+ let l = 0, M = !1;
1436
+ for (const y of t) {
1437
+ const Q = y.target, q = E.get(Q), ie = a(y);
1438
+ if (q === void 0 || ie <= 0) continue;
1439
+ const ce = O.get(q) ?? _.value;
1440
+ if (Math.abs(ce - ie) < 0.5) continue;
1441
+ const de = L.value.get(q);
1442
+ de !== void 0 && o.offsets[de + 1] <= j.value && (l += ie - ce), O.set(q, ie), M = !0;
1443
+ }
1444
+ M && (P.value += 1, $(() => {
1445
+ if (l !== 0 && typeof window < "u") {
1446
+ const y = Math.max(
1447
+ 0,
1448
+ x.value + l
1449
+ );
1450
+ x.value = y, window.scrollTo({ top: y, behavior: "auto" });
1451
+ }
1452
+ le(), h();
1453
+ }));
1454
+ }
1455
+ function r(t, o) {
1456
+ t instanceof HTMLElement && (E.set(t, o), p == null || p.observe(t));
1457
+ }
1458
+ function D() {
1459
+ for (const [t] of E)
1460
+ t.isConnected || (p == null || p.unobserve(t), E.delete(t));
1461
+ }
1462
+ function R(t, o = {}) {
1463
+ if (typeof window > "u") return;
1464
+ le();
1465
+ const l = Math.max(0, v.value - u.value), M = Math.min(
1466
+ Math.max(0, Number.isFinite(t) ? t : 0),
1467
+ l
1468
+ ), y = Math.max(0, V.value + M), Q = o.behavior ?? "auto";
1469
+ Q === "auto" && (x.value = y), window.scrollTo({ ...o, top: y, behavior: Q });
1470
+ }
1471
+ function Z(t, o = {}) {
1472
+ if (typeof window > "u" || e.items.length === 0) return;
1473
+ le();
1474
+ const l = Math.min(
1475
+ e.items.length - 1,
1476
+ Math.max(0, Math.floor(t))
1477
+ ), { align: M = "start", ...y } = o, Q = c.value.sizes[l];
1478
+ let q = V.value + c.value.offsets[l];
1479
+ M === "center" ? q -= (u.value - Q) / 2 : M === "end" && (q -= u.value - Q);
1480
+ const ie = Math.max(
1481
+ V.value,
1482
+ V.value + v.value - u.value
1483
+ ), ce = Math.max(0, Math.min(q, ie)), de = y.behavior ?? "auto", Se = Math.max(
1484
+ u.value * 3,
1485
+ _.value * 10
1486
+ ), Te = de === "smooth" && Math.abs(ce - x.value) > Se ? "auto" : de;
1487
+ Te === "auto" && (x.value = ce), window.scrollTo({
1488
+ ...y,
1489
+ top: ce,
1490
+ behavior: Te
1491
+ });
1492
+ }
1493
+ function ue(t = "auto") {
1494
+ typeof window > "u" || (le(), window.scrollTo({ top: Math.max(0, V.value), behavior: t }));
1495
+ }
1496
+ return ae(
1497
+ () => e.itemKey,
1498
+ () => {
1499
+ O.clear(), P.value += 1;
1500
+ }
1501
+ ), ae(
1502
+ () => e.items.length,
1503
+ async () => {
1504
+ const t = new Set(
1505
+ e.items.map((o, l) => T(o, l))
1506
+ );
1507
+ for (const o of O.keys())
1508
+ t.has(o) || O.delete(o);
1509
+ P.value += 1, await $(), le(), h();
1510
+ }
1511
+ ), ae(
1512
+ () => [e.hasMore, e.loading],
1513
+ async ([t]) => {
1514
+ t || (H = -1), await $(), le(), h();
1515
+ }
1516
+ ), pe(() => {
1517
+ if (le(), window.addEventListener("scroll", s, { passive: !0 }), window.addEventListener("resize", s, { passive: !0 }), typeof ResizeObserver < "u") {
1518
+ N = new ResizeObserver(() => {
1519
+ le(), h();
1520
+ }), p = new ResizeObserver(f), g.value && N.observe(g.value);
1521
+ for (const [t] of E)
1522
+ p.observe(t);
1523
+ }
1524
+ $(h);
1525
+ }), ze(D), ye(() => {
1526
+ window.removeEventListener("scroll", s), window.removeEventListener("resize", s), N == null || N.disconnect(), p == null || p.disconnect(), E.clear();
1527
+ }), W({
1528
+ scrollTo: R,
1529
+ scrollToIndex: Z,
1530
+ scrollToTop: ue
1531
+ }), (t, o) => (w(), b("div", {
1532
+ ref_key: "root",
1533
+ ref: g,
1534
+ class: $e(["vue-window-dynamic-virtual-scroll", { "vue-window-dynamic-virtual-scroll--pulling": m(B) }]),
1535
+ role: "list",
1536
+ "aria-label": n.ariaLabel,
1537
+ onTouchstartPassive: o[0] || (o[0] = //@ts-ignore
1538
+ (...l) => m(z) && m(z)(...l)),
1539
+ onTouchmove: o[1] || (o[1] = //@ts-ignore
1540
+ (...l) => m(te) && m(te)(...l)),
1541
+ onTouchend: o[2] || (o[2] = //@ts-ignore
1542
+ (...l) => m(G) && m(G)(...l)),
1543
+ onTouchcancel: o[3] || (o[3] = //@ts-ignore
1544
+ (...l) => m(J) && m(J)(...l))
1545
+ }, [
1546
+ n.pullToRefresh || n.refreshing ? (w(), b("div", {
1547
+ key: 0,
1548
+ class: "vue-window-dynamic-virtual-scroll__refresh",
1549
+ style: C({
1550
+ height: `${m(K)}px`,
1551
+ transform: `translateY(${m(I) - m(K)}px)`
1552
+ }),
1553
+ role: "status",
1554
+ "aria-live": "polite"
1555
+ }, [
1556
+ X(t.$slots, "refresh", {
1557
+ pullDistance: m(F),
1558
+ progress: m(U),
1559
+ refreshing: n.refreshing
1560
+ }, () => [
1561
+ me(ke(m(ee)), 1)
1562
+ ])
1563
+ ], 4)) : he("", !0),
1564
+ n.items.length || n.loading ? (w(), b("div", {
1565
+ key: 1,
1566
+ class: "vue-window-dynamic-virtual-scroll__spacer",
1567
+ style: C({
1568
+ height: `${v.value}px`,
1569
+ transform: `translateY(${m(I)}px)`
1570
+ })
1571
+ }, [
1572
+ (w(!0), b(ve, null, Me(fe.value, ({ item: l, index: M, key: y, top: Q }) => (w(), b("div", {
1573
+ key: y,
1574
+ ref_for: !0,
1575
+ ref: (q) => r(q, y),
1576
+ class: "vue-window-dynamic-virtual-scroll__item",
1577
+ style: C({ transform: `translateY(${Q}px)` }),
1578
+ role: "listitem",
1579
+ "aria-posinset": M + 1,
1580
+ "aria-setsize": n.items.length
1581
+ }, [
1582
+ X(t.$slots, "default", {
1583
+ item: l,
1584
+ index: M
1585
+ })
1586
+ ], 12, Xe))), 128)),
1587
+ n.loading ? (w(), b("div", {
1588
+ key: 0,
1589
+ class: "vue-window-dynamic-virtual-scroll__loading",
1590
+ style: C({
1591
+ height: `${oe.value}px`,
1592
+ transform: `translateY(${c.value.total}px)`
1593
+ }),
1594
+ role: "status",
1595
+ "aria-live": "polite"
1596
+ }, [
1597
+ X(t.$slots, "loading", {}, () => [
1598
+ o[4] || (o[4] = me("Loading more…", -1))
1599
+ ])
1600
+ ], 4)) : he("", !0)
1601
+ ], 4)) : (w(), b("div", {
1602
+ key: 2,
1603
+ class: "vue-window-dynamic-virtual-scroll__empty",
1604
+ style: C({ transform: `translateY(${m(I)}px)` })
1605
+ }, [
1606
+ X(t.$slots, "empty")
1607
+ ], 4))
1608
+ ], 42, Qe));
1609
+ }
1610
+ }), tt = Le, at = {
1611
+ install(n) {
1612
+ n.component("ChatVirtualScroll", Re), n.component("DynamicVirtualScroll", Le), n.component("ShortMediaFeed", Fe), n.component("VirtualCarousel", Ze), n.component("VirtualList", tt), n.component("VirtualScroll", Je), n.component(
1613
+ "WindowDynamicVirtualScroll",
1614
+ et
1615
+ );
1616
+ }
1617
+ };
1618
+ export {
1619
+ Re as ChatVirtualScroll,
1620
+ Le as DynamicVirtualScroll,
1621
+ Fe as ShortMediaFeed,
1622
+ Ze as VirtualCarousel,
1623
+ tt as VirtualList,
1624
+ Je as VirtualScroll,
1625
+ at as VueVirtualScroll,
1626
+ et as WindowDynamicVirtualScroll,
1627
+ at as default
1628
+ };