sibujs 1.5.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/dist/browser.cjs +238 -69
  2. package/dist/browser.d.cts +5 -0
  3. package/dist/browser.d.ts +5 -0
  4. package/dist/browser.js +6 -6
  5. package/dist/build.cjs +916 -292
  6. package/dist/build.js +15 -13
  7. package/dist/cdn.global.js +17 -16
  8. package/dist/chunk-2RA7SHDA.js +65 -0
  9. package/dist/chunk-2UPRY23K.js +80 -0
  10. package/dist/chunk-3JHCYHWN.js +125 -0
  11. package/dist/{chunk-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
  12. package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
  13. package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
  14. package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
  15. package/dist/chunk-7JDB7I65.js +1327 -0
  16. package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
  17. package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
  18. package/dist/{chunk-BGN5ZMP4.js → chunk-GTBNNBJ6.js} +14 -2
  19. package/dist/chunk-HB24TBAF.js +121 -0
  20. package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
  21. package/dist/{chunk-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
  22. package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
  23. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  24. package/dist/{chunk-SFKNRVCU.js → chunk-KLRMB5ZS.js} +135 -79
  25. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  26. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  27. package/dist/{chunk-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
  28. package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
  29. package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
  30. package/dist/{chunk-NHUC2QWH.js → chunk-R73P76YZ.js} +1 -1
  31. package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
  32. package/dist/chunk-UCS6AMJ7.js +79 -0
  33. package/dist/{chunk-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
  34. package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
  35. package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
  36. package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
  37. package/dist/data.cjs +410 -99
  38. package/dist/data.d.cts +20 -2
  39. package/dist/data.d.ts +20 -2
  40. package/dist/data.js +11 -9
  41. package/dist/devtools.cjs +513 -223
  42. package/dist/devtools.d.cts +1 -1
  43. package/dist/devtools.d.ts +1 -1
  44. package/dist/devtools.js +12 -6
  45. package/dist/ecosystem.cjs +475 -144
  46. package/dist/ecosystem.d.cts +9 -7
  47. package/dist/ecosystem.d.ts +9 -7
  48. package/dist/ecosystem.js +12 -11
  49. package/dist/extras.cjs +3355 -1541
  50. package/dist/extras.d.cts +9 -9
  51. package/dist/extras.d.ts +9 -9
  52. package/dist/extras.js +58 -45
  53. package/dist/index.cjs +920 -292
  54. package/dist/index.d.cts +71 -8
  55. package/dist/index.d.ts +71 -8
  56. package/dist/index.js +28 -16
  57. package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
  58. package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
  59. package/dist/motion.cjs +77 -34
  60. package/dist/motion.js +4 -4
  61. package/dist/patterns.cjs +335 -69
  62. package/dist/patterns.d.cts +11 -12
  63. package/dist/patterns.d.ts +11 -12
  64. package/dist/patterns.js +7 -7
  65. package/dist/performance.cjs +279 -108
  66. package/dist/performance.d.cts +23 -16
  67. package/dist/performance.d.ts +23 -16
  68. package/dist/performance.js +13 -8
  69. package/dist/plugin-D30wlGW5.d.cts +71 -0
  70. package/dist/plugin-D30wlGW5.d.ts +71 -0
  71. package/dist/plugins.cjs +635 -260
  72. package/dist/plugins.d.cts +10 -3
  73. package/dist/plugins.d.ts +10 -3
  74. package/dist/plugins.js +106 -38
  75. package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
  76. package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
  77. package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
  78. package/dist/ssr.cjs +642 -222
  79. package/dist/ssr.d.cts +26 -6
  80. package/dist/ssr.d.ts +26 -6
  81. package/dist/ssr.js +12 -11
  82. package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
  83. package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
  84. package/dist/testing.cjs +252 -63
  85. package/dist/testing.d.cts +17 -4
  86. package/dist/testing.d.ts +17 -4
  87. package/dist/testing.js +100 -44
  88. package/dist/ui.cjs +463 -137
  89. package/dist/ui.d.cts +1 -1
  90. package/dist/ui.d.ts +1 -1
  91. package/dist/ui.js +20 -17
  92. package/dist/widgets.cjs +977 -94
  93. package/dist/widgets.d.cts +104 -2
  94. package/dist/widgets.d.ts +104 -2
  95. package/dist/widgets.js +9 -7
  96. package/package.json +8 -2
  97. package/dist/chunk-32DY64NT.js +0 -282
  98. package/dist/chunk-3AIRKM3B.js +0 -1263
  99. package/dist/chunk-3ARAQO7B.js +0 -398
  100. package/dist/chunk-3CRQALYP.js +0 -877
  101. package/dist/chunk-4EI4AG32.js +0 -482
  102. package/dist/chunk-4MYMUBRS.js +0 -21
  103. package/dist/chunk-5ZYQ6KDD.js +0 -154
  104. package/dist/chunk-6BMPXPUW.js +0 -26
  105. package/dist/chunk-6HLLIF3K.js +0 -398
  106. package/dist/chunk-6LSNVCS2.js +0 -937
  107. package/dist/chunk-6SA3QQES.js +0 -61
  108. package/dist/chunk-77L6NL3X.js +0 -1097
  109. package/dist/chunk-7BF6TK55.js +0 -1097
  110. package/dist/chunk-7TQKR4PP.js +0 -294
  111. package/dist/chunk-7V26P53V.js +0 -712
  112. package/dist/chunk-AZ3ISID5.js +0 -298
  113. package/dist/chunk-B7SWRFUT.js +0 -332
  114. package/dist/chunk-BTU3TJDS.js +0 -365
  115. package/dist/chunk-BW3WT46K.js +0 -937
  116. package/dist/chunk-C6KFWOFV.js +0 -616
  117. package/dist/chunk-CHF5OHIA.js +0 -61
  118. package/dist/chunk-CHJ27IGK.js +0 -26
  119. package/dist/chunk-CMBFNA7L.js +0 -27
  120. package/dist/chunk-DAHRH4ON.js +0 -331
  121. package/dist/chunk-DKOHBI74.js +0 -924
  122. package/dist/chunk-DTCOOBMX.js +0 -725
  123. package/dist/chunk-EBGIRKQY.js +0 -616
  124. package/dist/chunk-EUZND3CB.js +0 -27
  125. package/dist/chunk-EVCZO745.js +0 -365
  126. package/dist/chunk-EWFVA3TJ.js +0 -282
  127. package/dist/chunk-F3FA4F32.js +0 -292
  128. package/dist/chunk-FGOEVHY3.js +0 -60
  129. package/dist/chunk-G3BOQPVO.js +0 -365
  130. package/dist/chunk-GCOK2LC3.js +0 -282
  131. package/dist/chunk-GJPXRJ45.js +0 -37
  132. package/dist/chunk-HGMJFBC7.js +0 -654
  133. package/dist/chunk-JAKHTMQU.js +0 -1000
  134. package/dist/chunk-JCI5M6U6.js +0 -956
  135. package/dist/chunk-K5ZUMYVS.js +0 -89
  136. package/dist/chunk-KQPDEVVS.js +0 -398
  137. package/dist/chunk-L6JRBDNS.js +0 -60
  138. package/dist/chunk-LA6KQEDU.js +0 -712
  139. package/dist/chunk-MB6QFH3I.js +0 -2776
  140. package/dist/chunk-MDVXJWFN.js +0 -304
  141. package/dist/chunk-MEZVEBPN.js +0 -2008
  142. package/dist/chunk-MK4ERFYL.js +0 -2249
  143. package/dist/chunk-MLKGABMK.js +0 -9
  144. package/dist/chunk-MQ5GOYPH.js +0 -2249
  145. package/dist/chunk-MYRV7VDM.js +0 -742
  146. package/dist/chunk-N6IZB6KJ.js +0 -567
  147. package/dist/chunk-NEKUBFPT.js +0 -60
  148. package/dist/chunk-NMRUZALC.js +0 -1097
  149. package/dist/chunk-NYVAC6P5.js +0 -37
  150. package/dist/chunk-NZIIMDWI.js +0 -84
  151. package/dist/chunk-OF7UZIVB.js +0 -725
  152. package/dist/chunk-P3XWXJZU.js +0 -282
  153. package/dist/chunk-P6W3STU4.js +0 -2249
  154. package/dist/chunk-PBHF5WKN.js +0 -616
  155. package/dist/chunk-PDZQY43A.js +0 -616
  156. package/dist/chunk-PTQJDMRT.js +0 -146
  157. package/dist/chunk-PZEGYCF5.js +0 -61
  158. package/dist/chunk-QBMDLBU2.js +0 -975
  159. package/dist/chunk-QWZG56ET.js +0 -2744
  160. package/dist/chunk-RQGQSLQK.js +0 -725
  161. package/dist/chunk-SDLZDHKP.js +0 -107
  162. package/dist/chunk-TDGZL5CU.js +0 -365
  163. package/dist/chunk-TNQWPPE6.js +0 -37
  164. package/dist/chunk-TSOKIX5Z.js +0 -654
  165. package/dist/chunk-UHNL42EF.js +0 -2730
  166. package/dist/chunk-UNXCEF6S.js +0 -21
  167. package/dist/chunk-V2XTI523.js +0 -347
  168. package/dist/chunk-VAU366PN.js +0 -2241
  169. package/dist/chunk-VMVDTCXB.js +0 -712
  170. package/dist/chunk-VQNQZCWJ.js +0 -61
  171. package/dist/chunk-VRW3FULF.js +0 -725
  172. package/dist/chunk-WADYRCO2.js +0 -304
  173. package/dist/chunk-WILQZRO4.js +0 -282
  174. package/dist/chunk-WR5D4EGH.js +0 -26
  175. package/dist/chunk-WUHJISPP.js +0 -298
  176. package/dist/chunk-XYU6TZOW.js +0 -182
  177. package/dist/chunk-Y6GP4QGG.js +0 -276
  178. package/dist/chunk-YECR7UIA.js +0 -347
  179. package/dist/chunk-YUTWTI4B.js +0 -654
  180. package/dist/chunk-Z65KYU7I.js +0 -26
  181. package/dist/chunk-Z6POF5YC.js +0 -975
  182. package/dist/chunk-ZBJP6WFL.js +0 -482
  183. package/dist/chunk-ZD6OAMTH.js +0 -277
  184. package/dist/chunk-ZWKZCBO6.js +0 -317
  185. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  186. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  187. package/dist/contracts-DOrhwbke.d.cts +0 -245
  188. package/dist/contracts-DOrhwbke.d.ts +0 -245
  189. package/dist/contracts-xo5ckdRP.d.cts +0 -240
  190. package/dist/contracts-xo5ckdRP.d.ts +0 -240
  191. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  192. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  193. package/dist/customElement-D2DJp_xn.d.cts +0 -313
  194. package/dist/customElement-D2DJp_xn.d.ts +0 -313
  195. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  196. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  197. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  198. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  199. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  200. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  201. package/dist/ssr-3RXHP5ES.js +0 -38
  202. package/dist/ssr-6GIMY5MX.js +0 -38
  203. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  204. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  205. package/dist/ssr-WKUPVSSK.js +0 -36
  206. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  207. package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
@@ -1,19 +1,22 @@
1
1
  import {
2
- bindAttribute,
3
- registerDisposer
4
- } from "./chunk-5ZYQ6KDD.js";
2
+ bindAttribute
3
+ } from "./chunk-DFPFITST.js";
5
4
  import {
6
5
  derived
7
- } from "./chunk-XHK6BDAJ.js";
6
+ } from "./chunk-54EDRCEF.js";
7
+ import {
8
+ dispose,
9
+ registerDisposer
10
+ } from "./chunk-2UPRY23K.js";
8
11
  import {
9
12
  effect
10
- } from "./chunk-VQNQZCWJ.js";
13
+ } from "./chunk-HB24TBAF.js";
11
14
  import {
12
15
  signal
13
- } from "./chunk-NZIIMDWI.js";
16
+ } from "./chunk-CC65Y57T.js";
14
17
  import {
15
18
  track
16
- } from "./chunk-K4G4ZQNR.js";
19
+ } from "./chunk-VLPPXTYG.js";
17
20
 
