sibujs 1.2.0 → 1.3.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.
Files changed (89) hide show
  1. package/README.md +29 -25
  2. package/dist/browser.cjs +804 -2
  3. package/dist/browser.d.cts +591 -1
  4. package/dist/browser.d.ts +591 -1
  5. package/dist/browser.js +50 -8
  6. package/dist/build.cjs +654 -144
  7. package/dist/build.js +14 -12
  8. package/dist/cdn.global.js +188 -7
  9. package/dist/chunk-2BYQDGN3.js +742 -0
  10. package/dist/chunk-32DY64NT.js +282 -0
  11. package/dist/chunk-3AIRKM3B.js +1263 -0
  12. package/dist/chunk-3X2YG6YM.js +505 -0
  13. package/dist/chunk-5X6PP2UK.js +28 -0
  14. package/dist/chunk-77L6NL3X.js +1097 -0
  15. package/dist/chunk-BGN5ZMP4.js +26 -0
  16. package/dist/chunk-BTU3TJDS.js +365 -0
  17. package/dist/chunk-CHF5OHIA.js +61 -0
  18. package/dist/chunk-CMBFNA7L.js +27 -0
  19. package/dist/chunk-DAHRH4ON.js +331 -0
  20. package/dist/chunk-EBGIRKQY.js +616 -0
  21. package/dist/chunk-EUZND3CB.js +27 -0
  22. package/dist/chunk-F3FA4F32.js +292 -0
  23. package/dist/chunk-JAKHTMQU.js +1000 -0
  24. package/dist/chunk-JCI5M6U6.js +956 -0
  25. package/dist/chunk-KQPDEVVS.js +398 -0
  26. package/dist/chunk-NEKUBFPT.js +60 -0
  27. package/dist/chunk-NYVAC6P5.js +37 -0
  28. package/dist/chunk-PTQJDMRT.js +146 -0
  29. package/dist/chunk-QWZG56ET.js +2744 -0
  30. package/dist/chunk-TSOKIX5Z.js +654 -0
  31. package/dist/chunk-VRW3FULF.js +725 -0
  32. package/dist/chunk-WZSPOOER.js +84 -0
  33. package/dist/chunk-YT6HQ6AM.js +14 -0
  34. package/dist/chunk-ZD6OAMTH.js +277 -0
  35. package/dist/contracts-DDrwxvJ-.d.cts +245 -0
  36. package/dist/contracts-DDrwxvJ-.d.ts +245 -0
  37. package/dist/data.cjs +35 -2
  38. package/dist/data.d.cts +7 -0
  39. package/dist/data.d.ts +7 -0
  40. package/dist/data.js +9 -8
  41. package/dist/devtools.cjs +122 -0
  42. package/dist/devtools.d.cts +69 -461
  43. package/dist/devtools.d.ts +69 -461
  44. package/dist/devtools.js +127 -6
  45. package/dist/ecosystem.cjs +23 -6
  46. package/dist/ecosystem.d.cts +1 -1
  47. package/dist/ecosystem.d.ts +1 -1
  48. package/dist/ecosystem.js +10 -9
  49. package/dist/extras.cjs +1207 -65
  50. package/dist/extras.d.cts +5 -5
  51. package/dist/extras.d.ts +5 -5
  52. package/dist/extras.js +69 -24
  53. package/dist/index.cjs +663 -144
  54. package/dist/index.d.cts +397 -17
  55. package/dist/index.d.ts +397 -17
  56. package/dist/index.js +39 -17
  57. package/dist/introspect-BumjnBKr.d.cts +477 -0
  58. package/dist/introspect-CZrlcaYy.d.ts +477 -0
  59. package/dist/introspect-Cb0zgpi2.d.cts +477 -0
  60. package/dist/introspect-Y2xNXGSf.d.ts +477 -0
  61. package/dist/motion.js +4 -4
  62. package/dist/patterns.cjs +51 -2
  63. package/dist/patterns.d.cts +18 -8
  64. package/dist/patterns.d.ts +18 -8
  65. package/dist/patterns.js +7 -7
  66. package/dist/performance.js +4 -4
  67. package/dist/plugins.cjs +428 -81
  68. package/dist/plugins.d.cts +27 -4
  69. package/dist/plugins.d.ts +27 -4
  70. package/dist/plugins.js +156 -37
  71. package/dist/ssr-4PBXAOO3.js +40 -0
  72. package/dist/ssr-Do_SiVoL.d.cts +201 -0
  73. package/dist/ssr-Do_SiVoL.d.ts +201 -0
  74. package/dist/ssr.cjs +312 -60
  75. package/dist/ssr.d.cts +10 -1
  76. package/dist/ssr.d.ts +10 -1
  77. package/dist/ssr.js +13 -10
  78. package/dist/tagFactory-DaJ0YWX6.d.cts +47 -0
  79. package/dist/tagFactory-DaJ0YWX6.d.ts +47 -0
  80. package/dist/testing.cjs +233 -2
  81. package/dist/testing.d.cts +42 -1
  82. package/dist/testing.d.ts +42 -1
  83. package/dist/testing.js +129 -2
  84. package/dist/ui.cjs +374 -3
  85. package/dist/ui.d.cts +252 -2
  86. package/dist/ui.d.ts +252 -2
  87. package/dist/ui.js +328 -8
  88. package/dist/widgets.js +7 -7
  89. package/package.json +1 -1
