sibujs 1.5.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.cjs +238 -69
- package/dist/browser.d.cts +5 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.js +6 -6
- package/dist/build.cjs +916 -292
- package/dist/build.js +15 -13
- package/dist/cdn.global.js +17 -16
- package/dist/chunk-2RA7SHDA.js +65 -0
- package/dist/chunk-2UPRY23K.js +80 -0
- package/dist/chunk-3JHCYHWN.js +125 -0
- package/dist/{chunk-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
- package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
- package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
- package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
- package/dist/chunk-7JDB7I65.js +1327 -0
- package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
- package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
- package/dist/{chunk-BGN5ZMP4.js → chunk-GTBNNBJ6.js} +14 -2
- package/dist/chunk-HB24TBAF.js +121 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
- package/dist/{chunk-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
- package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-SFKNRVCU.js → chunk-KLRMB5ZS.js} +135 -79
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
- package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
- package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
- package/dist/{chunk-NHUC2QWH.js → chunk-R73P76YZ.js} +1 -1
- package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
- package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
- package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
- package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
- package/dist/data.cjs +410 -99
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +513 -223
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +12 -6
- package/dist/ecosystem.cjs +475 -144
- package/dist/ecosystem.d.cts +9 -7
- package/dist/ecosystem.d.ts +9 -7
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3355 -1541
- package/dist/extras.d.cts +9 -9
- package/dist/extras.d.ts +9 -9
- package/dist/extras.js +58 -45
- package/dist/index.cjs +920 -292
- package/dist/index.d.cts +71 -8
- package/dist/index.d.ts +71 -8
- package/dist/index.js +28 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
- package/dist/motion.cjs +77 -34
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +335 -69
- package/dist/patterns.d.cts +11 -12
- package/dist/patterns.d.ts +11 -12
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +279 -108
- package/dist/performance.d.cts +23 -16
- package/dist/performance.d.ts +23 -16
- package/dist/performance.js +13 -8
- package/dist/plugin-D30wlGW5.d.cts +71 -0
- package/dist/plugin-D30wlGW5.d.ts +71 -0
- package/dist/plugins.cjs +635 -260
- package/dist/plugins.d.cts +10 -3
- package/dist/plugins.d.ts +10 -3
- package/dist/plugins.js +106 -38
- package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
- package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
- package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
- package/dist/ssr.cjs +642 -222
- package/dist/ssr.d.cts +26 -6
- package/dist/ssr.d.ts +26 -6
- package/dist/ssr.js +12 -11
- package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
- package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
- package/dist/testing.cjs +252 -63
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +463 -137
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +977 -94
- package/dist/widgets.d.cts +104 -2
- package/dist/widgets.d.ts +104 -2
- package/dist/widgets.js +9 -7
- package/package.json +8 -2
- package/dist/chunk-32DY64NT.js +0 -282
- package/dist/chunk-3AIRKM3B.js +0 -1263
- package/dist/chunk-3ARAQO7B.js +0 -398
- package/dist/chunk-3CRQALYP.js +0 -877
- package/dist/chunk-4EI4AG32.js +0 -482
- package/dist/chunk-4MYMUBRS.js +0 -21
- package/dist/chunk-5ZYQ6KDD.js +0 -154
- package/dist/chunk-6BMPXPUW.js +0 -26
- package/dist/chunk-6HLLIF3K.js +0 -398
- package/dist/chunk-6LSNVCS2.js +0 -937
- package/dist/chunk-6SA3QQES.js +0 -61
- package/dist/chunk-77L6NL3X.js +0 -1097
- package/dist/chunk-7BF6TK55.js +0 -1097
- package/dist/chunk-7TQKR4PP.js +0 -294
- package/dist/chunk-7V26P53V.js +0 -712
- package/dist/chunk-AZ3ISID5.js +0 -298
- package/dist/chunk-B7SWRFUT.js +0 -332
- package/dist/chunk-BTU3TJDS.js +0 -365
- package/dist/chunk-BW3WT46K.js +0 -937
- package/dist/chunk-C6KFWOFV.js +0 -616
- package/dist/chunk-CHF5OHIA.js +0 -61
- package/dist/chunk-CHJ27IGK.js +0 -26
- package/dist/chunk-CMBFNA7L.js +0 -27
- package/dist/chunk-DAHRH4ON.js +0 -331
- package/dist/chunk-DKOHBI74.js +0 -924
- package/dist/chunk-DTCOOBMX.js +0 -725
- package/dist/chunk-EBGIRKQY.js +0 -616
- package/dist/chunk-EUZND3CB.js +0 -27
- package/dist/chunk-EVCZO745.js +0 -365
- package/dist/chunk-EWFVA3TJ.js +0 -282
- package/dist/chunk-F3FA4F32.js +0 -292
- package/dist/chunk-FGOEVHY3.js +0 -60
- package/dist/chunk-G3BOQPVO.js +0 -365
- package/dist/chunk-GCOK2LC3.js +0 -282
- package/dist/chunk-GJPXRJ45.js +0 -37
- package/dist/chunk-HGMJFBC7.js +0 -654
- package/dist/chunk-JAKHTMQU.js +0 -1000
- package/dist/chunk-JCI5M6U6.js +0 -956
- package/dist/chunk-K5ZUMYVS.js +0 -89
- package/dist/chunk-KQPDEVVS.js +0 -398
- package/dist/chunk-L6JRBDNS.js +0 -60
- package/dist/chunk-LA6KQEDU.js +0 -712
- package/dist/chunk-MB6QFH3I.js +0 -2776
- package/dist/chunk-MDVXJWFN.js +0 -304
- package/dist/chunk-MEZVEBPN.js +0 -2008
- package/dist/chunk-MK4ERFYL.js +0 -2249
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-MQ5GOYPH.js +0 -2249
- package/dist/chunk-MYRV7VDM.js +0 -742
- package/dist/chunk-N6IZB6KJ.js +0 -567
- package/dist/chunk-NEKUBFPT.js +0 -60
- package/dist/chunk-NMRUZALC.js +0 -1097
- package/dist/chunk-NYVAC6P5.js +0 -37
- package/dist/chunk-NZIIMDWI.js +0 -84
- package/dist/chunk-OF7UZIVB.js +0 -725
- package/dist/chunk-P3XWXJZU.js +0 -282
- package/dist/chunk-P6W3STU4.js +0 -2249
- package/dist/chunk-PBHF5WKN.js +0 -616
- package/dist/chunk-PDZQY43A.js +0 -616
- package/dist/chunk-PTQJDMRT.js +0 -146
- package/dist/chunk-PZEGYCF5.js +0 -61
- package/dist/chunk-QBMDLBU2.js +0 -975
- package/dist/chunk-QWZG56ET.js +0 -2744
- package/dist/chunk-RQGQSLQK.js +0 -725
- package/dist/chunk-SDLZDHKP.js +0 -107
- package/dist/chunk-TDGZL5CU.js +0 -365
- package/dist/chunk-TNQWPPE6.js +0 -37
- package/dist/chunk-TSOKIX5Z.js +0 -654
- package/dist/chunk-UHNL42EF.js +0 -2730
- package/dist/chunk-UNXCEF6S.js +0 -21
- package/dist/chunk-V2XTI523.js +0 -347
- package/dist/chunk-VAU366PN.js +0 -2241
- package/dist/chunk-VMVDTCXB.js +0 -712
- package/dist/chunk-VQNQZCWJ.js +0 -61
- package/dist/chunk-VRW3FULF.js +0 -725
- package/dist/chunk-WADYRCO2.js +0 -304
- package/dist/chunk-WILQZRO4.js +0 -282
- package/dist/chunk-WR5D4EGH.js +0 -26
- package/dist/chunk-WUHJISPP.js +0 -298
- package/dist/chunk-XYU6TZOW.js +0 -182
- package/dist/chunk-Y6GP4QGG.js +0 -276
- package/dist/chunk-YECR7UIA.js +0 -347
- package/dist/chunk-YUTWTI4B.js +0 -654
- package/dist/chunk-Z65KYU7I.js +0 -26
- package/dist/chunk-Z6POF5YC.js +0 -975
- package/dist/chunk-ZBJP6WFL.js +0 -482
- package/dist/chunk-ZD6OAMTH.js +0 -277
- package/dist/chunk-ZWKZCBO6.js +0 -317
- package/dist/contracts-DDrwxvJ-.d.cts +0 -245
- package/dist/contracts-DDrwxvJ-.d.ts +0 -245
- package/dist/contracts-DOrhwbke.d.cts +0 -245
- package/dist/contracts-DOrhwbke.d.ts +0 -245
- package/dist/contracts-xo5ckdRP.d.cts +0 -240
- package/dist/contracts-xo5ckdRP.d.ts +0 -240
- package/dist/customElement-BKQfbSZQ.d.cts +0 -262
- package/dist/customElement-BKQfbSZQ.d.ts +0 -262
- package/dist/customElement-D2DJp_xn.d.cts +0 -313
- package/dist/customElement-D2DJp_xn.d.ts +0 -313
- package/dist/customElement-yz8uyk-0.d.cts +0 -308
- package/dist/customElement-yz8uyk-0.d.ts +0 -308
- package/dist/introspect-Cb0zgpi2.d.cts +0 -477
- package/dist/introspect-Y2xNXGSf.d.ts +0 -477
- package/dist/plugin-Bek4RhJY.d.cts +0 -43
- package/dist/plugin-Bek4RhJY.d.ts +0 -43
- package/dist/ssr-3RXHP5ES.js +0 -38
- package/dist/ssr-6GIMY5MX.js +0 -38
- package/dist/ssr-BA6sxxUd.d.cts +0 -135
- package/dist/ssr-BA6sxxUd.d.ts +0 -135
- package/dist/ssr-WKUPVSSK.js +0 -36
- package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
- package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
package/dist/ui.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(ui_exports, {
|
|
|
23
23
|
FocusTrap: () => FocusTrap,
|
|
24
24
|
RenderProp: () => RenderProp,
|
|
25
25
|
VirtualList: () => VirtualList,
|
|
26
|
+
__resetDialogStack: () => __resetDialogStack,
|
|
26
27
|
announce: () => announce,
|
|
27
28
|
aria: () => aria,
|
|
28
29
|
assertType: () => assertType,
|
|
@@ -91,12 +92,12 @@ function isDev() {
|
|
|
91
92
|
var _isDev = isDev();
|
|
92
93
|
function devAssert(condition, message) {
|
|
93
94
|
if (_isDev && !condition) {
|
|
94
|
-
throw new Error(`[
|
|
95
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
function devWarn(message) {
|
|
98
99
|
if (_isDev) {
|
|
99
|
-
console.warn(`[
|
|
100
|
+
console.warn(`[SibuJS] ${message}`);
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -106,11 +107,11 @@ var subscriberStack = new Array(32);
|
|
|
106
107
|
var stackCapacity = 32;
|
|
107
108
|
var stackTop = -1;
|
|
108
109
|
var currentSubscriber = null;
|
|
109
|
-
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
110
110
|
var SUBS = "__s";
|
|
111
111
|
var notifyDepth = 0;
|
|
112
112
|
var pendingQueue = [];
|
|
113
113
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
114
|
+
var propagateStack = [];
|
|
114
115
|
function safeInvoke(sub) {
|
|
115
116
|
try {
|
|
116
117
|
sub();
|
|
@@ -119,6 +120,15 @@ function safeInvoke(sub) {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
var trackingSuspended = false;
|
|
123
|
+
function retrack(effectFn, subscriber) {
|
|
124
|
+
const prev = currentSubscriber;
|
|
125
|
+
currentSubscriber = subscriber;
|
|
126
|
+
try {
|
|
127
|
+
effectFn();
|
|
128
|
+
} finally {
|
|
129
|
+
currentSubscriber = prev;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
122
132
|
function track(effectFn, subscriber) {
|
|
123
133
|
if (!subscriber) subscriber = effectFn;
|
|
124
134
|
cleanup(subscriber);
|
|
@@ -157,7 +167,6 @@ function recordDependency(signal2) {
|
|
|
157
167
|
let subs = signal2[SUBS];
|
|
158
168
|
if (!subs) {
|
|
159
169
|
subs = /* @__PURE__ */ new Set();
|
|
160
|
-
signalSubscribers.set(signal2, subs);
|
|
161
170
|
signal2[SUBS] = subs;
|
|
162
171
|
}
|
|
163
172
|
subs.add(currentSubscriber);
|
|
@@ -167,42 +176,46 @@ function recordDependency(signal2) {
|
|
|
167
176
|
signal2.__f = void 0;
|
|
168
177
|
}
|
|
169
178
|
}
|
|
179
|
+
var maxDrainIterations = 1e5;
|
|
170
180
|
function propagateDirty(sub) {
|
|
171
181
|
sub();
|
|
172
|
-
|
|
173
|
-
|
|
182
|
+
const rootSig = sub._sig;
|
|
183
|
+
if (!rootSig) return;
|
|
184
|
+
const stack = propagateStack;
|
|
185
|
+
const baseLen = stack.length;
|
|
186
|
+
stack.push(rootSig);
|
|
187
|
+
while (stack.length > baseLen) {
|
|
188
|
+
const sig = stack.pop();
|
|
174
189
|
const first = sig.__f;
|
|
175
190
|
if (first) {
|
|
176
191
|
if (first._c) {
|
|
177
192
|
const nSig = first._sig;
|
|
178
|
-
nSig._d
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
if (!pendingSet.has(first)) {
|
|
193
|
+
if (!nSig._d) {
|
|
194
|
+
nSig._d = true;
|
|
195
|
+
stack.push(nSig);
|
|
196
|
+
}
|
|
197
|
+
} else if (!pendingSet.has(first)) {
|
|
183
198
|
pendingSet.add(first);
|
|
184
199
|
pendingQueue.push(first);
|
|
185
200
|
}
|
|
186
|
-
|
|
201
|
+
continue;
|
|
187
202
|
}
|
|
188
203
|
const subs = sig[SUBS];
|
|
189
|
-
if (!subs)
|
|
190
|
-
let nextSig;
|
|
204
|
+
if (!subs) continue;
|
|
191
205
|
for (const s of subs) {
|
|
192
206
|
if (s._c) {
|
|
193
|
-
s();
|
|
194
207
|
const nSig = s._sig;
|
|
195
|
-
if (nSig && !
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
208
|
+
if (nSig && !nSig._d) {
|
|
209
|
+
nSig._d = true;
|
|
210
|
+
stack.push(nSig);
|
|
211
|
+
} else if (!nSig) {
|
|
212
|
+
s();
|
|
199
213
|
}
|
|
200
214
|
} else if (!pendingSet.has(s)) {
|
|
201
215
|
pendingSet.add(s);
|
|
202
216
|
pendingQueue.push(s);
|
|
203
217
|
}
|
|
204
218
|
}
|
|
205
|
-
sig = nextSig;
|
|
206
219
|
}
|
|
207
220
|
}
|
|
208
221
|
function notifySubscribers(signal2) {
|
|
@@ -226,13 +239,23 @@ function notifySubscribers(signal2) {
|
|
|
226
239
|
}
|
|
227
240
|
let i = 0;
|
|
228
241
|
while (i < pendingQueue.length) {
|
|
242
|
+
if (i >= maxDrainIterations) {
|
|
243
|
+
if (typeof console !== "undefined") {
|
|
244
|
+
console.error(
|
|
245
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
229
250
|
safeInvoke(pendingQueue[i]);
|
|
230
251
|
i++;
|
|
231
252
|
}
|
|
232
253
|
} finally {
|
|
233
|
-
pendingQueue.length = 0;
|
|
234
|
-
pendingSet.clear();
|
|
235
254
|
notifyDepth--;
|
|
255
|
+
if (notifyDepth === 0) {
|
|
256
|
+
pendingQueue.length = 0;
|
|
257
|
+
pendingSet.clear();
|
|
258
|
+
}
|
|
236
259
|
}
|
|
237
260
|
return;
|
|
238
261
|
}
|
|
@@ -252,30 +275,48 @@ function notifySubscribers(signal2) {
|
|
|
252
275
|
notifyDepth++;
|
|
253
276
|
try {
|
|
254
277
|
let directCount = 0;
|
|
278
|
+
let hasComputedSub = false;
|
|
255
279
|
for (const sub of subs) {
|
|
280
|
+
if (sub._c) hasComputedSub = true;
|
|
256
281
|
pendingQueue[directCount++] = sub;
|
|
257
282
|
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
283
|
+
if (!hasComputedSub) {
|
|
284
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
285
|
+
safeInvoke(pendingQueue[i2]);
|
|
261
286
|
}
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
287
|
+
} else {
|
|
288
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
289
|
+
if (pendingQueue[i2]._c) {
|
|
290
|
+
propagateDirty(pendingQueue[i2]);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
294
|
+
const sub = pendingQueue[i2];
|
|
295
|
+
if (!sub._c && !pendingSet.has(sub)) {
|
|
296
|
+
pendingSet.add(sub);
|
|
297
|
+
safeInvoke(sub);
|
|
267
298
|
}
|
|
268
299
|
}
|
|
269
300
|
}
|
|
270
301
|
let i = directCount;
|
|
271
302
|
while (i < pendingQueue.length) {
|
|
303
|
+
if (i - directCount >= maxDrainIterations) {
|
|
304
|
+
if (typeof console !== "undefined") {
|
|
305
|
+
console.error(
|
|
306
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
272
311
|
safeInvoke(pendingQueue[i]);
|
|
273
312
|
i++;
|
|
274
313
|
}
|
|
275
314
|
} finally {
|
|
276
|
-
pendingQueue.length = 0;
|
|
277
|
-
pendingSet.clear();
|
|
278
315
|
notifyDepth--;
|
|
316
|
+
if (notifyDepth === 0) {
|
|
317
|
+
pendingQueue.length = 0;
|
|
318
|
+
pendingSet.clear();
|
|
319
|
+
}
|
|
279
320
|
}
|
|
280
321
|
}
|
|
281
322
|
function cleanup(subscriber) {
|
|
@@ -286,7 +327,9 @@ function cleanup(subscriber) {
|
|
|
286
327
|
if (subs) {
|
|
287
328
|
subs.delete(subscriber);
|
|
288
329
|
if (singleDep.__f === subscriber) {
|
|
289
|
-
singleDep.__f = void 0;
|
|
330
|
+
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
331
|
+
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
332
|
+
singleDep.__f = subs.values().next().value;
|
|
290
333
|
}
|
|
291
334
|
}
|
|
292
335
|
sub._dep = void 0;
|
|
@@ -299,7 +342,9 @@ function cleanup(subscriber) {
|
|
|
299
342
|
if (subs) {
|
|
300
343
|
subs.delete(subscriber);
|
|
301
344
|
if (signal2.__f === subscriber) {
|
|
302
|
-
signal2.__f = void 0;
|
|
345
|
+
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
346
|
+
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
347
|
+
signal2.__f = subs.values().next().value;
|
|
303
348
|
}
|
|
304
349
|
}
|
|
305
350
|
}
|
|
@@ -310,6 +355,7 @@ function cleanup(subscriber) {
|
|
|
310
355
|
function derived(getter, options) {
|
|
311
356
|
devAssert(typeof getter === "function", "derived: argument must be a getter function.");
|
|
312
357
|
const debugName = options?.name;
|
|
358
|
+
const equals = options?.equals;
|
|
313
359
|
const cs = {};
|
|
314
360
|
cs._d = false;
|
|
315
361
|
cs._g = getter;
|
|
@@ -320,8 +366,14 @@ function derived(getter, options) {
|
|
|
320
366
|
markDirty._c = 1;
|
|
321
367
|
markDirty._sig = cs;
|
|
322
368
|
track(() => {
|
|
323
|
-
|
|
324
|
-
|
|
369
|
+
let threw = true;
|
|
370
|
+
try {
|
|
371
|
+
cs._v = getter();
|
|
372
|
+
cs._d = false;
|
|
373
|
+
threw = false;
|
|
374
|
+
} finally {
|
|
375
|
+
if (threw) cs._d = true;
|
|
376
|
+
}
|
|
325
377
|
}, markDirty);
|
|
326
378
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
327
379
|
let evaluating = false;
|
|
@@ -334,11 +386,16 @@ function derived(getter, options) {
|
|
|
334
386
|
if (trackingSuspended) {
|
|
335
387
|
if (cs._d) {
|
|
336
388
|
evaluating = true;
|
|
389
|
+
let threw = true;
|
|
337
390
|
try {
|
|
338
|
-
|
|
339
|
-
|
|
391
|
+
retrack(() => {
|
|
392
|
+
cs._v = getter();
|
|
393
|
+
cs._d = false;
|
|
394
|
+
threw = false;
|
|
395
|
+
}, markDirty);
|
|
340
396
|
} finally {
|
|
341
397
|
evaluating = false;
|
|
398
|
+
if (threw) cs._d = true;
|
|
342
399
|
}
|
|
343
400
|
}
|
|
344
401
|
return cs._v;
|
|
@@ -347,13 +404,17 @@ function derived(getter, options) {
|
|
|
347
404
|
if (cs._d) {
|
|
348
405
|
const oldValue = cs._v;
|
|
349
406
|
evaluating = true;
|
|
407
|
+
let threw = true;
|
|
350
408
|
try {
|
|
351
|
-
|
|
409
|
+
retrack(() => {
|
|
410
|
+
const next = getter();
|
|
411
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
352
412
|
cs._d = false;
|
|
353
|
-
|
|
413
|
+
threw = false;
|
|
354
414
|
}, markDirty);
|
|
355
415
|
} finally {
|
|
356
416
|
evaluating = false;
|
|
417
|
+
if (threw) cs._d = true;
|
|
357
418
|
}
|
|
358
419
|
if (hook && oldValue !== cs._v) {
|
|
359
420
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
@@ -518,9 +579,18 @@ function form(config) {
|
|
|
518
579
|
}
|
|
519
580
|
return null;
|
|
520
581
|
});
|
|
582
|
+
const wrappedSet = (next) => {
|
|
583
|
+
setValue(next);
|
|
584
|
+
setManualErrors((prev) => {
|
|
585
|
+
if (!(name in prev) || prev[name] == null) return prev;
|
|
586
|
+
const copy = { ...prev };
|
|
587
|
+
copy[name] = null;
|
|
588
|
+
return copy;
|
|
589
|
+
});
|
|
590
|
+
};
|
|
521
591
|
fieldMap[name] = {
|
|
522
592
|
value,
|
|
523
|
-
set:
|
|
593
|
+
set: wrappedSet,
|
|
524
594
|
error,
|
|
525
595
|
touched: isTouched,
|
|
526
596
|
touch: () => setTouched(true),
|
|
@@ -654,11 +724,77 @@ function registerDisposer(node, teardown) {
|
|
|
654
724
|
disposers.push(teardown);
|
|
655
725
|
if (_isDev4) activeBindingCount++;
|
|
656
726
|
}
|
|
727
|
+
function dispose(node) {
|
|
728
|
+
const stack = [node];
|
|
729
|
+
const order = [];
|
|
730
|
+
while (stack.length > 0) {
|
|
731
|
+
const current = stack.pop();
|
|
732
|
+
order.push(current);
|
|
733
|
+
const children = Array.from(current.childNodes);
|
|
734
|
+
for (let i = 0; i < children.length; i++) {
|
|
735
|
+
stack.push(children[i]);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
739
|
+
const current = order[i];
|
|
740
|
+
const disposers = elementDisposers.get(current);
|
|
741
|
+
if (disposers) {
|
|
742
|
+
const snapshot = disposers.slice();
|
|
743
|
+
elementDisposers.delete(current);
|
|
744
|
+
if (_isDev4) activeBindingCount -= snapshot.length;
|
|
745
|
+
for (const d of snapshot) {
|
|
746
|
+
try {
|
|
747
|
+
d();
|
|
748
|
+
} catch (err) {
|
|
749
|
+
if (_isDev4 && typeof console !== "undefined") {
|
|
750
|
+
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
let extraPasses = 0;
|
|
755
|
+
while (extraPasses++ < 8) {
|
|
756
|
+
const added = elementDisposers.get(current);
|
|
757
|
+
if (!added || added.length === 0) break;
|
|
758
|
+
const moreSnapshot = added.slice();
|
|
759
|
+
elementDisposers.delete(current);
|
|
760
|
+
if (_isDev4) activeBindingCount -= moreSnapshot.length;
|
|
761
|
+
for (const d of moreSnapshot) {
|
|
762
|
+
try {
|
|
763
|
+
d();
|
|
764
|
+
} catch (err) {
|
|
765
|
+
if (_isDev4 && typeof console !== "undefined") {
|
|
766
|
+
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
657
774
|
|
|
658
775
|
// src/core/ssr-context.ts
|
|
659
|
-
var
|
|
776
|
+
var als = null;
|
|
777
|
+
try {
|
|
778
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
779
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
780
|
+
if (req) {
|
|
781
|
+
const mod = req("node:async_hooks");
|
|
782
|
+
als = new mod.AsyncLocalStorage();
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
} catch {
|
|
786
|
+
als = null;
|
|
787
|
+
}
|
|
788
|
+
var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
|
|
789
|
+
function getSSRStore() {
|
|
790
|
+
if (als) {
|
|
791
|
+
const s = als.getStore();
|
|
792
|
+
if (s) return s;
|
|
793
|
+
}
|
|
794
|
+
return fallbackStore;
|
|
795
|
+
}
|
|
660
796
|
function isSSR() {
|
|
661
|
-
return
|
|
797
|
+
return getSSRStore().ssr;
|
|
662
798
|
}
|
|
663
799
|
|
|
664
800
|
// src/core/signals/effect.ts
|
|
@@ -668,26 +804,86 @@ function effect(effectFn, options) {
|
|
|
668
804
|
if (isSSR()) return () => {
|
|
669
805
|
};
|
|
670
806
|
const onError = options?.onError;
|
|
807
|
+
let userCleanups = [];
|
|
808
|
+
const onCleanup = (fn) => {
|
|
809
|
+
userCleanups.push(fn);
|
|
810
|
+
};
|
|
811
|
+
const runUserCleanups = () => {
|
|
812
|
+
if (userCleanups.length === 0) return;
|
|
813
|
+
const list = userCleanups;
|
|
814
|
+
userCleanups = [];
|
|
815
|
+
for (let i = list.length - 1; i >= 0; i--) {
|
|
816
|
+
try {
|
|
817
|
+
list[i]();
|
|
818
|
+
} catch (err) {
|
|
819
|
+
if (typeof console !== "undefined") {
|
|
820
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
const invokeBody = () => effectFn(onCleanup);
|
|
671
826
|
const wrappedFn = onError ? () => {
|
|
672
827
|
try {
|
|
673
|
-
|
|
828
|
+
invokeBody();
|
|
674
829
|
} catch (err) {
|
|
675
830
|
onError(err);
|
|
676
831
|
}
|
|
677
|
-
} :
|
|
832
|
+
} : invokeBody;
|
|
678
833
|
let cleanupHandle = () => {
|
|
679
834
|
};
|
|
835
|
+
let running = false;
|
|
680
836
|
const subscriber = () => {
|
|
681
|
-
|
|
682
|
-
|
|
837
|
+
if (running) {
|
|
838
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
839
|
+
console.warn(
|
|
840
|
+
"[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
running = true;
|
|
846
|
+
try {
|
|
847
|
+
runUserCleanups();
|
|
848
|
+
cleanupHandle();
|
|
849
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
850
|
+
} finally {
|
|
851
|
+
running = false;
|
|
852
|
+
}
|
|
683
853
|
};
|
|
684
|
-
|
|
854
|
+
running = true;
|
|
855
|
+
try {
|
|
856
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
857
|
+
} finally {
|
|
858
|
+
running = false;
|
|
859
|
+
}
|
|
685
860
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
686
861
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
862
|
+
let disposed = false;
|
|
687
863
|
return () => {
|
|
864
|
+
if (disposed) return;
|
|
865
|
+
disposed = true;
|
|
688
866
|
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
689
|
-
if (h)
|
|
690
|
-
|
|
867
|
+
if (h) {
|
|
868
|
+
try {
|
|
869
|
+
h.emit("effect:destroy", { effectFn });
|
|
870
|
+
} catch {
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
try {
|
|
874
|
+
runUserCleanups();
|
|
875
|
+
} catch (err) {
|
|
876
|
+
if (typeof console !== "undefined") {
|
|
877
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
try {
|
|
881
|
+
cleanupHandle();
|
|
882
|
+
} catch (err) {
|
|
883
|
+
if (typeof console !== "undefined") {
|
|
884
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
691
887
|
};
|
|
692
888
|
}
|
|
693
889
|
|
|
@@ -739,6 +935,7 @@ function intersection(options) {
|
|
|
739
935
|
let observer = null;
|
|
740
936
|
let currentElement = null;
|
|
741
937
|
function observe(element) {
|
|
938
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
742
939
|
unobserve();
|
|
743
940
|
currentElement = element;
|
|
744
941
|
observer = new IntersectionObserver((entries) => {
|
|
@@ -766,6 +963,11 @@ function intersection(options) {
|
|
|
766
963
|
};
|
|
767
964
|
}
|
|
768
965
|
function lazyLoad(element, loader, options) {
|
|
966
|
+
if (typeof IntersectionObserver === "undefined") {
|
|
967
|
+
loader();
|
|
968
|
+
return () => {
|
|
969
|
+
};
|
|
970
|
+
}
|
|
769
971
|
const observer = new IntersectionObserver((entries) => {
|
|
770
972
|
for (const entry of entries) {
|
|
771
973
|
if (entry.isIntersecting) {
|
|
@@ -840,7 +1042,7 @@ function inputMask(options) {
|
|
|
840
1042
|
const stripRegex = buildStripRegex();
|
|
841
1043
|
const rawCharTest = options.pattern.includes("*") ? () => true : (c) => /[a-zA-Z0-9]/.test(c);
|
|
842
1044
|
function bind(input) {
|
|
843
|
-
|
|
1045
|
+
const onInput = () => {
|
|
844
1046
|
const cursorBefore = input.selectionStart ?? input.value.length;
|
|
845
1047
|
const oldValue = input.value;
|
|
846
1048
|
const raw = oldValue.replace(stripRegex, "");
|
|
@@ -864,13 +1066,19 @@ function inputMask(options) {
|
|
|
864
1066
|
}
|
|
865
1067
|
}
|
|
866
1068
|
input.setSelectionRange(newCursor, newCursor);
|
|
867
|
-
}
|
|
868
|
-
|
|
1069
|
+
};
|
|
1070
|
+
const onFocus = () => {
|
|
869
1071
|
if (!input.value) {
|
|
870
1072
|
const display = options.pattern.replace(/9/g, placeholder).replace(/A/g, placeholder).replace(/\*/g, placeholder);
|
|
871
1073
|
input.placeholder = display;
|
|
872
1074
|
}
|
|
873
|
-
}
|
|
1075
|
+
};
|
|
1076
|
+
input.addEventListener("input", onInput);
|
|
1077
|
+
input.addEventListener("focus", onFocus);
|
|
1078
|
+
return () => {
|
|
1079
|
+
input.removeEventListener("input", onInput);
|
|
1080
|
+
input.removeEventListener("focus", onFocus);
|
|
1081
|
+
};
|
|
874
1082
|
}
|
|
875
1083
|
return { value, rawValue, bind };
|
|
876
1084
|
}
|
|
@@ -912,8 +1120,20 @@ function focus() {
|
|
|
912
1120
|
let currentElement = null;
|
|
913
1121
|
function bind(element) {
|
|
914
1122
|
currentElement = element;
|
|
915
|
-
|
|
916
|
-
|
|
1123
|
+
const onFocus = () => setIsFocused(true);
|
|
1124
|
+
const onBlur = () => setIsFocused(false);
|
|
1125
|
+
element.addEventListener("focus", onFocus);
|
|
1126
|
+
element.addEventListener("blur", onBlur);
|
|
1127
|
+
let disposed = false;
|
|
1128
|
+
const dispose2 = () => {
|
|
1129
|
+
if (disposed) return;
|
|
1130
|
+
disposed = true;
|
|
1131
|
+
element.removeEventListener("focus", onFocus);
|
|
1132
|
+
element.removeEventListener("blur", onBlur);
|
|
1133
|
+
if (currentElement === element) currentElement = null;
|
|
1134
|
+
};
|
|
1135
|
+
registerDisposer(element, dispose2);
|
|
1136
|
+
return dispose2;
|
|
917
1137
|
}
|
|
918
1138
|
function focus2() {
|
|
919
1139
|
currentElement?.focus();
|
|
@@ -928,11 +1148,35 @@ function FocusTrap(nodes, options = {}) {
|
|
|
928
1148
|
container.setAttribute("data-sibu-focus-trap", "true");
|
|
929
1149
|
container.appendChild(nodes);
|
|
930
1150
|
const previouslyFocused = document.activeElement;
|
|
931
|
-
|
|
1151
|
+
const FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]), [contenteditable]';
|
|
1152
|
+
function isEffectivelyVisible(el) {
|
|
1153
|
+
let node = el;
|
|
1154
|
+
while (node) {
|
|
1155
|
+
if (node.hasAttribute("inert")) return false;
|
|
1156
|
+
if (node.getAttribute("aria-hidden") === "true") return false;
|
|
1157
|
+
if (node.hidden) return false;
|
|
1158
|
+
node = node.parentElement;
|
|
1159
|
+
}
|
|
1160
|
+
if (el.offsetParent === null && el.getClientRects().length === 0) return false;
|
|
1161
|
+
return true;
|
|
1162
|
+
}
|
|
1163
|
+
function getFocusable() {
|
|
1164
|
+
const raw = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
|
|
1165
|
+
const out = [];
|
|
1166
|
+
for (const el of raw) {
|
|
1167
|
+
if (el.hasAttribute("disabled")) continue;
|
|
1168
|
+
if (el.getAttribute("aria-hidden") === "true") continue;
|
|
1169
|
+
if (el.hasAttribute("inert")) continue;
|
|
1170
|
+
const ce = el.getAttribute("contenteditable");
|
|
1171
|
+
if (ce !== null && ce === "false") continue;
|
|
1172
|
+
if (!isEffectivelyVisible(el)) continue;
|
|
1173
|
+
out.push(el);
|
|
1174
|
+
}
|
|
1175
|
+
return out;
|
|
1176
|
+
}
|
|
1177
|
+
const onTrapKeydown = (e) => {
|
|
932
1178
|
if (e.key !== "Tab") return;
|
|
933
|
-
const focusable =
|
|
934
|
-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
935
|
-
);
|
|
1179
|
+
const focusable = getFocusable();
|
|
936
1180
|
if (focusable.length === 0) {
|
|
937
1181
|
e.preventDefault();
|
|
938
1182
|
return;
|
|
@@ -950,18 +1194,18 @@ function FocusTrap(nodes, options = {}) {
|
|
|
950
1194
|
first.focus();
|
|
951
1195
|
}
|
|
952
1196
|
}
|
|
953
|
-
}
|
|
1197
|
+
};
|
|
1198
|
+
container.addEventListener("keydown", onTrapKeydown);
|
|
954
1199
|
if (options.autoFocus !== false) {
|
|
955
1200
|
queueMicrotask(() => {
|
|
956
|
-
const first =
|
|
957
|
-
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
958
|
-
);
|
|
1201
|
+
const first = getFocusable()[0];
|
|
959
1202
|
first?.focus();
|
|
960
1203
|
});
|
|
961
1204
|
}
|
|
962
1205
|
let trapObserver = null;
|
|
963
1206
|
function restoreFocusAndCleanup() {
|
|
964
1207
|
if (options.restoreFocus !== false) previouslyFocused?.focus();
|
|
1208
|
+
container.removeEventListener("keydown", onTrapKeydown);
|
|
965
1209
|
if (trapObserver) {
|
|
966
1210
|
trapObserver.disconnect();
|
|
967
1211
|
trapObserver = null;
|
|
@@ -975,7 +1219,7 @@ function FocusTrap(nodes, options = {}) {
|
|
|
975
1219
|
});
|
|
976
1220
|
queueMicrotask(() => {
|
|
977
1221
|
if (container.isConnected) {
|
|
978
|
-
trapObserver.observe(
|
|
1222
|
+
trapObserver.observe(container, { childList: true, subtree: true });
|
|
979
1223
|
}
|
|
980
1224
|
});
|
|
981
1225
|
}
|
|
@@ -1012,7 +1256,16 @@ function hotkey(combo, handler, options = {}) {
|
|
|
1012
1256
|
document.addEventListener("keydown", listener);
|
|
1013
1257
|
return () => document.removeEventListener("keydown", listener);
|
|
1014
1258
|
}
|
|
1015
|
-
|
|
1259
|
+
var announceQueues = {
|
|
1260
|
+
polite: [],
|
|
1261
|
+
assertive: []
|
|
1262
|
+
};
|
|
1263
|
+
var announceDraining = {
|
|
1264
|
+
polite: false,
|
|
1265
|
+
assertive: false
|
|
1266
|
+
};
|
|
1267
|
+
var ANNOUNCE_INTERVAL_MS = 150;
|
|
1268
|
+
function ensureLiveRegion(priority) {
|
|
1016
1269
|
let region = document.getElementById(`sibu-announce-${priority}`);
|
|
1017
1270
|
if (!region) {
|
|
1018
1271
|
region = document.createElement("div");
|
|
@@ -1023,11 +1276,33 @@ function announce(message, priority = "polite") {
|
|
|
1023
1276
|
region.style.cssText = "position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;";
|
|
1024
1277
|
document.body.appendChild(region);
|
|
1025
1278
|
}
|
|
1279
|
+
return region;
|
|
1280
|
+
}
|
|
1281
|
+
function drainAnnounceQueue(priority) {
|
|
1282
|
+
if (announceDraining[priority]) return;
|
|
1283
|
+
const queue = announceQueues[priority];
|
|
1284
|
+
if (queue.length === 0) return;
|
|
1285
|
+
announceDraining[priority] = true;
|
|
1286
|
+
const region = ensureLiveRegion(priority);
|
|
1287
|
+
const next = queue.shift();
|
|
1026
1288
|
region.textContent = "";
|
|
1027
1289
|
requestAnimationFrame(() => {
|
|
1028
|
-
if (region)
|
|
1290
|
+
if (!region.isConnected) {
|
|
1291
|
+
announceDraining[priority] = false;
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
region.textContent = next;
|
|
1295
|
+
setTimeout(() => {
|
|
1296
|
+
announceDraining[priority] = false;
|
|
1297
|
+
drainAnnounceQueue(priority);
|
|
1298
|
+
}, ANNOUNCE_INTERVAL_MS);
|
|
1029
1299
|
});
|
|
1030
1300
|
}
|
|
1301
|
+
function announce(message, priority = "polite") {
|
|
1302
|
+
if (typeof document === "undefined") return;
|
|
1303
|
+
announceQueues[priority].push(message);
|
|
1304
|
+
drainAnnounceQueue(priority);
|
|
1305
|
+
}
|
|
1031
1306
|
|
|
1032
1307
|
// src/core/rendering/createId.ts
|
|
1033
1308
|
var idCounter = 0;
|
|
@@ -1121,22 +1396,22 @@ function createListbox(container, options = {}) {
|
|
|
1121
1396
|
}
|
|
1122
1397
|
}
|
|
1123
1398
|
function select(value) {
|
|
1399
|
+
const previous = selectedValue();
|
|
1400
|
+
let nextSelectedSet;
|
|
1124
1401
|
if (multiple) {
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
setSelectedValue(Array.from(set).join(","));
|
|
1402
|
+
nextSelectedSet = new Set((previous ?? "").split(",").filter(Boolean));
|
|
1403
|
+
if (nextSelectedSet.has(value)) nextSelectedSet.delete(value);
|
|
1404
|
+
else nextSelectedSet.add(value);
|
|
1405
|
+
setSelectedValue(Array.from(nextSelectedSet).join(","));
|
|
1130
1406
|
} else {
|
|
1407
|
+
nextSelectedSet = /* @__PURE__ */ new Set([value]);
|
|
1131
1408
|
setSelectedValue(value);
|
|
1132
1409
|
}
|
|
1133
1410
|
options.onSelect?.(value);
|
|
1134
1411
|
const opts = getOptions();
|
|
1135
|
-
const current = selectedValue();
|
|
1136
|
-
const selected = new Set((current ?? "").split(",").filter(Boolean));
|
|
1137
1412
|
for (const opt of opts) {
|
|
1138
1413
|
const ov = opt.dataset.value ?? "";
|
|
1139
|
-
opt.setAttribute("aria-selected",
|
|
1414
|
+
opt.setAttribute("aria-selected", nextSelectedSet.has(ov) ? "true" : "false");
|
|
1140
1415
|
}
|
|
1141
1416
|
}
|
|
1142
1417
|
function moveActive(delta) {
|
|
@@ -1194,12 +1469,12 @@ function createListbox(container, options = {}) {
|
|
|
1194
1469
|
}
|
|
1195
1470
|
container.addEventListener("keydown", onKeyDown);
|
|
1196
1471
|
container.addEventListener("click", onClick);
|
|
1197
|
-
function
|
|
1472
|
+
function dispose2() {
|
|
1198
1473
|
container.removeEventListener("keydown", onKeyDown);
|
|
1199
1474
|
container.removeEventListener("click", onClick);
|
|
1200
1475
|
}
|
|
1201
|
-
registerDisposer(container,
|
|
1202
|
-
return { activeValue, selectedValue, activeDescendantId, dispose };
|
|
1476
|
+
registerDisposer(container, dispose2);
|
|
1477
|
+
return { activeValue, selectedValue, activeDescendantId, dispose: dispose2 };
|
|
1203
1478
|
}
|
|
1204
1479
|
function createDialogAria(element, options = {}) {
|
|
1205
1480
|
const titleId = options.labelledBy ?? createId("dialog-title");
|
|
@@ -1287,22 +1562,49 @@ function removeScopedStyle(scopeId) {
|
|
|
1287
1562
|
}
|
|
1288
1563
|
|
|
1289
1564
|
// src/utils/sanitize.ts
|
|
1565
|
+
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
1290
1566
|
function sanitizeUrl(url) {
|
|
1291
1567
|
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1292
1568
|
if (!trimmed) return "";
|
|
1293
1569
|
const lower = trimmed.toLowerCase();
|
|
1294
|
-
|
|
1295
|
-
|
|
1570
|
+
let schemeEnd = -1;
|
|
1571
|
+
for (let i = 0; i < lower.length; i++) {
|
|
1572
|
+
const ch = lower.charCodeAt(i);
|
|
1573
|
+
if (ch === 58) {
|
|
1574
|
+
schemeEnd = i;
|
|
1575
|
+
break;
|
|
1576
|
+
}
|
|
1577
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
1296
1578
|
}
|
|
1579
|
+
if (schemeEnd === -1) return trimmed;
|
|
1580
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
1581
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
1582
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
1297
1583
|
return trimmed;
|
|
1298
1584
|
}
|
|
1299
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
1585
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
1586
|
+
"href",
|
|
1587
|
+
"xlink:href",
|
|
1588
|
+
"src",
|
|
1589
|
+
"action",
|
|
1590
|
+
"formaction",
|
|
1591
|
+
"formtarget",
|
|
1592
|
+
"cite",
|
|
1593
|
+
"poster",
|
|
1594
|
+
"background",
|
|
1595
|
+
"srcset",
|
|
1596
|
+
"ping",
|
|
1597
|
+
"data"
|
|
1598
|
+
]);
|
|
1300
1599
|
function isUrlAttribute(attr) {
|
|
1301
1600
|
return URL_ATTRIBUTES.has(attr);
|
|
1302
1601
|
}
|
|
1303
1602
|
|
|
1304
1603
|
// src/reactivity/bindAttribute.ts
|
|
1305
1604
|
var _isDev5 = isDev();
|
|
1605
|
+
function setProp(el, key, val) {
|
|
1606
|
+
el[key] = val;
|
|
1607
|
+
}
|
|
1306
1608
|
function isEventHandlerAttr(name) {
|
|
1307
1609
|
if (name.length < 3) return false;
|
|
1308
1610
|
const lower = name.toLowerCase();
|
|
@@ -1328,7 +1630,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
1328
1630
|
}
|
|
1329
1631
|
if (typeof value === "boolean") {
|
|
1330
1632
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
1331
|
-
el
|
|
1633
|
+
setProp(el, attr, value);
|
|
1332
1634
|
} else if (value) {
|
|
1333
1635
|
el.setAttribute(attr, "");
|
|
1334
1636
|
} else {
|
|
@@ -1338,7 +1640,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
1338
1640
|
}
|
|
1339
1641
|
const str = String(value);
|
|
1340
1642
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
1341
|
-
el
|
|
1643
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
1342
1644
|
} else {
|
|
1343
1645
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
1344
1646
|
}
|
|
@@ -1408,66 +1710,91 @@ function bindData(el, key, getter) {
|
|
|
1408
1710
|
}
|
|
1409
1711
|
|
|
1410
1712
|
// src/ui/dialog.ts
|
|
1713
|
+
var dialogStack = [];
|
|
1714
|
+
var globalListenerAttached = false;
|
|
1715
|
+
function __resetDialogStack() {
|
|
1716
|
+
while (dialogStack.length > 0) dialogStack.pop();
|
|
1717
|
+
if (typeof window !== "undefined" && globalListenerAttached) {
|
|
1718
|
+
window.removeEventListener("keydown", handleGlobalKeydown);
|
|
1719
|
+
globalListenerAttached = false;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
function handleGlobalKeydown(event) {
|
|
1723
|
+
if (event.key !== "Escape") return;
|
|
1724
|
+
const top = dialogStack[dialogStack.length - 1];
|
|
1725
|
+
if (top) top.close();
|
|
1726
|
+
}
|
|
1727
|
+
function ensureGlobalListener() {
|
|
1728
|
+
if (typeof window === "undefined" || globalListenerAttached) return;
|
|
1729
|
+
window.addEventListener("keydown", handleGlobalKeydown);
|
|
1730
|
+
globalListenerAttached = true;
|
|
1731
|
+
}
|
|
1732
|
+
function removeGlobalListenerIfIdle() {
|
|
1733
|
+
if (typeof window === "undefined") return;
|
|
1734
|
+
if (!globalListenerAttached) return;
|
|
1735
|
+
if (dialogStack.length > 0) return;
|
|
1736
|
+
window.removeEventListener("keydown", handleGlobalKeydown);
|
|
1737
|
+
globalListenerAttached = false;
|
|
1738
|
+
}
|
|
1411
1739
|
function dialog() {
|
|
1412
1740
|
const [isOpen, setIsOpen] = signal(false);
|
|
1413
|
-
|
|
1414
|
-
function
|
|
1415
|
-
if (
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
}
|
|
1419
|
-
function attachListener() {
|
|
1420
|
-
if (typeof window !== "undefined" && !listenerAttached) {
|
|
1421
|
-
window.addEventListener("keydown", handleKeydown);
|
|
1422
|
-
listenerAttached = true;
|
|
1423
|
-
}
|
|
1741
|
+
const entry = { close: () => close() };
|
|
1742
|
+
function pushOnStack() {
|
|
1743
|
+
if (dialogStack.indexOf(entry) !== -1) return;
|
|
1744
|
+
dialogStack.push(entry);
|
|
1745
|
+
ensureGlobalListener();
|
|
1424
1746
|
}
|
|
1425
|
-
function
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
}
|
|
1747
|
+
function removeFromStack() {
|
|
1748
|
+
const idx = dialogStack.indexOf(entry);
|
|
1749
|
+
if (idx !== -1) dialogStack.splice(idx, 1);
|
|
1750
|
+
removeGlobalListenerIfIdle();
|
|
1430
1751
|
}
|
|
1431
1752
|
function open() {
|
|
1753
|
+
if (isOpen()) return;
|
|
1432
1754
|
setIsOpen(true);
|
|
1433
|
-
|
|
1755
|
+
pushOnStack();
|
|
1434
1756
|
}
|
|
1435
1757
|
function close() {
|
|
1758
|
+
if (!isOpen()) {
|
|
1759
|
+
removeFromStack();
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1436
1762
|
setIsOpen(false);
|
|
1437
|
-
|
|
1763
|
+
removeFromStack();
|
|
1438
1764
|
}
|
|
1439
1765
|
function toggle() {
|
|
1440
1766
|
if (isOpen()) close();
|
|
1441
1767
|
else open();
|
|
1442
1768
|
}
|
|
1443
|
-
function
|
|
1444
|
-
|
|
1769
|
+
function dispose2() {
|
|
1770
|
+
removeFromStack();
|
|
1445
1771
|
setIsOpen(false);
|
|
1446
1772
|
}
|
|
1447
|
-
return { open, close, isOpen, toggle, dispose };
|
|
1773
|
+
return { open, close, isOpen, toggle, dispose: dispose2 };
|
|
1448
1774
|
}
|
|
1449
1775
|
|
|
1450
1776
|
// src/ui/toast.ts
|
|
1451
|
-
var toastCounter = 0;
|
|
1452
1777
|
function toast(options) {
|
|
1453
1778
|
const duration = options?.duration ?? 3e3;
|
|
1454
1779
|
const maxToasts = options?.maxToasts ?? Infinity;
|
|
1455
1780
|
const [toasts, setToasts] = signal([]);
|
|
1456
1781
|
const timers = /* @__PURE__ */ new Map();
|
|
1782
|
+
let toastCounter = 0;
|
|
1457
1783
|
function show(message, type) {
|
|
1458
1784
|
const id = `toast-${++toastCounter}`;
|
|
1459
1785
|
const toast2 = { id, message, type };
|
|
1786
|
+
const trimmedIds = [];
|
|
1460
1787
|
setToasts((prev) => {
|
|
1461
1788
|
const next = [...prev, toast2];
|
|
1462
1789
|
if (next.length > maxToasts) {
|
|
1463
1790
|
const removed = next.splice(0, next.length - maxToasts);
|
|
1464
|
-
for (const r of removed)
|
|
1465
|
-
clearTimerForToast(r.id);
|
|
1466
|
-
}
|
|
1791
|
+
for (const r of removed) trimmedIds.push(r.id);
|
|
1467
1792
|
}
|
|
1468
1793
|
return next;
|
|
1469
1794
|
});
|
|
1470
|
-
|
|
1795
|
+
for (const tid of trimmedIds) clearTimerForToast(tid);
|
|
1796
|
+
const wasTrimmed = trimmedIds.indexOf(id) !== -1;
|
|
1797
|
+
if (duration > 0 && !wasTrimmed) {
|
|
1471
1798
|
const timer = setTimeout(() => {
|
|
1472
1799
|
dismiss(id);
|
|
1473
1800
|
}, duration);
|
|
@@ -1553,14 +1880,14 @@ function infiniteScroll(options) {
|
|
|
1553
1880
|
},
|
|
1554
1881
|
configurable: true
|
|
1555
1882
|
});
|
|
1556
|
-
function
|
|
1883
|
+
function dispose2() {
|
|
1557
1884
|
disposed = true;
|
|
1558
1885
|
if (observer) {
|
|
1559
1886
|
observer.disconnect();
|
|
1560
1887
|
observer = null;
|
|
1561
1888
|
}
|
|
1562
1889
|
}
|
|
1563
|
-
return { sentinelRef: originalRef, loading, dispose };
|
|
1890
|
+
return { sentinelRef: originalRef, loading, dispose: dispose2 };
|
|
1564
1891
|
}
|
|
1565
1892
|
|
|
1566
1893
|
// src/ui/pagination.ts
|
|
@@ -1635,21 +1962,21 @@ function eventBus() {
|
|
|
1635
1962
|
// src/ui/lazyEffect.ts
|
|
1636
1963
|
function lazyEffect(element, effectFn, options) {
|
|
1637
1964
|
if (typeof IntersectionObserver === "undefined") {
|
|
1638
|
-
const
|
|
1639
|
-
return
|
|
1965
|
+
const dispose3 = effect(effectFn);
|
|
1966
|
+
return dispose3;
|
|
1640
1967
|
}
|
|
1641
|
-
let
|
|
1968
|
+
let dispose2 = null;
|
|
1642
1969
|
let disposed = false;
|
|
1643
1970
|
const observer = new IntersectionObserver(
|
|
1644
1971
|
(entries) => {
|
|
1645
1972
|
if (disposed) return;
|
|
1646
1973
|
const entry = entries[0];
|
|
1647
1974
|
if (!entry) return;
|
|
1648
|
-
if (entry.isIntersecting && !
|
|
1649
|
-
|
|
1650
|
-
} else if (!entry.isIntersecting &&
|
|
1651
|
-
|
|
1652
|
-
|
|
1975
|
+
if (entry.isIntersecting && !dispose2) {
|
|
1976
|
+
dispose2 = effect(effectFn);
|
|
1977
|
+
} else if (!entry.isIntersecting && dispose2) {
|
|
1978
|
+
dispose2();
|
|
1979
|
+
dispose2 = null;
|
|
1653
1980
|
}
|
|
1654
1981
|
},
|
|
1655
1982
|
{ threshold: 0, ...options }
|
|
@@ -1658,9 +1985,9 @@ function lazyEffect(element, effectFn, options) {
|
|
|
1658
1985
|
return () => {
|
|
1659
1986
|
disposed = true;
|
|
1660
1987
|
observer.disconnect();
|
|
1661
|
-
if (
|
|
1662
|
-
|
|
1663
|
-
|
|
1988
|
+
if (dispose2) {
|
|
1989
|
+
dispose2();
|
|
1990
|
+
dispose2 = null;
|
|
1664
1991
|
}
|
|
1665
1992
|
};
|
|
1666
1993
|
}
|
|
@@ -1717,11 +2044,11 @@ function hover(target) {
|
|
|
1717
2044
|
const onLeave = () => setHovered(false);
|
|
1718
2045
|
target.addEventListener("pointerenter", onEnter);
|
|
1719
2046
|
target.addEventListener("pointerleave", onLeave);
|
|
1720
|
-
function
|
|
2047
|
+
function dispose2() {
|
|
1721
2048
|
target.removeEventListener("pointerenter", onEnter);
|
|
1722
2049
|
target.removeEventListener("pointerleave", onLeave);
|
|
1723
2050
|
}
|
|
1724
|
-
return { hovered, dispose };
|
|
2051
|
+
return { hovered, dispose: dispose2 };
|
|
1725
2052
|
}
|
|
1726
2053
|
|
|
1727
2054
|
// src/ui/scrollLock.ts
|
|
@@ -1765,7 +2092,7 @@ function defineElement(name, component, options = {}) {
|
|
|
1765
2092
|
class SibuElement extends HTMLElement {
|
|
1766
2093
|
constructor() {
|
|
1767
2094
|
super();
|
|
1768
|
-
this._rendered =
|
|
2095
|
+
this._rendered = null;
|
|
1769
2096
|
if (options.shadow !== false) {
|
|
1770
2097
|
this._root = this.attachShadow({ mode: options.mode || "open" });
|
|
1771
2098
|
} else {
|
|
@@ -1779,25 +2106,23 @@ function defineElement(name, component, options = {}) {
|
|
|
1779
2106
|
this._render();
|
|
1780
2107
|
}
|
|
1781
2108
|
disconnectedCallback() {
|
|
1782
|
-
|
|
1783
|
-
this._root.innerHTML = "";
|
|
1784
|
-
}
|
|
1785
|
-
this._rendered = false;
|
|
2109
|
+
this._teardown();
|
|
1786
2110
|
}
|
|
1787
2111
|
attributeChangedCallback() {
|
|
1788
2112
|
if (this._rendered) {
|
|
1789
2113
|
this._render();
|
|
1790
2114
|
}
|
|
1791
2115
|
}
|
|
2116
|
+
_teardown() {
|
|
2117
|
+
if (this._rendered) {
|
|
2118
|
+
dispose(this._rendered);
|
|
2119
|
+
this._rendered = null;
|
|
2120
|
+
}
|
|
2121
|
+
this._root.replaceChildren();
|
|
2122
|
+
}
|
|
1792
2123
|
_render() {
|
|
2124
|
+
this._teardown();
|
|
1793
2125
|
const props = this._getProps();
|
|
1794
|
-
if (this._root instanceof ShadowRoot) {
|
|
1795
|
-
this._root.innerHTML = "";
|
|
1796
|
-
} else {
|
|
1797
|
-
while (this._root.firstChild) {
|
|
1798
|
-
this._root.removeChild(this._root.firstChild);
|
|
1799
|
-
}
|
|
1800
|
-
}
|
|
1801
2126
|
if (options.styles && this._root instanceof ShadowRoot) {
|
|
1802
2127
|
const styleEl = document.createElement("style");
|
|
1803
2128
|
styleEl.textContent = options.styles;
|
|
@@ -1805,7 +2130,7 @@ function defineElement(name, component, options = {}) {
|
|
|
1805
2130
|
}
|
|
1806
2131
|
const el = component(props, this);
|
|
1807
2132
|
this._root.appendChild(el);
|
|
1808
|
-
this._rendered =
|
|
2133
|
+
this._rendered = el;
|
|
1809
2134
|
}
|
|
1810
2135
|
_getProps() {
|
|
1811
2136
|
const props = {};
|
|
@@ -2004,6 +2329,7 @@ function createGuard(validator) {
|
|
|
2004
2329
|
FocusTrap,
|
|
2005
2330
|
RenderProp,
|
|
2006
2331
|
VirtualList,
|
|
2332
|
+
__resetDialogStack,
|
|
2007
2333
|
announce,
|
|
2008
2334
|
aria,
|
|
2009
2335
|
assertType,
|