18
21
  // src/ui/form.ts
19
22
  function required(message = "This field is required") {
@@ -116,9 +119,18 @@ function form(config) {
116
119
  }
117
120
  return null;
118
121
  });
122
+ const wrappedSet = (next) => {
123
+ setValue(next);
124
+ setManualErrors((prev) => {
125
+ if (!(name in prev) || prev[name] == null) return prev;
126
+ const copy = { ...prev };
127
+ copy[name] = null;
128
+ return copy;
129
+ });
130
+ };
119
131
  fieldMap[name] = {
120
132
  value,
121
- set: setValue,
133
+ set: wrappedSet,
122
134
  error,
123
135
  touched: isTouched,
124
136
  touch: () => setTouched(true),
@@ -252,6 +264,7 @@ function intersection(options) {
252
264
  let observer = null;
253
265
  let currentElement = null;
254
266
  function observe(element) {
267
+ if (typeof IntersectionObserver === "undefined") return;
255
268
  unobserve();
256
269
  currentElement = element;
257
270
  observer = new IntersectionObserver((entries) => {
@@ -279,6 +292,11 @@ function intersection(options) {
279
292
  };
280
293
  }
281
294
  function lazyLoad(element, loader, options) {
295
+ if (typeof IntersectionObserver === "undefined") {
296
+ loader();
297
+ return () => {
298
+ };
299
+ }
282
300
  const observer = new IntersectionObserver((entries) => {
283
301
  for (const entry of entries) {
284
302
  if (entry.isIntersecting) {
@@ -353,7 +371,7 @@ function inputMask(options) {
353
371
  const stripRegex = buildStripRegex();
354
372
  const rawCharTest = options.pattern.includes("*") ? () => true : (c) => /[a-zA-Z0-9]/.test(c);
355
373
  function bind(input) {
356
- input.addEventListener("input", () => {
374
+ const onInput = () => {
357
375
  const cursorBefore = input.selectionStart ?? input.value.length;
358
376
  const oldValue = input.value;
359
377
  const raw = oldValue.replace(stripRegex, "");
@@ -377,13 +395,19 @@ function inputMask(options) {
377
395
  }
378
396
  }
379
397
  input.setSelectionRange(newCursor, newCursor);
380
- });
381
- input.addEventListener("focus", () => {
398
+ };
399
+ const onFocus = () => {
382
400
  if (!input.value) {
383
401
  const display = options.pattern.replace(/9/g, placeholder).replace(/A/g, placeholder).replace(/\*/g, placeholder);
384
402
  input.placeholder = display;
385
403
  }
386
- });
404
+ };
405
+ input.addEventListener("input", onInput);
406
+ input.addEventListener("focus", onFocus);
407
+ return () => {
408
+ input.removeEventListener("input", onInput);
409
+ input.removeEventListener("focus", onFocus);
410
+ };
387
411
  }
388
412
  return { value, rawValue, bind };
389
413
  }
@@ -425,8 +449,20 @@ function focus() {
425
449
  let currentElement = null;
426
450
  function bind(element) {
427
451
  currentElement = element;
428
- element.addEventListener("focus", () => setIsFocused(true));
429
- element.addEventListener("blur", () => setIsFocused(false));
452
+ const onFocus = () => setIsFocused(true);
453
+ const onBlur = () => setIsFocused(false);
454
+ element.addEventListener("focus", onFocus);
455
+ element.addEventListener("blur", onBlur);
456
+ let disposed = false;
457
+ const dispose2 = () => {
458
+ if (disposed) return;
459
+ disposed = true;
460
+ element.removeEventListener("focus", onFocus);
461
+ element.removeEventListener("blur", onBlur);
462
+ if (currentElement === element) currentElement = null;
463
+ };
464
+ registerDisposer(element, dispose2);
465
+ return dispose2;
430
466
  }
431
467
  function focus2() {
432
468
  currentElement?.focus();
@@ -441,11 +477,35 @@ function FocusTrap(nodes, options = {}) {
441
477
  container.setAttribute("data-sibu-focus-trap", "true");
442
478
  container.appendChild(nodes);
443
479
  const previouslyFocused = document.activeElement;
444
- container.addEventListener("keydown", (e) => {
480
+ const FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"]), [contenteditable]';
481
+ function isEffectivelyVisible(el) {
482
+ let node = el;
483
+ while (node) {
484
+ if (node.hasAttribute("inert")) return false;
485
+ if (node.getAttribute("aria-hidden") === "true") return false;
486
+ if (node.hidden) return false;
487
+ node = node.parentElement;
488
+ }
489
+ if (el.offsetParent === null && el.getClientRects().length === 0) return false;
490
+ return true;
491
+ }
492
+ function getFocusable() {
493
+ const raw = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
494
+ const out = [];
495
+ for (const el of raw) {
496
+ if (el.hasAttribute("disabled")) continue;
497
+ if (el.getAttribute("aria-hidden") === "true") continue;
498
+ if (el.hasAttribute("inert")) continue;
499
+ const ce = el.getAttribute("contenteditable");
500
+ if (ce !== null && ce === "false") continue;
501
+ if (!isEffectivelyVisible(el)) continue;
502
+ out.push(el);
503
+ }
504
+ return out;
505
+ }
506
+ const onTrapKeydown = (e) => {
445
507
  if (e.key !== "Tab") return;
446
- const focusable = container.querySelectorAll(
447
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
448
- );
508
+ const focusable = getFocusable();
449
509
  if (focusable.length === 0) {
450
510
  e.preventDefault();
451
511
  return;
@@ -463,18 +523,18 @@ function FocusTrap(nodes, options = {}) {
463
523
  first.focus();
464
524
  }
465
525
  }
466
- });
526
+ };
527
+ container.addEventListener("keydown", onTrapKeydown);
467
528
  if (options.autoFocus !== false) {
468
529
  queueMicrotask(() => {
469
- const first = container.querySelector(
470
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
471
- );
530
+ const first = getFocusable()[0];
472
531
  first?.focus();
473
532
  });
474
533
  }
475
534
  let trapObserver = null;
476
535
  function restoreFocusAndCleanup() {
477
536
  if (options.restoreFocus !== false) previouslyFocused?.focus();
537
+ container.removeEventListener("keydown", onTrapKeydown);
478
538
  if (trapObserver) {
479
539
  trapObserver.disconnect();
480
540
  trapObserver = null;
@@ -488,7 +548,7 @@ function FocusTrap(nodes, options = {}) {
488
548
  });
489
549
  queueMicrotask(() => {
490
550
  if (container.isConnected) {
491
- trapObserver.observe(document.body, { childList: true, subtree: true });
551
+ trapObserver.observe(container, { childList: true, subtree: true });
492
552
  }
493
553
  });
494
554
  }
@@ -525,7 +585,16 @@ function hotkey(combo, handler, options = {}) {
525
585
  document.addEventListener("keydown", listener);
526
586
  return () => document.removeEventListener("keydown", listener);
527
587
  }
528
- function announce(message, priority = "polite") {
588
+ var announceQueues = {
589
+ polite: [],
590
+ assertive: []
591
+ };
592
+ var announceDraining = {
593
+ polite: false,
594
+ assertive: false
595
+ };
596
+ var ANNOUNCE_INTERVAL_MS = 150;
597
+ function ensureLiveRegion(priority) {
529
598
  let region = document.getElementById(`sibu-announce-${priority}`);
530
599
  if (!region) {
531
600
  region = document.createElement("div");
@@ -536,11 +605,33 @@ function announce(message, priority = "polite") {
536
605
  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;";
537
606
  document.body.appendChild(region);
538
607
  }
608
+ return region;
609
+ }
610
+ function drainAnnounceQueue(priority) {
611
+ if (announceDraining[priority]) return;
612
+ const queue = announceQueues[priority];
613
+ if (queue.length === 0) return;
614
+ announceDraining[priority] = true;
615
+ const region = ensureLiveRegion(priority);
616
+ const next = queue.shift();
539
617
  region.textContent = "";
540
618
  requestAnimationFrame(() => {
541
- if (region) region.textContent = message;
619
+ if (!region.isConnected) {
620
+ announceDraining[priority] = false;
621
+ return;
622
+ }
623
+ region.textContent = next;
624
+ setTimeout(() => {
625
+ announceDraining[priority] = false;
626
+ drainAnnounceQueue(priority);
627
+ }, ANNOUNCE_INTERVAL_MS);
542
628
  });
543
629
  }
630
+ function announce(message, priority = "polite") {
631
+ if (typeof document === "undefined") return;
632
+ announceQueues[priority].push(message);
633
+ drainAnnounceQueue(priority);
634
+ }
544
635
 
545
636
  // src/ui/scopedStyle.ts
546
637
  var scopeCounter = 0;
@@ -677,66 +768,91 @@ function bindData(el, key, getter) {
677
768
  }
678
769
 
679
770
  // src/ui/dialog.ts
771
+ var dialogStack = [];
772
+ var globalListenerAttached = false;
773
+ function __resetDialogStack() {
774
+ while (dialogStack.length > 0) dialogStack.pop();
775
+ if (typeof window !== "undefined" && globalListenerAttached) {
776
+ window.removeEventListener("keydown", handleGlobalKeydown);
777
+ globalListenerAttached = false;
778
+ }
779
+ }
780
+ function handleGlobalKeydown(event) {
781
+ if (event.key !== "Escape") return;
782
+ const top = dialogStack[dialogStack.length - 1];
783
+ if (top) top.close();
784
+ }
785
+ function ensureGlobalListener() {
786
+ if (typeof window === "undefined" || globalListenerAttached) return;
787
+ window.addEventListener("keydown", handleGlobalKeydown);
788
+ globalListenerAttached = true;
789
+ }
790
+ function removeGlobalListenerIfIdle() {
791
+ if (typeof window === "undefined") return;
792
+ if (!globalListenerAttached) return;
793
+ if (dialogStack.length > 0) return;
794
+ window.removeEventListener("keydown", handleGlobalKeydown);
795
+ globalListenerAttached = false;
796
+ }
680
797
  function dialog() {
681
798
  const [isOpen, setIsOpen] = signal(false);
682
- let listenerAttached = false;
683
- function handleKeydown(event) {
684
- if (event.key === "Escape") {
685
- close();
686
- }
799
+ const entry = { close: () => close() };
800
+ function pushOnStack() {
801
+ if (dialogStack.indexOf(entry) !== -1) return;
802
+ dialogStack.push(entry);
803
+ ensureGlobalListener();
687
804
  }
688
- function attachListener() {
689
- if (typeof window !== "undefined" && !listenerAttached) {
690
- window.addEventListener("keydown", handleKeydown);
691
- listenerAttached = true;
692
- }
693
- }
694
- function detachListener() {
695
- if (typeof window !== "undefined" && listenerAttached) {
696
- window.removeEventListener("keydown", handleKeydown);
697
- listenerAttached = false;
698
- }
805
+ function removeFromStack() {
806
+ const idx = dialogStack.indexOf(entry);
807
+ if (idx !== -1) dialogStack.splice(idx, 1);
808
+ removeGlobalListenerIfIdle();
699
809
  }
700
810
  function open() {
811
+ if (isOpen()) return;
701
812
  setIsOpen(true);
702
- attachListener();
813
+ pushOnStack();
703
814
  }
704
815
  function close() {
816
+ if (!isOpen()) {
817
+ removeFromStack();
818
+ return;
819
+ }
705
820
  setIsOpen(false);
706
- detachListener();
821
+ removeFromStack();
707
822
  }
708
823
  function toggle() {
709
824
  if (isOpen()) close();
710
825
  else open();
711
826
  }
712
- function dispose() {
713
- detachListener();
827
+ function dispose2() {
828
+ removeFromStack();
714
829
  setIsOpen(false);
715
830
  }
716
- return { open, close, isOpen, toggle, dispose };
831
+ return { open, close, isOpen, toggle, dispose: dispose2 };
717
832
  }
718
833
 
719
834
  // src/ui/toast.ts
720
- var toastCounter = 0;
721
835
  function toast(options) {
722
836
  const duration = options?.duration ?? 3e3;
723
837
  const maxToasts = options?.maxToasts ?? Infinity;
724
838
  const [toasts, setToasts] = signal([]);
725
839
  const timers = /* @__PURE__ */ new Map();
840
+ let toastCounter = 0;
726
841
  function show(message, type) {
727
842
  const id = `toast-${++toastCounter}`;
728
843
  const toast2 = { id, message, type };
844
+ const trimmedIds = [];
729
845
  setToasts((prev) => {
730
846
  const next = [...prev, toast2];
731
847
  if (next.length > maxToasts) {
732
848
  const removed = next.splice(0, next.length - maxToasts);
733
- for (const r of removed) {
734
- clearTimerForToast(r.id);
735
- }
849
+ for (const r of removed) trimmedIds.push(r.id);
736
850
  }
737
851
  return next;
738
852
  });
739
- if (duration > 0) {
853
+ for (const tid of trimmedIds) clearTimerForToast(tid);
854
+ const wasTrimmed = trimmedIds.indexOf(id) !== -1;
855
+ if (duration > 0 && !wasTrimmed) {
740
856
  const timer = setTimeout(() => {
741
857
  dismiss(id);
742
858
  }, duration);
@@ -822,14 +938,14 @@ function infiniteScroll(options) {
822
938
  },
823
939
  configurable: true
824
940
  });
825
- function dispose() {
941
+ function dispose2() {
826
942
  disposed = true;
827
943
  if (observer) {
828
944
  observer.disconnect();
829
945
  observer = null;
830
946
  }
831
947
  }
832
- return { sentinelRef: originalRef, loading, dispose };
948
+ return { sentinelRef: originalRef, loading, dispose: dispose2 };
833
949
  }
834
950
 
835
951
  // src/ui/pagination.ts
@@ -908,7 +1024,7 @@ function defineElement(name, component, options = {}) {
908
1024
  class SibuElement extends HTMLElement {
909
1025
  constructor() {
910
1026
  super();
911
- this._rendered = false;
1027
+ this._rendered = null;
912
1028
  if (options.shadow !== false) {
913
1029
  this._root = this.attachShadow({ mode: options.mode || "open" });
914
1030
  } else {
@@ -922,25 +1038,23 @@ function defineElement(name, component, options = {}) {
922
1038
  this._render();
923
1039
  }
924
1040
  disconnectedCallback() {
925
- if (this._root instanceof ShadowRoot) {
926
- this._root.innerHTML = "";
927
- }
928
- this._rendered = false;
1041
+ this._teardown();
929
1042
  }
930
1043
  attributeChangedCallback() {
931
1044
  if (this._rendered) {
932
1045
  this._render();
933
1046
  }
934
1047
  }
1048
+ _teardown() {
1049
+ if (this._rendered) {
1050
+ dispose(this._rendered);
1051
+ this._rendered = null;
1052
+ }
1053
+ this._root.replaceChildren();
1054
+ }
935
1055
  _render() {
1056
+ this._teardown();
936
1057
  const props = this._getProps();
937
- if (this._root instanceof ShadowRoot) {
938
- this._root.innerHTML = "";
939
- } else {
940
- while (this._root.firstChild) {
941
- this._root.removeChild(this._root.firstChild);
942
- }
943
- }
944
1058
  if (options.styles && this._root instanceof ShadowRoot) {
945
1059
  const styleEl = document.createElement("style");
946
1060
  styleEl.textContent = options.styles;
@@ -948,7 +1062,7 @@ function defineElement(name, component, options = {}) {
948
1062
  }
949
1063
  const el = component(props, this);
950
1064
  this._root.appendChild(el);
951
- this._rendered = true;
1065
+ this._rendered = el;
952
1066
  }
953
1067
  _getProps() {
954
1068
  const props = {};
@@ -1013,6 +1127,7 @@ export {
1013
1127
  bindAttrs,
1014
1128
  bindBoolAttr,
1015
1129
  bindData,
1130
+ __resetDialogStack,
1016
1131
  dialog,
1017
1132
  toast,
1018
1133
  infiniteScroll,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SVG_NS,
3
3
  tagFactory
4
- } from "./chunk-WADYRCO2.js";
4
+ } from "./chunk-KLRMB5ZS.js";
5
5
 
6
6
  // src/core/rendering/html.ts
7
7
  var html = tagFactory("html");