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
package/dist/widgets.cjs
CHANGED
|
@@ -32,14 +32,6 @@ __export(widgets_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(widgets_exports);
|
|
34
34
|
|
|
35
|
-
// src/core/rendering/createId.ts
|
|
36
|
-
var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
|
|
37
|
-
var _counter = globalThis[COUNTER_KEY] ?? (globalThis[COUNTER_KEY] = { n: 0 });
|
|
38
|
-
function createId(prefix = "sibu") {
|
|
39
|
-
_counter.n++;
|
|
40
|
-
return `${prefix}-${_counter.n}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
35
|
// src/core/dev.ts
|
|
44
36
|
var DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
|
|
45
37
|
// safe default: off in browser, on in test/dev Node
|
|
@@ -56,6 +48,69 @@ function devWarn(message) {
|
|
|
56
48
|
}
|
|
57
49
|
}
|
|
58
50
|
|
|
51
|
+
// src/core/ssr-context.ts
|
|
52
|
+
var SSR_KEY = /* @__PURE__ */ Symbol.for("sibujs.ssr.v1");
|
|
53
|
+
function detectSSRShared() {
|
|
54
|
+
let detected = null;
|
|
55
|
+
try {
|
|
56
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
57
|
+
let mod = null;
|
|
58
|
+
const getBuiltin = process.getBuiltinModule;
|
|
59
|
+
if (typeof getBuiltin === "function") {
|
|
60
|
+
mod = getBuiltin("node:async_hooks");
|
|
61
|
+
} else if (typeof require === "function") {
|
|
62
|
+
mod = require("async_hooks");
|
|
63
|
+
}
|
|
64
|
+
if (mod) detected = new mod.AsyncLocalStorage();
|
|
65
|
+
}
|
|
66
|
+
} catch {
|
|
67
|
+
detected = null;
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
als: detected,
|
|
71
|
+
fallbackStore: { ssr: false, suspenseIdCounter: 0, locale: void 0 },
|
|
72
|
+
fallbackDepth: 0
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
var _shared = globalThis[SSR_KEY] ?? (globalThis[SSR_KEY] = detectSSRShared());
|
|
76
|
+
var als = _shared.als;
|
|
77
|
+
var fallbackStore = _shared.fallbackStore;
|
|
78
|
+
_shared.fallbackDepth ?? (_shared.fallbackDepth = 0);
|
|
79
|
+
function getSSRStore() {
|
|
80
|
+
if (als) {
|
|
81
|
+
const s = als.getStore();
|
|
82
|
+
if (s) return s;
|
|
83
|
+
}
|
|
84
|
+
return fallbackStore;
|
|
85
|
+
}
|
|
86
|
+
function getRequestStore() {
|
|
87
|
+
if (als) return als.getStore() ?? null;
|
|
88
|
+
return _shared.fallbackDepth > 0 ? fallbackStore : null;
|
|
89
|
+
}
|
|
90
|
+
function isSSR() {
|
|
91
|
+
return getSSRStore().ssr;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// src/core/rendering/createId.ts
|
|
95
|
+
var COUNTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.createId.v1");
|
|
96
|
+
var _counter = globalThis[COUNTER_KEY] ?? (globalThis[COUNTER_KEY] = { n: 0 });
|
|
97
|
+
function createId(prefix = "sibu") {
|
|
98
|
+
const request = getRequestStore();
|
|
99
|
+
if (request) {
|
|
100
|
+
request.idCounter = (request.idCounter ?? 0) + 1;
|
|
101
|
+
return `${prefix}-${request.idCounter}`;
|
|
102
|
+
}
|
|
103
|
+
_counter.n++;
|
|
104
|
+
return `${prefix}-${_counter.n}`;
|
|
105
|
+
}
|
|
106
|
+
function idSegment(key) {
|
|
107
|
+
let out = "";
|
|
108
|
+
for (const ch of String(key)) {
|
|
109
|
+
out += /[A-Za-z0-9-]/.test(ch) ? ch : `_${(ch.codePointAt(0) ?? 0).toString(16)}_`;
|
|
110
|
+
}
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
|
|
59
114
|
// src/core/errors.ts
|
|
60
115
|
var ERROR_STATE_KEY = /* @__PURE__ */ Symbol.for("sibujs.runtime-errors.v1");
|
|
61
116
|
function state() {
|
|
@@ -144,6 +199,25 @@ function reportError(error, context) {
|
|
|
144
199
|
});
|
|
145
200
|
}
|
|
146
201
|
|
|
202
|
+
// src/core/rendering/dispose.ts
|
|
203
|
+
function resolveCapture(capture) {
|
|
204
|
+
let frame = capture;
|
|
205
|
+
while (frame?.closed) frame = frame.forwardTo;
|
|
206
|
+
return frame ?? null;
|
|
207
|
+
}
|
|
208
|
+
var registrationCaptures = [];
|
|
209
|
+
function currentDisposerCapture() {
|
|
210
|
+
return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
211
|
+
}
|
|
212
|
+
function beginDisposerCapture(capture) {
|
|
213
|
+
if (capture === null && registrationCaptures.length === 0) return false;
|
|
214
|
+
registrationCaptures.push(resolveCapture(capture));
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
function endDisposerCapture() {
|
|
218
|
+
registrationCaptures.pop();
|
|
219
|
+
}
|
|
220
|
+
|
|
147
221
|
// src/reactivity/track-core.ts
|
|
148
222
|
var POOL_MAX = 4096;
|
|
149
223
|
var nodePool = [];
|
|
@@ -291,8 +365,18 @@ function untracked(fn) {
|
|
|
291
365
|
var subscriberEpochCounter = 0;
|
|
292
366
|
function retrack(effectFn, subscriber) {
|
|
293
367
|
const prev = currentSubscriber;
|
|
368
|
+
let savedDepth = 0;
|
|
369
|
+
let savedSuspendSub = null;
|
|
370
|
+
if (trackingSuspended) {
|
|
371
|
+
savedDepth = suspendDepth;
|
|
372
|
+
savedSuspendSub = suspendSavedSub;
|
|
373
|
+
suspendDepth = 0;
|
|
374
|
+
suspendSavedSub = null;
|
|
375
|
+
trackingSuspended = false;
|
|
376
|
+
}
|
|
294
377
|
currentSubscriber = subscriber;
|
|
295
378
|
const sub = subscriber;
|
|
379
|
+
if (sub._cap === void 0) sub._cap = currentDisposerCapture();
|
|
296
380
|
const epoch = ++subscriberEpochCounter;
|
|
297
381
|
sub._epoch = epoch;
|
|
298
382
|
sub._structDirty = false;
|
|
@@ -305,6 +389,11 @@ function retrack(effectFn, subscriber) {
|
|
|
305
389
|
effectFn();
|
|
306
390
|
} finally {
|
|
307
391
|
currentSubscriber = prev;
|
|
392
|
+
if (savedDepth !== 0) {
|
|
393
|
+
suspendDepth = savedDepth;
|
|
394
|
+
suspendSavedSub = savedSuspendSub;
|
|
395
|
+
trackingSuspended = true;
|
|
396
|
+
}
|
|
308
397
|
let node = sub.depsHead ?? null;
|
|
309
398
|
while (node !== null) {
|
|
310
399
|
const next = node.subNext;
|
|
@@ -324,11 +413,25 @@ function track(effectFn, subscriber) {
|
|
|
324
413
|
if (!subscriber) return reactiveBinding(effectFn);
|
|
325
414
|
cleanup(subscriber);
|
|
326
415
|
const prev = currentSubscriber;
|
|
416
|
+
let savedDepth = 0;
|
|
417
|
+
let savedSuspendSub = null;
|
|
418
|
+
if (trackingSuspended) {
|
|
419
|
+
savedDepth = suspendDepth;
|
|
420
|
+
savedSuspendSub = suspendSavedSub;
|
|
421
|
+
suspendDepth = 0;
|
|
422
|
+
suspendSavedSub = null;
|
|
423
|
+
trackingSuspended = false;
|
|
424
|
+
}
|
|
327
425
|
currentSubscriber = subscriber;
|
|
328
426
|
try {
|
|
329
427
|
effectFn();
|
|
330
428
|
} finally {
|
|
331
429
|
currentSubscriber = prev;
|
|
430
|
+
if (savedDepth !== 0) {
|
|
431
|
+
suspendDepth = savedDepth;
|
|
432
|
+
suspendSavedSub = savedSuspendSub;
|
|
433
|
+
trackingSuspended = true;
|
|
434
|
+
}
|
|
332
435
|
const sub2 = subscriber;
|
|
333
436
|
for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
|
|
334
437
|
const sig = n.sig;
|
|
@@ -465,7 +568,12 @@ function drainQueue() {
|
|
|
465
568
|
quarantined.add(sub);
|
|
466
569
|
continue;
|
|
467
570
|
}
|
|
468
|
-
|
|
571
|
+
const pushed = beginDisposerCapture(sub._cap ?? null);
|
|
572
|
+
try {
|
|
573
|
+
safeInvoke(sub);
|
|
574
|
+
} finally {
|
|
575
|
+
if (pushed) endDisposerCapture();
|
|
576
|
+
}
|
|
469
577
|
}
|
|
470
578
|
}
|
|
471
579
|
function drainNotificationQueue() {
|
|
@@ -499,8 +607,9 @@ function propagateDirty(sub) {
|
|
|
499
607
|
if (s._c) {
|
|
500
608
|
const nSig = s._sig;
|
|
501
609
|
if (nSig) {
|
|
502
|
-
if (!nSig._d) {
|
|
610
|
+
if (!nSig._d || nSig._f === true) {
|
|
503
611
|
nSig._d = true;
|
|
612
|
+
nSig._f = false;
|
|
504
613
|
stack.push(nSig);
|
|
505
614
|
}
|
|
506
615
|
} else {
|
|
@@ -600,7 +709,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
600
709
|
}
|
|
601
710
|
|
|
602
711
|
// src/reactivity/track.ts
|
|
603
|
-
var _runtimeVersion = true ? "4.
|
|
712
|
+
var _runtimeVersion = true ? "4.6.0" : "dev";
|
|
604
713
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
605
714
|
function resolveReactiveApi() {
|
|
606
715
|
const g = globalThis;
|
|
@@ -664,10 +773,14 @@ function derived(getter, options) {
|
|
|
664
773
|
const cs = {};
|
|
665
774
|
cs._d = false;
|
|
666
775
|
cs._init = false;
|
|
776
|
+
cs._f = false;
|
|
667
777
|
cs._g = getter;
|
|
668
778
|
cs.__v = 0;
|
|
779
|
+
let evaluating = false;
|
|
780
|
+
let disposed = false;
|
|
781
|
+
let pendingError;
|
|
669
782
|
const markDirty = () => {
|
|
670
|
-
if (cs._d) return;
|
|
783
|
+
if (cs._d || disposed) return;
|
|
671
784
|
cs._d = true;
|
|
672
785
|
};
|
|
673
786
|
markDirty._c = 1;
|
|
@@ -690,33 +803,53 @@ function derived(getter, options) {
|
|
|
690
803
|
}
|
|
691
804
|
}, markDirty);
|
|
692
805
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
693
|
-
let evaluating = false;
|
|
694
806
|
const validate = () => {
|
|
695
|
-
if (!cs._d) return;
|
|
807
|
+
if (!cs._d || disposed || pendingError !== void 0) return;
|
|
696
808
|
const oldValue = cs._v;
|
|
697
809
|
evaluating = true;
|
|
698
810
|
try {
|
|
699
811
|
retrack2(recompute, markDirty);
|
|
700
812
|
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
813
|
+
} catch (err) {
|
|
814
|
+
pendingError = { error: err };
|
|
815
|
+
cs.__v++;
|
|
816
|
+
if (disposed) cs._d = true;
|
|
817
|
+
else cs._f = true;
|
|
701
818
|
} finally {
|
|
702
819
|
evaluating = false;
|
|
820
|
+
if (disposed) cleanup2(markDirty);
|
|
703
821
|
}
|
|
704
|
-
if (hook && !Object.is(oldValue, cs._v)) {
|
|
822
|
+
if (hook && !disposed && !Object.is(oldValue, cs._v)) {
|
|
705
823
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
706
824
|
}
|
|
707
825
|
};
|
|
708
826
|
cs._validate = validate;
|
|
827
|
+
const throwPending = () => {
|
|
828
|
+
const { error } = pendingError;
|
|
829
|
+
pendingError = void 0;
|
|
830
|
+
if (disposed) cs._d = false;
|
|
831
|
+
throw error;
|
|
832
|
+
};
|
|
709
833
|
function computedGetter() {
|
|
710
834
|
if (evaluating) {
|
|
711
835
|
throw new Error(
|
|
712
836
|
`[SibuJS] Circular dependency detected in derived${debugName ? ` "${debugName}"` : ""}. A derived signal cannot read itself (directly or through a chain).`
|
|
713
837
|
);
|
|
714
838
|
}
|
|
715
|
-
if (isTrackingSuspended2()) {
|
|
716
|
-
if (cs._d)
|
|
839
|
+
if (isTrackingSuspended2() || disposed) {
|
|
840
|
+
if (cs._d) {
|
|
841
|
+
validate();
|
|
842
|
+
if (pendingError !== void 0) throwPending();
|
|
843
|
+
}
|
|
717
844
|
return cs._v;
|
|
718
845
|
}
|
|
719
|
-
if (cs._d)
|
|
846
|
+
if (cs._d) {
|
|
847
|
+
validate();
|
|
848
|
+
if (pendingError !== void 0) {
|
|
849
|
+
recordDependency2(cs);
|
|
850
|
+
throwPending();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
720
853
|
recordDependency2(cs);
|
|
721
854
|
return cs._v;
|
|
722
855
|
}
|
|
@@ -725,171 +858,21 @@ function derived(getter, options) {
|
|
|
725
858
|
cs.__name = debugName;
|
|
726
859
|
}
|
|
727
860
|
computedGetter.__signal = cs;
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
let mod = null;
|
|
739
|
-
const getBuiltin = process.getBuiltinModule;
|
|
740
|
-
if (typeof getBuiltin === "function") {
|
|
741
|
-
mod = getBuiltin("node:async_hooks");
|
|
742
|
-
} else if (typeof require === "function") {
|
|
743
|
-
mod = require("async_hooks");
|
|
861
|
+
computedGetter.dispose = () => {
|
|
862
|
+
if (disposed) return;
|
|
863
|
+
disposed = true;
|
|
864
|
+
cs._d = pendingError !== void 0;
|
|
865
|
+
cleanup2(markDirty);
|
|
866
|
+
const h = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
867
|
+
if (h) {
|
|
868
|
+
try {
|
|
869
|
+
h.emit("computed:destroy", { signal: cs, getter: computedGetter });
|
|
870
|
+
} catch {
|
|
744
871
|
}
|
|
745
|
-
if (mod) detected = new mod.AsyncLocalStorage();
|
|
746
872
|
}
|
|
747
|
-
} catch {
|
|
748
|
-
detected = null;
|
|
749
|
-
}
|
|
750
|
-
return {
|
|
751
|
-
als: detected,
|
|
752
|
-
fallbackStore: { ssr: false, suspenseIdCounter: 0, locale: void 0 },
|
|
753
|
-
fallbackDepth: 0
|
|
754
|
-
};
|
|
755
|
-
}
|
|
756
|
-
var _shared = globalThis[SSR_KEY] ?? (globalThis[SSR_KEY] = detectSSRShared());
|
|
757
|
-
var als = _shared.als;
|
|
758
|
-
var fallbackStore = _shared.fallbackStore;
|
|
759
|
-
_shared.fallbackDepth ?? (_shared.fallbackDepth = 0);
|
|
760
|
-
function getSSRStore() {
|
|
761
|
-
if (als) {
|
|
762
|
-
const s = als.getStore();
|
|
763
|
-
if (s) return s;
|
|
764
|
-
}
|
|
765
|
-
return fallbackStore;
|
|
766
|
-
}
|
|
767
|
-
function isSSR() {
|
|
768
|
-
return getSSRStore().ssr;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// src/core/signals/effect.ts
|
|
772
|
-
var _g = globalThis;
|
|
773
|
-
var MAX_RERUNS = 100;
|
|
774
|
-
function flushUserCleanups(ctx) {
|
|
775
|
-
const list = ctx.userCleanups;
|
|
776
|
-
if (list.length === 0) return;
|
|
777
|
-
ctx.userCleanups = [];
|
|
778
|
-
for (let i = list.length - 1; i >= 0; i--) {
|
|
779
|
-
try {
|
|
780
|
-
list[i]();
|
|
781
|
-
} catch (err) {
|
|
782
|
-
reportError(err, { phase: "cleanup" });
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
function drainReruns(ctx) {
|
|
787
|
-
let reruns = 1;
|
|
788
|
-
do {
|
|
789
|
-
ctx.rerunPending = false;
|
|
790
|
-
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
791
|
-
retrack2(ctx.bodyFn, ctx.subscriber);
|
|
792
|
-
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
793
|
-
if (ctx.rerunPending) {
|
|
794
|
-
ctx.rerunPending = false;
|
|
795
|
-
reportError(
|
|
796
|
-
new Error(
|
|
797
|
-
`effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
798
|
-
),
|
|
799
|
-
{ phase: "effect" }
|
|
800
|
-
);
|
|
801
|
-
}
|
|
802
|
-
}
|
|
803
|
-
function disposeEffect(ctx) {
|
|
804
|
-
if (ctx.disposed) return;
|
|
805
|
-
ctx.disposed = true;
|
|
806
|
-
const h = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
807
|
-
if (h) {
|
|
808
|
-
try {
|
|
809
|
-
h.emit("effect:destroy", { effectFn: ctx.fn });
|
|
810
|
-
} catch {
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
try {
|
|
814
|
-
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
815
|
-
} catch (err) {
|
|
816
|
-
if (typeof console !== "undefined") {
|
|
817
|
-
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
try {
|
|
821
|
-
cleanup2(ctx.subscriber);
|
|
822
|
-
} catch (err) {
|
|
823
|
-
if (typeof console !== "undefined") {
|
|
824
|
-
console.warn("[SibuJS effect] dispose threw:", err);
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
function effect(effectFn, options) {
|
|
829
|
-
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
830
|
-
if (isSSR()) return () => {
|
|
831
|
-
};
|
|
832
|
-
const ctx = {
|
|
833
|
-
fn: effectFn,
|
|
834
|
-
onError: options?.onError,
|
|
835
|
-
userCleanups: [],
|
|
836
|
-
running: false,
|
|
837
|
-
rerunPending: false,
|
|
838
|
-
disposed: false,
|
|
839
|
-
onCleanup: null,
|
|
840
|
-
subscriber: null,
|
|
841
|
-
bodyFn: null
|
|
842
|
-
};
|
|
843
|
-
ctx.onCleanup = (fn) => {
|
|
844
|
-
ctx.userCleanups.push(fn);
|
|
845
|
-
};
|
|
846
|
-
const onErrorCaptured = ctx.onError;
|
|
847
|
-
ctx.bodyFn = onErrorCaptured ? () => {
|
|
848
|
-
try {
|
|
849
|
-
ctx.fn(ctx.onCleanup);
|
|
850
|
-
} catch (err) {
|
|
851
|
-
onErrorCaptured(err);
|
|
852
|
-
}
|
|
853
|
-
} : () => {
|
|
854
|
-
ctx.fn(ctx.onCleanup);
|
|
855
873
|
};
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
if (ctx.running) {
|
|
859
|
-
ctx.rerunPending = true;
|
|
860
|
-
return;
|
|
861
|
-
}
|
|
862
|
-
ctx.running = true;
|
|
863
|
-
try {
|
|
864
|
-
ctx.rerunPending = false;
|
|
865
|
-
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
866
|
-
retrack2(ctx.bodyFn, sub);
|
|
867
|
-
if (ctx.rerunPending) drainReruns(ctx);
|
|
868
|
-
} finally {
|
|
869
|
-
ctx.running = false;
|
|
870
|
-
ctx.rerunPending = false;
|
|
871
|
-
}
|
|
872
|
-
});
|
|
873
|
-
sub.depsHead = null;
|
|
874
|
-
sub.depsTail = null;
|
|
875
|
-
sub._epoch = 0;
|
|
876
|
-
sub._structDirty = false;
|
|
877
|
-
sub._hasComputedDep = false;
|
|
878
|
-
sub._errorPhase = "effect";
|
|
879
|
-
sub._runEpoch = 0;
|
|
880
|
-
sub._runs = 0;
|
|
881
|
-
ctx.subscriber = sub;
|
|
882
|
-
ctx.running = true;
|
|
883
|
-
try {
|
|
884
|
-
retrack2(ctx.bodyFn, ctx.subscriber);
|
|
885
|
-
if (ctx.rerunPending) drainReruns(ctx);
|
|
886
|
-
} finally {
|
|
887
|
-
ctx.running = false;
|
|
888
|
-
ctx.rerunPending = false;
|
|
889
|
-
}
|
|
890
|
-
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
891
|
-
if (hook) hook.emit("effect:create", { effectFn });
|
|
892
|
-
return () => disposeEffect(ctx);
|
|
874
|
+
if (hook) hook.emit("computed:create", { signal: cs, name: debugName, getter: computedGetter });
|
|
875
|
+
return computedGetter;
|
|
893
876
|
}
|
|
894
877
|
|
|
895
878
|
// src/reactivity/batch.ts
|
|
@@ -943,7 +926,7 @@ var enqueueBatchedSignal = API2.enqueueBatchedSignal;
|
|
|
943
926
|
var isBatching = API2.isBatching;
|
|
944
927
|
|
|
945
928
|
// src/core/signals/signal.ts
|
|
946
|
-
var
|
|
929
|
+
var _g = globalThis;
|
|
947
930
|
function signal(initial, options) {
|
|
948
931
|
const state2 = {
|
|
949
932
|
value: initial,
|
|
@@ -974,7 +957,7 @@ function signal(initial, options) {
|
|
|
974
957
|
state2.value = newValue;
|
|
975
958
|
state2.__v++;
|
|
976
959
|
if (DEV) {
|
|
977
|
-
const hook =
|
|
960
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
978
961
|
if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
979
962
|
}
|
|
980
963
|
if (!enqueueBatchedSignal(state2)) {
|
|
@@ -988,7 +971,7 @@ function signal(initial, options) {
|
|
|
988
971
|
if (Object.is(newValue, prev)) return;
|
|
989
972
|
state2.value = newValue;
|
|
990
973
|
state2.__v++;
|
|
991
|
-
const hook =
|
|
974
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
992
975
|
if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
993
976
|
if (!enqueueBatchedSignal(state2)) {
|
|
994
977
|
notifySubscribers2(state2);
|
|
@@ -1007,7 +990,7 @@ function signal(initial, options) {
|
|
|
1007
990
|
};
|
|
1008
991
|
}
|
|
1009
992
|
if (DEV) {
|
|
1010
|
-
const hook =
|
|
993
|
+
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1011
994
|
if (hook) hook.emit("signal:create", { signal: state2, name: debugName, getter: get, initial });
|
|
1012
995
|
}
|
|
1013
996
|
return [get, set];
|
|
@@ -1043,6 +1026,13 @@ function watch(getter, callback) {
|
|
|
1043
1026
|
return teardown;
|
|
1044
1027
|
}
|
|
1045
1028
|
|
|
1029
|
+
// src/reactivity/domBinding.ts
|
|
1030
|
+
function domBinding(commit, ownerNode) {
|
|
1031
|
+
if (isSSR()) return () => {
|
|
1032
|
+
};
|
|
1033
|
+
return reactiveBinding2(commit, ownerNode);
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1046
1036
|
// src/widgets/Combobox.ts
|
|
1047
1037
|
var boundComboboxes = /* @__PURE__ */ new WeakMap();
|
|
1048
1038
|
function combobox(options) {
|
|
@@ -1116,7 +1106,7 @@ function combobox(options) {
|
|
|
1116
1106
|
els.input.setAttribute("role", "combobox");
|
|
1117
1107
|
els.input.setAttribute("aria-autocomplete", "list");
|
|
1118
1108
|
els.input.setAttribute("aria-controls", listboxId);
|
|
1119
|
-
const fxTeardown =
|
|
1109
|
+
const fxTeardown = domBinding(() => {
|
|
1120
1110
|
const open2 = isOpen();
|
|
1121
1111
|
els.input.setAttribute("aria-expanded", open2 ? "true" : "false");
|
|
1122
1112
|
els.listbox.hidden = !open2;
|
|
@@ -1134,7 +1124,7 @@ function combobox(options) {
|
|
|
1134
1124
|
}
|
|
1135
1125
|
if (activeId) els.input.setAttribute("aria-activedescendant", activeId);
|
|
1136
1126
|
else els.input.removeAttribute("aria-activedescendant");
|
|
1137
|
-
});
|
|
1127
|
+
}, els.input);
|
|
1138
1128
|
const onInput = () => {
|
|
1139
1129
|
setQuery(els.input.value);
|
|
1140
1130
|
open();
|
|
@@ -1182,8 +1172,11 @@ function combobox(options) {
|
|
|
1182
1172
|
els.input.addEventListener("focus", onFocus);
|
|
1183
1173
|
els.input.addEventListener("blur", onBlur);
|
|
1184
1174
|
els.listbox.addEventListener("mousedown", onListboxPointerDown);
|
|
1175
|
+
let tornDown = false;
|
|
1185
1176
|
const teardown = () => {
|
|
1186
|
-
|
|
1177
|
+
if (tornDown) return;
|
|
1178
|
+
tornDown = true;
|
|
1179
|
+
if (boundComboboxes.get(els.input) === teardown) boundComboboxes.delete(els.input);
|
|
1187
1180
|
fxTeardown();
|
|
1188
1181
|
els.input.removeEventListener("input", onInput);
|
|
1189
1182
|
els.input.removeEventListener("keydown", onKey);
|
|
@@ -1228,11 +1221,23 @@ function combobox(options) {
|
|
|
1228
1221
|
};
|
|
1229
1222
|
}
|
|
1230
1223
|
|
|
1224
|
+
// src/widgets/attributeSnapshot.ts
|
|
1225
|
+
function snapshotAttributes(el, names) {
|
|
1226
|
+
const previous = names.map((name) => [name, el.getAttribute(name)]);
|
|
1227
|
+
return () => {
|
|
1228
|
+
for (const [name, value] of previous) {
|
|
1229
|
+
if (value === null) el.removeAttribute(name);
|
|
1230
|
+
else el.setAttribute(name, value);
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1231
1235
|
// src/widgets/Tabs.ts
|
|
1232
1236
|
var boundTablists = /* @__PURE__ */ new WeakMap();
|
|
1233
1237
|
function tabs(options) {
|
|
1234
1238
|
const { tabs: tabDefs, defaultTab } = options;
|
|
1235
|
-
const
|
|
1239
|
+
const firstEnabled = tabDefs.find((t) => !t.disabled)?.id ?? "";
|
|
1240
|
+
const initialTab = defaultTab !== void 0 && tabDefs.some((t) => t.id === defaultTab && !t.disabled) ? defaultTab : firstEnabled;
|
|
1236
1241
|
const [activeTab, setActiveTabState] = signal(initialTab);
|
|
1237
1242
|
function setActiveTab(id) {
|
|
1238
1243
|
const tab = tabDefs.find((t) => t.id === id);
|
|
@@ -1279,58 +1284,29 @@ function tabs(options) {
|
|
|
1279
1284
|
function bind(els) {
|
|
1280
1285
|
const existing = boundTablists.get(els.tablist);
|
|
1281
1286
|
if (existing) return existing;
|
|
1282
|
-
const restore = [];
|
|
1283
|
-
const prevTablistRole = els.tablist.getAttribute("role");
|
|
1287
|
+
const restore = [snapshotAttributes(els.tablist, ["role"])];
|
|
1284
1288
|
els.tablist.setAttribute("role", "tablist");
|
|
1285
|
-
|
|
1286
|
-
if (prevTablistRole === null) els.tablist.removeAttribute("role");
|
|
1287
|
-
else els.tablist.setAttribute("role", prevTablistRole);
|
|
1288
|
-
});
|
|
1289
|
+
const idPrefix = createId("sibu-tabs");
|
|
1289
1290
|
for (const def of tabDefs) {
|
|
1290
1291
|
const tabEl = els.tabs[def.id];
|
|
1291
1292
|
if (!tabEl) continue;
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
const prevControls = tabEl.getAttribute("aria-controls");
|
|
1293
|
+
restore.push(
|
|
1294
|
+
snapshotAttributes(tabEl, ["role", "id", "aria-disabled", "aria-controls", "aria-selected", "tabindex"])
|
|
1295
|
+
);
|
|
1296
1296
|
tabEl.setAttribute("role", "tab");
|
|
1297
|
-
tabEl.
|
|
1297
|
+
if (!tabEl.id) tabEl.id = `${idPrefix}-tab-${idSegment(def.id)}`;
|
|
1298
1298
|
if (def.disabled) tabEl.setAttribute("aria-disabled", "true");
|
|
1299
|
+
else tabEl.removeAttribute("aria-disabled");
|
|
1299
1300
|
const panelEl = els.panels?.[def.id];
|
|
1300
|
-
let prevPanelRole = null;
|
|
1301
|
-
let prevPanelId = "";
|
|
1302
|
-
let prevPanelLabelledBy = null;
|
|
1303
1301
|
if (panelEl) {
|
|
1304
|
-
|
|
1305
|
-
prevPanelId = panelEl.id;
|
|
1306
|
-
prevPanelLabelledBy = panelEl.getAttribute("aria-labelledby");
|
|
1302
|
+
restore.push(snapshotAttributes(panelEl, ["role", "id", "aria-labelledby", "hidden"]));
|
|
1307
1303
|
panelEl.setAttribute("role", "tabpanel");
|
|
1308
|
-
panelEl.
|
|
1309
|
-
panelEl.setAttribute("aria-labelledby",
|
|
1310
|
-
tabEl.setAttribute("aria-controls",
|
|
1304
|
+
if (!panelEl.id) panelEl.id = `${idPrefix}-panel-${idSegment(def.id)}`;
|
|
1305
|
+
panelEl.setAttribute("aria-labelledby", tabEl.id);
|
|
1306
|
+
tabEl.setAttribute("aria-controls", panelEl.id);
|
|
1311
1307
|
}
|
|
1312
|
-
restore.push(() => {
|
|
1313
|
-
if (prevRole === null) tabEl.removeAttribute("role");
|
|
1314
|
-
else tabEl.setAttribute("role", prevRole);
|
|
1315
|
-
if (prevId === "") tabEl.removeAttribute("id");
|
|
1316
|
-
else tabEl.id = prevId;
|
|
1317
|
-
if (prevDisabled === null) tabEl.removeAttribute("aria-disabled");
|
|
1318
|
-
else tabEl.setAttribute("aria-disabled", prevDisabled);
|
|
1319
|
-
if (prevControls === null) tabEl.removeAttribute("aria-controls");
|
|
1320
|
-
else tabEl.setAttribute("aria-controls", prevControls);
|
|
1321
|
-
tabEl.removeAttribute("aria-selected");
|
|
1322
|
-
tabEl.removeAttribute("tabindex");
|
|
1323
|
-
if (panelEl) {
|
|
1324
|
-
if (prevPanelRole === null) panelEl.removeAttribute("role");
|
|
1325
|
-
else panelEl.setAttribute("role", prevPanelRole);
|
|
1326
|
-
if (prevPanelId === "") panelEl.removeAttribute("id");
|
|
1327
|
-
else panelEl.id = prevPanelId;
|
|
1328
|
-
if (prevPanelLabelledBy === null) panelEl.removeAttribute("aria-labelledby");
|
|
1329
|
-
else panelEl.setAttribute("aria-labelledby", prevPanelLabelledBy);
|
|
1330
|
-
}
|
|
1331
|
-
});
|
|
1332
1308
|
}
|
|
1333
|
-
const fxTeardown =
|
|
1309
|
+
const fxTeardown = domBinding(() => {
|
|
1334
1310
|
const active = activeTab();
|
|
1335
1311
|
for (const def of tabDefs) {
|
|
1336
1312
|
const tabEl = els.tabs[def.id];
|
|
@@ -1341,7 +1317,7 @@ function tabs(options) {
|
|
|
1341
1317
|
const panelEl = els.panels?.[def.id];
|
|
1342
1318
|
if (panelEl) panelEl.hidden = !isAct;
|
|
1343
1319
|
}
|
|
1344
|
-
});
|
|
1320
|
+
}, els.tablist);
|
|
1345
1321
|
const onKey = (e) => {
|
|
1346
1322
|
if (e.key === "ArrowRight" || e.key === "ArrowDown") {
|
|
1347
1323
|
e.preventDefault();
|
|
@@ -1378,7 +1354,10 @@ function tabs(options) {
|
|
|
1378
1354
|
tabEl.addEventListener("click", fn);
|
|
1379
1355
|
clickHandlers.push({ el: tabEl, fn });
|
|
1380
1356
|
}
|
|
1357
|
+
let tornDown = false;
|
|
1381
1358
|
const teardown = () => {
|
|
1359
|
+
if (tornDown) return;
|
|
1360
|
+
tornDown = true;
|
|
1382
1361
|
boundTablists.delete(els.tablist);
|
|
1383
1362
|
fxTeardown();
|
|
1384
1363
|
els.tablist.removeEventListener("keydown", onKey);
|
|
@@ -1404,7 +1383,10 @@ function tabs(options) {
|
|
|
1404
1383
|
var boundAccordions = /* @__PURE__ */ new WeakMap();
|
|
1405
1384
|
function accordion(options) {
|
|
1406
1385
|
const { items: itemDefs, multiple = false, defaultExpanded = [] } = options;
|
|
1407
|
-
const
|
|
1386
|
+
const knownIds = new Set(itemDefs.map((item) => item.id));
|
|
1387
|
+
const validDefaults = defaultExpanded.filter((id) => knownIds.has(id));
|
|
1388
|
+
const initialExpanded = multiple ? validDefaults : validDefaults.slice(0, 1);
|
|
1389
|
+
const [expandedIds, setExpandedIds] = signal(new Set(initialExpanded));
|
|
1408
1390
|
const items = derived(
|
|
1409
1391
|
() => itemDefs.map((item) => ({
|
|
1410
1392
|
...item,
|
|
@@ -1455,42 +1437,22 @@ function accordion(options) {
|
|
|
1455
1437
|
if (existing) return existing;
|
|
1456
1438
|
}
|
|
1457
1439
|
const restore = [];
|
|
1440
|
+
const idPrefix = createId("sibu-accordion");
|
|
1458
1441
|
for (const item of itemDefs) {
|
|
1459
1442
|
const trig = els.triggers[item.id];
|
|
1460
1443
|
const panel = els.panels[item.id];
|
|
1461
1444
|
if (!trig) continue;
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
trig.id = `sibu-accordion-trigger-${item.id}`;
|
|
1465
|
-
let prevPanelRole = null;
|
|
1466
|
-
let prevPanelId = "";
|
|
1467
|
-
let prevPanelLabelledBy = null;
|
|
1445
|
+
restore.push(snapshotAttributes(trig, ["id", "aria-controls", "aria-expanded"]));
|
|
1446
|
+
if (!trig.id) trig.id = `${idPrefix}-trigger-${idSegment(item.id)}`;
|
|
1468
1447
|
if (panel) {
|
|
1469
|
-
|
|
1470
|
-
prevPanelId = panel.id;
|
|
1471
|
-
prevPanelLabelledBy = panel.getAttribute("aria-labelledby");
|
|
1448
|
+
restore.push(snapshotAttributes(panel, ["role", "id", "aria-labelledby", "hidden"]));
|
|
1472
1449
|
panel.setAttribute("role", "region");
|
|
1473
|
-
panel.id =
|
|
1450
|
+
if (!panel.id) panel.id = `${idPrefix}-panel-${idSegment(item.id)}`;
|
|
1474
1451
|
panel.setAttribute("aria-labelledby", trig.id);
|
|
1475
1452
|
trig.setAttribute("aria-controls", panel.id);
|
|
1476
1453
|
}
|
|
1477
|
-
restore.push(() => {
|
|
1478
|
-
if (prevTrigId === "") trig.removeAttribute("id");
|
|
1479
|
-
else trig.id = prevTrigId;
|
|
1480
|
-
if (prevTrigControls === null) trig.removeAttribute("aria-controls");
|
|
1481
|
-
else trig.setAttribute("aria-controls", prevTrigControls);
|
|
1482
|
-
trig.removeAttribute("aria-expanded");
|
|
1483
|
-
if (panel) {
|
|
1484
|
-
if (prevPanelRole === null) panel.removeAttribute("role");
|
|
1485
|
-
else panel.setAttribute("role", prevPanelRole);
|
|
1486
|
-
if (prevPanelId === "") panel.removeAttribute("id");
|
|
1487
|
-
else panel.id = prevPanelId;
|
|
1488
|
-
if (prevPanelLabelledBy === null) panel.removeAttribute("aria-labelledby");
|
|
1489
|
-
else panel.setAttribute("aria-labelledby", prevPanelLabelledBy);
|
|
1490
|
-
}
|
|
1491
|
-
});
|
|
1492
1454
|
}
|
|
1493
|
-
const fxTeardown =
|
|
1455
|
+
const fxTeardown = domBinding(() => {
|
|
1494
1456
|
const ids = expandedIds();
|
|
1495
1457
|
for (const item of itemDefs) {
|
|
1496
1458
|
const trig = els.triggers[item.id];
|
|
@@ -1500,7 +1462,7 @@ function accordion(options) {
|
|
|
1500
1462
|
trig.setAttribute("aria-expanded", expanded ? "true" : "false");
|
|
1501
1463
|
if (panel) panel.hidden = !expanded;
|
|
1502
1464
|
}
|
|
1503
|
-
});
|
|
1465
|
+
}, idempotencyKey);
|
|
1504
1466
|
const handlers = [];
|
|
1505
1467
|
for (const item of itemDefs) {
|
|
1506
1468
|
const trig = els.triggers[item.id];
|
|
@@ -1516,7 +1478,10 @@ function accordion(options) {
|
|
|
1516
1478
|
trig.addEventListener("keydown", key);
|
|
1517
1479
|
handlers.push({ el: trig, click, key });
|
|
1518
1480
|
}
|
|
1481
|
+
let tornDown = false;
|
|
1519
1482
|
const teardown = () => {
|
|
1483
|
+
if (tornDown) return;
|
|
1484
|
+
tornDown = true;
|
|
1520
1485
|
if (idempotencyKey) boundAccordions.delete(idempotencyKey);
|
|
1521
1486
|
fxTeardown();
|
|
1522
1487
|
for (const { el, click, key } of handlers) {
|
|
@@ -1575,11 +1540,11 @@ function popover() {
|
|
|
1575
1540
|
}
|
|
1576
1541
|
els.popover.setAttribute("aria-labelledby", els.labelledBy.id);
|
|
1577
1542
|
}
|
|
1578
|
-
const fxTeardown =
|
|
1543
|
+
const fxTeardown = domBinding(() => {
|
|
1579
1544
|
const open2 = isOpen();
|
|
1580
1545
|
els.trigger.setAttribute("aria-expanded", open2 ? "true" : "false");
|
|
1581
1546
|
els.popover.hidden = !open2;
|
|
1582
|
-
});
|
|
1547
|
+
}, els.trigger);
|
|
1583
1548
|
const onTriggerClick = (e) => {
|
|
1584
1549
|
e.preventDefault();
|
|
1585
1550
|
toggle();
|
|
@@ -1602,8 +1567,11 @@ function popover() {
|
|
|
1602
1567
|
els.popover.addEventListener("keydown", onKey);
|
|
1603
1568
|
els.trigger.addEventListener("keydown", onKey);
|
|
1604
1569
|
document.addEventListener("pointerdown", onDocPointer);
|
|
1570
|
+
let tornDown = false;
|
|
1605
1571
|
const teardown = () => {
|
|
1606
|
-
|
|
1572
|
+
if (tornDown) return;
|
|
1573
|
+
tornDown = true;
|
|
1574
|
+
if (boundPopovers.get(els.trigger) === teardown) boundPopovers.delete(els.trigger);
|
|
1607
1575
|
fxTeardown();
|
|
1608
1576
|
els.trigger.removeEventListener("click", onTriggerClick);
|
|
1609
1577
|
els.popover.removeEventListener("keydown", onKey);
|
|
@@ -1721,7 +1689,7 @@ function select(options) {
|
|
|
1721
1689
|
els.listbox.setAttribute("aria-multiselectable", multiple ? "true" : "false");
|
|
1722
1690
|
if (els.listbox.tabIndex < 0) els.listbox.tabIndex = 0;
|
|
1723
1691
|
const toStr = els.itemToString ?? itemToString ?? ((it) => String(it));
|
|
1724
|
-
const fxTeardown =
|
|
1692
|
+
const fxTeardown = domBinding(() => {
|
|
1725
1693
|
const idx = highlightedIndex();
|
|
1726
1694
|
const sel = selectedItems();
|
|
1727
1695
|
let activeId = "";
|
|
@@ -1731,13 +1699,14 @@ function select(options) {
|
|
|
1731
1699
|
if (!optEl.id) optEl.id = `${listboxId}-opt-${i}`;
|
|
1732
1700
|
optEl.setAttribute("role", "option");
|
|
1733
1701
|
optEl.setAttribute("aria-selected", sel.includes(items[i]) ? "true" : "false");
|
|
1734
|
-
|
|
1702
|
+
const disabled = isItemDisabled(items[i]);
|
|
1703
|
+
if (disabled) optEl.setAttribute("aria-disabled", "true");
|
|
1735
1704
|
else optEl.removeAttribute("aria-disabled");
|
|
1736
|
-
if (i === idx) activeId = optEl.id;
|
|
1705
|
+
if (i === idx && !disabled) activeId = optEl.id;
|
|
1737
1706
|
}
|
|
1738
1707
|
if (activeId) els.listbox.setAttribute("aria-activedescendant", activeId);
|
|
1739
1708
|
else els.listbox.removeAttribute("aria-activedescendant");
|
|
1740
|
-
});
|
|
1709
|
+
}, els.listbox);
|
|
1741
1710
|
let typeBuffer = "";
|
|
1742
1711
|
let typeTimer = null;
|
|
1743
1712
|
const onKey = (e) => {
|
|
@@ -1749,10 +1718,12 @@ function select(options) {
|
|
|
1749
1718
|
highlightPrev();
|
|
1750
1719
|
} else if (e.key === "Home") {
|
|
1751
1720
|
e.preventDefault();
|
|
1752
|
-
|
|
1721
|
+
const first = nextEnabled(-1, 1);
|
|
1722
|
+
if (first !== -1) setHighlightedIndex(first);
|
|
1753
1723
|
} else if (e.key === "End") {
|
|
1754
1724
|
e.preventDefault();
|
|
1755
|
-
|
|
1725
|
+
const last = nextEnabled(items.length, -1);
|
|
1726
|
+
if (last !== -1) setHighlightedIndex(last);
|
|
1756
1727
|
} else if (e.key === "Enter" || e.key === " ") {
|
|
1757
1728
|
if (highlightedIndex() >= 0) {
|
|
1758
1729
|
e.preventDefault();
|
|
@@ -1770,8 +1741,11 @@ function select(options) {
|
|
|
1770
1741
|
}
|
|
1771
1742
|
};
|
|
1772
1743
|
els.listbox.addEventListener("keydown", onKey);
|
|
1744
|
+
let tornDown = false;
|
|
1773
1745
|
const teardown = () => {
|
|
1774
|
-
|
|
1746
|
+
if (tornDown) return;
|
|
1747
|
+
tornDown = true;
|
|
1748
|
+
if (boundSelects.get(els.listbox) === teardown) boundSelects.delete(els.listbox);
|
|
1775
1749
|
fxTeardown();
|
|
1776
1750
|
els.listbox.removeEventListener("keydown", onKey);
|
|
1777
1751
|
if (typeTimer !== null) clearTimeout(typeTimer);
|
|
@@ -1857,9 +1831,9 @@ function tooltip(options) {
|
|
|
1857
1831
|
els.tooltip.id = id;
|
|
1858
1832
|
const prevDescribedBy = els.trigger.getAttribute("aria-describedby");
|
|
1859
1833
|
els.trigger.setAttribute("aria-describedby", prevDescribedBy ? `${prevDescribedBy} ${id}` : id);
|
|
1860
|
-
const fxTeardown =
|
|
1834
|
+
const fxTeardown = domBinding(() => {
|
|
1861
1835
|
els.tooltip.hidden = !isVisible();
|
|
1862
|
-
});
|
|
1836
|
+
}, els.trigger);
|
|
1863
1837
|
const onTriggerEnter = () => show();
|
|
1864
1838
|
const onTriggerLeave = () => scheduleHide();
|
|
1865
1839
|
const onTooltipEnter = () => {
|
|
@@ -1884,8 +1858,11 @@ function tooltip(options) {
|
|
|
1884
1858
|
els.trigger.addEventListener("keydown", onKey);
|
|
1885
1859
|
els.tooltip.addEventListener("pointerenter", onTooltipEnter);
|
|
1886
1860
|
els.tooltip.addEventListener("pointerleave", onTooltipLeave);
|
|
1861
|
+
let tornDown = false;
|
|
1887
1862
|
const teardown = () => {
|
|
1888
|
-
|
|
1863
|
+
if (tornDown) return;
|
|
1864
|
+
tornDown = true;
|
|
1865
|
+
if (boundTriggers.get(els.trigger) === teardown) boundTriggers.delete(els.trigger);
|
|
1889
1866
|
fxTeardown();
|
|
1890
1867
|
els.trigger.removeEventListener("pointerenter", onTriggerEnter);
|
|
1891
1868
|
els.trigger.removeEventListener("pointerleave", onTriggerLeave);
|
|
@@ -1923,7 +1900,8 @@ function fileUpload(options) {
|
|
|
1923
1900
|
const [isDragOver, setDragOver] = signal(false);
|
|
1924
1901
|
function isAccepted(file) {
|
|
1925
1902
|
if (!accept) return true;
|
|
1926
|
-
const acceptedTypes = accept.split(",").map((t) => t.trim().toLowerCase());
|
|
1903
|
+
const acceptedTypes = accept.split(",").map((t) => t.trim().toLowerCase()).filter((t) => t.length > 0);
|
|
1904
|
+
if (acceptedTypes.length === 0) return true;
|
|
1927
1905
|
const fileName = file.name.toLowerCase();
|
|
1928
1906
|
const fileType = file.type.toLowerCase();
|
|
1929
1907
|
return acceptedTypes.some((pattern) => {
|
|
@@ -1952,16 +1930,17 @@ function fileUpload(options) {
|
|
|
1952
1930
|
}
|
|
1953
1931
|
validFiles.push(file);
|
|
1954
1932
|
}
|
|
1933
|
+
const committed = multiple ? validFiles : validFiles.slice(-1);
|
|
1955
1934
|
batch(() => {
|
|
1956
1935
|
setErrors(newErrors);
|
|
1957
|
-
if (
|
|
1936
|
+
if (committed.length > 0) {
|
|
1958
1937
|
if (multiple) {
|
|
1959
|
-
setFiles((prev) => [...prev, ...
|
|
1938
|
+
setFiles((prev) => [...prev, ...committed]);
|
|
1960
1939
|
} else {
|
|
1961
|
-
setFiles(
|
|
1940
|
+
setFiles(committed);
|
|
1962
1941
|
}
|
|
1963
1942
|
if (onFiles) {
|
|
1964
|
-
onFiles(
|
|
1943
|
+
onFiles(committed);
|
|
1965
1944
|
}
|
|
1966
1945
|
}
|
|
1967
1946
|
});
|
|
@@ -1985,8 +1964,15 @@ function fileUpload(options) {
|
|
|
1985
1964
|
if (existing) return existing;
|
|
1986
1965
|
const id = createId("sibu-fileupload");
|
|
1987
1966
|
const restore = [];
|
|
1967
|
+
const prevAccept = els.input.getAttribute("accept");
|
|
1968
|
+
const prevMultiple = els.input.hasAttribute("multiple");
|
|
1988
1969
|
if (accept) els.input.accept = accept;
|
|
1989
1970
|
els.input.multiple = multiple;
|
|
1971
|
+
restore.push(() => {
|
|
1972
|
+
if (prevAccept === null) els.input.removeAttribute("accept");
|
|
1973
|
+
else els.input.setAttribute("accept", prevAccept);
|
|
1974
|
+
els.input.multiple = prevMultiple;
|
|
1975
|
+
});
|
|
1990
1976
|
let hintId = null;
|
|
1991
1977
|
if (els.hint) {
|
|
1992
1978
|
const assignedHintId = !els.hint.id;
|
|
@@ -2007,6 +1993,7 @@ function fileUpload(options) {
|
|
|
2007
1993
|
if (els.errorRegion) {
|
|
2008
1994
|
const prevRole = els.errorRegion.getAttribute("role");
|
|
2009
1995
|
const prevLive = els.errorRegion.getAttribute("aria-live");
|
|
1996
|
+
const prevText = els.errorRegion.textContent;
|
|
2010
1997
|
els.errorRegion.setAttribute("role", "status");
|
|
2011
1998
|
els.errorRegion.setAttribute("aria-live", "polite");
|
|
2012
1999
|
restore.push(() => {
|
|
@@ -2014,12 +2001,14 @@ function fileUpload(options) {
|
|
|
2014
2001
|
else els.errorRegion.setAttribute("role", prevRole);
|
|
2015
2002
|
if (prevLive === null) els.errorRegion.removeAttribute("aria-live");
|
|
2016
2003
|
else els.errorRegion.setAttribute("aria-live", prevLive);
|
|
2004
|
+
els.errorRegion.textContent = prevText;
|
|
2017
2005
|
});
|
|
2018
2006
|
}
|
|
2019
2007
|
if (els.dropZone) {
|
|
2020
2008
|
const prevDzRole = els.dropZone.getAttribute("role");
|
|
2021
2009
|
const prevDzLabel = els.dropZone.getAttribute("aria-label");
|
|
2022
2010
|
const prevDzTabindex = els.dropZone.hasAttribute("tabindex") ? els.dropZone.getAttribute("tabindex") : null;
|
|
2011
|
+
const prevDzDragOver = els.dropZone.getAttribute("data-drag-over");
|
|
2023
2012
|
els.dropZone.setAttribute("role", "button");
|
|
2024
2013
|
els.dropZone.setAttribute("aria-label", "File drop zone \u2014 click or press Enter to browse");
|
|
2025
2014
|
if (els.dropZone.tabIndex < 0) els.dropZone.tabIndex = 0;
|
|
@@ -2030,13 +2019,15 @@ function fileUpload(options) {
|
|
|
2030
2019
|
else els.dropZone.setAttribute("aria-label", prevDzLabel);
|
|
2031
2020
|
if (prevDzTabindex === null) els.dropZone.removeAttribute("tabindex");
|
|
2032
2021
|
else els.dropZone.setAttribute("tabindex", prevDzTabindex);
|
|
2022
|
+
if (prevDzDragOver === null) els.dropZone.removeAttribute("data-drag-over");
|
|
2023
|
+
else els.dropZone.setAttribute("data-drag-over", prevDzDragOver);
|
|
2033
2024
|
});
|
|
2034
2025
|
}
|
|
2035
|
-
const fxTeardown =
|
|
2026
|
+
const fxTeardown = domBinding(() => {
|
|
2036
2027
|
const errs = errors();
|
|
2037
2028
|
if (els.errorRegion) els.errorRegion.textContent = errs.join(". ");
|
|
2038
2029
|
if (els.dropZone) els.dropZone.setAttribute("data-drag-over", isDragOver() ? "true" : "false");
|
|
2039
|
-
});
|
|
2030
|
+
}, els.input);
|
|
2040
2031
|
const onChange = () => {
|
|
2041
2032
|
if (els.input.files) addFiles(els.input.files);
|
|
2042
2033
|
};
|
|
@@ -2065,7 +2056,10 @@ function fileUpload(options) {
|
|
|
2065
2056
|
els.dropZone.addEventListener("dragleave", onDragLeave);
|
|
2066
2057
|
els.dropZone.addEventListener("drop", onDrop);
|
|
2067
2058
|
}
|
|
2059
|
+
let tornDown = false;
|
|
2068
2060
|
const teardown = () => {
|
|
2061
|
+
if (tornDown) return;
|
|
2062
|
+
tornDown = true;
|
|
2069
2063
|
boundFileUploads.delete(els.input);
|
|
2070
2064
|
fxTeardown();
|
|
2071
2065
|
els.input.removeEventListener("change", onChange);
|
|
@@ -2112,12 +2106,15 @@ function stripHtml(html) {
|
|
|
2112
2106
|
}
|
|
2113
2107
|
|
|
2114
2108
|
// src/widgets/contentEditable.ts
|
|
2109
|
+
function toInertText(html) {
|
|
2110
|
+
return stripHtml(String(html)).replace(/<(?=[a-z!/?])/gi, "<");
|
|
2111
|
+
}
|
|
2115
2112
|
function contentEditable(element) {
|
|
2116
2113
|
const [content, setContentInternal] = signal("");
|
|
2117
2114
|
const [isFocused, setFocused] = signal(false);
|
|
2118
2115
|
function setContent(input) {
|
|
2119
2116
|
if (typeof input === "string") {
|
|
2120
|
-
setContentInternal(input);
|
|
2117
|
+
setContentInternal(toInertText(input));
|
|
2121
2118
|
return;
|
|
2122
2119
|
}
|
|
2123
2120
|
if (typeof input.text === "string") {
|
|
@@ -2126,7 +2123,7 @@ function contentEditable(element) {
|
|
|
2126
2123
|
}
|
|
2127
2124
|
if (typeof input.html === "string") {
|
|
2128
2125
|
const shouldSanitize = input.sanitize !== false;
|
|
2129
|
-
setContentInternal(shouldSanitize ?
|
|
2126
|
+
setContentInternal(shouldSanitize ? toInertText(input.html) : input.html);
|
|
2130
2127
|
return;
|
|
2131
2128
|
}
|
|
2132
2129
|
setContentInternal("");
|
|
@@ -2138,7 +2135,7 @@ function contentEditable(element) {
|
|
|
2138
2135
|
const range = selection.getRangeAt(0);
|
|
2139
2136
|
if (element && !element.contains(range.commonAncestorContainer)) return;
|
|
2140
2137
|
const ancestor = range.commonAncestorContainer;
|
|
2141
|
-
const existingWrap =
|
|
2138
|
+
const existingWrap = findWrapperWithinEditor(
|
|
2142
2139
|
ancestor instanceof HTMLElement ? ancestor : ancestor.parentElement,
|
|
2143
2140
|
tagName
|
|
2144
2141
|
);
|
|
@@ -2179,14 +2176,19 @@ function contentEditable(element) {
|
|
|
2179
2176
|
selection.addRange(newRange);
|
|
2180
2177
|
}
|
|
2181
2178
|
}
|
|
2182
|
-
function
|
|
2179
|
+
function findWrapperWithinEditor(el, tagName) {
|
|
2183
2180
|
const upper = tagName.toUpperCase();
|
|
2184
2181
|
while (el) {
|
|
2182
|
+
if (el === element || isEditingHost(el)) return null;
|
|
2185
2183
|
if (el.tagName === upper) return el;
|
|
2186
2184
|
el = el.parentElement;
|
|
2187
2185
|
}
|
|
2188
2186
|
return null;
|
|
2189
2187
|
}
|
|
2188
|
+
function isEditingHost(el) {
|
|
2189
|
+
const attr = el.getAttribute("contenteditable");
|
|
2190
|
+
return attr !== null && attr.toLowerCase() !== "false";
|
|
2191
|
+
}
|
|
2190
2192
|
function bold() {
|
|
2191
2193
|
wrapSelection("strong");
|
|
2192
2194
|
}
|
|
@@ -2322,15 +2324,36 @@ function datePicker(options) {
|
|
|
2322
2324
|
els.grid.setAttribute("role", "grid");
|
|
2323
2325
|
if (els.grid.tabIndex < 0) els.grid.tabIndex = 0;
|
|
2324
2326
|
let pendingFocus = false;
|
|
2325
|
-
const
|
|
2327
|
+
const touchedCells = /* @__PURE__ */ new Map();
|
|
2328
|
+
const restoreAttr = (el, name, value) => {
|
|
2329
|
+
if (value === null) el.removeAttribute(name);
|
|
2330
|
+
else el.setAttribute(name, value);
|
|
2331
|
+
};
|
|
2332
|
+
const restoreCell = (cell, snap) => {
|
|
2333
|
+
restoreAttr(cell, "role", snap.role);
|
|
2334
|
+
restoreAttr(cell, "aria-selected", snap.selected);
|
|
2335
|
+
restoreAttr(cell, "aria-disabled", snap.disabled);
|
|
2336
|
+
restoreAttr(cell, "tabindex", snap.tabindex);
|
|
2337
|
+
};
|
|
2338
|
+
const fxTeardown = domBinding(() => {
|
|
2326
2339
|
const sel = selectedDate();
|
|
2327
2340
|
const view = viewDate();
|
|
2328
2341
|
const days = daysInMonth();
|
|
2329
2342
|
els.grid.setAttribute("aria-label", view.toLocaleDateString(void 0, { month: "long", year: "numeric" }));
|
|
2330
2343
|
let viewCell = null;
|
|
2344
|
+
const displayed = /* @__PURE__ */ new Set();
|
|
2331
2345
|
for (const d of days) {
|
|
2332
2346
|
const cell = els.cell(d.date);
|
|
2333
2347
|
if (!cell) continue;
|
|
2348
|
+
displayed.add(cell);
|
|
2349
|
+
if (!touchedCells.has(cell)) {
|
|
2350
|
+
touchedCells.set(cell, {
|
|
2351
|
+
role: cell.getAttribute("role"),
|
|
2352
|
+
selected: cell.getAttribute("aria-selected"),
|
|
2353
|
+
disabled: cell.getAttribute("aria-disabled"),
|
|
2354
|
+
tabindex: cell.getAttribute("tabindex")
|
|
2355
|
+
});
|
|
2356
|
+
}
|
|
2334
2357
|
cell.setAttribute("role", "gridcell");
|
|
2335
2358
|
cell.setAttribute("aria-selected", sel && isSameCalendarDay(sel, d.date) ? "true" : "false");
|
|
2336
2359
|
if (d.isDisabled) cell.setAttribute("aria-disabled", "true");
|
|
@@ -2339,11 +2362,17 @@ function datePicker(options) {
|
|
|
2339
2362
|
cell.tabIndex = isView ? 0 : -1;
|
|
2340
2363
|
if (isView) viewCell = cell;
|
|
2341
2364
|
}
|
|
2365
|
+
for (const [cell, snap] of touchedCells) {
|
|
2366
|
+
if (!displayed.has(cell)) {
|
|
2367
|
+
restoreCell(cell, snap);
|
|
2368
|
+
touchedCells.delete(cell);
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2342
2371
|
if (pendingFocus && viewCell && typeof viewCell.focus === "function") {
|
|
2343
2372
|
pendingFocus = false;
|
|
2344
2373
|
viewCell.focus();
|
|
2345
2374
|
}
|
|
2346
|
-
});
|
|
2375
|
+
}, els.grid);
|
|
2347
2376
|
function isSameCalendarDay(a, b) {
|
|
2348
2377
|
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2349
2378
|
}
|
|
@@ -2398,8 +2427,11 @@ function datePicker(options) {
|
|
|
2398
2427
|
}
|
|
2399
2428
|
};
|
|
2400
2429
|
els.grid.addEventListener("keydown", onKey);
|
|
2430
|
+
let tornDown = false;
|
|
2401
2431
|
const teardown = () => {
|
|
2402
|
-
|
|
2432
|
+
if (tornDown) return;
|
|
2433
|
+
tornDown = true;
|
|
2434
|
+
if (boundDatePickers.get(els.grid) === teardown) boundDatePickers.delete(els.grid);
|
|
2403
2435
|
fxTeardown();
|
|
2404
2436
|
els.grid.removeEventListener("keydown", onKey);
|
|
2405
2437
|
if (prevGridRole === null) els.grid.removeAttribute("role");
|
|
@@ -2408,6 +2440,8 @@ function datePicker(options) {
|
|
|
2408
2440
|
else els.grid.setAttribute("tabindex", prevGridTabIndex);
|
|
2409
2441
|
if (prevGridLabel === null) els.grid.removeAttribute("aria-label");
|
|
2410
2442
|
else els.grid.setAttribute("aria-label", prevGridLabel);
|
|
2443
|
+
for (const [cell, snap] of touchedCells) restoreCell(cell, snap);
|
|
2444
|
+
touchedCells.clear();
|
|
2411
2445
|
};
|
|
2412
2446
|
boundDatePickers.set(els.grid, teardown);
|
|
2413
2447
|
return teardown;
|