@wyxos/vibe 1.4.0 → 1.4.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.
- package/lib/index.js +278 -279
- package/lib/vibe.css +1 -1
- package/package.json +5 -1
- package/src/Masonry.vue +16 -9
- package/src/useMasonryScroll.ts +8 -2
package/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { nextTick as X, defineComponent as
|
|
1
|
+
import { nextTick as X, defineComponent as gt, computed as et, ref as B, onMounted as pt, onUnmounted as mt, createElementBlock as Y, openBlock as J, normalizeClass as nt, createElementVNode as C, normalizeStyle as ht, createVNode as yt, createCommentVNode as vt, TransitionGroup as bt, unref as q, withCtx as xt, Fragment as wt, renderList as Tt, mergeProps as at, renderSlot as Mt, toDisplayString as rt } from "vue";
|
|
2
2
|
function It() {
|
|
3
3
|
const t = document.createElement("div");
|
|
4
4
|
t.style.visibility = "hidden", t.style.overflow = "scroll", t.style.msOverflowStyle = "scrollbar", t.style.width = "100px", t.style.height = "100px", document.body.appendChild(t);
|
|
@@ -7,15 +7,15 @@ function It() {
|
|
|
7
7
|
const o = t.offsetWidth - a.offsetWidth;
|
|
8
8
|
return document.body.removeChild(t), o;
|
|
9
9
|
}
|
|
10
|
-
function St(t, a, o,
|
|
10
|
+
function St(t, a, o, l = {}) {
|
|
11
11
|
const {
|
|
12
12
|
gutterX: b = 0,
|
|
13
13
|
gutterY: r = 0,
|
|
14
14
|
header: d = 0,
|
|
15
15
|
footer: i = 0,
|
|
16
16
|
paddingLeft: w = 0,
|
|
17
|
-
paddingRight:
|
|
18
|
-
sizes:
|
|
17
|
+
paddingRight: m = 0,
|
|
18
|
+
sizes: h = {
|
|
19
19
|
base: 1,
|
|
20
20
|
sm: 2,
|
|
21
21
|
md: 3,
|
|
@@ -23,81 +23,81 @@ function St(t, a, o, s = {}) {
|
|
|
23
23
|
xl: 5,
|
|
24
24
|
"2xl": 6
|
|
25
25
|
},
|
|
26
|
-
placement:
|
|
27
|
-
} =
|
|
28
|
-
let
|
|
26
|
+
placement: g = "masonry"
|
|
27
|
+
} = l;
|
|
28
|
+
let x = 0, E = 0;
|
|
29
29
|
try {
|
|
30
30
|
if (a && a.nodeType === 1 && typeof window < "u" && window.getComputedStyle) {
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const u = window.getComputedStyle(a);
|
|
32
|
+
x = parseFloat(u.paddingLeft) || 0, E = parseFloat(u.paddingRight) || 0;
|
|
33
33
|
}
|
|
34
34
|
} catch {
|
|
35
35
|
}
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
return Math.round(I *
|
|
36
|
+
const W = (w || 0) + x, O = (m || 0) + E, M = a.offsetWidth - a.clientWidth, T = M > 0 ? M + 2 : It() + 2, L = a.offsetWidth - T - W - O, $ = b * (o - 1), I = Math.floor((L - $) / o), p = t.map((u) => {
|
|
37
|
+
const k = u.width, H = u.height;
|
|
38
|
+
return Math.round(I * H / k) + i + d;
|
|
39
39
|
});
|
|
40
|
-
if (
|
|
41
|
-
const
|
|
42
|
-
if (
|
|
43
|
-
const
|
|
44
|
-
let
|
|
40
|
+
if (g === "sequential-balanced") {
|
|
41
|
+
const u = p.length;
|
|
42
|
+
if (u === 0) return [];
|
|
43
|
+
const k = (e, n, c) => e + (n > 0 ? r : 0) + c;
|
|
44
|
+
let H = Math.max(...p), N = p.reduce((e, n) => e + n, 0) + r * Math.max(0, u - 1);
|
|
45
45
|
const R = (e) => {
|
|
46
|
-
let n = 1,
|
|
47
|
-
for (let
|
|
48
|
-
const P = y
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
else if (n++,
|
|
46
|
+
let n = 1, c = 0, f = 0;
|
|
47
|
+
for (let y = 0; y < u; y++) {
|
|
48
|
+
const P = p[y], S = k(c, f, P);
|
|
49
|
+
if (S <= e)
|
|
50
|
+
c = S, f++;
|
|
51
|
+
else if (n++, c = P, f = 1, P > e || n > o) return !1;
|
|
52
52
|
}
|
|
53
53
|
return n <= o;
|
|
54
54
|
};
|
|
55
|
-
for (;
|
|
56
|
-
const e = Math.floor((
|
|
57
|
-
R(e) ?
|
|
55
|
+
for (; H < N; ) {
|
|
56
|
+
const e = Math.floor((H + N) / 2);
|
|
57
|
+
R(e) ? N = e : H = e + 1;
|
|
58
58
|
}
|
|
59
|
-
const _ =
|
|
59
|
+
const _ = N, A = new Array(o).fill(0);
|
|
60
60
|
let z = o - 1, D = 0, j = 0;
|
|
61
|
-
for (let e =
|
|
62
|
-
const n =
|
|
63
|
-
!(
|
|
61
|
+
for (let e = u - 1; e >= 0; e--) {
|
|
62
|
+
const n = p[e], c = e < z;
|
|
63
|
+
!(k(D, j, n) <= _) || c ? (A[z] = e + 1, z--, D = n, j = 1) : (D = k(D, j, n), j++);
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
const
|
|
65
|
+
A[0] = 0;
|
|
66
|
+
const V = [], U = new Array(o).fill(0);
|
|
67
67
|
for (let e = 0; e < o; e++) {
|
|
68
|
-
const n =
|
|
69
|
-
for (let
|
|
70
|
-
const
|
|
71
|
-
|
|
68
|
+
const n = A[e], c = e + 1 < o ? A[e + 1] : u, f = e * (I + b);
|
|
69
|
+
for (let y = n; y < c; y++) {
|
|
70
|
+
const S = { ...t[y], columnWidth: I, imageHeight: 0, columnHeight: 0, left: 0, top: 0 }, F = p[y] - (i + d);
|
|
71
|
+
S.imageHeight = F, S.columnHeight = p[y], S.left = f, S.top = U[e], U[e] += S.columnHeight + (y + 1 < c ? r : 0), V.push(S);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
return
|
|
74
|
+
return V;
|
|
75
75
|
}
|
|
76
|
-
const
|
|
77
|
-
for (let
|
|
78
|
-
const
|
|
79
|
-
|
|
76
|
+
const s = new Array(o).fill(0), v = [];
|
|
77
|
+
for (let u = 0; u < t.length; u++) {
|
|
78
|
+
const k = t[u], H = { ...k, columnWidth: 0, imageHeight: 0, columnHeight: 0, left: 0, top: 0 }, N = s.indexOf(Math.min(...s)), R = k.width, _ = k.height;
|
|
79
|
+
H.columnWidth = I, H.left = N * (I + b), H.imageHeight = Math.round(I * _ / R), H.columnHeight = H.imageHeight + i + d, H.top = s[N], s[N] += H.columnHeight + r, v.push(H);
|
|
80
80
|
}
|
|
81
|
-
return
|
|
81
|
+
return v;
|
|
82
82
|
}
|
|
83
|
-
var kt = typeof global == "object" && global && global.Object === Object && global, Ht = typeof self == "object" && self && self.Object === Object && self,
|
|
83
|
+
var kt = typeof global == "object" && global && global.Object === Object && global, Ht = typeof self == "object" && self && self.Object === Object && self, ft = kt || Ht || Function("return this")(), K = ft.Symbol, dt = Object.prototype, Et = dt.hasOwnProperty, Pt = dt.toString, G = K ? K.toStringTag : void 0;
|
|
84
84
|
function Lt(t) {
|
|
85
85
|
var a = Et.call(t, G), o = t[G];
|
|
86
86
|
try {
|
|
87
87
|
t[G] = void 0;
|
|
88
|
-
var
|
|
88
|
+
var l = !0;
|
|
89
89
|
} catch {
|
|
90
90
|
}
|
|
91
91
|
var b = Pt.call(t);
|
|
92
|
-
return
|
|
92
|
+
return l && (a ? t[G] = o : delete t[G]), b;
|
|
93
93
|
}
|
|
94
94
|
var $t = Object.prototype, Nt = $t.toString;
|
|
95
95
|
function Wt(t) {
|
|
96
96
|
return Nt.call(t);
|
|
97
97
|
}
|
|
98
|
-
var
|
|
98
|
+
var Ot = "[object Null]", At = "[object Undefined]", ot = K ? K.toStringTag : void 0;
|
|
99
99
|
function jt(t) {
|
|
100
|
-
return t == null ? t === void 0 ?
|
|
100
|
+
return t == null ? t === void 0 ? At : Ot : ot && ot in Object(t) ? Lt(t) : Wt(t);
|
|
101
101
|
}
|
|
102
102
|
function Bt(t) {
|
|
103
103
|
return t != null && typeof t == "object";
|
|
@@ -120,12 +120,12 @@ function Z(t) {
|
|
|
120
120
|
var a = typeof t;
|
|
121
121
|
return t != null && (a == "object" || a == "function");
|
|
122
122
|
}
|
|
123
|
-
var
|
|
124
|
-
function
|
|
123
|
+
var it = NaN, Vt = /^[-+]0x[0-9a-f]+$/i, qt = /^0b[01]+$/i, Gt = /^0o[0-7]+$/i, Xt = parseInt;
|
|
124
|
+
function st(t) {
|
|
125
125
|
if (typeof t == "number")
|
|
126
126
|
return t;
|
|
127
127
|
if (zt(t))
|
|
128
|
-
return
|
|
128
|
+
return it;
|
|
129
129
|
if (Z(t)) {
|
|
130
130
|
var a = typeof t.valueOf == "function" ? t.valueOf() : t;
|
|
131
131
|
t = Z(a) ? a + "" : a;
|
|
@@ -133,65 +133,65 @@ function it(t) {
|
|
|
133
133
|
if (typeof t != "string")
|
|
134
134
|
return t === 0 ? t : +t;
|
|
135
135
|
t = _t(t);
|
|
136
|
-
var o =
|
|
137
|
-
return o || Gt.test(t) ? Xt(t.slice(2), o ? 2 : 8) :
|
|
136
|
+
var o = qt.test(t);
|
|
137
|
+
return o || Gt.test(t) ? Xt(t.slice(2), o ? 2 : 8) : Vt.test(t) ? it : +t;
|
|
138
138
|
}
|
|
139
139
|
var Q = function() {
|
|
140
|
-
return
|
|
140
|
+
return ft.Date.now();
|
|
141
141
|
}, Ut = "Expected a function", Yt = Math.max, Jt = Math.min;
|
|
142
|
-
function
|
|
143
|
-
var
|
|
142
|
+
function lt(t, a, o) {
|
|
143
|
+
var l, b, r, d, i, w, m = 0, h = !1, g = !1, x = !0;
|
|
144
144
|
if (typeof t != "function")
|
|
145
145
|
throw new TypeError(Ut);
|
|
146
|
-
a =
|
|
147
|
-
function E(
|
|
148
|
-
var
|
|
149
|
-
return
|
|
146
|
+
a = st(a) || 0, Z(o) && (h = !!o.leading, g = "maxWait" in o, r = g ? Yt(st(o.maxWait) || 0, a) : r, x = "trailing" in o ? !!o.trailing : x);
|
|
147
|
+
function E(s) {
|
|
148
|
+
var v = l, u = b;
|
|
149
|
+
return l = b = void 0, m = s, d = t.apply(u, v), d;
|
|
150
150
|
}
|
|
151
|
-
function
|
|
152
|
-
return
|
|
151
|
+
function W(s) {
|
|
152
|
+
return m = s, i = setTimeout(T, a), h ? E(s) : d;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
var
|
|
156
|
-
return
|
|
154
|
+
function O(s) {
|
|
155
|
+
var v = s - w, u = s - m, k = a - v;
|
|
156
|
+
return g ? Jt(k, r - u) : k;
|
|
157
157
|
}
|
|
158
|
-
function
|
|
159
|
-
var
|
|
160
|
-
return w === void 0 ||
|
|
158
|
+
function M(s) {
|
|
159
|
+
var v = s - w, u = s - m;
|
|
160
|
+
return w === void 0 || v >= a || v < 0 || g && u >= r;
|
|
161
161
|
}
|
|
162
|
-
function
|
|
163
|
-
var
|
|
164
|
-
if (
|
|
165
|
-
return
|
|
166
|
-
i = setTimeout(
|
|
162
|
+
function T() {
|
|
163
|
+
var s = Q();
|
|
164
|
+
if (M(s))
|
|
165
|
+
return L(s);
|
|
166
|
+
i = setTimeout(T, O(s));
|
|
167
167
|
}
|
|
168
|
-
function
|
|
169
|
-
return i = void 0,
|
|
168
|
+
function L(s) {
|
|
169
|
+
return i = void 0, x && l ? E(s) : (l = b = void 0, d);
|
|
170
170
|
}
|
|
171
|
-
function
|
|
172
|
-
i !== void 0 && clearTimeout(i),
|
|
171
|
+
function $() {
|
|
172
|
+
i !== void 0 && clearTimeout(i), m = 0, l = w = b = i = void 0;
|
|
173
173
|
}
|
|
174
174
|
function I() {
|
|
175
|
-
return i === void 0 ? d :
|
|
175
|
+
return i === void 0 ? d : L(Q());
|
|
176
176
|
}
|
|
177
|
-
function
|
|
178
|
-
var
|
|
179
|
-
if (
|
|
177
|
+
function p() {
|
|
178
|
+
var s = Q(), v = M(s);
|
|
179
|
+
if (l = arguments, b = this, w = s, v) {
|
|
180
180
|
if (i === void 0)
|
|
181
|
-
return
|
|
182
|
-
if (
|
|
183
|
-
return clearTimeout(i), i = setTimeout(
|
|
181
|
+
return W(w);
|
|
182
|
+
if (g)
|
|
183
|
+
return clearTimeout(i), i = setTimeout(T, a), E(w);
|
|
184
184
|
}
|
|
185
|
-
return i === void 0 && (i = setTimeout(
|
|
185
|
+
return i === void 0 && (i = setTimeout(T, a)), d;
|
|
186
186
|
}
|
|
187
|
-
return
|
|
187
|
+
return p.cancel = $, p.flush = I, p;
|
|
188
188
|
}
|
|
189
|
-
function
|
|
189
|
+
function ct(t) {
|
|
190
190
|
const a = window.innerWidth, o = t.sizes;
|
|
191
191
|
return a >= 1536 && o["2xl"] ? o["2xl"] : a >= 1280 && o.xl ? o.xl : a >= 1024 && o.lg ? o.lg : a >= 768 && o.md ? o.md : a >= 640 && o.sm ? o.sm : o.base;
|
|
192
192
|
}
|
|
193
193
|
function Kt(t) {
|
|
194
|
-
return t.reduce((o,
|
|
194
|
+
return t.reduce((o, l) => Math.max(o, l.top + l.columnHeight), 0) + 500;
|
|
195
195
|
}
|
|
196
196
|
function Qt(t) {
|
|
197
197
|
return {
|
|
@@ -213,47 +213,47 @@ function Zt(t, a = 0) {
|
|
|
213
213
|
}
|
|
214
214
|
function tt(t, a) {
|
|
215
215
|
const o = new Array(a).fill(0);
|
|
216
|
-
for (let
|
|
217
|
-
const b = t[
|
|
216
|
+
for (let l = 0; l < t.length; l++) {
|
|
217
|
+
const b = t[l], r = l % a;
|
|
218
218
|
o[r] = Math.max(o[r], b.top + b.columnHeight);
|
|
219
219
|
}
|
|
220
220
|
return o;
|
|
221
221
|
}
|
|
222
222
|
function te(t) {
|
|
223
223
|
function a(r, d) {
|
|
224
|
-
const i = parseInt(r.dataset.left || "0", 10), w = parseInt(r.dataset.top || "0", 10),
|
|
225
|
-
r.style.setProperty("--masonry-opacity-delay", `${
|
|
224
|
+
const i = parseInt(r.dataset.left || "0", 10), w = parseInt(r.dataset.top || "0", 10), m = parseInt(r.dataset.index || "0", 10), h = Math.min(m * 20, 160), g = r.style.getPropertyValue("--masonry-opacity-delay");
|
|
225
|
+
r.style.setProperty("--masonry-opacity-delay", `${h}ms`), requestAnimationFrame(() => {
|
|
226
226
|
r.style.opacity = "1", r.style.transform = `translate3d(${i}px, ${w}px, 0) scale(1)`;
|
|
227
|
-
const
|
|
228
|
-
|
|
227
|
+
const x = () => {
|
|
228
|
+
g ? r.style.setProperty("--masonry-opacity-delay", g) : r.style.removeProperty("--masonry-opacity-delay"), r.removeEventListener("transitionend", x), d();
|
|
229
229
|
};
|
|
230
|
-
r.addEventListener("transitionend",
|
|
230
|
+
r.addEventListener("transitionend", x);
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
function o(r) {
|
|
234
234
|
const d = parseInt(r.dataset.left || "0", 10), i = parseInt(r.dataset.top || "0", 10);
|
|
235
235
|
r.style.opacity = "0", r.style.transform = `translate3d(${d}px, ${i + 10}px, 0) scale(0.985)`;
|
|
236
236
|
}
|
|
237
|
-
function
|
|
237
|
+
function l(r) {
|
|
238
238
|
const d = parseInt(r.dataset.left || "0", 10), i = parseInt(r.dataset.top || "0", 10);
|
|
239
239
|
r.style.transition = "none", r.style.opacity = "1", r.style.transform = `translate3d(${d}px, ${i}px, 0) scale(1)`, r.style.removeProperty("--masonry-opacity-delay"), r.offsetWidth, r.style.transition = "";
|
|
240
240
|
}
|
|
241
241
|
function b(r, d) {
|
|
242
|
-
const i = parseInt(r.dataset.left || "0", 10), w = parseInt(r.dataset.top || "0", 10),
|
|
243
|
-
r.removeEventListener("transitionend",
|
|
244
|
-
},
|
|
245
|
-
(!
|
|
246
|
-
},
|
|
247
|
-
|
|
248
|
-
},
|
|
242
|
+
const i = parseInt(r.dataset.left || "0", 10), w = parseInt(r.dataset.top || "0", 10), h = getComputedStyle(r).getPropertyValue("--masonry-leave-duration") || "", g = parseFloat(h), x = Number.isFinite(g) && g > 0 ? g : 200, E = r.style.transitionDuration, W = () => {
|
|
243
|
+
r.removeEventListener("transitionend", O), clearTimeout(M), r.style.transitionDuration = E || "";
|
|
244
|
+
}, O = (T) => {
|
|
245
|
+
(!T || T.target === r) && (W(), d());
|
|
246
|
+
}, M = setTimeout(() => {
|
|
247
|
+
W(), d();
|
|
248
|
+
}, x + 100);
|
|
249
249
|
requestAnimationFrame(() => {
|
|
250
|
-
r.style.transitionDuration = `${
|
|
250
|
+
r.style.transitionDuration = `${x}ms`, r.style.opacity = "0", r.style.transform = `translate3d(${i}px, ${w + 10}px, 0) scale(0.985)`, r.addEventListener("transitionend", O);
|
|
251
251
|
});
|
|
252
252
|
}
|
|
253
253
|
return {
|
|
254
254
|
onEnter: a,
|
|
255
255
|
onBeforeEnter: o,
|
|
256
|
-
onBeforeLeave:
|
|
256
|
+
onBeforeLeave: l,
|
|
257
257
|
onLeave: b
|
|
258
258
|
};
|
|
259
259
|
}
|
|
@@ -261,61 +261,57 @@ function ee({
|
|
|
261
261
|
container: t,
|
|
262
262
|
masonry: a,
|
|
263
263
|
columns: o,
|
|
264
|
-
containerHeight:
|
|
264
|
+
containerHeight: l,
|
|
265
265
|
isLoading: b,
|
|
266
266
|
maxItems: r,
|
|
267
267
|
pageSize: d,
|
|
268
268
|
refreshLayout: i,
|
|
269
269
|
setItemsRaw: w,
|
|
270
|
-
loadNext:
|
|
271
|
-
leaveEstimateMs:
|
|
270
|
+
loadNext: m,
|
|
271
|
+
leaveEstimateMs: h
|
|
272
272
|
}) {
|
|
273
|
-
let
|
|
274
|
-
async function
|
|
273
|
+
let g = !1, x = 0;
|
|
274
|
+
async function E() {
|
|
275
275
|
if (!t.value) return;
|
|
276
|
-
const { scrollTop: M, clientHeight:
|
|
277
|
-
|
|
276
|
+
const { scrollTop: M, clientHeight: T } = t.value, L = M + T, $ = M > x + 1;
|
|
277
|
+
x = M;
|
|
278
|
+
const I = tt(a.value, o.value), s = Math.max(...I) + 300 < L - 1, v = M + T >= l.value - 1;
|
|
279
|
+
if ((s || v) && $ && !b.value && !g)
|
|
278
280
|
try {
|
|
279
|
-
a.value.length > r && await
|
|
280
|
-
} catch (
|
|
281
|
-
console.error("Error in scroll handler:",
|
|
281
|
+
a.value.length > r && await W(I), await m(), await X();
|
|
282
|
+
} catch (u) {
|
|
283
|
+
console.error("Error in scroll handler:", u);
|
|
282
284
|
}
|
|
283
285
|
}
|
|
284
|
-
async function
|
|
286
|
+
async function W(M) {
|
|
285
287
|
if (!a.value.length || a.value.length <= d) return;
|
|
286
|
-
const
|
|
287
|
-
const
|
|
288
|
-
return u
|
|
289
|
-
}, {}),
|
|
290
|
-
if (
|
|
291
|
-
let
|
|
292
|
-
const
|
|
293
|
-
for (const
|
|
294
|
-
if (
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
function $() {
|
|
299
|
-
return (typeof m == "number" && m > 0 ? m : 250) + 50;
|
|
288
|
+
const T = a.value.reduce((s, v) => {
|
|
289
|
+
const u = v.page;
|
|
290
|
+
return s[u] || (s[u] = []), s[u].push(v), s;
|
|
291
|
+
}, {}), L = Object.keys(T).sort((s, v) => parseInt(s) - parseInt(v));
|
|
292
|
+
if (L.length === 0) return;
|
|
293
|
+
let $ = 0;
|
|
294
|
+
const I = [];
|
|
295
|
+
for (const s of L)
|
|
296
|
+
if (I.push(s), $ += T[s].length, $ >= d) break;
|
|
297
|
+
const p = a.value.filter((s) => !I.includes(String(s.page)));
|
|
298
|
+
p.length !== a.value.length && (g = !0, w(p), await X(), await new Promise((s) => requestAnimationFrame(() => s())), i(p), await X(), await O(), g = !1);
|
|
300
299
|
}
|
|
301
|
-
function
|
|
302
|
-
return new Promise((H) => setTimeout(H, M));
|
|
303
|
-
}
|
|
304
|
-
async function W() {
|
|
300
|
+
async function O() {
|
|
305
301
|
if (!t.value) return;
|
|
306
|
-
const { scrollTop: M, clientHeight:
|
|
307
|
-
if (
|
|
308
|
-
let
|
|
309
|
-
for (const
|
|
310
|
-
|
|
311
|
-
const
|
|
312
|
-
Math.abs(
|
|
302
|
+
const { scrollTop: M, clientHeight: T } = t.value, L = M + T * 0.4, $ = tt(a.value, o.value), I = $.indexOf(Math.max(...$)), p = a.value.filter((u, k) => k % o.value === I);
|
|
303
|
+
if (p.length === 0) return;
|
|
304
|
+
let s = p[0];
|
|
305
|
+
for (const u of p)
|
|
306
|
+
u.top <= L && u.top >= s.top && (s = u);
|
|
307
|
+
const v = Math.max(0, s.top - T * 0.4);
|
|
308
|
+
Math.abs(v - M) > 4 && t.value.scrollTo({ top: v, behavior: "auto" });
|
|
313
309
|
}
|
|
314
310
|
return {
|
|
315
|
-
handleScroll:
|
|
311
|
+
handleScroll: E
|
|
316
312
|
};
|
|
317
313
|
}
|
|
318
|
-
const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */
|
|
314
|
+
const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */ gt({
|
|
319
315
|
__name: "Masonry",
|
|
320
316
|
props: {
|
|
321
317
|
getNextPage: {
|
|
@@ -390,6 +386,11 @@ const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */ dt({
|
|
|
390
386
|
transitionEasing: {
|
|
391
387
|
type: String,
|
|
392
388
|
default: "cubic-bezier(.22,.61,.36,1)"
|
|
389
|
+
},
|
|
390
|
+
// Force motion even when user has reduced-motion enabled
|
|
391
|
+
forceMotion: {
|
|
392
|
+
type: Boolean,
|
|
393
|
+
default: !1
|
|
393
394
|
}
|
|
394
395
|
},
|
|
395
396
|
emits: [
|
|
@@ -402,7 +403,7 @@ const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */ dt({
|
|
|
402
403
|
"retry:stop"
|
|
403
404
|
],
|
|
404
405
|
setup(t, { expose: a, emit: o }) {
|
|
405
|
-
const
|
|
406
|
+
const l = t, b = {
|
|
406
407
|
sizes: { base: 1, sm: 2, md: 3, lg: 4, xl: 5, "2xl": 6 },
|
|
407
408
|
gutterX: 10,
|
|
408
409
|
gutterY: 10,
|
|
@@ -415,241 +416,239 @@ const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */ dt({
|
|
|
415
416
|
var e;
|
|
416
417
|
return {
|
|
417
418
|
...b,
|
|
418
|
-
...
|
|
419
|
+
...l.layout,
|
|
419
420
|
sizes: {
|
|
420
421
|
...b.sizes,
|
|
421
|
-
...((e =
|
|
422
|
+
...((e = l.layout) == null ? void 0 : e.sizes) || {}
|
|
422
423
|
}
|
|
423
424
|
};
|
|
424
425
|
}), d = o, i = et({
|
|
425
|
-
get: () =>
|
|
426
|
+
get: () => l.items,
|
|
426
427
|
set: (e) => d("update:items", e)
|
|
427
|
-
}), w = B(7),
|
|
428
|
+
}), w = B(7), m = B(null), h = B([]);
|
|
428
429
|
B(null);
|
|
429
|
-
const
|
|
430
|
+
const g = B(!1), x = B(0), E = B({
|
|
430
431
|
distanceToTrigger: 0,
|
|
431
432
|
isNearTrigger: !1
|
|
432
|
-
}),
|
|
433
|
-
if (!
|
|
434
|
-
const { scrollTop: e, clientHeight: n } =
|
|
433
|
+
}), W = () => {
|
|
434
|
+
if (!m.value) return;
|
|
435
|
+
const { scrollTop: e, clientHeight: n } = m.value, c = e + n, f = tt(i.value, w.value), P = Math.max(...f) + 300, S = Math.max(0, P - c), F = S <= 100;
|
|
435
436
|
E.value = {
|
|
436
|
-
distanceToTrigger: Math.round(
|
|
437
|
+
distanceToTrigger: Math.round(S),
|
|
437
438
|
isNearTrigger: F
|
|
438
439
|
};
|
|
439
|
-
}, { onEnter:
|
|
440
|
-
container:
|
|
440
|
+
}, { onEnter: O, onBeforeEnter: M, onBeforeLeave: T, onLeave: L } = te(), { handleScroll: $ } = ee({
|
|
441
|
+
container: m,
|
|
441
442
|
masonry: i,
|
|
442
443
|
columns: w,
|
|
443
|
-
containerHeight:
|
|
444
|
-
isLoading:
|
|
445
|
-
maxItems:
|
|
446
|
-
pageSize:
|
|
447
|
-
refreshLayout:
|
|
444
|
+
containerHeight: x,
|
|
445
|
+
isLoading: g,
|
|
446
|
+
maxItems: l.maxItems,
|
|
447
|
+
pageSize: l.pageSize,
|
|
448
|
+
refreshLayout: p,
|
|
448
449
|
setItemsRaw: (e) => {
|
|
449
450
|
i.value = e;
|
|
450
451
|
},
|
|
451
|
-
loadNext:
|
|
452
|
-
leaveEstimateMs:
|
|
452
|
+
loadNext: H,
|
|
453
|
+
leaveEstimateMs: l.leaveDurationMs
|
|
453
454
|
});
|
|
454
455
|
a({
|
|
455
|
-
isLoading:
|
|
456
|
-
refreshLayout:
|
|
457
|
-
containerHeight:
|
|
458
|
-
remove:
|
|
456
|
+
isLoading: g,
|
|
457
|
+
refreshLayout: p,
|
|
458
|
+
containerHeight: x,
|
|
459
|
+
remove: N,
|
|
459
460
|
removeMany: R,
|
|
460
|
-
loadNext:
|
|
461
|
-
loadPage:
|
|
461
|
+
loadNext: H,
|
|
462
|
+
loadPage: k,
|
|
462
463
|
reset: D,
|
|
463
464
|
init: U,
|
|
464
|
-
paginationHistory:
|
|
465
|
+
paginationHistory: h
|
|
465
466
|
});
|
|
466
467
|
function I(e) {
|
|
467
468
|
const n = Kt(e);
|
|
468
|
-
let
|
|
469
|
-
if (
|
|
470
|
-
const { scrollTop:
|
|
471
|
-
|
|
469
|
+
let c = 0;
|
|
470
|
+
if (m.value) {
|
|
471
|
+
const { scrollTop: f, clientHeight: y } = m.value;
|
|
472
|
+
c = f + y + 100;
|
|
472
473
|
}
|
|
473
|
-
|
|
474
|
+
x.value = Math.max(n, c);
|
|
474
475
|
}
|
|
475
|
-
function
|
|
476
|
-
if (!
|
|
477
|
-
const n = St(e,
|
|
476
|
+
function p(e) {
|
|
477
|
+
if (!m.value) return;
|
|
478
|
+
const n = St(e, m.value, w.value, r.value);
|
|
478
479
|
I(n), i.value = n;
|
|
479
480
|
}
|
|
480
|
-
function
|
|
481
|
-
return new Promise((
|
|
482
|
-
const
|
|
483
|
-
n(
|
|
481
|
+
function s(e, n) {
|
|
482
|
+
return new Promise((c) => {
|
|
483
|
+
const f = Math.max(0, e | 0), y = Date.now();
|
|
484
|
+
n(f, f);
|
|
484
485
|
const P = setInterval(() => {
|
|
485
|
-
const
|
|
486
|
-
n(F,
|
|
486
|
+
const S = Date.now() - y, F = Math.max(0, f - S);
|
|
487
|
+
n(F, f), F <= 0 && (clearInterval(P), c());
|
|
487
488
|
}, 100);
|
|
488
489
|
});
|
|
489
490
|
}
|
|
490
|
-
async function
|
|
491
|
+
async function v(e) {
|
|
491
492
|
try {
|
|
492
|
-
const n = await
|
|
493
|
-
return
|
|
493
|
+
const n = await u(() => l.getNextPage(e));
|
|
494
|
+
return p([...i.value, ...n.items]), n;
|
|
494
495
|
} catch (n) {
|
|
495
496
|
throw console.error("Error in getContent:", n), n;
|
|
496
497
|
}
|
|
497
498
|
}
|
|
498
|
-
async function
|
|
499
|
+
async function u(e) {
|
|
499
500
|
let n = 0;
|
|
500
|
-
const
|
|
501
|
-
let
|
|
501
|
+
const c = l.retryMaxAttempts;
|
|
502
|
+
let f = l.retryInitialDelayMs;
|
|
502
503
|
for (; ; )
|
|
503
504
|
try {
|
|
504
|
-
const
|
|
505
|
-
return n > 0 && d("retry:stop", { attempt: n, success: !0 }),
|
|
506
|
-
} catch (
|
|
507
|
-
if (n++, n >
|
|
508
|
-
throw d("retry:stop", { attempt: n - 1, success: !1 }),
|
|
509
|
-
d("retry:start", { attempt: n, max:
|
|
510
|
-
d("retry:tick", { attempt: n, remainingMs: P, totalMs:
|
|
511
|
-
}),
|
|
505
|
+
const y = await e();
|
|
506
|
+
return n > 0 && d("retry:stop", { attempt: n, success: !0 }), y;
|
|
507
|
+
} catch (y) {
|
|
508
|
+
if (n++, n > c)
|
|
509
|
+
throw d("retry:stop", { attempt: n - 1, success: !1 }), y;
|
|
510
|
+
d("retry:start", { attempt: n, max: c, totalMs: f }), await s(f, (P, S) => {
|
|
511
|
+
d("retry:tick", { attempt: n, remainingMs: P, totalMs: S });
|
|
512
|
+
}), f += l.retryBackoffStepMs;
|
|
512
513
|
}
|
|
513
514
|
}
|
|
514
|
-
async function
|
|
515
|
-
if (!
|
|
516
|
-
|
|
515
|
+
async function k(e) {
|
|
516
|
+
if (!g.value) {
|
|
517
|
+
g.value = !0;
|
|
517
518
|
try {
|
|
518
|
-
const n = i.value.length,
|
|
519
|
-
return
|
|
519
|
+
const n = i.value.length, c = await v(e);
|
|
520
|
+
return h.value.push(c.nextPage), await z(n), c;
|
|
520
521
|
} catch (n) {
|
|
521
522
|
throw console.error("Error loading page:", n), n;
|
|
522
523
|
} finally {
|
|
523
|
-
|
|
524
|
+
g.value = !1;
|
|
524
525
|
}
|
|
525
526
|
}
|
|
526
527
|
}
|
|
527
|
-
async function
|
|
528
|
-
if (!
|
|
529
|
-
|
|
528
|
+
async function H() {
|
|
529
|
+
if (!g.value) {
|
|
530
|
+
g.value = !0;
|
|
530
531
|
try {
|
|
531
|
-
const e = i.value.length, n =
|
|
532
|
-
return
|
|
532
|
+
const e = i.value.length, n = h.value[h.value.length - 1], c = await v(n);
|
|
533
|
+
return h.value.push(c.nextPage), await z(e), c;
|
|
533
534
|
} catch (e) {
|
|
534
535
|
throw console.error("Error loading next page:", e), e;
|
|
535
536
|
} finally {
|
|
536
|
-
|
|
537
|
+
g.value = !1;
|
|
537
538
|
}
|
|
538
539
|
}
|
|
539
540
|
}
|
|
540
|
-
async function
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
});
|
|
541
|
+
async function N(e) {
|
|
542
|
+
var c;
|
|
543
|
+
const n = i.value.filter((f) => f.id !== e.id);
|
|
544
|
+
i.value = n, await X(), (c = m.value) == null || c.offsetHeight, requestAnimationFrame(() => {
|
|
545
|
+
p(n);
|
|
546
546
|
});
|
|
547
547
|
}
|
|
548
548
|
async function R(e) {
|
|
549
|
+
var f;
|
|
549
550
|
if (!e || e.length === 0) return;
|
|
550
|
-
const n = new Set(e.map((
|
|
551
|
-
i.value =
|
|
552
|
-
|
|
553
|
-
y(l);
|
|
554
|
-
});
|
|
551
|
+
const n = new Set(e.map((y) => y.id)), c = i.value.filter((y) => !n.has(y.id));
|
|
552
|
+
i.value = c, await X(), (f = m.value) == null || f.offsetHeight, requestAnimationFrame(() => {
|
|
553
|
+
p(c);
|
|
555
554
|
});
|
|
556
555
|
}
|
|
557
556
|
function _() {
|
|
558
|
-
w.value =
|
|
557
|
+
w.value = ct(r.value), p(i.value);
|
|
559
558
|
}
|
|
560
|
-
let
|
|
559
|
+
let A = !1;
|
|
561
560
|
async function z(e) {
|
|
562
|
-
if (!
|
|
563
|
-
const n = (e || 0) + (
|
|
564
|
-
if (!(!
|
|
565
|
-
|
|
561
|
+
if (!l.backfillEnabled || A) return;
|
|
562
|
+
const n = (e || 0) + (l.pageSize || 0);
|
|
563
|
+
if (!(!l.pageSize || l.pageSize <= 0 || h.value[h.value.length - 1] == null) && !(i.value.length >= n)) {
|
|
564
|
+
A = !0;
|
|
566
565
|
try {
|
|
567
|
-
let
|
|
568
|
-
for (d("backfill:start", { target: n, fetched: i.value.length, calls:
|
|
569
|
-
await
|
|
566
|
+
let f = 0;
|
|
567
|
+
for (d("backfill:start", { target: n, fetched: i.value.length, calls: f }); i.value.length < n && f < l.backfillMaxCalls && h.value[h.value.length - 1] != null; ) {
|
|
568
|
+
await s(l.backfillDelayMs, (P, S) => {
|
|
570
569
|
d("backfill:tick", {
|
|
571
570
|
fetched: i.value.length,
|
|
572
571
|
target: n,
|
|
573
|
-
calls:
|
|
572
|
+
calls: f,
|
|
574
573
|
remainingMs: P,
|
|
575
|
-
totalMs:
|
|
574
|
+
totalMs: S
|
|
576
575
|
});
|
|
577
576
|
});
|
|
578
|
-
const
|
|
577
|
+
const y = h.value[h.value.length - 1];
|
|
579
578
|
try {
|
|
580
|
-
|
|
581
|
-
const P = await
|
|
582
|
-
|
|
579
|
+
g.value = !0;
|
|
580
|
+
const P = await v(y);
|
|
581
|
+
h.value.push(P.nextPage);
|
|
583
582
|
} finally {
|
|
584
|
-
|
|
583
|
+
g.value = !1;
|
|
585
584
|
}
|
|
586
|
-
|
|
585
|
+
f++;
|
|
587
586
|
}
|
|
588
|
-
d("backfill:stop", { fetched: i.value.length, calls:
|
|
587
|
+
d("backfill:stop", { fetched: i.value.length, calls: f });
|
|
589
588
|
} finally {
|
|
590
|
-
|
|
589
|
+
A = !1;
|
|
591
590
|
}
|
|
592
591
|
}
|
|
593
592
|
}
|
|
594
593
|
function D() {
|
|
595
|
-
|
|
594
|
+
m.value && m.value.scrollTo({
|
|
596
595
|
top: 0,
|
|
597
596
|
behavior: "smooth"
|
|
598
|
-
}), i.value = [],
|
|
597
|
+
}), i.value = [], x.value = 0, h.value = [l.loadAtPage], E.value = {
|
|
599
598
|
distanceToTrigger: 0,
|
|
600
599
|
isNearTrigger: !1
|
|
601
600
|
};
|
|
602
601
|
}
|
|
603
|
-
const j =
|
|
604
|
-
|
|
605
|
-
}, 200),
|
|
606
|
-
function U(e, n,
|
|
607
|
-
|
|
602
|
+
const j = lt(() => {
|
|
603
|
+
$(), W();
|
|
604
|
+
}, 200), V = lt(_, 200);
|
|
605
|
+
function U(e, n, c) {
|
|
606
|
+
h.value = [n], h.value.push(c), p([...i.value, ...e]), W();
|
|
608
607
|
}
|
|
609
|
-
return
|
|
608
|
+
return pt(async () => {
|
|
610
609
|
var e;
|
|
611
610
|
try {
|
|
612
|
-
w.value =
|
|
613
|
-
const n =
|
|
614
|
-
|
|
611
|
+
w.value = ct(r.value);
|
|
612
|
+
const n = l.loadAtPage;
|
|
613
|
+
h.value = [n], l.skipInitialLoad || await k(h.value[0]), W();
|
|
615
614
|
} catch (n) {
|
|
616
|
-
console.error("Error during component initialization:", n),
|
|
615
|
+
console.error("Error during component initialization:", n), g.value = !1;
|
|
617
616
|
}
|
|
618
|
-
(e =
|
|
619
|
-
}),
|
|
617
|
+
(e = m.value) == null || e.addEventListener("scroll", j), window.addEventListener("resize", V);
|
|
618
|
+
}), mt(() => {
|
|
620
619
|
var e;
|
|
621
|
-
(e =
|
|
620
|
+
(e = m.value) == null || e.removeEventListener("scroll", j), window.removeEventListener("resize", V);
|
|
622
621
|
}), (e, n) => (J(), Y("div", {
|
|
623
|
-
class: "overflow-auto w-full flex-1 masonry-container",
|
|
622
|
+
class: nt(["overflow-auto w-full flex-1 masonry-container", { "force-motion": l.forceMotion }]),
|
|
624
623
|
ref_key: "container",
|
|
625
|
-
ref:
|
|
624
|
+
ref: m
|
|
626
625
|
}, [
|
|
627
626
|
C("div", {
|
|
628
627
|
class: "relative",
|
|
629
|
-
style:
|
|
628
|
+
style: ht({ height: `${x.value}px`, "--masonry-duration": `${t.transitionDurationMs}ms`, "--masonry-leave-duration": `${t.leaveDurationMs}ms`, "--masonry-ease": t.transitionEasing })
|
|
630
629
|
}, [
|
|
631
|
-
|
|
630
|
+
yt(bt, {
|
|
632
631
|
name: "masonry",
|
|
633
632
|
css: !1,
|
|
634
|
-
onEnter:
|
|
635
|
-
onBeforeEnter:
|
|
636
|
-
onLeave:
|
|
637
|
-
onBeforeLeave:
|
|
633
|
+
onEnter: q(O),
|
|
634
|
+
onBeforeEnter: q(M),
|
|
635
|
+
onLeave: q(L),
|
|
636
|
+
onBeforeLeave: q(T)
|
|
638
637
|
}, {
|
|
639
|
-
default:
|
|
640
|
-
(J(!0), Y(
|
|
641
|
-
key: `${
|
|
638
|
+
default: xt(() => [
|
|
639
|
+
(J(!0), Y(wt, null, Tt(i.value, (c, f) => (J(), Y("div", at({
|
|
640
|
+
key: `${c.page}-${c.id}`,
|
|
642
641
|
class: "absolute masonry-item",
|
|
643
642
|
ref_for: !0
|
|
644
|
-
},
|
|
645
|
-
|
|
643
|
+
}, q(Zt)(c, f)), [
|
|
644
|
+
Mt(e.$slots, "item", at({ ref_for: !0 }, { item: c, remove: N }), () => [
|
|
646
645
|
C("img", {
|
|
647
|
-
src:
|
|
646
|
+
src: c.src,
|
|
648
647
|
class: "w-full"
|
|
649
648
|
}, null, 8, ne),
|
|
650
649
|
C("button", {
|
|
651
650
|
class: "absolute bottom-0 right-0 bg-red-500 text-white p-2 rounded cursor-pointer",
|
|
652
|
-
onClick: (
|
|
651
|
+
onClick: (y) => N(c)
|
|
653
652
|
}, n[0] || (n[0] = [
|
|
654
653
|
C("i", { class: "fas fa-trash" }, null, -1)
|
|
655
654
|
]), 8, ae)
|
|
@@ -658,28 +657,28 @@ const ne = ["src"], ae = ["onClick"], re = /* @__PURE__ */ dt({
|
|
|
658
657
|
]),
|
|
659
658
|
_: 3
|
|
660
659
|
}, 8, ["onEnter", "onBeforeEnter", "onLeave", "onBeforeLeave"]),
|
|
661
|
-
|
|
660
|
+
x.value > 0 ? (J(), Y("div", {
|
|
662
661
|
key: 0,
|
|
663
|
-
class:
|
|
662
|
+
class: nt(["fixed bottom-4 right-4 bg-gray-800 text-white text-xs rounded-full px-3 py-1.5 shadow-lg z-10 transition-opacity duration-300", { "opacity-50 hover:opacity-100": !E.value.isNearTrigger, "opacity-100": E.value.isNearTrigger }])
|
|
664
663
|
}, [
|
|
665
|
-
C("span", null,
|
|
664
|
+
C("span", null, rt(i.value.length) + " items", 1),
|
|
666
665
|
n[1] || (n[1] = C("span", { class: "mx-2" }, "|", -1)),
|
|
667
|
-
C("span", null,
|
|
668
|
-
], 2)) :
|
|
666
|
+
C("span", null, rt(E.value.distanceToTrigger) + "px to load", 1)
|
|
667
|
+
], 2)) : vt("", !0)
|
|
669
668
|
], 4)
|
|
670
|
-
],
|
|
669
|
+
], 2));
|
|
671
670
|
}
|
|
672
671
|
}), oe = (t, a) => {
|
|
673
672
|
const o = t.__vccOpts || t;
|
|
674
|
-
for (const [
|
|
675
|
-
o[
|
|
673
|
+
for (const [l, b] of a)
|
|
674
|
+
o[l] = b;
|
|
676
675
|
return o;
|
|
677
|
-
},
|
|
676
|
+
}, ut = /* @__PURE__ */ oe(re, [["__scopeId", "data-v-a75cd886"]]), se = {
|
|
678
677
|
install(t) {
|
|
679
|
-
t.component("WyxosMasonry",
|
|
678
|
+
t.component("WyxosMasonry", ut), t.component("WMasonry", ut);
|
|
680
679
|
}
|
|
681
680
|
};
|
|
682
681
|
export {
|
|
683
|
-
|
|
682
|
+
ut as Masonry,
|
|
684
683
|
se as default
|
|
685
684
|
};
|
package/lib/vibe.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.masonry-container[data-v-
|
|
1
|
+
.masonry-container[data-v-a75cd886]{overflow-anchor:none}.masonry-item[data-v-a75cd886]{will-change:transform,opacity;contain:layout paint;transition:transform var(--masonry-duration, .45s) var(--masonry-ease, cubic-bezier(.22, .61, .36, 1)),opacity var(--masonry-leave-duration, .16s) ease-out var(--masonry-opacity-delay, 0ms);backface-visibility:hidden}.masonry-move[data-v-a75cd886]{transition:transform var(--masonry-duration, .45s) var(--masonry-ease, cubic-bezier(.22, .61, .36, 1))}@media (prefers-reduced-motion: reduce){.masonry-container:not(.force-motion) .masonry-item[data-v-a75cd886],.masonry-container:not(.force-motion) .masonry-move[data-v-a75cd886]{transition-duration:1ms!important}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wyxos/vibe",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"module": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"import": "./lib/index.js",
|
|
10
10
|
"types": "./lib/index.d.ts"
|
|
11
11
|
},
|
|
12
|
+
"./vibe.css": "./lib/vibe.css",
|
|
12
13
|
"./package.json": "./package.json"
|
|
13
14
|
},
|
|
14
15
|
"type": "module",
|
|
@@ -16,6 +17,9 @@
|
|
|
16
17
|
"lib",
|
|
17
18
|
"src"
|
|
18
19
|
],
|
|
20
|
+
"sideEffects": [
|
|
21
|
+
"./lib/vibe.css"
|
|
22
|
+
],
|
|
19
23
|
"scripts": {
|
|
20
24
|
"dev": "vite",
|
|
21
25
|
"build": "vue-tsc --noEmit && vite build && node write-cname.js",
|
package/src/Masonry.vue
CHANGED
|
@@ -82,6 +82,11 @@ const props = defineProps({
|
|
|
82
82
|
transitionEasing: {
|
|
83
83
|
type: String,
|
|
84
84
|
default: 'cubic-bezier(.22,.61,.36,1)'
|
|
85
|
+
},
|
|
86
|
+
// Force motion even when user has reduced-motion enabled
|
|
87
|
+
forceMotion: {
|
|
88
|
+
type: Boolean,
|
|
89
|
+
default: false
|
|
85
90
|
}
|
|
86
91
|
})
|
|
87
92
|
|
|
@@ -295,10 +300,11 @@ async function remove(item: any) {
|
|
|
295
300
|
const next = (masonry.value as any[]).filter(i => i.id !== item.id)
|
|
296
301
|
masonry.value = next
|
|
297
302
|
await nextTick()
|
|
303
|
+
// Force a reflow so current transforms are committed
|
|
304
|
+
void container.value?.offsetHeight
|
|
305
|
+
// Start FLIP on next frame (single RAF)
|
|
298
306
|
requestAnimationFrame(() => {
|
|
299
|
-
|
|
300
|
-
refreshLayout(next)
|
|
301
|
-
})
|
|
307
|
+
refreshLayout(next)
|
|
302
308
|
})
|
|
303
309
|
}
|
|
304
310
|
|
|
@@ -308,10 +314,11 @@ async function removeMany(items: any[]) {
|
|
|
308
314
|
const next = (masonry.value as any[]).filter(i => !ids.has(i.id))
|
|
309
315
|
masonry.value = next
|
|
310
316
|
await nextTick()
|
|
317
|
+
// Force a reflow so survivors' current transforms are committed
|
|
318
|
+
void container.value?.offsetHeight
|
|
319
|
+
// Start FLIP on next frame (single RAF)
|
|
311
320
|
requestAnimationFrame(() => {
|
|
312
|
-
|
|
313
|
-
refreshLayout(next)
|
|
314
|
-
})
|
|
321
|
+
refreshLayout(next)
|
|
315
322
|
})
|
|
316
323
|
}
|
|
317
324
|
|
|
@@ -433,7 +440,7 @@ onUnmounted(() => {
|
|
|
433
440
|
</script>
|
|
434
441
|
|
|
435
442
|
<template>
|
|
436
|
-
<div class="overflow-auto w-full flex-1 masonry-container" ref="container">
|
|
443
|
+
<div class="overflow-auto w-full flex-1 masonry-container" :class="{ 'force-motion': props.forceMotion }" ref="container">
|
|
437
444
|
<div class="relative"
|
|
438
445
|
:style="{height: `${containerHeight}px`, '--masonry-duration': `${transitionDurationMs}ms`, '--masonry-leave-duration': `${leaveDurationMs}ms`, '--masonry-ease': transitionEasing}">
|
|
439
446
|
<transition-group name="masonry" :css="false" @enter="onEnter" @before-enter="onBeforeEnter"
|
|
@@ -482,8 +489,8 @@ onUnmounted(() => {
|
|
|
482
489
|
}
|
|
483
490
|
|
|
484
491
|
@media (prefers-reduced-motion: reduce) {
|
|
485
|
-
.masonry-item,
|
|
486
|
-
.masonry-move {
|
|
492
|
+
.masonry-container:not(.force-motion) .masonry-item,
|
|
493
|
+
.masonry-container:not(.force-motion) .masonry-move {
|
|
487
494
|
transition-duration: 1ms !important;
|
|
488
495
|
}
|
|
489
496
|
}
|
package/src/useMasonryScroll.ts
CHANGED
|
@@ -31,6 +31,7 @@ export function useMasonryScroll({
|
|
|
31
31
|
leaveEstimateMs?: number
|
|
32
32
|
}) {
|
|
33
33
|
let cleanupInProgress = false
|
|
34
|
+
let lastScrollTop = 0
|
|
34
35
|
|
|
35
36
|
async function handleScroll() {
|
|
36
37
|
if (!container.value) return
|
|
@@ -38,12 +39,16 @@ export function useMasonryScroll({
|
|
|
38
39
|
const { scrollTop, clientHeight } = container.value
|
|
39
40
|
const visibleBottom = scrollTop + clientHeight
|
|
40
41
|
|
|
42
|
+
// Determine scroll direction (down only)
|
|
43
|
+
const isScrollingDown = scrollTop > lastScrollTop + 1 // tolerate tiny jitter
|
|
44
|
+
lastScrollTop = scrollTop
|
|
45
|
+
|
|
41
46
|
const columnHeights = calculateColumnHeights(masonry.value, columns.value)
|
|
42
47
|
const longestColumn = Math.max(...columnHeights)
|
|
43
48
|
const whitespaceVisible = longestColumn + 300 < visibleBottom - 1
|
|
44
49
|
const reachedContainerBottom = scrollTop + clientHeight >= containerHeight.value - 1
|
|
45
50
|
|
|
46
|
-
if ((whitespaceVisible || reachedContainerBottom) && !isLoading.value && !cleanupInProgress) {
|
|
51
|
+
if ((whitespaceVisible || reachedContainerBottom) && isScrollingDown && !isLoading.value && !cleanupInProgress) {
|
|
47
52
|
try {
|
|
48
53
|
if (masonry.value.length > maxItems) {
|
|
49
54
|
await handleItemCleanup(columnHeights)
|
|
@@ -87,7 +92,8 @@ export function useMasonryScroll({
|
|
|
87
92
|
|
|
88
93
|
setItemsRaw(remainingItems)
|
|
89
94
|
await nextTick()
|
|
90
|
-
|
|
95
|
+
// Allow leave to start, then FLIP survivors concurrently (single RAF)
|
|
96
|
+
await new Promise<void>(r => requestAnimationFrame(() => r()))
|
|
91
97
|
|
|
92
98
|
refreshLayout(remainingItems)
|
|
93
99
|
await nextTick()
|