sibujs 4.4.0 → 4.6.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/README.md +11 -0
- package/dist/browser.cjs +339 -130
- package/dist/browser.d.cts +61 -16
- package/dist/browser.d.ts +61 -16
- package/dist/browser.js +8 -6
- package/dist/build.cjs +273 -82
- package/dist/build.js +15 -16
- package/dist/cdn.dev.global.js +12 -12
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +12 -12
- package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
- package/dist/chunk-3ISI6ACU.js +44 -0
- package/dist/{chunk-VCTAEPSB.js → chunk-47M47FOM.js} +11 -3
- package/dist/chunk-5HZXGZ6T.js +24 -0
- package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
- package/dist/{chunk-3BTTCZ5J.js → chunk-5Q4R7HCL.js} +42 -4
- package/dist/{chunk-ADM46X22.js → chunk-7GQCWFOE.js} +157 -61
- package/dist/{chunk-4Z3SPQ67.js → chunk-7NCARGJW.js} +16 -8
- package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
- package/dist/{chunk-LQFGQNMV.js → chunk-AIF3Z2T7.js} +302 -39
- package/dist/{chunk-UCALUKB5.js → chunk-BAAG6ZTI.js} +98 -29
- package/dist/{chunk-NVNJH22U.js → chunk-D33YTSX5.js} +2 -2
- package/dist/{chunk-M2F7TZHH.js → chunk-DKGBBKOF.js} +136 -80
- package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
- package/dist/{chunk-HFCOH2GN.js → chunk-HYXDKS4N.js} +153 -110
- package/dist/chunk-J6FW5TV6.js +233 -0
- package/dist/{chunk-36S2YPP4.js → chunk-JSXPZCET.js} +1 -1
- package/dist/chunk-NYNYSPK7.js +318 -0
- package/dist/{chunk-HQSEH5F6.js → chunk-ORMZXBKQ.js} +108 -45
- package/dist/{chunk-LYVUX7NT.js → chunk-OXUY2A6L.js} +287 -130
- package/dist/{chunk-6GSIXTWX.js → chunk-PK6FK2G2.js} +187 -66
- package/dist/{chunk-W2EQ7X2L.js → chunk-QE4TTDU3.js} +47 -9
- package/dist/{chunk-XLO7SLIX.js → chunk-SXXVZMKZ.js} +262 -70
- package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
- package/dist/{chunk-RR7M3FHM.js → chunk-UZQ6ALFS.js} +3 -3
- package/dist/{chunk-PNIRUQ4C.js → chunk-VVWPJ543.js} +6 -8
- package/dist/{chunk-7GIHSAWB.js → chunk-XC4MEKGA.js} +3 -3
- package/dist/{chunk-SKPTERHP.js → chunk-XRRZKZYX.js} +55 -31
- package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
- package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
- package/dist/{customElement-CNZxEB9G.d.ts → customElement-MmInOW1U.d.cts} +59 -10
- package/dist/{customElement-CNZxEB9G.d.cts → customElement-MmInOW1U.d.ts} +59 -10
- package/dist/data.cjs +293 -125
- package/dist/data.d.cts +47 -9
- package/dist/data.d.ts +47 -9
- package/dist/data.js +12 -9
- package/dist/devtools.cjs +121 -58
- package/dist/devtools.js +7 -8
- package/dist/dispose-GEIG2KOF.js +28 -0
- package/dist/ecosystem.cjs +391 -112
- package/dist/ecosystem.d.cts +31 -7
- package/dist/ecosystem.d.ts +31 -7
- package/dist/ecosystem.js +12 -12
- package/dist/extras.cjs +2250 -879
- package/dist/extras.d.cts +10 -9
- package/dist/extras.d.ts +10 -9
- package/dist/extras.js +39 -28
- package/dist/index.cjs +273 -82
- package/dist/index.d.cts +44 -154
- package/dist/index.d.ts +44 -154
- package/dist/index.js +24 -27
- package/dist/motion.cjs +137 -42
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +397 -48
- package/dist/patterns.d.cts +32 -9
- package/dist/patterns.d.ts +32 -9
- package/dist/patterns.js +8 -8
- package/dist/performance.cjs +338 -217
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -9
- package/dist/plugin-DVgSnTfK.d.cts +112 -0
- package/dist/plugin-DVgSnTfK.d.ts +112 -0
- package/dist/plugins.cjs +587 -203
- package/dist/plugins.d.cts +3 -3
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +35 -23
- package/dist/signal-EotCj4hS.d.cts +110 -0
- package/dist/signal-EotCj4hS.d.ts +110 -0
- package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
- package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
- package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
- package/dist/ssr.cjs +214 -73
- package/dist/ssr.d.cts +9 -3
- package/dist/ssr.d.ts +9 -3
- package/dist/ssr.js +11 -12
- package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
- package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
- package/dist/tagFactory-DFstCLQV.d.cts +117 -0
- package/dist/tagFactory-DkaNVUNV.d.ts +117 -0
- package/dist/testing.cjs +2481 -2153
- package/dist/testing.d.cts +56 -5
- package/dist/testing.d.ts +56 -5
- package/dist/testing.js +580 -307
- package/dist/ui.cjs +798 -328
- package/dist/ui.d.cts +40 -7
- package/dist/ui.d.ts +40 -7
- package/dist/ui.js +151 -56
- package/dist/widgets.cjs +319 -285
- package/dist/widgets.js +9 -10
- package/package.json +2 -2
- package/dist/chunk-2WLZ6757.js +0 -149
- package/dist/chunk-7NBDXVHS.js +0 -60
- package/dist/chunk-CCSJMTRN.js +0 -15
- package/dist/chunk-QKRPLZ2V.js +0 -108
- package/dist/chunk-WWV3SJ3L.js +0 -131
- package/dist/dispose-46BOMMQJ.js +0 -19
- package/dist/plugin-D30wlGW5.d.cts +0 -71
- package/dist/plugin-D30wlGW5.d.ts +0 -71
- package/dist/tagFactory-Bzupt4Pj.d.cts +0 -55
- package/dist/tagFactory-Bzupt4Pj.d.ts +0 -55
|
@@ -1,33 +1,38 @@
|
|
|
1
|
+
import {
|
|
2
|
+
domBinding
|
|
3
|
+
} from "./chunk-3ISI6ACU.js";
|
|
1
4
|
import {
|
|
2
5
|
bindAttribute,
|
|
3
6
|
setSafeAttribute
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-47M47FOM.js";
|
|
5
8
|
import {
|
|
6
9
|
derived
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QE4TTDU3.js";
|
|
8
11
|
import {
|
|
9
12
|
isEventHandlerAttr
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-2INLLLMZ.js";
|
|
11
14
|
import {
|
|
12
15
|
globalSingleton
|
|
13
16
|
} from "./chunk-7ZHH77QA.js";
|
|
14
17
|
import {
|
|
15
|
-
|
|
16
|
-
} from "./chunk-
|
|
17
|
-
import {
|
|
18
|
-
dispose,
|
|
19
|
-
registerDisposer,
|
|
20
|
-
replaceChildrenSafely
|
|
21
|
-
} from "./chunk-QKRPLZ2V.js";
|
|
18
|
+
adoptThenable
|
|
19
|
+
} from "./chunk-5HZXGZ6T.js";
|
|
22
20
|
import {
|
|
23
21
|
signal
|
|
24
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-D33YTSX5.js";
|
|
25
23
|
import {
|
|
24
|
+
reactiveBinding,
|
|
26
25
|
track
|
|
27
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-5Q4R7HCL.js";
|
|
28
27
|
import {
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
dispose,
|
|
29
|
+
disposeNodeOwn,
|
|
30
|
+
registerDisposer,
|
|
31
|
+
replaceChildrenSafely,
|
|
32
|
+
reportError,
|
|
33
|
+
unregisterDisposer,
|
|
34
|
+
withDisposerRollback
|
|
35
|
+
} from "./chunk-NYNYSPK7.js";
|
|
31
36
|
|
|
32
37
|
// src/ui/form.ts
|
|
33
38
|
function required(message = "This field is required") {
|
|
@@ -56,10 +61,14 @@ function maxLength(max2, message) {
|
|
|
56
61
|
}
|
|
57
62
|
function matchesPattern(regex, message = "Invalid format") {
|
|
58
63
|
return (value) => {
|
|
59
|
-
if (
|
|
60
|
-
|
|
64
|
+
if (!value) return null;
|
|
65
|
+
const savedLastIndex = regex.lastIndex;
|
|
66
|
+
regex.lastIndex = 0;
|
|
67
|
+
try {
|
|
68
|
+
return regex.test(value) ? null : message;
|
|
69
|
+
} finally {
|
|
70
|
+
regex.lastIndex = savedLastIndex;
|
|
61
71
|
}
|
|
62
|
-
return null;
|
|
63
72
|
};
|
|
64
73
|
}
|
|
65
74
|
function email(message = "Invalid email address") {
|
|
@@ -108,13 +117,13 @@ function bindField(field, extras) {
|
|
|
108
117
|
const mergedOn = extraOn && typeof extraOn === "object" ? { ...extraOn, ...fieldOn } : fieldOn;
|
|
109
118
|
const onElement = (el) => {
|
|
110
119
|
if (el instanceof HTMLSelectElement && el.multiple) {
|
|
111
|
-
const stop =
|
|
120
|
+
const stop = domBinding(() => {
|
|
112
121
|
const v = field.value();
|
|
113
122
|
const selected = Array.isArray(v) ? v.map(String) : [];
|
|
114
123
|
for (const opt of Array.from(el.options)) {
|
|
115
124
|
opt.selected = selected.includes(opt.value);
|
|
116
125
|
}
|
|
117
|
-
});
|
|
126
|
+
}, el);
|
|
118
127
|
registerDisposer(el, stop);
|
|
119
128
|
}
|
|
120
129
|
if (typeof extraOnElement === "function") {
|
|
@@ -134,6 +143,7 @@ function form(config) {
|
|
|
134
143
|
const fieldEntries = Object.entries(config);
|
|
135
144
|
const fieldMap = {};
|
|
136
145
|
const [manualErrors, setManualErrors] = signal({});
|
|
146
|
+
const fieldErrors = [];
|
|
137
147
|
for (const [name, cfg] of fieldEntries) {
|
|
138
148
|
const [value, setValue] = signal(cfg.initial);
|
|
139
149
|
const [isTouched, setTouched] = signal(false);
|
|
@@ -148,6 +158,7 @@ function form(config) {
|
|
|
148
158
|
}
|
|
149
159
|
return null;
|
|
150
160
|
});
|
|
161
|
+
fieldErrors.push(error);
|
|
151
162
|
const wrappedSet = (next) => {
|
|
152
163
|
setValue(next);
|
|
153
164
|
setManualErrors((prev) => {
|
|
@@ -224,12 +235,22 @@ function form(config) {
|
|
|
224
235
|
field.touch();
|
|
225
236
|
}
|
|
226
237
|
if (isValid()) {
|
|
227
|
-
const
|
|
228
|
-
|
|
238
|
+
const report = (error) => reportError(error, { phase: "async", name: "form.handleSubmit" });
|
|
239
|
+
let pending;
|
|
240
|
+
try {
|
|
241
|
+
pending = adoptThenable(onSubmit(values()));
|
|
242
|
+
} catch (error) {
|
|
243
|
+
report(error);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (pending) {
|
|
229
247
|
setSubmitting(true);
|
|
230
|
-
|
|
248
|
+
pending.then(
|
|
231
249
|
() => setSubmitting(false),
|
|
232
|
-
() =>
|
|
250
|
+
(error) => {
|
|
251
|
+
setSubmitting(false);
|
|
252
|
+
report(error);
|
|
253
|
+
}
|
|
233
254
|
);
|
|
234
255
|
}
|
|
235
256
|
}
|
|
@@ -243,6 +264,17 @@ function form(config) {
|
|
|
243
264
|
function setError(field, message) {
|
|
244
265
|
setManualErrors((prev) => ({ ...prev, [field]: message }));
|
|
245
266
|
}
|
|
267
|
+
let disposed = false;
|
|
268
|
+
function dispose2() {
|
|
269
|
+
if (disposed) return;
|
|
270
|
+
disposed = true;
|
|
271
|
+
errors.dispose();
|
|
272
|
+
isValid.dispose();
|
|
273
|
+
isDirty.dispose();
|
|
274
|
+
touchedState.dispose();
|
|
275
|
+
values.dispose();
|
|
276
|
+
for (const error of fieldErrors) error.dispose();
|
|
277
|
+
}
|
|
246
278
|
return {
|
|
247
279
|
fields: fieldMap,
|
|
248
280
|
errors,
|
|
@@ -253,7 +285,8 @@ function form(config) {
|
|
|
253
285
|
values,
|
|
254
286
|
handleSubmit,
|
|
255
287
|
reset,
|
|
256
|
-
setError
|
|
288
|
+
setError,
|
|
289
|
+
dispose: dispose2
|
|
257
290
|
};
|
|
258
291
|
}
|
|
259
292
|
|
|
@@ -297,7 +330,7 @@ function VirtualList(props) {
|
|
|
297
330
|
content.appendChild(itemEl);
|
|
298
331
|
}
|
|
299
332
|
};
|
|
300
|
-
registerDisposer(container,
|
|
333
|
+
registerDisposer(container, domBinding(update, container));
|
|
301
334
|
return container;
|
|
302
335
|
}
|
|
303
336
|
|
|
@@ -307,11 +340,14 @@ function intersection(options) {
|
|
|
307
340
|
const [ratio, setRatio] = signal(0);
|
|
308
341
|
let observer = null;
|
|
309
342
|
let currentElement = null;
|
|
343
|
+
let generation = 0;
|
|
310
344
|
function observe(element) {
|
|
311
345
|
if (typeof IntersectionObserver === "undefined") return;
|
|
312
346
|
unobserve();
|
|
313
347
|
currentElement = element;
|
|
348
|
+
const observation = ++generation;
|
|
314
349
|
observer = new IntersectionObserver((entries) => {
|
|
350
|
+
if (observation !== generation) return;
|
|
315
351
|
const entry = entries[0];
|
|
316
352
|
if (entry) {
|
|
317
353
|
setIsIntersecting(entry.isIntersecting);
|
|
@@ -321,8 +357,10 @@ function intersection(options) {
|
|
|
321
357
|
observer.observe(element);
|
|
322
358
|
}
|
|
323
359
|
function unobserve() {
|
|
360
|
+
generation++;
|
|
324
361
|
if (observer) {
|
|
325
362
|
if (currentElement) observer.unobserve(currentElement);
|
|
363
|
+
observer.takeRecords();
|
|
326
364
|
observer.disconnect();
|
|
327
365
|
observer = null;
|
|
328
366
|
currentElement = null;
|
|
@@ -341,17 +379,26 @@ function lazyLoad(element, loader, options) {
|
|
|
341
379
|
return () => {
|
|
342
380
|
};
|
|
343
381
|
}
|
|
382
|
+
let done = false;
|
|
383
|
+
const stop = () => {
|
|
384
|
+
done = true;
|
|
385
|
+
observer.takeRecords();
|
|
386
|
+
observer.disconnect();
|
|
387
|
+
};
|
|
344
388
|
const observer = new IntersectionObserver((entries) => {
|
|
389
|
+
if (done) return;
|
|
345
390
|
for (const entry of entries) {
|
|
346
391
|
if (entry.isIntersecting) {
|
|
392
|
+
stop();
|
|
347
393
|
loader();
|
|
348
|
-
observer.disconnect();
|
|
349
394
|
break;
|
|
350
395
|
}
|
|
351
396
|
}
|
|
352
397
|
}, options);
|
|
353
398
|
observer.observe(element);
|
|
354
|
-
return () =>
|
|
399
|
+
return () => {
|
|
400
|
+
if (!done) stop();
|
|
401
|
+
};
|
|
355
402
|
}
|
|
356
403
|
|
|
357
404
|
// src/ui/inputMask.ts
|
|
@@ -500,6 +547,7 @@ function focus() {
|
|
|
500
547
|
const dispose2 = () => {
|
|
501
548
|
if (disposed) return;
|
|
502
549
|
disposed = true;
|
|
550
|
+
unregisterDisposer(element, dispose2);
|
|
503
551
|
element.removeEventListener("focus", onFocus);
|
|
504
552
|
element.removeEventListener("blur", onBlur);
|
|
505
553
|
if (currentElement === element) currentElement = null;
|
|
@@ -568,14 +616,19 @@ function FocusTrap(nodes, options = {}) {
|
|
|
568
616
|
}
|
|
569
617
|
};
|
|
570
618
|
container.addEventListener("keydown", onTrapKeydown);
|
|
619
|
+
let disposed = false;
|
|
571
620
|
if (options.autoFocus !== false) {
|
|
572
621
|
queueMicrotask(() => {
|
|
622
|
+
if (disposed || !container.isConnected) return;
|
|
573
623
|
const first = getFocusable()[0];
|
|
574
624
|
first?.focus();
|
|
575
625
|
});
|
|
576
626
|
}
|
|
577
627
|
let trapObserver = null;
|
|
578
628
|
function restoreFocusAndCleanup() {
|
|
629
|
+
if (disposed) return;
|
|
630
|
+
disposed = true;
|
|
631
|
+
unregisterDisposer(container, restoreFocusAndCleanup);
|
|
579
632
|
if (options.restoreFocus !== false) previouslyFocused?.focus();
|
|
580
633
|
container.removeEventListener("keydown", onTrapKeydown);
|
|
581
634
|
if (trapObserver) {
|
|
@@ -590,29 +643,45 @@ function FocusTrap(nodes, options = {}) {
|
|
|
590
643
|
}
|
|
591
644
|
});
|
|
592
645
|
queueMicrotask(() => {
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
}
|
|
646
|
+
const observer = trapObserver;
|
|
647
|
+
if (disposed || !container.isConnected || !observer) return;
|
|
648
|
+
observer.observe(container, { childList: true, subtree: true });
|
|
596
649
|
});
|
|
597
650
|
}
|
|
598
651
|
registerDisposer(container, restoreFocusAndCleanup);
|
|
599
652
|
return container;
|
|
600
653
|
}
|
|
654
|
+
function isApplePlatform() {
|
|
655
|
+
if (typeof navigator === "undefined") return false;
|
|
656
|
+
const nav = navigator;
|
|
657
|
+
return /mac|iphone|ipad|ipod/i.test(nav.userAgentData?.platform || nav.platform || "");
|
|
658
|
+
}
|
|
601
659
|
function hotkey(combo, handler, options = {}) {
|
|
602
660
|
let key = combo;
|
|
603
661
|
let needCtrl = options.ctrl ?? false;
|
|
604
662
|
let needShift = options.shift ?? false;
|
|
605
663
|
let needAlt = options.alt ?? false;
|
|
606
664
|
let needMeta = options.meta ?? false;
|
|
607
|
-
if (combo
|
|
608
|
-
|
|
665
|
+
if (combo === "+") {
|
|
666
|
+
key = "+";
|
|
667
|
+
} else if (combo.includes("+")) {
|
|
668
|
+
const literalPlus = combo.endsWith("++");
|
|
669
|
+
const parts = (literalPlus ? combo.slice(0, -2) : combo).toLowerCase().split("+");
|
|
670
|
+
if (literalPlus) parts.push("+");
|
|
609
671
|
key = parts[parts.length - 1];
|
|
672
|
+
if (key === "") throw new Error(`hotkey("${combo}"): missing key`);
|
|
610
673
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
611
674
|
const mod = parts[i];
|
|
612
675
|
if (mod === "ctrl" || mod === "control") needCtrl = true;
|
|
613
676
|
else if (mod === "shift") needShift = true;
|
|
614
|
-
else if (mod === "alt") needAlt = true;
|
|
677
|
+
else if (mod === "alt" || mod === "option") needAlt = true;
|
|
615
678
|
else if (mod === "meta" || mod === "cmd" || mod === "command") needMeta = true;
|
|
679
|
+
else if (mod === "mod") {
|
|
680
|
+
if (isApplePlatform()) needMeta = true;
|
|
681
|
+
else needCtrl = true;
|
|
682
|
+
} else {
|
|
683
|
+
throw new Error(`hotkey("${combo}"): unknown modifier "${mod}"`);
|
|
684
|
+
}
|
|
616
685
|
}
|
|
617
686
|
}
|
|
618
687
|
const listener = (e) => {
|
|
@@ -916,13 +985,13 @@ function bindBoolAttr(el, attr, getter) {
|
|
|
916
985
|
let value;
|
|
917
986
|
try {
|
|
918
987
|
value = reactiveGetter();
|
|
919
|
-
} catch {
|
|
988
|
+
} catch (err) {
|
|
989
|
+
reportError(err, { phase: "binding", name: "bindBoolAttr", node: el });
|
|
920
990
|
return;
|
|
921
991
|
}
|
|
922
992
|
setSafeAttribute(el, attr, Boolean(value), { label: "bindBoolAttr" });
|
|
923
993
|
}
|
|
924
|
-
|
|
925
|
-
return teardown;
|
|
994
|
+
return reactiveBinding(commit, el);
|
|
926
995
|
}
|
|
927
996
|
function bindData(el, key, getter) {
|
|
928
997
|
const dataAttr = `data-${key}`;
|
|
@@ -967,6 +1036,8 @@ function removeGlobalListenerIfIdle() {
|
|
|
967
1036
|
function dialog() {
|
|
968
1037
|
const [isOpen, setIsOpen] = signal(false);
|
|
969
1038
|
const entry = { close: () => close() };
|
|
1039
|
+
let opened = false;
|
|
1040
|
+
let disposed = false;
|
|
970
1041
|
function pushOnStack() {
|
|
971
1042
|
if (dialogStack.indexOf(entry) !== -1) return;
|
|
972
1043
|
dialogStack.push(entry);
|
|
@@ -978,23 +1049,27 @@ function dialog() {
|
|
|
978
1049
|
removeGlobalListenerIfIdle();
|
|
979
1050
|
}
|
|
980
1051
|
function open() {
|
|
981
|
-
if (
|
|
982
|
-
|
|
1052
|
+
if (disposed || opened) return;
|
|
1053
|
+
opened = true;
|
|
983
1054
|
pushOnStack();
|
|
1055
|
+
setIsOpen(true);
|
|
984
1056
|
}
|
|
985
1057
|
function close() {
|
|
986
|
-
if (!
|
|
1058
|
+
if (!opened) {
|
|
987
1059
|
removeFromStack();
|
|
988
1060
|
return;
|
|
989
1061
|
}
|
|
990
|
-
|
|
1062
|
+
opened = false;
|
|
991
1063
|
removeFromStack();
|
|
1064
|
+
setIsOpen(false);
|
|
992
1065
|
}
|
|
993
1066
|
function toggle() {
|
|
994
|
-
if (
|
|
1067
|
+
if (opened) close();
|
|
995
1068
|
else open();
|
|
996
1069
|
}
|
|
997
1070
|
function dispose2() {
|
|
1071
|
+
disposed = true;
|
|
1072
|
+
opened = false;
|
|
998
1073
|
removeFromStack();
|
|
999
1074
|
setIsOpen(false);
|
|
1000
1075
|
}
|
|
@@ -1186,39 +1261,62 @@ function pagination(options) {
|
|
|
1186
1261
|
const clamped = Math.max(1, Math.min(target, totalPages()));
|
|
1187
1262
|
setPage(clamped);
|
|
1188
1263
|
}
|
|
1189
|
-
|
|
1264
|
+
function dispose2() {
|
|
1265
|
+
startIndex.dispose();
|
|
1266
|
+
endIndex.dispose();
|
|
1267
|
+
currentPage.dispose();
|
|
1268
|
+
totalPages.dispose();
|
|
1269
|
+
}
|
|
1270
|
+
return { page: currentPage, pageSize, totalPages, next, prev, goTo, startIndex, endIndex, dispose: dispose2 };
|
|
1190
1271
|
}
|
|
1191
1272
|
|
|
1192
1273
|
// src/ui/eventBus.ts
|
|
1193
1274
|
function eventBus() {
|
|
1194
1275
|
const listeners = /* @__PURE__ */ new Map();
|
|
1195
1276
|
function on(event, handler) {
|
|
1196
|
-
let
|
|
1197
|
-
if (!
|
|
1198
|
-
|
|
1199
|
-
listeners.set(event,
|
|
1277
|
+
let subs = listeners.get(event);
|
|
1278
|
+
if (!subs) {
|
|
1279
|
+
subs = /* @__PURE__ */ new Map();
|
|
1280
|
+
listeners.set(event, subs);
|
|
1281
|
+
}
|
|
1282
|
+
let subscription = subs.get(handler);
|
|
1283
|
+
if (!subscription) {
|
|
1284
|
+
subscription = { handler, active: true };
|
|
1285
|
+
subs.set(handler, subscription);
|
|
1200
1286
|
}
|
|
1201
|
-
|
|
1202
|
-
return () =>
|
|
1287
|
+
const own = subscription;
|
|
1288
|
+
return () => {
|
|
1289
|
+
if (listeners.get(event)?.get(handler) !== own) return;
|
|
1290
|
+
off(event, handler);
|
|
1291
|
+
};
|
|
1203
1292
|
}
|
|
1204
1293
|
function emit(event, data) {
|
|
1205
|
-
const
|
|
1206
|
-
if (
|
|
1207
|
-
|
|
1208
|
-
|
|
1294
|
+
const subs = listeners.get(event);
|
|
1295
|
+
if (!subs || subs.size === 0) return;
|
|
1296
|
+
for (const subscription of Array.from(subs.values())) {
|
|
1297
|
+
if (!subscription.active) continue;
|
|
1298
|
+
try {
|
|
1299
|
+
subscription.handler(data);
|
|
1300
|
+
} catch (err) {
|
|
1301
|
+
reportError(err, { phase: "event", name: `eventBus(${String(event)})` });
|
|
1209
1302
|
}
|
|
1210
1303
|
}
|
|
1211
1304
|
}
|
|
1212
1305
|
function off(event, handler) {
|
|
1213
|
-
const
|
|
1214
|
-
if (
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1306
|
+
const subs = listeners.get(event);
|
|
1307
|
+
if (!subs) return;
|
|
1308
|
+
const subscription = subs.get(handler);
|
|
1309
|
+
if (!subscription) return;
|
|
1310
|
+
subscription.active = false;
|
|
1311
|
+
subs.delete(handler);
|
|
1312
|
+
if (subs.size === 0) {
|
|
1313
|
+
listeners.delete(event);
|
|
1219
1314
|
}
|
|
1220
1315
|
}
|
|
1221
1316
|
function clear() {
|
|
1317
|
+
for (const subs of listeners.values()) {
|
|
1318
|
+
for (const subscription of subs.values()) subscription.active = false;
|
|
1319
|
+
}
|
|
1222
1320
|
listeners.clear();
|
|
1223
1321
|
}
|
|
1224
1322
|
return { on, emit, off, clear };
|
|
@@ -1226,13 +1324,33 @@ function eventBus() {
|
|
|
1226
1324
|
|
|
1227
1325
|
// src/platform/customElement.ts
|
|
1228
1326
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1327
|
+
var MAX_RENDER_PASSES = 10;
|
|
1328
|
+
var ABANDONED_RENDER = /* @__PURE__ */ Symbol("sibujs.defineElement.abandonedRender");
|
|
1229
1329
|
function defineElement(name, component, options = {}) {
|
|
1230
1330
|
if (customElements.get(name)) return;
|
|
1231
1331
|
const observed = options.observedAttributes || [];
|
|
1232
1332
|
class SibuElement extends HTMLElement {
|
|
1233
1333
|
constructor() {
|
|
1234
1334
|
super();
|
|
1235
|
-
|
|
1335
|
+
// Re-rendering is keyed on connection, not on a previous render: a first render
|
|
1336
|
+
// that throws leaves nothing rendered, and the element must still re-render
|
|
1337
|
+
// when a later attribute change fixes the input.
|
|
1338
|
+
this._connected = false;
|
|
1339
|
+
// A render in progress, and whether an attribute changed during it. The
|
|
1340
|
+
// component may write its host's observed attributes while rendering; with
|
|
1341
|
+
// the old subtree kept during the build, rendering again from inside the
|
|
1342
|
+
// callback recursed until the stack overflowed.
|
|
1343
|
+
this._rendering = false;
|
|
1344
|
+
this._dirty = false;
|
|
1345
|
+
// How many teardowns are draining. A host teardown may reconnect the element
|
|
1346
|
+
// (and a nested disconnect may run inside it), and rendering the next
|
|
1347
|
+
// generation from inside that drain would let the drain tear down what the
|
|
1348
|
+
// new render registers. A counter, not a flag: a nested teardown returning
|
|
1349
|
+
// must not declare the outer one finished.
|
|
1350
|
+
this._teardownDepth = 0;
|
|
1351
|
+
// Disconnects so far. A render compares it across its old-subtree teardown
|
|
1352
|
+
// to detect a disconnect that happened inside it.
|
|
1353
|
+
this._disconnects = 0;
|
|
1236
1354
|
if (options.shadow !== false) {
|
|
1237
1355
|
this._root = this.attachShadow({ mode: options.mode || "open" });
|
|
1238
1356
|
} else {
|
|
@@ -1242,32 +1360,106 @@ function defineElement(name, component, options = {}) {
|
|
|
1242
1360
|
static get observedAttributes() {
|
|
1243
1361
|
return observed;
|
|
1244
1362
|
}
|
|
1363
|
+
/** Whether rendering must wait for work already in progress. */
|
|
1364
|
+
get _busy() {
|
|
1365
|
+
return this._rendering || this._teardownDepth > 0;
|
|
1366
|
+
}
|
|
1245
1367
|
connectedCallback() {
|
|
1368
|
+
this._connected = true;
|
|
1369
|
+
if (this._busy) {
|
|
1370
|
+
this._dirty = true;
|
|
1371
|
+
return;
|
|
1372
|
+
}
|
|
1246
1373
|
this._render();
|
|
1247
1374
|
}
|
|
1248
1375
|
disconnectedCallback() {
|
|
1249
|
-
this.
|
|
1376
|
+
this._connected = false;
|
|
1377
|
+
this._disconnects++;
|
|
1378
|
+
this._teardownDepth++;
|
|
1379
|
+
try {
|
|
1380
|
+
this._teardown();
|
|
1381
|
+
} finally {
|
|
1382
|
+
this._teardownDepth--;
|
|
1383
|
+
if (this._teardownDepth === 0 && this._connected && this._dirty) {
|
|
1384
|
+
this._dirty = false;
|
|
1385
|
+
if (!this._rendering) this._render();
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1250
1388
|
}
|
|
1251
|
-
attributeChangedCallback() {
|
|
1252
|
-
if (this.
|
|
1253
|
-
|
|
1389
|
+
attributeChangedCallback(_name, oldValue, newValue) {
|
|
1390
|
+
if (oldValue === newValue || !this._connected) return;
|
|
1391
|
+
if (this._busy) {
|
|
1392
|
+
this._dirty = true;
|
|
1393
|
+
return;
|
|
1254
1394
|
}
|
|
1395
|
+
this._render();
|
|
1255
1396
|
}
|
|
1256
1397
|
_teardown() {
|
|
1257
|
-
this._rendered = null;
|
|
1258
1398
|
replaceChildrenSafely(this._root);
|
|
1259
|
-
|
|
1399
|
+
disposeNodeOwn(this);
|
|
1400
|
+
}
|
|
1401
|
+
/**
|
|
1402
|
+
* Render as a transaction: build the replacement first, commit only if that
|
|
1403
|
+
* succeeds. Tearing the current subtree down before calling the factory
|
|
1404
|
+
* meant a throwing rerender (an invalid attribute, say) left the element
|
|
1405
|
+
* blank with its live state already disposed. Now a failure keeps the
|
|
1406
|
+
* working subtree, releases whatever the failed attempt registered, and is
|
|
1407
|
+
* reported with this element as its node so an enclosing ErrorBoundary can
|
|
1408
|
+
* claim it.
|
|
1409
|
+
*/
|
|
1260
1410
|
_render() {
|
|
1261
|
-
this.
|
|
1411
|
+
this._rendering = true;
|
|
1412
|
+
try {
|
|
1413
|
+
let passes = 0;
|
|
1414
|
+
do {
|
|
1415
|
+
this._dirty = false;
|
|
1416
|
+
if (++passes > MAX_RENDER_PASSES) {
|
|
1417
|
+
reportError(
|
|
1418
|
+
new Error(
|
|
1419
|
+
`[SibuJS] defineElement(${name}): the component changed its own observed attributes on ${MAX_RENDER_PASSES} consecutive renders; stopped re-rendering.`
|
|
1420
|
+
),
|
|
1421
|
+
{ phase: "render", name: `defineElement(${name})`, node: this }
|
|
1422
|
+
);
|
|
1423
|
+
break;
|
|
1424
|
+
}
|
|
1425
|
+
this._renderOnce();
|
|
1426
|
+
} while (this._dirty && this._connected);
|
|
1427
|
+
} finally {
|
|
1428
|
+
this._rendering = false;
|
|
1429
|
+
this._dirty = false;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
_renderOnce() {
|
|
1262
1433
|
const props = this._getProps();
|
|
1434
|
+
let el;
|
|
1435
|
+
try {
|
|
1436
|
+
el = withDisposerRollback(() => {
|
|
1437
|
+
const built = component(props, this);
|
|
1438
|
+
if (!this._connected) throw ABANDONED_RENDER;
|
|
1439
|
+
return built;
|
|
1440
|
+
});
|
|
1441
|
+
} catch (err) {
|
|
1442
|
+
if (err !== ABANDONED_RENDER) {
|
|
1443
|
+
reportError(err, { phase: "render", name: `defineElement(${name})`, node: this });
|
|
1444
|
+
}
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
const next = [];
|
|
1263
1448
|
if (options.styles && this._root instanceof ShadowRoot) {
|
|
1264
1449
|
const styleEl = document.createElement("style");
|
|
1265
1450
|
styleEl.textContent = options.styles;
|
|
1266
|
-
|
|
1451
|
+
next.push(styleEl);
|
|
1452
|
+
}
|
|
1453
|
+
next.push(el);
|
|
1454
|
+
const disconnects = this._disconnects;
|
|
1455
|
+
for (const node of next) node.parentNode?.removeChild(node);
|
|
1456
|
+
replaceChildrenSafely(this._root);
|
|
1457
|
+
if (this._disconnects !== disconnects) {
|
|
1458
|
+
for (const node of next) dispose(node);
|
|
1459
|
+
if (this._connected) this._dirty = true;
|
|
1460
|
+
return;
|
|
1267
1461
|
}
|
|
1268
|
-
|
|
1269
|
-
this._root.appendChild(el);
|
|
1270
|
-
this._rendered = el;
|
|
1462
|
+
this._root.replaceChildren(...next);
|
|
1271
1463
|
}
|
|
1272
1464
|
_getProps() {
|
|
1273
1465
|
const props = {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEV,
|
|
3
3
|
devWarn
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NYNYSPK7.js";
|
|
5
5
|
|
|
6
6
|
// src/patterns/hoc.ts
|
|
7
7
|
function withWrapper(WrappedComponent, wrapper) {
|
|
@@ -122,7 +122,7 @@ function validateProps(props, schema) {
|
|
|
122
122
|
const errors = [];
|
|
123
123
|
for (const [key, def] of Object.entries(schema)) {
|
|
124
124
|
const propDef = typeof def === "function" ? { type: def } : def;
|
|
125
|
-
if (result[key]
|
|
125
|
+
if (result[key] === void 0 && propDef.default !== void 0) {
|
|
126
126
|
result[key] = typeof propDef.default === "function" ? propDef.default() : propDef.default;
|
|
127
127
|
}
|
|
128
128
|
if (propDef.required && result[key] == null) {
|
|
@@ -148,7 +148,7 @@ ${errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
|
148
148
|
for (const [key, def] of Object.entries(schema)) {
|
|
149
149
|
if (typeof def === "function") continue;
|
|
150
150
|
const fallback = def.default;
|
|
151
|
-
if (result[key]
|
|
151
|
+
if (result[key] === void 0 && fallback !== void 0) {
|
|
152
152
|
result[key] = typeof fallback === "function" ? fallback() : fallback;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isSSR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7XHATCIH.js";
|
|
4
4
|
import {
|
|
5
5
|
resumeTracking,
|
|
6
6
|
suspendTracking,
|
|
7
7
|
track
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5Q4R7HCL.js";
|
|
9
9
|
import {
|
|
10
10
|
devAssert
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-NYNYSPK7.js";
|
|
12
12
|
|
|
13
13
|
// src/core/signals/watch.ts
|
|
14
14
|
function watch(getter, callback) {
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bindAttribute,
|
|
3
3
|
setSafeAttribute
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-47M47FOM.js";
|
|
5
5
|
import {
|
|
6
6
|
isEventHandlerAttr,
|
|
7
7
|
sanitizeCSSValue,
|
|
8
8
|
sanitizeStyleAttribute
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import {
|
|
11
|
-
dispose,
|
|
12
|
-
registerDisposer
|
|
13
|
-
} from "./chunk-QKRPLZ2V.js";
|
|
9
|
+
} from "./chunk-2INLLLMZ.js";
|
|
14
10
|
import {
|
|
15
11
|
reactiveBinding
|
|
16
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5Q4R7HCL.js";
|
|
17
13
|
import {
|
|
18
14
|
DEV,
|
|
19
15
|
devWarn,
|
|
20
16
|
devWarnLazy,
|
|
17
|
+
dispose,
|
|
18
|
+
registerDisposer,
|
|
21
19
|
reportError
|
|
22
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-NYNYSPK7.js";
|
|
23
21
|
|
|
24
22
|
// src/core/rendering/focusPreservation.ts
|
|
25
23
|
var IDENTITY_ATTRS = ["data-focus-key", "id", "name"];
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isSSR
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7XHATCIH.js";
|
|
4
4
|
import {
|
|
5
5
|
cleanup,
|
|
6
6
|
retrack,
|
|
7
7
|
untracked
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5Q4R7HCL.js";
|
|
9
9
|
import {
|
|
10
10
|
devAssert,
|
|
11
11
|
reportError
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-NYNYSPK7.js";
|
|
13
13
|
|
|
14
14
|
// src/core/signals/effect.ts
|
|
15
15
|
var _g = globalThis;
|