sibujs 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1630 -0
- package/dist/browser.cjs +815 -0
- package/dist/browser.d.cts +174 -0
- package/dist/browser.d.ts +174 -0
- package/dist/browser.js +458 -0
- package/dist/build.cjs +4970 -0
- package/dist/build.d.cts +630 -0
- package/dist/build.d.ts +630 -0
- package/dist/build.js +2478 -0
- package/dist/cdn.global.js +115 -0
- package/dist/chunk-27QC4FPL.js +67 -0
- package/dist/chunk-2ABBWCGC.js +65 -0
- package/dist/chunk-2MUNQYZ7.js +26 -0
- package/dist/chunk-2PSPKNUI.js +1711 -0
- package/dist/chunk-35CDLDX5.js +1758 -0
- package/dist/chunk-36MU4CFV.js +41 -0
- package/dist/chunk-3FIQOFI6.js +182 -0
- package/dist/chunk-3GHNC2BN.js +28 -0
- package/dist/chunk-3HLWWEPU.js +909 -0
- package/dist/chunk-3IVI3J54.js +252 -0
- package/dist/chunk-3KZ72WNW.js +944 -0
- package/dist/chunk-4AU64SQV.js +182 -0
- package/dist/chunk-4MOK7HAR.js +84 -0
- package/dist/chunk-4QK6FBDH.js +1429 -0
- package/dist/chunk-566Z7HXB.js +737 -0
- package/dist/chunk-5CRBB7XP.js +358 -0
- package/dist/chunk-5G67D3IZ.js +168 -0
- package/dist/chunk-5NCPAWBE.js +99 -0
- package/dist/chunk-5O2RKXR3.js +1444 -0
- package/dist/chunk-6BTBDO6A.js +633 -0
- package/dist/chunk-6IWEHW57.js +43 -0
- package/dist/chunk-6JGMNCD6.js +282 -0
- package/dist/chunk-6QRLJNXR.js +1425 -0
- package/dist/chunk-7HM5UE5T.js +270 -0
- package/dist/chunk-7JOLTGUH.js +58 -0
- package/dist/chunk-7MCWJCQK.js +909 -0
- package/dist/chunk-7RIIFP3E.js +1758 -0
- package/dist/chunk-7UASYN3G.js +254 -0
- package/dist/chunk-7W2WYHDI.js +741 -0
- package/dist/chunk-7Y35RDSJ.js +872 -0
- package/dist/chunk-A65GFJBL.js +65 -0
- package/dist/chunk-AD6ZIEDK.js +67 -0
- package/dist/chunk-AK5Y72F3.js +1426 -0
- package/dist/chunk-APOMMWH4.js +282 -0
- package/dist/chunk-ARZVTWIQ.js +1750 -0
- package/dist/chunk-AWWBM2BI.js +664 -0
- package/dist/chunk-AX5VEQTY.js +58 -0
- package/dist/chunk-AYTXVOW3.js +1708 -0
- package/dist/chunk-BG4A246G.js +1746 -0
- package/dist/chunk-BNFJJA2L.js +1425 -0
- package/dist/chunk-BPKPBVU5.js +59 -0
- package/dist/chunk-BPKPPSXC.js +282 -0
- package/dist/chunk-BPWKKK7F.js +1711 -0
- package/dist/chunk-CCKX6YTC.js +1735 -0
- package/dist/chunk-CIF5Z3MP.js +58 -0
- package/dist/chunk-CSXYU7IO.js +457 -0
- package/dist/chunk-D6JD4FDC.js +26 -0
- package/dist/chunk-E7NGA7X2.js +59 -0
- package/dist/chunk-EEPPJKAE.js +443 -0
- package/dist/chunk-EJMYGAGQ.js +717 -0
- package/dist/chunk-EL6Z5MDY.js +55 -0
- package/dist/chunk-EP7VRLEB.js +41 -0
- package/dist/chunk-ETMEC6FH.js +99 -0
- package/dist/chunk-EZ2WHYVL.js +65 -0
- package/dist/chunk-EZRVMSZK.js +67 -0
- package/dist/chunk-F2TRGINX.js +254 -0
- package/dist/chunk-F5JCIH3Q.js +642 -0
- package/dist/chunk-FGK3JKMN.js +909 -0
- package/dist/chunk-FQWPKSTD.js +1437 -0
- package/dist/chunk-FWHVLMCI.js +26 -0
- package/dist/chunk-GBEYQRO2.js +303 -0
- package/dist/chunk-GBLES3NK.js +248 -0
- package/dist/chunk-GQVGUQW6.js +1436 -0
- package/dist/chunk-HCV2T76T.js +457 -0
- package/dist/chunk-HS7ZKVPR.js +182 -0
- package/dist/chunk-HXDVV7HZ.js +909 -0
- package/dist/chunk-IB23VMO3.js +1746 -0
- package/dist/chunk-IEMZ7RTT.js +99 -0
- package/dist/chunk-IPGRSN42.js +1750 -0
- package/dist/chunk-IVMOK2QN.js +1750 -0
- package/dist/chunk-JCLGQO7T.js +443 -0
- package/dist/chunk-JDXL7KDB.js +1436 -0
- package/dist/chunk-JIIFW636.js +270 -0
- package/dist/chunk-JWGEEH7H.js +944 -0
- package/dist/chunk-K2BESAG7.js +1688 -0
- package/dist/chunk-K2U5YGF4.js +877 -0
- package/dist/chunk-K45FQ4Y4.js +175 -0
- package/dist/chunk-K7BPE427.js +1432 -0
- package/dist/chunk-KL3266RS.js +26 -0
- package/dist/chunk-KNN4P7DZ.js +84 -0
- package/dist/chunk-KP2DZH5Q.js +254 -0
- package/dist/chunk-KZHAJSQR.js +1636 -0
- package/dist/chunk-LBKGHMQV.js +1750 -0
- package/dist/chunk-LBTEPL7A.js +1731 -0
- package/dist/chunk-LEBBPTDB.js +1444 -0
- package/dist/chunk-LLH63WVQ.js +98 -0
- package/dist/chunk-LWVR2C4G.js +1711 -0
- package/dist/chunk-M3MDTVV2.js +896 -0
- package/dist/chunk-M5GNLDEO.js +303 -0
- package/dist/chunk-MFHVGKET.js +267 -0
- package/dist/chunk-MGWSG3PM.js +358 -0
- package/dist/chunk-MJNB47HB.js +19 -0
- package/dist/chunk-MLKGABMK.js +9 -0
- package/dist/chunk-MQWTY3JY.js +944 -0
- package/dist/chunk-MZZOQHNI.js +642 -0
- package/dist/chunk-NIHWGZS4.js +1426 -0
- package/dist/chunk-NSVVHQK5.js +41 -0
- package/dist/chunk-NVI2WE7D.js +443 -0
- package/dist/chunk-O7QBO3PH.js +58 -0
- package/dist/chunk-OAUPQBO2.js +270 -0
- package/dist/chunk-OB2LMD7C.js +297 -0
- package/dist/chunk-OHEYBWQU.js +58 -0
- package/dist/chunk-OI6OXUHJ.js +443 -0
- package/dist/chunk-OX2VMRMV.js +633 -0
- package/dist/chunk-P4FYE5TX.js +866 -0
- package/dist/chunk-P5KFWM4H.js +98 -0
- package/dist/chunk-PUMLE7RJ.js +1711 -0
- package/dist/chunk-Q4MFANBF.js +282 -0
- package/dist/chunk-QLEKZMMU.js +282 -0
- package/dist/chunk-RGGNGVO3.js +98 -0
- package/dist/chunk-RKJDRVV6.js +443 -0
- package/dist/chunk-S5BHU353.js +43 -0
- package/dist/chunk-SHQUSFH7.js +1426 -0
- package/dist/chunk-SMB4DBMD.js +182 -0
- package/dist/chunk-SNYHQP3D.js +743 -0
- package/dist/chunk-T24L3TBF.js +1717 -0
- package/dist/chunk-TAQNSOKT.js +692 -0
- package/dist/chunk-TDNY4SUA.js +41 -0
- package/dist/chunk-TNNF56IQ.js +1750 -0
- package/dist/chunk-TR7E6LYX.js +457 -0
- package/dist/chunk-URWUFH45.js +98 -0
- package/dist/chunk-UUSIH3XH.js +1429 -0
- package/dist/chunk-UYFNXLKR.js +1436 -0
- package/dist/chunk-V6F7KUWD.js +270 -0
- package/dist/chunk-VCZLXRMR.js +254 -0
- package/dist/chunk-VDHXSSBT.js +1426 -0
- package/dist/chunk-VM4QMKVK.js +254 -0
- package/dist/chunk-VWGYKYL2.js +737 -0
- package/dist/chunk-VX2OFBJN.js +1426 -0
- package/dist/chunk-VXVIE6DG.js +84 -0
- package/dist/chunk-W4OH7HG4.js +40 -0
- package/dist/chunk-WBVJX4GZ.js +98 -0
- package/dist/chunk-WDU2ZV4I.js +1426 -0
- package/dist/chunk-X6VUCICU.js +457 -0
- package/dist/chunk-XAY7FM7Y.js +618 -0
- package/dist/chunk-XJZ5Z2CM.js +642 -0
- package/dist/chunk-XKVFQTJJ.js +254 -0
- package/dist/chunk-XRLFASCY.js +22 -0
- package/dist/chunk-XYU6TZOW.js +182 -0
- package/dist/chunk-Y745CBVB.js +944 -0
- package/dist/chunk-YLBJSXYY.js +944 -0
- package/dist/chunk-YQJIKVPZ.js +1429 -0
- package/dist/chunk-YRM2VCZF.js +457 -0
- package/dist/chunk-YS33KBVJ.js +944 -0
- package/dist/chunk-Z27DZPDG.js +41 -0
- package/dist/chunk-ZXQ5NAEN.js +32 -0
- package/dist/contracts-B552GopR.d.cts +245 -0
- package/dist/contracts-B552GopR.d.ts +245 -0
- package/dist/contracts-Bg1ECISC.d.cts +245 -0
- package/dist/contracts-Bg1ECISC.d.ts +245 -0
- package/dist/contracts-CMriKJ6P.d.cts +245 -0
- package/dist/contracts-CMriKJ6P.d.ts +245 -0
- package/dist/contracts-DOrhwbke.d.cts +245 -0
- package/dist/contracts-DOrhwbke.d.ts +245 -0
- package/dist/data.cjs +1373 -0
- package/dist/data.d.cts +434 -0
- package/dist/data.d.ts +434 -0
- package/dist/data.js +945 -0
- package/dist/devtools.cjs +1357 -0
- package/dist/devtools.d.cts +473 -0
- package/dist/devtools.d.ts +473 -0
- package/dist/devtools.js +1084 -0
- package/dist/ecosystem.cjs +1046 -0
- package/dist/ecosystem.d.cts +247 -0
- package/dist/ecosystem.d.ts +247 -0
- package/dist/ecosystem.js +369 -0
- package/dist/extras.cjs +8457 -0
- package/dist/extras.d.cts +2356 -0
- package/dist/extras.d.ts +2356 -0
- package/dist/extras.js +5152 -0
- package/dist/index.cjs +2648 -0
- package/dist/index.d.cts +869 -0
- package/dist/index.d.ts +869 -0
- package/dist/index.js +386 -0
- package/dist/motion.cjs +604 -0
- package/dist/motion.d.cts +146 -0
- package/dist/motion.d.ts +146 -0
- package/dist/motion.js +346 -0
- package/dist/patterns.cjs +815 -0
- package/dist/patterns.d.cts +163 -0
- package/dist/patterns.d.ts +163 -0
- package/dist/patterns.js +296 -0
- package/dist/performance.cjs +927 -0
- package/dist/performance.d.cts +416 -0
- package/dist/performance.d.ts +416 -0
- package/dist/performance.js +654 -0
- package/dist/plugins.cjs +2487 -0
- package/dist/plugins.d.cts +393 -0
- package/dist/plugins.d.ts +393 -0
- package/dist/plugins.js +1504 -0
- package/dist/signal-BnWpq6WB.d.cts +5 -0
- package/dist/signal-BnWpq6WB.d.ts +5 -0
- package/dist/src/components/ErrorBoundary.d.ts +15 -0
- package/dist/src/components/ErrorBoundary.js +119 -0
- package/dist/src/core/catch.d.ts +11 -0
- package/dist/src/core/catch.js +28 -0
- package/dist/src/core/each.d.ts +13 -0
- package/dist/src/core/each.js +68 -0
- package/dist/src/core/for.d.ts +12 -0
- package/dist/src/core/for.js +67 -0
- package/dist/src/core/html.d.ts +137 -0
- package/dist/src/core/html.js +155 -0
- package/dist/src/core/htmlIf.d.ts +11 -0
- package/dist/src/core/htmlIf.js +18 -0
- package/dist/src/core/lazy.d.ts +7 -0
- package/dist/src/core/lazy.js +16 -0
- package/dist/src/core/mount.d.ts +7 -0
- package/dist/src/core/mount.js +12 -0
- package/dist/src/core/slots.d.ts +3 -0
- package/dist/src/core/slots.js +3 -0
- package/dist/src/core/suspense.d.ts +10 -0
- package/dist/src/core/suspense.js +33 -0
- package/dist/src/core/tagFactory.d.ts +13 -0
- package/dist/src/core/tagFactory.js +86 -0
- package/dist/src/core/test.d.ts +11 -0
- package/dist/src/core/test.js +28 -0
- package/dist/src/core/types.d.ts +2 -0
- package/dist/src/core/types.js +1 -0
- package/dist/src/core/useComputed.d.ts +6 -0
- package/dist/src/core/useComputed.js +30 -0
- package/dist/src/core/useEffect.d.ts +6 -0
- package/dist/src/core/useEffect.js +23 -0
- package/dist/src/core/useState.d.ts +10 -0
- package/dist/src/core/useState.js +34 -0
- package/dist/src/core/useStore.d.ts +19 -0
- package/dist/src/core/useStore.js +53 -0
- package/dist/src/core/useWatch.d.ts +8 -0
- package/dist/src/core/useWatch.js +23 -0
- package/dist/src/plugins/i18n.d.ts +6 -0
- package/dist/src/plugins/i18n.js +16 -0
- package/dist/src/plugins/router.d.ts +188 -0
- package/dist/src/plugins/router.js +1178 -0
- package/dist/src/reactivity/bindAttribute.d.ts +5 -0
- package/dist/src/reactivity/bindAttribute.js +31 -0
- package/dist/src/reactivity/bindChildNode.d.ts +10 -0
- package/dist/src/reactivity/bindChildNode.js +46 -0
- package/dist/src/reactivity/bindTextNode.d.ts +10 -0
- package/dist/src/reactivity/bindTextNode.js +27 -0
- package/dist/src/reactivity/signal.d.ts +3 -0
- package/dist/src/reactivity/signal.js +1 -0
- package/dist/src/reactivity/track.d.ts +18 -0
- package/dist/src/reactivity/track.js +73 -0
- package/dist/src/reactivity/useComputed.d.ts +6 -0
- package/dist/src/reactivity/useComputed.js +30 -0
- package/dist/src/reactivity/useEffect.d.ts +6 -0
- package/dist/src/reactivity/useEffect.js +23 -0
- package/dist/src/reactivity/useState.d.ts +10 -0
- package/dist/src/reactivity/useState.js +34 -0
- package/dist/src/reactivity/useStore.d.ts +19 -0
- package/dist/src/reactivity/useStore.js +53 -0
- package/dist/src/reactivity/useWatch.d.ts +8 -0
- package/dist/src/reactivity/useWatch.js +23 -0
- package/dist/src/utils/sanitize.d.ts +1 -0
- package/dist/src/utils/sanitize.js +8 -0
- package/dist/ssr-27FOM46T.js +35 -0
- package/dist/ssr-GFUTTSJD.js +22 -0
- package/dist/ssr-K7DCR6BZ.js +35 -0
- package/dist/ssr-O6LFMRFP.js +35 -0
- package/dist/ssr-QZEVGMMK.js +35 -0
- package/dist/ssr-SGVBCAGC.js +35 -0
- package/dist/ssr-UB2IXCYX.js +35 -0
- package/dist/ssr-XBZQNV4O.js +22 -0
- package/dist/ssr-Y76FSXDU.js +35 -0
- package/dist/ssr-YQJ4AYBD.js +35 -0
- package/dist/ssr.cjs +1757 -0
- package/dist/ssr.d.cts +478 -0
- package/dist/ssr.d.ts +478 -0
- package/dist/ssr.js +743 -0
- package/dist/tagFactory-CZPO4RXF.d.cts +34 -0
- package/dist/tagFactory-CZPO4RXF.d.ts +34 -0
- package/dist/tagFactory-CgImPVMY.d.cts +22 -0
- package/dist/tagFactory-CgImPVMY.d.ts +22 -0
- package/dist/tagFactory-Cw1iv5if.d.cts +22 -0
- package/dist/tagFactory-Cw1iv5if.d.ts +22 -0
- package/dist/tagFactory-DeAXq9ef.d.cts +30 -0
- package/dist/tagFactory-DeAXq9ef.d.ts +30 -0
- package/dist/tagFactory-SkY0a7L1.d.cts +22 -0
- package/dist/tagFactory-SkY0a7L1.d.ts +22 -0
- package/dist/testing.cjs +1919 -0
- package/dist/testing.d.cts +491 -0
- package/dist/testing.d.ts +491 -0
- package/dist/testing.js +1862 -0
- package/dist/ui.cjs +1497 -0
- package/dist/ui.d.cts +264 -0
- package/dist/ui.d.ts +264 -0
- package/dist/ui.js +900 -0
- package/dist/widgets.cjs +919 -0
- package/dist/widgets.d.cts +165 -0
- package/dist/widgets.d.ts +165 -0
- package/dist/widgets.js +545 -0
- package/package.json +134 -0
package/dist/ui.cjs
ADDED
|
@@ -0,0 +1,1497 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// ui.ts
|
|
21
|
+
var ui_exports = {};
|
|
22
|
+
__export(ui_exports, {
|
|
23
|
+
FocusTrap: () => FocusTrap,
|
|
24
|
+
RenderProp: () => RenderProp,
|
|
25
|
+
VirtualList: () => VirtualList,
|
|
26
|
+
announce: () => announce,
|
|
27
|
+
aria: () => aria,
|
|
28
|
+
assertType: () => assertType,
|
|
29
|
+
bindAttrs: () => bindAttrs,
|
|
30
|
+
bindBoolAttr: () => bindBoolAttr,
|
|
31
|
+
bindData: () => bindData,
|
|
32
|
+
composable: () => composable,
|
|
33
|
+
compose: () => compose,
|
|
34
|
+
createGuard: () => createGuard,
|
|
35
|
+
createSlots: () => createSlots,
|
|
36
|
+
creditCardMask: () => creditCardMask,
|
|
37
|
+
custom: () => custom,
|
|
38
|
+
dateMask: () => dateMask,
|
|
39
|
+
defineComponent: () => defineComponent,
|
|
40
|
+
defineElement: () => defineElement,
|
|
41
|
+
defineSlottedComponent: () => defineSlottedComponent,
|
|
42
|
+
defineStrictComponent: () => defineStrictComponent,
|
|
43
|
+
dialog: () => dialog,
|
|
44
|
+
email: () => email,
|
|
45
|
+
eventBus: () => eventBus,
|
|
46
|
+
focus: () => focus,
|
|
47
|
+
form: () => form,
|
|
48
|
+
hotkey: () => hotkey,
|
|
49
|
+
infiniteScroll: () => infiniteScroll,
|
|
50
|
+
inputMask: () => inputMask,
|
|
51
|
+
intersection: () => intersection,
|
|
52
|
+
lazyLoad: () => lazyLoad,
|
|
53
|
+
matchesPattern: () => matchesPattern,
|
|
54
|
+
max: () => max,
|
|
55
|
+
maxLength: () => maxLength,
|
|
56
|
+
min: () => min,
|
|
57
|
+
minLength: () => minLength,
|
|
58
|
+
pagination: () => pagination,
|
|
59
|
+
phoneMask: () => phoneMask,
|
|
60
|
+
removeScopedStyle: () => removeScopedStyle,
|
|
61
|
+
required: () => required,
|
|
62
|
+
scopedStyle: () => scopedStyle,
|
|
63
|
+
ssnMask: () => ssnMask,
|
|
64
|
+
svgElement: () => svgElement,
|
|
65
|
+
timeMask: () => timeMask,
|
|
66
|
+
toast: () => toast,
|
|
67
|
+
validateProps: () => validateProps,
|
|
68
|
+
validators: () => validators,
|
|
69
|
+
withBoundary: () => withBoundary,
|
|
70
|
+
withDefaults: () => withDefaults,
|
|
71
|
+
withProps: () => withProps,
|
|
72
|
+
withScopedStyle: () => withScopedStyle,
|
|
73
|
+
withWrapper: () => withWrapper,
|
|
74
|
+
zipMask: () => zipMask
|
|
75
|
+
});
|
|
76
|
+
module.exports = __toCommonJS(ui_exports);
|
|
77
|
+
|
|
78
|
+
// src/reactivity/track.ts
|
|
79
|
+
var subscriberStack = [];
|
|
80
|
+
var currentSubscriber = null;
|
|
81
|
+
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
82
|
+
var SUBS = "__s";
|
|
83
|
+
var notifyDepth = 0;
|
|
84
|
+
var pendingQueue = [];
|
|
85
|
+
var pendingSet = /* @__PURE__ */ new Set();
|
|
86
|
+
var suspendDepth = 0;
|
|
87
|
+
var trackingSuspended = false;
|
|
88
|
+
function track(effectFn, subscriber) {
|
|
89
|
+
if (!subscriber) subscriber = effectFn;
|
|
90
|
+
cleanup(subscriber);
|
|
91
|
+
subscriberStack.push(subscriber);
|
|
92
|
+
currentSubscriber = subscriber;
|
|
93
|
+
effectFn();
|
|
94
|
+
subscriberStack.pop();
|
|
95
|
+
currentSubscriber = subscriberStack[subscriberStack.length - 1] || null;
|
|
96
|
+
return () => cleanup(subscriber);
|
|
97
|
+
}
|
|
98
|
+
function suspendTracking() {
|
|
99
|
+
if (suspendDepth === 0) {
|
|
100
|
+
subscriberStack.push(null);
|
|
101
|
+
currentSubscriber = null;
|
|
102
|
+
trackingSuspended = true;
|
|
103
|
+
}
|
|
104
|
+
suspendDepth++;
|
|
105
|
+
}
|
|
106
|
+
function resumeTracking() {
|
|
107
|
+
suspendDepth--;
|
|
108
|
+
if (suspendDepth === 0) {
|
|
109
|
+
subscriberStack.pop();
|
|
110
|
+
currentSubscriber = subscriberStack[subscriberStack.length - 1] || null;
|
|
111
|
+
trackingSuspended = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function recordDependency(signal2) {
|
|
115
|
+
if (!currentSubscriber) return;
|
|
116
|
+
let deps = currentSubscriber._deps;
|
|
117
|
+
if (!deps) {
|
|
118
|
+
deps = /* @__PURE__ */ new Set();
|
|
119
|
+
currentSubscriber._deps = deps;
|
|
120
|
+
}
|
|
121
|
+
if (!deps.has(signal2)) {
|
|
122
|
+
deps.add(signal2);
|
|
123
|
+
let subs = signal2[SUBS];
|
|
124
|
+
if (!subs) {
|
|
125
|
+
subs = /* @__PURE__ */ new Set();
|
|
126
|
+
signalSubscribers.set(signal2, subs);
|
|
127
|
+
signal2[SUBS] = subs;
|
|
128
|
+
}
|
|
129
|
+
subs.add(currentSubscriber);
|
|
130
|
+
if (subs.size === 1) {
|
|
131
|
+
signal2.__f = currentSubscriber;
|
|
132
|
+
} else if (signal2.__f !== void 0) {
|
|
133
|
+
signal2.__f = void 0;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function propagateDirty(sub) {
|
|
138
|
+
sub();
|
|
139
|
+
let sig = sub._sig;
|
|
140
|
+
let suspended = false;
|
|
141
|
+
if (sig && sig._g) {
|
|
142
|
+
const sDeps = sub._deps;
|
|
143
|
+
if (sDeps && sDeps.size === 1) {
|
|
144
|
+
suspendTracking();
|
|
145
|
+
suspended = true;
|
|
146
|
+
const s = sig;
|
|
147
|
+
s._d = false;
|
|
148
|
+
s._v = s._g();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
while (sig) {
|
|
152
|
+
const first = sig.__f;
|
|
153
|
+
if (first) {
|
|
154
|
+
if (first._c) {
|
|
155
|
+
const nSig = first._sig;
|
|
156
|
+
nSig._d = true;
|
|
157
|
+
if (suspended && nSig._g) {
|
|
158
|
+
const fDeps = first._deps;
|
|
159
|
+
if (fDeps && fDeps.size === 1) {
|
|
160
|
+
nSig._d = false;
|
|
161
|
+
nSig._v = nSig._g();
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
sig = nSig;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (!pendingSet.has(first)) {
|
|
168
|
+
pendingSet.add(first);
|
|
169
|
+
pendingQueue.push(first);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
const subs = sig[SUBS];
|
|
174
|
+
if (!subs) break;
|
|
175
|
+
let nextSig;
|
|
176
|
+
for (const s of subs) {
|
|
177
|
+
if (s._c) {
|
|
178
|
+
s();
|
|
179
|
+
const nSig = s._sig;
|
|
180
|
+
if (nSig && !nextSig) {
|
|
181
|
+
nextSig = nSig;
|
|
182
|
+
} else if (nSig) {
|
|
183
|
+
propagateDirty(s);
|
|
184
|
+
}
|
|
185
|
+
} else if (!pendingSet.has(s)) {
|
|
186
|
+
pendingSet.add(s);
|
|
187
|
+
pendingQueue.push(s);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
sig = nextSig;
|
|
191
|
+
}
|
|
192
|
+
if (suspended) resumeTracking();
|
|
193
|
+
}
|
|
194
|
+
function notifySubscribers(signal2) {
|
|
195
|
+
const first = signal2.__f;
|
|
196
|
+
if (first) {
|
|
197
|
+
if (notifyDepth > 0) {
|
|
198
|
+
if (first._c) {
|
|
199
|
+
propagateDirty(first);
|
|
200
|
+
} else if (!pendingSet.has(first)) {
|
|
201
|
+
pendingSet.add(first);
|
|
202
|
+
pendingQueue.push(first);
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
notifyDepth++;
|
|
207
|
+
try {
|
|
208
|
+
if (first._c) {
|
|
209
|
+
propagateDirty(first);
|
|
210
|
+
} else {
|
|
211
|
+
first();
|
|
212
|
+
}
|
|
213
|
+
let i = 0;
|
|
214
|
+
while (i < pendingQueue.length) {
|
|
215
|
+
pendingQueue[i]();
|
|
216
|
+
i++;
|
|
217
|
+
}
|
|
218
|
+
} finally {
|
|
219
|
+
pendingQueue.length = 0;
|
|
220
|
+
pendingSet.clear();
|
|
221
|
+
notifyDepth--;
|
|
222
|
+
}
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const subs = signal2[SUBS];
|
|
226
|
+
if (!subs || subs.size === 0) return;
|
|
227
|
+
if (notifyDepth > 0) {
|
|
228
|
+
for (const sub of subs) {
|
|
229
|
+
if (sub._c) {
|
|
230
|
+
propagateDirty(sub);
|
|
231
|
+
} else if (!pendingSet.has(sub)) {
|
|
232
|
+
pendingSet.add(sub);
|
|
233
|
+
pendingQueue.push(sub);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
notifyDepth++;
|
|
239
|
+
try {
|
|
240
|
+
let directCount = 0;
|
|
241
|
+
for (const sub of subs) {
|
|
242
|
+
pendingQueue[directCount++] = sub;
|
|
243
|
+
}
|
|
244
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
245
|
+
if (pendingQueue[i2]._c) {
|
|
246
|
+
propagateDirty(pendingQueue[i2]);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (let i2 = 0; i2 < directCount; i2++) {
|
|
250
|
+
if (!pendingQueue[i2]._c) {
|
|
251
|
+
if (!pendingSet.has(pendingQueue[i2])) {
|
|
252
|
+
pendingQueue[i2]();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
let i = directCount;
|
|
257
|
+
while (i < pendingQueue.length) {
|
|
258
|
+
pendingQueue[i]();
|
|
259
|
+
i++;
|
|
260
|
+
}
|
|
261
|
+
} finally {
|
|
262
|
+
pendingQueue.length = 0;
|
|
263
|
+
pendingSet.clear();
|
|
264
|
+
notifyDepth--;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function cleanup(subscriber) {
|
|
268
|
+
const deps = subscriber._deps;
|
|
269
|
+
if (!deps || deps.size === 0) return;
|
|
270
|
+
for (const signal2 of deps) {
|
|
271
|
+
const subs = signal2[SUBS];
|
|
272
|
+
if (subs) {
|
|
273
|
+
subs.delete(subscriber);
|
|
274
|
+
if (signal2.__f === subscriber) {
|
|
275
|
+
signal2.__f = void 0;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
deps.clear();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/core/dev.ts
|
|
283
|
+
function isDev() {
|
|
284
|
+
return typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : true;
|
|
285
|
+
}
|
|
286
|
+
function devAssert(condition, message) {
|
|
287
|
+
if (isDev() && !condition) {
|
|
288
|
+
throw new Error(`[Sibu] ${message}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/core/signals/derived.ts
|
|
293
|
+
function derived(getter, options) {
|
|
294
|
+
devAssert(typeof getter === "function", "derived: argument must be a getter function.");
|
|
295
|
+
const debugName = options?.name;
|
|
296
|
+
const cs = {};
|
|
297
|
+
cs._d = false;
|
|
298
|
+
cs._g = getter;
|
|
299
|
+
const markDirty = () => {
|
|
300
|
+
if (cs._d) return;
|
|
301
|
+
cs._d = true;
|
|
302
|
+
};
|
|
303
|
+
markDirty._c = 1;
|
|
304
|
+
markDirty._sig = cs;
|
|
305
|
+
track(() => {
|
|
306
|
+
cs._d = false;
|
|
307
|
+
cs._v = getter();
|
|
308
|
+
}, markDirty);
|
|
309
|
+
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
310
|
+
function computedGetter() {
|
|
311
|
+
if (trackingSuspended) {
|
|
312
|
+
if (cs._d) {
|
|
313
|
+
cs._d = false;
|
|
314
|
+
cs._v = getter();
|
|
315
|
+
}
|
|
316
|
+
return cs._v;
|
|
317
|
+
}
|
|
318
|
+
recordDependency(cs);
|
|
319
|
+
if (cs._d) {
|
|
320
|
+
const oldValue = cs._v;
|
|
321
|
+
cs._d = false;
|
|
322
|
+
suspendTracking();
|
|
323
|
+
try {
|
|
324
|
+
cs._v = getter();
|
|
325
|
+
} finally {
|
|
326
|
+
resumeTracking();
|
|
327
|
+
}
|
|
328
|
+
if (hook && oldValue !== cs._v) {
|
|
329
|
+
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return cs._v;
|
|
333
|
+
}
|
|
334
|
+
if (debugName) {
|
|
335
|
+
computedGetter.__name = debugName;
|
|
336
|
+
cs.__name = debugName;
|
|
337
|
+
}
|
|
338
|
+
computedGetter.__signal = cs;
|
|
339
|
+
if (hook) hook.emit("computed:create", { signal: cs, name: debugName, getter: computedGetter });
|
|
340
|
+
return computedGetter;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/reactivity/batch.ts
|
|
344
|
+
var batchDepth = 0;
|
|
345
|
+
var pendingSignals = /* @__PURE__ */ new Set();
|
|
346
|
+
function enqueueBatchedSignal(signal2) {
|
|
347
|
+
if (batchDepth === 0) return false;
|
|
348
|
+
pendingSignals.add(signal2);
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// src/core/signals/signal.ts
|
|
353
|
+
function signal(initial, options) {
|
|
354
|
+
const state = { value: initial };
|
|
355
|
+
const debugName = options?.name;
|
|
356
|
+
if (debugName) {
|
|
357
|
+
state.__name = debugName;
|
|
358
|
+
}
|
|
359
|
+
function get() {
|
|
360
|
+
recordDependency(state);
|
|
361
|
+
return state.value;
|
|
362
|
+
}
|
|
363
|
+
get.__signal = state;
|
|
364
|
+
if (debugName) get.__name = debugName;
|
|
365
|
+
function set(next) {
|
|
366
|
+
const newValue = typeof next === "function" ? next(state.value) : next;
|
|
367
|
+
if (Object.is(newValue, state.value)) return;
|
|
368
|
+
const oldValue = state.value;
|
|
369
|
+
state.value = newValue;
|
|
370
|
+
const hook2 = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
371
|
+
if (hook2) hook2.emit("signal:update", { signal: state, name: debugName, oldValue, newValue });
|
|
372
|
+
if (!enqueueBatchedSignal(state)) {
|
|
373
|
+
notifySubscribers(state);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
377
|
+
if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
|
|
378
|
+
return [get, set];
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/ui/form.ts
|
|
382
|
+
function required(message = "This field is required") {
|
|
383
|
+
return (value) => {
|
|
384
|
+
if (value == null || value === "" || Array.isArray(value) && value.length === 0) {
|
|
385
|
+
return message;
|
|
386
|
+
}
|
|
387
|
+
return null;
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
function minLength(min2, message) {
|
|
391
|
+
return (value) => {
|
|
392
|
+
if (value && value.length < min2) {
|
|
393
|
+
return message || `Must be at least ${min2} characters`;
|
|
394
|
+
}
|
|
395
|
+
return null;
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function maxLength(max2, message) {
|
|
399
|
+
return (value) => {
|
|
400
|
+
if (value && value.length > max2) {
|
|
401
|
+
return message || `Must be at most ${max2} characters`;
|
|
402
|
+
}
|
|
403
|
+
return null;
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
function matchesPattern(regex, message = "Invalid format") {
|
|
407
|
+
return (value) => {
|
|
408
|
+
if (value && !regex.test(value)) {
|
|
409
|
+
return message;
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function email(message = "Invalid email address") {
|
|
415
|
+
return matchesPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, message);
|
|
416
|
+
}
|
|
417
|
+
function min(minVal, message) {
|
|
418
|
+
return (value) => {
|
|
419
|
+
if (value != null && value < minVal) {
|
|
420
|
+
return message || `Must be at least ${minVal}`;
|
|
421
|
+
}
|
|
422
|
+
return null;
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function max(maxVal, message) {
|
|
426
|
+
return (value) => {
|
|
427
|
+
if (value != null && value > maxVal) {
|
|
428
|
+
return message || `Must be at most ${maxVal}`;
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
function custom(fn, message) {
|
|
434
|
+
return (value) => fn(value) ? null : message;
|
|
435
|
+
}
|
|
436
|
+
function form(config) {
|
|
437
|
+
const fieldEntries = Object.entries(config);
|
|
438
|
+
const fieldMap = {};
|
|
439
|
+
const manualErrors = {};
|
|
440
|
+
for (const [name, cfg] of fieldEntries) {
|
|
441
|
+
const [value, setValue] = signal(cfg.initial);
|
|
442
|
+
const [isTouched, setTouched] = signal(false);
|
|
443
|
+
const error = derived(() => {
|
|
444
|
+
if (manualErrors[name]) return manualErrors[name];
|
|
445
|
+
const val = value();
|
|
446
|
+
if (!cfg.validators) return null;
|
|
447
|
+
for (const validator of cfg.validators) {
|
|
448
|
+
const msg = validator(val);
|
|
449
|
+
if (msg) return msg;
|
|
450
|
+
}
|
|
451
|
+
return null;
|
|
452
|
+
});
|
|
453
|
+
fieldMap[name] = {
|
|
454
|
+
value,
|
|
455
|
+
set: setValue,
|
|
456
|
+
error,
|
|
457
|
+
touched: isTouched,
|
|
458
|
+
touch: () => setTouched(true),
|
|
459
|
+
reset: () => {
|
|
460
|
+
setValue(cfg.initial);
|
|
461
|
+
setTouched(false);
|
|
462
|
+
manualErrors[name] = null;
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
const errors = derived(() => {
|
|
467
|
+
const result = {};
|
|
468
|
+
for (const [name, field] of Object.entries(fieldMap)) {
|
|
469
|
+
result[name] = field.error();
|
|
470
|
+
}
|
|
471
|
+
return result;
|
|
472
|
+
});
|
|
473
|
+
const isValid = derived(() => {
|
|
474
|
+
for (const field of Object.values(fieldMap)) {
|
|
475
|
+
if (field.error() != null) return false;
|
|
476
|
+
}
|
|
477
|
+
return true;
|
|
478
|
+
});
|
|
479
|
+
const isDirty = derived(() => {
|
|
480
|
+
for (const [name, cfg] of fieldEntries) {
|
|
481
|
+
if (!Object.is(fieldMap[name].value(), cfg.initial)) return true;
|
|
482
|
+
}
|
|
483
|
+
return false;
|
|
484
|
+
});
|
|
485
|
+
const touchedState = derived(() => {
|
|
486
|
+
const result = {};
|
|
487
|
+
for (const [name, field] of Object.entries(fieldMap)) {
|
|
488
|
+
result[name] = field.touched();
|
|
489
|
+
}
|
|
490
|
+
return result;
|
|
491
|
+
});
|
|
492
|
+
const values = derived(() => {
|
|
493
|
+
const result = {};
|
|
494
|
+
for (const [name, field] of Object.entries(fieldMap)) {
|
|
495
|
+
result[name] = field.value();
|
|
496
|
+
}
|
|
497
|
+
return result;
|
|
498
|
+
});
|
|
499
|
+
function handleSubmit(onSubmit) {
|
|
500
|
+
return (e) => {
|
|
501
|
+
if (e) e.preventDefault();
|
|
502
|
+
for (const field of Object.values(fieldMap)) {
|
|
503
|
+
field.touch();
|
|
504
|
+
}
|
|
505
|
+
if (isValid()) {
|
|
506
|
+
onSubmit(values());
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
function reset() {
|
|
511
|
+
for (const field of Object.values(fieldMap)) {
|
|
512
|
+
field.reset();
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
function setError(field, message) {
|
|
516
|
+
manualErrors[field] = message;
|
|
517
|
+
}
|
|
518
|
+
return {
|
|
519
|
+
fields: fieldMap,
|
|
520
|
+
errors,
|
|
521
|
+
isValid,
|
|
522
|
+
isDirty,
|
|
523
|
+
touched: touchedState,
|
|
524
|
+
values,
|
|
525
|
+
handleSubmit,
|
|
526
|
+
reset,
|
|
527
|
+
setError
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// src/core/ssr-context.ts
|
|
532
|
+
var ssrMode = false;
|
|
533
|
+
function isSSR() {
|
|
534
|
+
return ssrMode;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// src/core/signals/effect.ts
|
|
538
|
+
function effect(effectFn) {
|
|
539
|
+
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
540
|
+
if (isSSR()) return () => {
|
|
541
|
+
};
|
|
542
|
+
let runCount = 0;
|
|
543
|
+
let cleanupHandle = () => {
|
|
544
|
+
};
|
|
545
|
+
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
546
|
+
const subscriber = () => {
|
|
547
|
+
cleanupHandle();
|
|
548
|
+
runCount++;
|
|
549
|
+
if (hook) hook.emit("effect:run", { effectFn, runCount });
|
|
550
|
+
cleanupHandle = track(effectFn, subscriber);
|
|
551
|
+
};
|
|
552
|
+
cleanupHandle = track(effectFn, subscriber);
|
|
553
|
+
runCount = 1;
|
|
554
|
+
if (hook) hook.emit("effect:create", { effectFn });
|
|
555
|
+
return () => {
|
|
556
|
+
if (hook) hook.emit("effect:destroy", { effectFn });
|
|
557
|
+
cleanupHandle();
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
// src/ui/virtualList.ts
|
|
562
|
+
function VirtualList(props) {
|
|
563
|
+
const overscan = props.overscan ?? 3;
|
|
564
|
+
const [scrollTop, setScrollTop] = signal(0);
|
|
565
|
+
const container = document.createElement("div");
|
|
566
|
+
container.style.overflow = "auto";
|
|
567
|
+
container.style.height = `${props.containerHeight}px`;
|
|
568
|
+
container.style.position = "relative";
|
|
569
|
+
if (props.class) container.className = props.class;
|
|
570
|
+
const spacer = document.createElement("div");
|
|
571
|
+
spacer.style.position = "relative";
|
|
572
|
+
const content = document.createElement("div");
|
|
573
|
+
content.style.position = "absolute";
|
|
574
|
+
content.style.left = "0";
|
|
575
|
+
content.style.right = "0";
|
|
576
|
+
spacer.appendChild(content);
|
|
577
|
+
container.appendChild(spacer);
|
|
578
|
+
container.addEventListener("scroll", () => {
|
|
579
|
+
setScrollTop(container.scrollTop);
|
|
580
|
+
});
|
|
581
|
+
const update = () => {
|
|
582
|
+
const items = props.items();
|
|
583
|
+
const totalHeight = items.length * props.itemHeight;
|
|
584
|
+
spacer.style.height = `${totalHeight}px`;
|
|
585
|
+
const currentScroll = scrollTop();
|
|
586
|
+
const startIndex = Math.max(0, Math.floor(currentScroll / props.itemHeight) - overscan);
|
|
587
|
+
const visibleCount = Math.ceil(props.containerHeight / props.itemHeight) + 2 * overscan;
|
|
588
|
+
const endIndex = Math.min(items.length, startIndex + visibleCount);
|
|
589
|
+
content.style.top = `${startIndex * props.itemHeight}px`;
|
|
590
|
+
content.innerHTML = "";
|
|
591
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
592
|
+
const itemEl = props.renderItem(items[i], i);
|
|
593
|
+
itemEl.style.height = `${props.itemHeight}px`;
|
|
594
|
+
itemEl.style.boxSizing = "border-box";
|
|
595
|
+
content.appendChild(itemEl);
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
effect(update);
|
|
599
|
+
return container;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// src/ui/intersection.ts
|
|
603
|
+
function intersection(options) {
|
|
604
|
+
const [isIntersecting, setIsIntersecting] = signal(false);
|
|
605
|
+
const [ratio, setRatio] = signal(0);
|
|
606
|
+
let observer = null;
|
|
607
|
+
let currentElement = null;
|
|
608
|
+
function observe(element) {
|
|
609
|
+
unobserve();
|
|
610
|
+
currentElement = element;
|
|
611
|
+
observer = new IntersectionObserver((entries) => {
|
|
612
|
+
const entry = entries[0];
|
|
613
|
+
if (entry) {
|
|
614
|
+
setIsIntersecting(entry.isIntersecting);
|
|
615
|
+
setRatio(entry.intersectionRatio);
|
|
616
|
+
}
|
|
617
|
+
}, options);
|
|
618
|
+
observer.observe(element);
|
|
619
|
+
}
|
|
620
|
+
function unobserve() {
|
|
621
|
+
if (observer) {
|
|
622
|
+
if (currentElement) observer.unobserve(currentElement);
|
|
623
|
+
observer.disconnect();
|
|
624
|
+
observer = null;
|
|
625
|
+
currentElement = null;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
return {
|
|
629
|
+
isIntersecting,
|
|
630
|
+
intersectionRatio: ratio,
|
|
631
|
+
observe,
|
|
632
|
+
unobserve
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
function lazyLoad(element, loader, options) {
|
|
636
|
+
const observer = new IntersectionObserver((entries) => {
|
|
637
|
+
for (const entry of entries) {
|
|
638
|
+
if (entry.isIntersecting) {
|
|
639
|
+
loader();
|
|
640
|
+
observer.disconnect();
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}, options);
|
|
645
|
+
observer.observe(element);
|
|
646
|
+
return () => observer.disconnect();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// src/ui/inputMask.ts
|
|
650
|
+
function inputMask(options) {
|
|
651
|
+
const placeholder = options.placeholder || "_";
|
|
652
|
+
const [value, setValue] = signal("");
|
|
653
|
+
const [rawValue, setRawValue] = signal("");
|
|
654
|
+
function applyMask(raw) {
|
|
655
|
+
let result = "";
|
|
656
|
+
let rawIndex = 0;
|
|
657
|
+
for (let i = 0; i < options.pattern.length && rawIndex < raw.length; i++) {
|
|
658
|
+
const maskChar = options.pattern[i];
|
|
659
|
+
if (maskChar === "9") {
|
|
660
|
+
while (rawIndex < raw.length && !/\d/.test(raw[rawIndex])) rawIndex++;
|
|
661
|
+
if (rawIndex < raw.length) {
|
|
662
|
+
result += raw[rawIndex++];
|
|
663
|
+
}
|
|
664
|
+
} else if (maskChar === "A") {
|
|
665
|
+
while (rawIndex < raw.length && !/[a-zA-Z]/.test(raw[rawIndex])) rawIndex++;
|
|
666
|
+
if (rawIndex < raw.length) {
|
|
667
|
+
result += raw[rawIndex++];
|
|
668
|
+
}
|
|
669
|
+
} else if (maskChar === "*") {
|
|
670
|
+
result += raw[rawIndex++];
|
|
671
|
+
} else {
|
|
672
|
+
result += maskChar;
|
|
673
|
+
if (raw[rawIndex] === maskChar) rawIndex++;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return result;
|
|
677
|
+
}
|
|
678
|
+
function extractRaw(masked) {
|
|
679
|
+
let raw = "";
|
|
680
|
+
for (let i = 0; i < masked.length && i < options.pattern.length; i++) {
|
|
681
|
+
const maskChar = options.pattern[i];
|
|
682
|
+
if (maskChar === "9" || maskChar === "A" || maskChar === "*") {
|
|
683
|
+
raw += masked[i];
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return raw;
|
|
687
|
+
}
|
|
688
|
+
function bind(input) {
|
|
689
|
+
input.addEventListener("input", () => {
|
|
690
|
+
const raw = input.value.replace(/[^a-zA-Z0-9]/g, "");
|
|
691
|
+
const masked = applyMask(raw);
|
|
692
|
+
setValue(masked);
|
|
693
|
+
setRawValue(extractRaw(masked));
|
|
694
|
+
input.value = masked;
|
|
695
|
+
});
|
|
696
|
+
input.addEventListener("focus", () => {
|
|
697
|
+
if (!input.value) {
|
|
698
|
+
const display = options.pattern.replace(/9/g, placeholder).replace(/A/g, placeholder).replace(/\*/g, placeholder);
|
|
699
|
+
input.placeholder = display;
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
}
|
|
703
|
+
return { value, rawValue, bind };
|
|
704
|
+
}
|
|
705
|
+
function phoneMask() {
|
|
706
|
+
return { pattern: "(999) 999-9999" };
|
|
707
|
+
}
|
|
708
|
+
function dateMask() {
|
|
709
|
+
return { pattern: "99/99/9999" };
|
|
710
|
+
}
|
|
711
|
+
function creditCardMask() {
|
|
712
|
+
return { pattern: "9999 9999 9999 9999" };
|
|
713
|
+
}
|
|
714
|
+
function timeMask() {
|
|
715
|
+
return { pattern: "99:99" };
|
|
716
|
+
}
|
|
717
|
+
function ssnMask() {
|
|
718
|
+
return { pattern: "999-99-9999" };
|
|
719
|
+
}
|
|
720
|
+
function zipMask() {
|
|
721
|
+
return { pattern: "99999" };
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// src/ui/a11y.ts
|
|
725
|
+
function aria(element, attrs) {
|
|
726
|
+
for (const [key, value] of Object.entries(attrs)) {
|
|
727
|
+
const ariaKey = key.startsWith("aria-") ? key : `aria-${key}`;
|
|
728
|
+
if (typeof value === "function") {
|
|
729
|
+
const getter = value;
|
|
730
|
+
track(() => {
|
|
731
|
+
element.setAttribute(ariaKey, String(getter()));
|
|
732
|
+
});
|
|
733
|
+
} else {
|
|
734
|
+
element.setAttribute(ariaKey, String(value));
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
function focus() {
|
|
739
|
+
const [isFocused, setIsFocused] = signal(false);
|
|
740
|
+
let currentElement = null;
|
|
741
|
+
function bind(element) {
|
|
742
|
+
currentElement = element;
|
|
743
|
+
element.addEventListener("focus", () => setIsFocused(true));
|
|
744
|
+
element.addEventListener("blur", () => setIsFocused(false));
|
|
745
|
+
}
|
|
746
|
+
function focus2() {
|
|
747
|
+
currentElement?.focus();
|
|
748
|
+
}
|
|
749
|
+
function blur() {
|
|
750
|
+
currentElement?.blur();
|
|
751
|
+
}
|
|
752
|
+
return { isFocused, focus: focus2, blur, bind };
|
|
753
|
+
}
|
|
754
|
+
function FocusTrap(nodes, options = {}) {
|
|
755
|
+
const container = document.createElement("div");
|
|
756
|
+
container.setAttribute("data-sibu-focus-trap", "true");
|
|
757
|
+
container.appendChild(nodes);
|
|
758
|
+
const previouslyFocused = document.activeElement;
|
|
759
|
+
container.addEventListener("keydown", (e) => {
|
|
760
|
+
if (e.key !== "Tab") return;
|
|
761
|
+
const focusable = container.querySelectorAll(
|
|
762
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
763
|
+
);
|
|
764
|
+
if (focusable.length === 0) return;
|
|
765
|
+
const first = focusable[0];
|
|
766
|
+
const last = focusable[focusable.length - 1];
|
|
767
|
+
if (e.shiftKey) {
|
|
768
|
+
if (document.activeElement === first) {
|
|
769
|
+
e.preventDefault();
|
|
770
|
+
last.focus();
|
|
771
|
+
}
|
|
772
|
+
} else {
|
|
773
|
+
if (document.activeElement === last) {
|
|
774
|
+
e.preventDefault();
|
|
775
|
+
first.focus();
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
if (options.autoFocus !== false) {
|
|
780
|
+
queueMicrotask(() => {
|
|
781
|
+
const first = container.querySelector(
|
|
782
|
+
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
|
|
783
|
+
);
|
|
784
|
+
first?.focus();
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
if (options.restoreFocus !== false) {
|
|
788
|
+
const observer = new MutationObserver((mutations) => {
|
|
789
|
+
for (const mutation of mutations) {
|
|
790
|
+
for (const removed of Array.from(mutation.removedNodes)) {
|
|
791
|
+
if (removed === container || removed.contains(container)) {
|
|
792
|
+
previouslyFocused?.focus();
|
|
793
|
+
observer.disconnect();
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
queueMicrotask(() => {
|
|
800
|
+
if (container.parentNode) {
|
|
801
|
+
observer.observe(container.parentNode, { childList: true });
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
return container;
|
|
806
|
+
}
|
|
807
|
+
function hotkey(key, handler, options = {}) {
|
|
808
|
+
const listener = (e) => {
|
|
809
|
+
const ke = e;
|
|
810
|
+
if (ke.key.toLowerCase() !== key.toLowerCase()) return;
|
|
811
|
+
if (options.ctrl && !ke.ctrlKey) return;
|
|
812
|
+
if (options.shift && !ke.shiftKey) return;
|
|
813
|
+
if (options.alt && !ke.altKey) return;
|
|
814
|
+
if (options.meta && !ke.metaKey) return;
|
|
815
|
+
handler(ke);
|
|
816
|
+
};
|
|
817
|
+
document.addEventListener("keydown", listener);
|
|
818
|
+
return () => document.removeEventListener("keydown", listener);
|
|
819
|
+
}
|
|
820
|
+
function announce(message, priority = "polite") {
|
|
821
|
+
let region = document.getElementById(`sibu-announce-${priority}`);
|
|
822
|
+
if (!region) {
|
|
823
|
+
region = document.createElement("div");
|
|
824
|
+
region.id = `sibu-announce-${priority}`;
|
|
825
|
+
region.setAttribute("aria-live", priority);
|
|
826
|
+
region.setAttribute("aria-atomic", "true");
|
|
827
|
+
region.setAttribute("role", priority === "assertive" ? "alert" : "status");
|
|
828
|
+
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;";
|
|
829
|
+
document.body.appendChild(region);
|
|
830
|
+
}
|
|
831
|
+
region.textContent = "";
|
|
832
|
+
requestAnimationFrame(() => {
|
|
833
|
+
if (region) region.textContent = message;
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
// src/ui/scopedStyle.ts
|
|
838
|
+
var scopeCounter = 0;
|
|
839
|
+
function scopedStyle(css) {
|
|
840
|
+
const id = `sibu-s${scopeCounter++}`;
|
|
841
|
+
const attr = `data-${id}`;
|
|
842
|
+
const scopedCSS = css.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, (match, selector, delimiter) => {
|
|
843
|
+
const trimmed = selector.trim();
|
|
844
|
+
if (trimmed.startsWith("@") || trimmed.startsWith("from") || trimmed.startsWith("to") || /^\d+%$/.test(trimmed)) {
|
|
845
|
+
return match;
|
|
846
|
+
}
|
|
847
|
+
return `${trimmed}[${attr}]${delimiter}`;
|
|
848
|
+
});
|
|
849
|
+
const styleEl = document.createElement("style");
|
|
850
|
+
styleEl.setAttribute("data-sibu-scope", id);
|
|
851
|
+
styleEl.textContent = scopedCSS;
|
|
852
|
+
document.head.appendChild(styleEl);
|
|
853
|
+
return { scope: id, attr };
|
|
854
|
+
}
|
|
855
|
+
function withScopedStyle(css, component) {
|
|
856
|
+
const { attr } = scopedStyle(css);
|
|
857
|
+
return (props) => {
|
|
858
|
+
const el = component(props);
|
|
859
|
+
applyScopeRecursive(el, attr);
|
|
860
|
+
return el;
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
function applyScopeRecursive(element, attr) {
|
|
864
|
+
element.setAttribute(attr, "");
|
|
865
|
+
for (const child of Array.from(element.children)) {
|
|
866
|
+
if (child instanceof HTMLElement) {
|
|
867
|
+
applyScopeRecursive(child, attr);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
function removeScopedStyle(scopeId) {
|
|
872
|
+
const el = document.head.querySelector(`style[data-sibu-scope="${scopeId}"]`);
|
|
873
|
+
if (el) el.remove();
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
// src/utils/sanitize.ts
|
|
877
|
+
function sanitize(value) {
|
|
878
|
+
return String(value).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
879
|
+
}
|
|
880
|
+
function sanitizeUrl(url) {
|
|
881
|
+
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
882
|
+
if (!trimmed) return "";
|
|
883
|
+
const lower = trimmed.toLowerCase();
|
|
884
|
+
if (lower.startsWith("javascript:") || lower.startsWith("data:") || lower.startsWith("vbscript:") || lower.startsWith("blob:")) {
|
|
885
|
+
return "";
|
|
886
|
+
}
|
|
887
|
+
return trimmed;
|
|
888
|
+
}
|
|
889
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set(["href", "src", "action", "formaction", "cite", "poster", "background", "srcset"]);
|
|
890
|
+
function isUrlAttribute(attr) {
|
|
891
|
+
return URL_ATTRIBUTES.has(attr);
|
|
892
|
+
}
|
|
893
|
+
function sanitizeAttribute(attr, value) {
|
|
894
|
+
if (isUrlAttribute(attr)) {
|
|
895
|
+
return sanitizeUrl(value);
|
|
896
|
+
}
|
|
897
|
+
return sanitize(value);
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// src/reactivity/bindAttribute.ts
|
|
901
|
+
function bindAttribute(el, attr, getter) {
|
|
902
|
+
function commit() {
|
|
903
|
+
let value;
|
|
904
|
+
try {
|
|
905
|
+
value = getter();
|
|
906
|
+
} catch {
|
|
907
|
+
return;
|
|
908
|
+
}
|
|
909
|
+
if (typeof value === "boolean") {
|
|
910
|
+
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
911
|
+
el[attr] = value;
|
|
912
|
+
} else if (value) {
|
|
913
|
+
el.setAttribute(attr, "");
|
|
914
|
+
} else {
|
|
915
|
+
el.removeAttribute(attr);
|
|
916
|
+
}
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
const str = sanitizeAttribute(attr, String(value));
|
|
920
|
+
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
921
|
+
el[attr] = attr === "checked" ? Boolean(value) : str;
|
|
922
|
+
} else {
|
|
923
|
+
el.setAttribute(attr, str);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
const teardown = track(commit);
|
|
927
|
+
return teardown;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
// src/ui/reactiveAttr.ts
|
|
931
|
+
function bindAttrs(el, attrs) {
|
|
932
|
+
const teardowns = [];
|
|
933
|
+
for (const [attr, value] of Object.entries(attrs)) {
|
|
934
|
+
if (typeof value === "function") {
|
|
935
|
+
const teardown = bindAttribute(el, attr, value);
|
|
936
|
+
teardowns.push(teardown);
|
|
937
|
+
} else if (typeof value === "boolean") {
|
|
938
|
+
if (value) {
|
|
939
|
+
el.setAttribute(attr, "");
|
|
940
|
+
} else {
|
|
941
|
+
el.removeAttribute(attr);
|
|
942
|
+
}
|
|
943
|
+
} else {
|
|
944
|
+
el.setAttribute(attr, String(value));
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return () => {
|
|
948
|
+
for (const td of teardowns) {
|
|
949
|
+
td();
|
|
950
|
+
}
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
function bindBoolAttr(el, attr, getter) {
|
|
954
|
+
if (typeof getter !== "function") {
|
|
955
|
+
if (getter) {
|
|
956
|
+
el.setAttribute(attr, "");
|
|
957
|
+
} else {
|
|
958
|
+
el.removeAttribute(attr);
|
|
959
|
+
}
|
|
960
|
+
return () => {
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
const reactiveGetter = getter;
|
|
964
|
+
function commit() {
|
|
965
|
+
let value;
|
|
966
|
+
try {
|
|
967
|
+
value = reactiveGetter();
|
|
968
|
+
} catch {
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
971
|
+
if (value) {
|
|
972
|
+
el.setAttribute(attr, "");
|
|
973
|
+
} else {
|
|
974
|
+
el.removeAttribute(attr);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
const teardown = track(commit);
|
|
978
|
+
return teardown;
|
|
979
|
+
}
|
|
980
|
+
function bindData(el, key, getter) {
|
|
981
|
+
const dataAttr = `data-${key}`;
|
|
982
|
+
if (typeof getter !== "function") {
|
|
983
|
+
el.setAttribute(dataAttr, String(getter));
|
|
984
|
+
return () => {
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
return bindAttribute(el, dataAttr, getter);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// src/ui/dialog.ts
|
|
991
|
+
function dialog() {
|
|
992
|
+
const [isOpen, setIsOpen] = signal(false);
|
|
993
|
+
let listenerAttached = false;
|
|
994
|
+
function handleKeydown(event) {
|
|
995
|
+
if (event.key === "Escape") {
|
|
996
|
+
close();
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
function open() {
|
|
1000
|
+
setIsOpen(true);
|
|
1001
|
+
if (typeof window !== "undefined" && !listenerAttached) {
|
|
1002
|
+
window.addEventListener("keydown", handleKeydown);
|
|
1003
|
+
listenerAttached = true;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
function close() {
|
|
1007
|
+
setIsOpen(false);
|
|
1008
|
+
if (typeof window !== "undefined" && listenerAttached) {
|
|
1009
|
+
window.removeEventListener("keydown", handleKeydown);
|
|
1010
|
+
listenerAttached = false;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
function toggle() {
|
|
1014
|
+
if (isOpen()) {
|
|
1015
|
+
close();
|
|
1016
|
+
} else {
|
|
1017
|
+
open();
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return { open, close, isOpen, toggle };
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
// src/ui/toast.ts
|
|
1024
|
+
var toastCounter = 0;
|
|
1025
|
+
function toast(options) {
|
|
1026
|
+
const duration = options?.duration ?? 3e3;
|
|
1027
|
+
const maxToasts = options?.maxToasts ?? Infinity;
|
|
1028
|
+
const [toasts, setToasts] = signal([]);
|
|
1029
|
+
const timers = /* @__PURE__ */ new Map();
|
|
1030
|
+
function show(message, type) {
|
|
1031
|
+
const id = `toast-${++toastCounter}`;
|
|
1032
|
+
const toast2 = { id, message, type };
|
|
1033
|
+
setToasts((prev) => {
|
|
1034
|
+
const next = [...prev, toast2];
|
|
1035
|
+
if (next.length > maxToasts) {
|
|
1036
|
+
const removed = next.splice(0, next.length - maxToasts);
|
|
1037
|
+
for (const r of removed) {
|
|
1038
|
+
clearTimerForToast(r.id);
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return next;
|
|
1042
|
+
});
|
|
1043
|
+
if (duration > 0) {
|
|
1044
|
+
const timer = setTimeout(() => {
|
|
1045
|
+
dismiss(id);
|
|
1046
|
+
}, duration);
|
|
1047
|
+
timers.set(id, timer);
|
|
1048
|
+
}
|
|
1049
|
+
return id;
|
|
1050
|
+
}
|
|
1051
|
+
function dismiss(id) {
|
|
1052
|
+
clearTimerForToast(id);
|
|
1053
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
1054
|
+
}
|
|
1055
|
+
function dismissAll() {
|
|
1056
|
+
for (const timer of timers.values()) {
|
|
1057
|
+
clearTimeout(timer);
|
|
1058
|
+
}
|
|
1059
|
+
timers.clear();
|
|
1060
|
+
setToasts([]);
|
|
1061
|
+
}
|
|
1062
|
+
function clearTimerForToast(id) {
|
|
1063
|
+
const timer = timers.get(id);
|
|
1064
|
+
if (timer !== void 0) {
|
|
1065
|
+
clearTimeout(timer);
|
|
1066
|
+
timers.delete(id);
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return { toasts, show, dismiss, dismissAll };
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
// src/ui/infiniteScroll.ts
|
|
1073
|
+
function infiniteScroll(options) {
|
|
1074
|
+
const { onLoadMore, hasMore, threshold = 0 } = options;
|
|
1075
|
+
const [loading, setLoading] = signal(false);
|
|
1076
|
+
const sentinelRef = { current: null };
|
|
1077
|
+
let observer = null;
|
|
1078
|
+
let disposed = false;
|
|
1079
|
+
function createObserver() {
|
|
1080
|
+
if (typeof IntersectionObserver === "undefined") return;
|
|
1081
|
+
observer = new IntersectionObserver(
|
|
1082
|
+
(entries) => {
|
|
1083
|
+
const entry = entries[0];
|
|
1084
|
+
if (entry?.isIntersecting && !loading() && hasMore() && !disposed) {
|
|
1085
|
+
loadMore();
|
|
1086
|
+
}
|
|
1087
|
+
},
|
|
1088
|
+
{ threshold }
|
|
1089
|
+
);
|
|
1090
|
+
if (sentinelRef.current) {
|
|
1091
|
+
observer.observe(sentinelRef.current);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
async function loadMore() {
|
|
1095
|
+
setLoading(true);
|
|
1096
|
+
try {
|
|
1097
|
+
await onLoadMore();
|
|
1098
|
+
} finally {
|
|
1099
|
+
setLoading(false);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
const originalRef = sentinelRef;
|
|
1103
|
+
let _current = null;
|
|
1104
|
+
Object.defineProperty(originalRef, "current", {
|
|
1105
|
+
get() {
|
|
1106
|
+
return _current;
|
|
1107
|
+
},
|
|
1108
|
+
set(el) {
|
|
1109
|
+
_current = el;
|
|
1110
|
+
if (observer) {
|
|
1111
|
+
observer.disconnect();
|
|
1112
|
+
observer = null;
|
|
1113
|
+
}
|
|
1114
|
+
if (el && !disposed) {
|
|
1115
|
+
createObserver();
|
|
1116
|
+
}
|
|
1117
|
+
},
|
|
1118
|
+
configurable: true
|
|
1119
|
+
});
|
|
1120
|
+
function dispose() {
|
|
1121
|
+
disposed = true;
|
|
1122
|
+
if (observer) {
|
|
1123
|
+
observer.disconnect();
|
|
1124
|
+
observer = null;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return { sentinelRef: originalRef, loading, dispose };
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1130
|
+
// src/ui/pagination.ts
|
|
1131
|
+
function pagination(options) {
|
|
1132
|
+
const pageSizeValue = options.pageSize ?? 10;
|
|
1133
|
+
const [page, setPage] = signal(options.initialPage ?? 1);
|
|
1134
|
+
const [pageSize] = signal(pageSizeValue);
|
|
1135
|
+
const totalPages = derived(() => {
|
|
1136
|
+
const total = options.totalItems();
|
|
1137
|
+
return Math.max(1, Math.ceil(total / pageSizeValue));
|
|
1138
|
+
});
|
|
1139
|
+
const startIndex = derived(() => {
|
|
1140
|
+
return (page() - 1) * pageSizeValue;
|
|
1141
|
+
});
|
|
1142
|
+
const endIndex = derived(() => {
|
|
1143
|
+
const end = page() * pageSizeValue;
|
|
1144
|
+
const total = options.totalItems();
|
|
1145
|
+
return Math.min(end, total);
|
|
1146
|
+
});
|
|
1147
|
+
function next() {
|
|
1148
|
+
if (page() < totalPages()) {
|
|
1149
|
+
setPage((p) => p + 1);
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
function prev() {
|
|
1153
|
+
if (page() > 1) {
|
|
1154
|
+
setPage((p) => p - 1);
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
function goTo(target) {
|
|
1158
|
+
const clamped = Math.max(1, Math.min(target, totalPages()));
|
|
1159
|
+
setPage(clamped);
|
|
1160
|
+
}
|
|
1161
|
+
return { page, pageSize, totalPages, next, prev, goTo, startIndex, endIndex };
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
// src/ui/eventBus.ts
|
|
1165
|
+
function eventBus() {
|
|
1166
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
1167
|
+
function on(event, handler) {
|
|
1168
|
+
let set = listeners.get(event);
|
|
1169
|
+
if (!set) {
|
|
1170
|
+
set = /* @__PURE__ */ new Set();
|
|
1171
|
+
listeners.set(event, set);
|
|
1172
|
+
}
|
|
1173
|
+
set.add(handler);
|
|
1174
|
+
return () => off(event, handler);
|
|
1175
|
+
}
|
|
1176
|
+
function emit(event, data) {
|
|
1177
|
+
const set = listeners.get(event);
|
|
1178
|
+
if (set) {
|
|
1179
|
+
for (const handler of set) {
|
|
1180
|
+
handler(data);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
function off(event, handler) {
|
|
1185
|
+
const set = listeners.get(event);
|
|
1186
|
+
if (set) {
|
|
1187
|
+
set.delete(handler);
|
|
1188
|
+
if (set.size === 0) {
|
|
1189
|
+
listeners.delete(event);
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
function clear() {
|
|
1194
|
+
listeners.clear();
|
|
1195
|
+
}
|
|
1196
|
+
return { on, emit, off, clear };
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
// src/platform/customElement.ts
|
|
1200
|
+
function defineElement(name, component, options = {}) {
|
|
1201
|
+
if (customElements.get(name)) return;
|
|
1202
|
+
const observed = options.observedAttributes || [];
|
|
1203
|
+
class SibuElement extends HTMLElement {
|
|
1204
|
+
constructor() {
|
|
1205
|
+
super();
|
|
1206
|
+
this._rendered = false;
|
|
1207
|
+
if (options.shadow !== false) {
|
|
1208
|
+
this._root = this.attachShadow({ mode: options.mode || "open" });
|
|
1209
|
+
} else {
|
|
1210
|
+
this._root = this;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
static get observedAttributes() {
|
|
1214
|
+
return observed;
|
|
1215
|
+
}
|
|
1216
|
+
connectedCallback() {
|
|
1217
|
+
this._render();
|
|
1218
|
+
}
|
|
1219
|
+
disconnectedCallback() {
|
|
1220
|
+
if (this._root instanceof ShadowRoot) {
|
|
1221
|
+
this._root.innerHTML = "";
|
|
1222
|
+
}
|
|
1223
|
+
this._rendered = false;
|
|
1224
|
+
}
|
|
1225
|
+
attributeChangedCallback() {
|
|
1226
|
+
if (this._rendered) {
|
|
1227
|
+
this._render();
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
_render() {
|
|
1231
|
+
const props = this._getProps();
|
|
1232
|
+
if (this._root instanceof ShadowRoot) {
|
|
1233
|
+
this._root.innerHTML = "";
|
|
1234
|
+
} else {
|
|
1235
|
+
while (this._root.firstChild) {
|
|
1236
|
+
this._root.removeChild(this._root.firstChild);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
if (options.styles && this._root instanceof ShadowRoot) {
|
|
1240
|
+
const styleEl = document.createElement("style");
|
|
1241
|
+
styleEl.textContent = options.styles;
|
|
1242
|
+
this._root.appendChild(styleEl);
|
|
1243
|
+
}
|
|
1244
|
+
const el = component(props, this);
|
|
1245
|
+
this._root.appendChild(el);
|
|
1246
|
+
this._rendered = true;
|
|
1247
|
+
}
|
|
1248
|
+
_getProps() {
|
|
1249
|
+
const props = {};
|
|
1250
|
+
for (const attr of this.attributes) {
|
|
1251
|
+
props[attr.name] = attr.value;
|
|
1252
|
+
}
|
|
1253
|
+
return props;
|
|
1254
|
+
}
|
|
1255
|
+
}
|
|
1256
|
+
customElements.define(name, SibuElement);
|
|
1257
|
+
}
|
|
1258
|
+
function svgElement(tag, props = {}, ...nodes) {
|
|
1259
|
+
const SVG_NS = "http://www.w3.org/2000/svg";
|
|
1260
|
+
const el = document.createElementNS(SVG_NS, tag);
|
|
1261
|
+
for (const [key, value] of Object.entries(props)) {
|
|
1262
|
+
if (key === "nodes") continue;
|
|
1263
|
+
if (typeof value === "function" && key.startsWith("on")) {
|
|
1264
|
+
el.addEventListener(key.slice(2).toLowerCase(), value);
|
|
1265
|
+
} else if (value != null) {
|
|
1266
|
+
el.setAttribute(key, String(value));
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
for (const child of nodes) {
|
|
1270
|
+
if (typeof child === "string") {
|
|
1271
|
+
el.appendChild(document.createTextNode(child));
|
|
1272
|
+
} else if (child instanceof Node) {
|
|
1273
|
+
el.appendChild(child);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return el;
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
// src/patterns/composable.ts
|
|
1280
|
+
function composable(setup) {
|
|
1281
|
+
return setup;
|
|
1282
|
+
}
|
|
1283
|
+
function RenderProp(props) {
|
|
1284
|
+
return props.render(props.data());
|
|
1285
|
+
}
|
|
1286
|
+
function withBoundary(name, component) {
|
|
1287
|
+
return (props) => {
|
|
1288
|
+
const wrapper = document.createElement("div");
|
|
1289
|
+
wrapper.setAttribute("data-sibu-boundary", name);
|
|
1290
|
+
try {
|
|
1291
|
+
const el = component(props);
|
|
1292
|
+
wrapper.appendChild(el);
|
|
1293
|
+
} catch (error) {
|
|
1294
|
+
const errorEl = document.createElement("div");
|
|
1295
|
+
errorEl.setAttribute("data-sibu-boundary-error", name);
|
|
1296
|
+
errorEl.style.cssText = "color: red; border: 1px solid red; padding: 8px; margin: 4px;";
|
|
1297
|
+
errorEl.textContent = `[${name}] ${error instanceof Error ? error.message : String(error)}`;
|
|
1298
|
+
wrapper.appendChild(errorEl);
|
|
1299
|
+
}
|
|
1300
|
+
return wrapper;
|
|
1301
|
+
};
|
|
1302
|
+
}
|
|
1303
|
+
function createSlots(slots) {
|
|
1304
|
+
return {
|
|
1305
|
+
renderSlot(name, fallback) {
|
|
1306
|
+
const slotFn = slots[name];
|
|
1307
|
+
if (slotFn) {
|
|
1308
|
+
const result = slotFn();
|
|
1309
|
+
if (Array.isArray(result)) {
|
|
1310
|
+
const fragment = document.createElement("div");
|
|
1311
|
+
fragment.style.display = "contents";
|
|
1312
|
+
for (const el of result) fragment.appendChild(el);
|
|
1313
|
+
return fragment;
|
|
1314
|
+
}
|
|
1315
|
+
return result;
|
|
1316
|
+
}
|
|
1317
|
+
return fallback ? fallback() : null;
|
|
1318
|
+
},
|
|
1319
|
+
hasSlot(name) {
|
|
1320
|
+
return name in slots;
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
// src/patterns/hoc.ts
|
|
1326
|
+
function withWrapper(WrappedComponent, wrapper) {
|
|
1327
|
+
return (props) => wrapper(WrappedComponent, props);
|
|
1328
|
+
}
|
|
1329
|
+
function withDefaults(component, defaults) {
|
|
1330
|
+
return (props) => component({ ...defaults, ...props });
|
|
1331
|
+
}
|
|
1332
|
+
function compose(...wrappers) {
|
|
1333
|
+
return (component) => wrappers.reduceRight((comp, wrapper) => wrapper(comp), component);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
// src/patterns/componentProps.ts
|
|
1337
|
+
function defineComponent(config) {
|
|
1338
|
+
const { defaults, setup } = config;
|
|
1339
|
+
return (props) => {
|
|
1340
|
+
const merged = defaults ? { ...defaults, ...props } : props;
|
|
1341
|
+
return setup(merged);
|
|
1342
|
+
};
|
|
1343
|
+
}
|
|
1344
|
+
function defineSlottedComponent(config) {
|
|
1345
|
+
const { defaults, setup } = config;
|
|
1346
|
+
return (props) => {
|
|
1347
|
+
const merged = defaults ? { ...defaults, ...props } : props;
|
|
1348
|
+
return setup(merged);
|
|
1349
|
+
};
|
|
1350
|
+
}
|
|
1351
|
+
function withProps(component, mapProps) {
|
|
1352
|
+
return (props) => component(mapProps(props));
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// src/patterns/contracts.ts
|
|
1356
|
+
var validators = {
|
|
1357
|
+
string: ((value, name) => typeof value === "string" || `${name} must be a string, got ${typeof value}`),
|
|
1358
|
+
number: ((value, name) => typeof value === "number" || `${name} must be a number, got ${typeof value}`),
|
|
1359
|
+
boolean: ((value, name) => typeof value === "boolean" || `${name} must be a boolean, got ${typeof value}`),
|
|
1360
|
+
function: ((value, name) => typeof value === "function" || `${name} must be a function, got ${typeof value}`),
|
|
1361
|
+
object: ((value, name) => typeof value === "object" && value !== null || `${name} must be an object`),
|
|
1362
|
+
array: ((value, name) => Array.isArray(value) || `${name} must be an array`),
|
|
1363
|
+
required: ((value, name) => value != null || `${name} is required`),
|
|
1364
|
+
oneOf: (...values) => (value, name) => values.includes(value) || `${name} must be one of: ${values.join(", ")}`,
|
|
1365
|
+
instanceOf: (ctor) => (value, name) => value instanceof ctor || `${name} must be an instance of ${ctor.name}`,
|
|
1366
|
+
arrayOf: (itemValidator) => (value, name) => {
|
|
1367
|
+
if (!Array.isArray(value)) return `${name} must be an array`;
|
|
1368
|
+
for (let i = 0; i < value.length; i++) {
|
|
1369
|
+
const result = itemValidator(value[i], `${name}[${i}]`);
|
|
1370
|
+
if (result !== true) return result;
|
|
1371
|
+
}
|
|
1372
|
+
return true;
|
|
1373
|
+
},
|
|
1374
|
+
shape: (schema) => (value, name) => {
|
|
1375
|
+
if (typeof value !== "object" || value === null) return `${name} must be an object`;
|
|
1376
|
+
for (const [key, validator] of Object.entries(schema)) {
|
|
1377
|
+
const result = validator(value[key], `${name}.${key}`);
|
|
1378
|
+
if (result !== true) return result;
|
|
1379
|
+
}
|
|
1380
|
+
return true;
|
|
1381
|
+
},
|
|
1382
|
+
optional: (validator) => (value, name) => {
|
|
1383
|
+
if (value == null) return true;
|
|
1384
|
+
return validator(value, name);
|
|
1385
|
+
},
|
|
1386
|
+
range: (min2, max2) => (value, name) => {
|
|
1387
|
+
if (typeof value !== "number") return `${name} must be a number`;
|
|
1388
|
+
return value >= min2 && value <= max2 || `${name} must be between ${min2} and ${max2}`;
|
|
1389
|
+
},
|
|
1390
|
+
pattern: (regex) => (value, name) => {
|
|
1391
|
+
if (typeof value !== "string") return `${name} must be a string`;
|
|
1392
|
+
return regex.test(value) || `${name} must match pattern ${regex}`;
|
|
1393
|
+
}
|
|
1394
|
+
};
|
|
1395
|
+
function validateProps(props, schema) {
|
|
1396
|
+
const result = { ...props };
|
|
1397
|
+
const errors = [];
|
|
1398
|
+
const isDev2 = typeof process === "undefined" || process?.env?.NODE_ENV !== "production";
|
|
1399
|
+
for (const [key, def] of Object.entries(schema)) {
|
|
1400
|
+
const propDef = typeof def === "function" ? { type: def } : def;
|
|
1401
|
+
if (result[key] == null && propDef.default !== void 0) {
|
|
1402
|
+
result[key] = typeof propDef.default === "function" ? propDef.default() : propDef.default;
|
|
1403
|
+
}
|
|
1404
|
+
if (!isDev2) continue;
|
|
1405
|
+
if (propDef.required && result[key] == null) {
|
|
1406
|
+
errors.push(`Prop '${key}' is required`);
|
|
1407
|
+
continue;
|
|
1408
|
+
}
|
|
1409
|
+
if (result[key] == null) continue;
|
|
1410
|
+
if (propDef.type) {
|
|
1411
|
+
const typeResult = propDef.type(result[key], key);
|
|
1412
|
+
if (typeResult !== true) errors.push(typeResult);
|
|
1413
|
+
}
|
|
1414
|
+
if (propDef.validator) {
|
|
1415
|
+
const validResult = propDef.validator(result[key], key);
|
|
1416
|
+
if (validResult !== true) errors.push(validResult);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
if (errors.length > 0 && isDev2) {
|
|
1420
|
+
console.warn(`[SibuJS] Prop validation errors:
|
|
1421
|
+
${errors.map((e) => ` - ${e}`).join("\n")}`);
|
|
1422
|
+
}
|
|
1423
|
+
return result;
|
|
1424
|
+
}
|
|
1425
|
+
function defineStrictComponent(config) {
|
|
1426
|
+
return (props) => {
|
|
1427
|
+
const validated = validateProps(props, config.props);
|
|
1428
|
+
return config.setup(validated);
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
function assertType(value, validator, label) {
|
|
1432
|
+
if (typeof process !== "undefined" && process?.env?.NODE_ENV === "production") return;
|
|
1433
|
+
const result = validator(value, label || "value");
|
|
1434
|
+
if (result !== true) {
|
|
1435
|
+
throw new TypeError(`[SibuJS Contract] ${result}`);
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
function createGuard(validator) {
|
|
1439
|
+
return (value) => {
|
|
1440
|
+
return validator(value, "value") === true;
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1444
|
+
0 && (module.exports = {
|
|
1445
|
+
FocusTrap,
|
|
1446
|
+
RenderProp,
|
|
1447
|
+
VirtualList,
|
|
1448
|
+
announce,
|
|
1449
|
+
aria,
|
|
1450
|
+
assertType,
|
|
1451
|
+
bindAttrs,
|
|
1452
|
+
bindBoolAttr,
|
|
1453
|
+
bindData,
|
|
1454
|
+
composable,
|
|
1455
|
+
compose,
|
|
1456
|
+
createGuard,
|
|
1457
|
+
createSlots,
|
|
1458
|
+
creditCardMask,
|
|
1459
|
+
custom,
|
|
1460
|
+
dateMask,
|
|
1461
|
+
defineComponent,
|
|
1462
|
+
defineElement,
|
|
1463
|
+
defineSlottedComponent,
|
|
1464
|
+
defineStrictComponent,
|
|
1465
|
+
dialog,
|
|
1466
|
+
email,
|
|
1467
|
+
eventBus,
|
|
1468
|
+
focus,
|
|
1469
|
+
form,
|
|
1470
|
+
hotkey,
|
|
1471
|
+
infiniteScroll,
|
|
1472
|
+
inputMask,
|
|
1473
|
+
intersection,
|
|
1474
|
+
lazyLoad,
|
|
1475
|
+
matchesPattern,
|
|
1476
|
+
max,
|
|
1477
|
+
maxLength,
|
|
1478
|
+
min,
|
|
1479
|
+
minLength,
|
|
1480
|
+
pagination,
|
|
1481
|
+
phoneMask,
|
|
1482
|
+
removeScopedStyle,
|
|
1483
|
+
required,
|
|
1484
|
+
scopedStyle,
|
|
1485
|
+
ssnMask,
|
|
1486
|
+
svgElement,
|
|
1487
|
+
timeMask,
|
|
1488
|
+
toast,
|
|
1489
|
+
validateProps,
|
|
1490
|
+
validators,
|
|
1491
|
+
withBoundary,
|
|
1492
|
+
withDefaults,
|
|
1493
|
+
withProps,
|
|
1494
|
+
withScopedStyle,
|
|
1495
|
+
withWrapper,
|
|
1496
|
+
zipMask
|
|
1497
|
+
});
|