package/dist/ui.cjs CHANGED
@@ -32,7 +32,10 @@ __export(ui_exports, {
32
32
  bindField: () => bindField,
33
33
  composable: () => composable,
34
34
  compose: () => compose,
35
+ createDialogAria: () => createDialogAria,
36
+ createFocusManager: () => createFocusManager,
35
37
  createGuard: () => createGuard,
38
+ createListbox: () => createListbox,
36
39
  createSlots: () => createSlots,
37
40
  creditCardMask: () => creditCardMask,
38
41
  custom: () => custom,
@@ -46,10 +49,13 @@ __export(ui_exports, {
46
49
  eventBus: () => eventBus,
47
50
  focus: () => focus,
48
51
  form: () => form,
52
+ formAction: () => formAction,
49
53
  hotkey: () => hotkey,
54
+ hover: () => hover,
50
55
  infiniteScroll: () => infiniteScroll,
51
56
  inputMask: () => inputMask,
52
57
  intersection: () => intersection,
58
+ interval: () => interval,
53
59
  lazyEffect: () => lazyEffect,
54
60
  lazyLoad: () => lazyLoad,
55
61
  matchesPattern: () => matchesPattern,
@@ -62,9 +68,11 @@ __export(ui_exports, {
62
68
  removeScopedStyle: () => removeScopedStyle,
63
69
  required: () => required,
64
70
  scopedStyle: () => scopedStyle,
71
+ scrollLock: () => scrollLock,
65
72
  ssnMask: () => ssnMask,
66
73
  svgElement: () => svgElement,
67
74
  timeMask: () => timeMask,
75
+ timeout: () => timeout,
68
76
  toast: () => toast,
69
77
  validateProps: () => validateProps,
70
78
  validators: () => validators,
@@ -573,6 +581,41 @@ function form(config) {
573
581
  };
574
582
  }
575
583
 
584
+ // src/ui/formAction.ts
585
+ function formAction(fn) {
586
+ const [pending, setPending] = signal(false);
587
+ const [error, setError] = signal(null);
588
+ const [result, setResult] = signal(null);
589
+ let runId = 0;
590
+ async function run(...args) {
591
+ const currentId = ++runId;
592
+ setPending(true);
593
+ setError(null);
594
+ try {
595
+ const value = await fn(...args);
596
+ if (currentId !== runId) return;
597
+ setResult(value);
598
+ } catch (err) {
599
+ if (currentId !== runId) return;
600
+ setError(err);
601
+ } finally {
602
+ if (currentId === runId) setPending(false);
603
+ }
604
+ }
605
+ function reset() {
606
+ setError(null);
607
+ setResult(null);
608
+ }
609
+ function onSubmit(e) {
610
+ e.preventDefault();
611
+ const formEl = e.currentTarget;
612
+ if (!formEl || typeof FormData === "undefined") return;
613
+ const data = new FormData(formEl);
614
+ run(data);
615
+ }
616
+ return { run, pending, error, result, reset, onSubmit };
617
+ }
618
+
576
619
  // src/core/ssr-context.ts
577
620
  var ssrMode = false;
578
621
  function isSSR() {
@@ -902,10 +945,224 @@ function announce(message, priority = "polite") {
902
945
  });
903
946
  }
904
947
 
948
+ // src/core/rendering/createId.ts
949
+ var idCounter = 0;
950
+ function createId(prefix = "sibu") {
951
+ idCounter++;
952
+ return `${prefix}-${idCounter}`;
953
+ }
954
+
955
+ // src/core/rendering/dispose.ts
956
+ var elementDisposers = /* @__PURE__ */ new WeakMap();
957
+ var _isDev4 = isDev();
958
+ var activeBindingCount = 0;
959
+ function registerDisposer(node, teardown) {
960
+ let disposers = elementDisposers.get(node);
961
+ if (!disposers) {
962
+ disposers = [];
963
+ elementDisposers.set(node, disposers);
964
+ }
965
+ disposers.push(teardown);
966
+ if (_isDev4) activeBindingCount++;
967
+ }
968
+
969
+ // src/ui/a11yPrimitives.ts
970
+ var DEFAULT_FOCUS_SELECTOR = 'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])';
971
+ function createFocusManager(container, options = {}) {
972
+ const selector = options.selector ?? DEFAULT_FOCUS_SELECTOR;
973
+ const loop = options.loop ?? true;
974
+ function items() {
975
+ return Array.from(container.querySelectorAll(selector));
976
+ }
977
+ function focusFirst() {
978
+ const all = items();
979
+ if (all.length > 0) all[0].focus();
980
+ }
981
+ function focusLast() {
982
+ const all = items();
983
+ if (all.length > 0) all[all.length - 1].focus();
984
+ }
985
+ function focusNext() {
986
+ const all = items();
987
+ if (all.length === 0) return;
988
+ const idx = all.indexOf(document.activeElement);
989
+ if (idx === -1) {
990
+ all[0].focus();
991
+ return;
992
+ }
993
+ const next = idx + 1;
994
+ if (next >= all.length) {
995
+ if (loop) all[0].focus();
996
+ return;
997
+ }
998
+ all[next].focus();
999
+ }
1000
+ function focusPrev() {
1001
+ const all = items();
1002
+ if (all.length === 0) return;
1003
+ const idx = all.indexOf(document.activeElement);
1004
+ if (idx === -1) {
1005
+ all[all.length - 1].focus();
1006
+ return;
1007
+ }
1008
+ const prev = idx - 1;
1009
+ if (prev < 0) {
1010
+ if (loop) all[all.length - 1].focus();
1011
+ return;
1012
+ }
1013
+ all[prev].focus();
1014
+ }
1015
+ return { focusFirst, focusLast, focusNext, focusPrev, items };
1016
+ }
1017
+ function createListbox(container, options = {}) {
1018
+ const multiple = options.multiple ?? false;
1019
+ const optionSelector = options.optionSelector ?? '[role="option"]';
1020
+ container.setAttribute("role", "listbox");
1021
+ if (multiple) container.setAttribute("aria-multiselectable", "true");
1022
+ if (!container.hasAttribute("tabindex")) container.setAttribute("tabindex", "0");
1023
+ const [activeValue, setActiveValue] = signal(null);
1024
+ const [selectedValue, setSelectedValue] = signal(null);
1025
+ const [activeDescendantId, setActiveDescendantId] = signal(null);
1026
+ function stampIds() {
1027
+ const opts = Array.from(container.querySelectorAll(optionSelector));
1028
+ for (const opt of opts) {
1029
+ if (!opt.id) opt.id = createId("listbox-option");
1030
+ }
1031
+ }
1032
+ stampIds();
1033
+ function getOptions() {
1034
+ return Array.from(container.querySelectorAll(optionSelector));
1035
+ }
1036
+ function setActive(value) {
1037
+ setActiveValue(value);
1038
+ const opts = getOptions();
1039
+ for (const opt of opts) {
1040
+ if (opt.dataset.value === value) {
1041
+ opt.setAttribute("data-highlighted", "");
1042
+ setActiveDescendantId(opt.id || null);
1043
+ container.setAttribute("aria-activedescendant", opt.id || "");
1044
+ } else {
1045
+ opt.removeAttribute("data-highlighted");
1046
+ }
1047
+ }
1048
+ if (value === null) {
1049
+ setActiveDescendantId(null);
1050
+ container.removeAttribute("aria-activedescendant");
1051
+ }
1052
+ }
1053
+ function select(value) {
1054
+ if (multiple) {
1055
+ const current2 = selectedValue();
1056
+ const set = new Set((current2 ?? "").split(",").filter(Boolean));
1057
+ if (set.has(value)) set.delete(value);
1058
+ else set.add(value);
1059
+ setSelectedValue(Array.from(set).join(","));
1060
+ } else {
1061
+ setSelectedValue(value);
1062
+ }
1063
+ options.onSelect?.(value);
1064
+ const opts = getOptions();
1065
+ const current = selectedValue();
1066
+ const selected = new Set((current ?? "").split(",").filter(Boolean));
1067
+ for (const opt of opts) {
1068
+ const ov = opt.dataset.value ?? "";
1069
+ opt.setAttribute("aria-selected", selected.has(ov) ? "true" : "false");
1070
+ }
1071
+ }
1072
+ function moveActive(delta) {
1073
+ const opts = getOptions();
1074
+ if (opts.length === 0) return;
1075
+ const currentIdx = opts.findIndex((o) => o.dataset.value === activeValue());
1076
+ let next = currentIdx + delta;
1077
+ if (next < 0) next = opts.length - 1;
1078
+ if (next >= opts.length) next = 0;
1079
+ const nextValue = opts[next].dataset.value ?? null;
1080
+ setActive(nextValue);
1081
+ if (typeof opts[next].scrollIntoView === "function") {
1082
+ opts[next].scrollIntoView({ block: "nearest" });
1083
+ }
1084
+ }
1085
+ function onKeyDown(e) {
1086
+ switch (e.key) {
1087
+ case "ArrowDown":
1088
+ e.preventDefault();
1089
+ moveActive(1);
1090
+ break;
1091
+ case "ArrowUp":
1092
+ e.preventDefault();
1093
+ moveActive(-1);
1094
+ break;
1095
+ case "Home": {
1096
+ e.preventDefault();
1097
+ const opts = getOptions();
1098
+ if (opts.length > 0) setActive(opts[0].dataset.value ?? null);
1099
+ break;
1100
+ }
1101
+ case "End": {
1102
+ e.preventDefault();
1103
+ const opts = getOptions();
1104
+ if (opts.length > 0) setActive(opts[opts.length - 1].dataset.value ?? null);
1105
+ break;
1106
+ }
1107
+ case "Enter":
1108
+ case " ": {
1109
+ e.preventDefault();
1110
+ const active = activeValue();
1111
+ if (active !== null) select(active);
1112
+ break;
1113
+ }
1114
+ }
1115
+ }
1116
+ function onClick(e) {
1117
+ const target = e.target.closest(optionSelector);
1118
+ if (!target || !container.contains(target)) return;
1119
+ const value = target.dataset.value ?? null;
1120
+ if (value !== null) {
1121
+ setActive(value);
1122
+ select(value);
1123
+ }
1124
+ }
1125
+ container.addEventListener("keydown", onKeyDown);
1126
+ container.addEventListener("click", onClick);
1127
+ function dispose() {
1128
+ container.removeEventListener("keydown", onKeyDown);
1129
+ container.removeEventListener("click", onClick);
1130
+ }
1131
+ registerDisposer(container, dispose);
1132
+ return { activeValue, selectedValue, activeDescendantId, dispose };
1133
+ }
1134
+ function createDialogAria(element, options = {}) {
1135
+ const titleId = options.labelledBy ?? createId("dialog-title");
1136
+ const descriptionId = options.describedBy ?? createId("dialog-desc");
1137
+ element.setAttribute("role", options.alert ? "alertdialog" : "dialog");
1138
+ if (options.modal ?? true) element.setAttribute("aria-modal", "true");
1139
+ element.setAttribute("aria-labelledby", titleId);
1140
+ element.setAttribute("aria-describedby", descriptionId);
1141
+ if (!element.hasAttribute("tabindex")) element.setAttribute("tabindex", "-1");
1142
+ return { titleId, descriptionId };
1143
+ }
1144
+
905
1145
  // src/ui/scopedStyle.ts
906
1146
  var scopeCounter = 0;
1147
+ function decodeCssEscapes(css) {
1148
+ return css.replace(/\\([0-9a-f]{1,6})[ \t\n\r\f]?|\\([^\n])/gi, (_match, hex, ch) => {
1149
+ if (hex) {
1150
+ const code = Number.parseInt(hex, 16);
1151
+ if (Number.isFinite(code) && code > 0 && code <= 1114111) {
1152
+ try {
1153
+ return String.fromCodePoint(code);
1154
+ } catch {
1155
+ return "";
1156
+ }
1157
+ }
1158
+ return "";
1159
+ }
1160
+ return ch || "";
1161
+ });
1162
+ }
907
1163
  function sanitizeCSS(css) {
908
- let sanitized = css.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
1164
+ let sanitized = decodeCssEscapes(css);
1165
+ sanitized = sanitized.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
909
1166
  sanitized = sanitized.replace(/url\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* url() removed */");
910
1167
  sanitized = sanitized.replace(/expression\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* expression() removed */");
911
1168
  sanitized = sanitized.replace(/-moz-binding\s*:[^;]+;/gi, "/* -moz-binding removed */");
@@ -971,14 +1228,27 @@ function isUrlAttribute(attr) {
971
1228
  }
972
1229
 
973
1230
  // src/reactivity/bindAttribute.ts
974
- var _isDev4 = isDev();
1231
+ var _isDev5 = isDev();
1232
+ function isEventHandlerAttr(name) {
1233
+ if (name.length < 3) return false;
1234
+ const lower = name.toLowerCase();
1235
+ return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
1236
+ }
975
1237
  function bindAttribute(el, attr, getter) {
1238
+ if (isEventHandlerAttr(attr)) {
1239
+ if (_isDev5)
1240
+ devWarn(
1241
+ `bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
1242
+ );
1243
+ return () => {
1244
+ };
1245
+ }
976
1246
  function commit() {
977
1247
  let value;
978
1248
  try {
979
1249
  value = getter();
980
1250
  } catch (err) {
981
- if (_isDev4)
1251
+ if (_isDev5)
982
1252
  devWarn(`bindAttribute: getter for "${attr}" threw: ${err instanceof Error ? err.message : String(err)}`);
983
1253
  return;
984
1254
  }
@@ -1314,6 +1584,99 @@ function lazyEffect(element, effectFn, options) {
1314
1584
  };
1315
1585
  }
1316
1586
 
1587
+ // src/ui/timers.ts
1588
+ function interval(fn, ms) {
1589
+ let id = null;
1590
+ let running = false;
1591
+ function start() {
1592
+ if (running) return;
1593
+ id = setInterval(fn, ms);
1594
+ running = true;
1595
+ }
1596
+ function stop() {
1597
+ if (id !== null) {
1598
+ clearInterval(id);
1599
+ id = null;
1600
+ }
1601
+ running = false;
1602
+ }
1603
+ start();
1604
+ return {
1605
+ stop,
1606
+ pause: stop,
1607
+ resume: start,
1608
+ isRunning: () => running
1609
+ };
1610
+ }
1611
+ function timeout(fn, ms) {
1612
+ let pending = true;
1613
+ const id = setTimeout(() => {
1614
+ pending = false;
1615
+ fn();
1616
+ }, ms);
1617
+ return {
1618
+ cancel: () => {
1619
+ if (pending) {
1620
+ clearTimeout(id);
1621
+ pending = false;
1622
+ }
1623
+ },
1624
+ isPending: () => pending
1625
+ };
1626
+ }
1627
+
1628
+ // src/ui/hover.ts
1629
+ function hover(target) {
1630
+ const [hovered, setHovered] = signal(false);
1631
+ if (typeof window === "undefined") {
1632
+ return { hovered, dispose: () => {
1633
+ } };
1634
+ }
1635
+ const onEnter = () => setHovered(true);
1636
+ const onLeave = () => setHovered(false);
1637
+ target.addEventListener("pointerenter", onEnter);
1638
+ target.addEventListener("pointerleave", onLeave);
1639
+ function dispose() {
1640
+ target.removeEventListener("pointerenter", onEnter);
1641
+ target.removeEventListener("pointerleave", onLeave);
1642
+ }
1643
+ return { hovered, dispose };
1644
+ }
1645
+
1646
+ // src/ui/scrollLock.ts
1647
+ var lockCount = 0;
1648
+ var savedOverflow = null;
1649
+ var savedPaddingRight = null;
1650
+ function scrollLock() {
1651
+ let owned = false;
1652
+ function lock() {
1653
+ if (owned) return;
1654
+ owned = true;
1655
+ lockCount++;
1656
+ if (lockCount !== 1 || typeof document === "undefined") return;
1657
+ const body = document.body;
1658
+ const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth;
1659
+ savedOverflow = body.style.overflow;
1660
+ savedPaddingRight = body.style.paddingRight;
1661
+ body.style.overflow = "hidden";
1662
+ if (scrollBarWidth > 0) {
1663
+ body.style.paddingRight = `${scrollBarWidth}px`;
1664
+ }
1665
+ }
1666
+ function unlock() {
1667
+ if (!owned) return;
1668
+ owned = false;
1669
+ lockCount = Math.max(0, lockCount - 1);
1670
+ if (lockCount !== 0 || typeof document === "undefined") return;
1671
+ const body = document.body;
1672
+ body.style.overflow = savedOverflow ?? "";
1673
+ body.style.paddingRight = savedPaddingRight ?? "";
1674
+ savedOverflow = null;
1675
+ savedPaddingRight = null;
1676
+ }
1677
+ return { lock, unlock };
1678
+ }
1679
+
1317
1680
  // src/platform/customElement.ts
1318
1681
  function defineElement(name, component, options = {}) {
1319
1682
  if (customElements.get(name)) return;
@@ -1572,7 +1935,10 @@ function createGuard(validator) {
1572
1935
  bindField,
1573
1936
  composable,
1574
1937
  compose,
1938
+ createDialogAria,
1939
+ createFocusManager,
1575
1940
  createGuard,
1941
+ createListbox,
1576
1942
  createSlots,
1577
1943
  creditCardMask,
1578
1944
  custom,
@@ -1586,10 +1952,13 @@ function createGuard(validator) {
1586
1952
  eventBus,
1587
1953
  focus,
1588
1954
  form,
1955
+ formAction,
1589
1956
  hotkey,
1957
+ hover,
1590
1958
  infiniteScroll,
1591
1959
  inputMask,
1592
1960
  intersection,
1961
+ interval,
1593
1962
  lazyEffect,
1594
1963
  lazyLoad,
1595
1964
  matchesPattern,
@@ -1602,9 +1971,11 @@ function createGuard(validator) {
1602
1971
  removeScopedStyle,
1603
1972
  required,
1604
1973
  scopedStyle,
1974
+ scrollLock,
1605
1975
  ssnMask,
1606
1976
  svgElement,
1607
1977
  timeMask,
1978
+ timeout,
1608
1979
  toast,
1609
1980
  validateProps,
1610
1981
  validators,