sibujs 4.6.0 → 4.8.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 (94) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +62 -8
  3. package/dist/browser.d.cts +23 -0
  4. package/dist/browser.d.ts +23 -0
  5. package/dist/browser.js +6 -5
  6. package/dist/build.cjs +2388 -1004
  7. package/dist/build.d.cts +147 -44
  8. package/dist/build.d.ts +147 -44
  9. package/dist/build.js +1410 -564
  10. package/dist/cdn.dev.global.js +14 -12
  11. package/dist/cdn.full.dev.global.js +15 -13
  12. package/dist/cdn.full.global.js +14 -12
  13. package/dist/cdn.global.js +12 -10
  14. package/dist/chunk-3ACAAQIN.js +224 -0
  15. package/dist/{chunk-7NCARGJW.js → chunk-44MTL7ED.js} +6 -6
  16. package/dist/{chunk-BAAG6ZTI.js → chunk-4WMSTZ7J.js} +8 -5
  17. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  18. package/dist/{chunk-DKGBBKOF.js → chunk-C5PEWEGH.js} +20 -5
  19. package/dist/{chunk-3ISI6ACU.js → chunk-C7AA2CZX.js} +1 -1
  20. package/dist/{chunk-UZQ6ALFS.js → chunk-CZPRSWSS.js} +1 -1
  21. package/dist/{chunk-D33YTSX5.js → chunk-DSID757X.js} +5 -4
  22. package/dist/{chunk-OXUY2A6L.js → chunk-EGUQLBHE.js} +22 -8
  23. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  24. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  25. package/dist/{chunk-HYXDKS4N.js → chunk-GSGNX35Q.js} +5 -5
  26. package/dist/{chunk-7GQCWFOE.js → chunk-J3YQ457H.js} +171 -85
  27. package/dist/{chunk-ORMZXBKQ.js → chunk-JUTFX2RM.js} +18 -10
  28. package/dist/{chunk-QE4TTDU3.js → chunk-KJ3UKABJ.js} +12 -11
  29. package/dist/{chunk-XRRZKZYX.js → chunk-LI4W3U6C.js} +1 -1
  30. package/dist/{chunk-47M47FOM.js → chunk-O6TRVMJI.js} +58 -6
  31. package/dist/{chunk-JSXPZCET.js → chunk-Q5J2LVKH.js} +1 -1
  32. package/dist/{chunk-5MT6SJ3P.js → chunk-QGMSESDD.js} +10 -5
  33. package/dist/{chunk-AIF3Z2T7.js → chunk-RGLPEBDE.js} +13 -10
  34. package/dist/{chunk-5Q4R7HCL.js → chunk-TQQUN4WR.js} +11 -2
  35. package/dist/{chunk-PK6FK2G2.js → chunk-UCNP3HVM.js} +183 -30
  36. package/dist/{chunk-XC4MEKGA.js → chunk-V3LHZSU5.js} +8 -2
  37. package/dist/{chunk-VVWPJ543.js → chunk-VWT3VXPL.js} +55 -20
  38. package/dist/{chunk-SXXVZMKZ.js → chunk-ZVLHNEEL.js} +17 -35
  39. package/dist/{contracts-DRIuclVT.d.cts → contracts-CLqzJnOV.d.ts} +28 -17
  40. package/dist/{contracts-DRIuclVT.d.ts → contracts-CTOJXu-x.d.cts} +28 -17
  41. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  42. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  43. package/dist/data.cjs +205 -39
  44. package/dist/data.d.cts +119 -3
  45. package/dist/data.d.ts +119 -3
  46. package/dist/data.js +6 -6
  47. package/dist/devtools.cjs +18 -5
  48. package/dist/devtools.js +5 -5
  49. package/dist/ecosystem.cjs +462 -58
  50. package/dist/ecosystem.d.cts +2 -1
  51. package/dist/ecosystem.d.ts +2 -1
  52. package/dist/ecosystem.js +9 -8
  53. package/dist/extras.cjs +852 -296
  54. package/dist/extras.d.cts +5 -4
  55. package/dist/extras.d.ts +5 -4
  56. package/dist/extras.js +24 -23
  57. package/dist/index.cjs +721 -176
  58. package/dist/index.d.cts +220 -169
  59. package/dist/index.d.ts +220 -169
  60. package/dist/index.js +16 -12
  61. package/dist/motion.cjs +12 -4
  62. package/dist/motion.js +3 -3
  63. package/dist/patterns.cjs +37 -21
  64. package/dist/patterns.d.cts +2 -1
  65. package/dist/patterns.d.ts +2 -1
  66. package/dist/patterns.js +6 -6
  67. package/dist/performance.cjs +48 -6
  68. package/dist/performance.d.cts +12 -2
  69. package/dist/performance.d.ts +12 -2
  70. package/dist/performance.js +8 -6
  71. package/dist/plugins.cjs +672 -261
  72. package/dist/plugins.d.cts +131 -13
  73. package/dist/plugins.d.ts +131 -13
  74. package/dist/plugins.js +83 -47
  75. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  76. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.cts} +6 -0
  77. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.ts} +6 -0
  78. package/dist/ssr.cjs +509 -142
  79. package/dist/ssr.d.cts +55 -5
  80. package/dist/ssr.d.ts +55 -5
  81. package/dist/ssr.js +11 -9
  82. package/dist/{tagFactory-DFstCLQV.d.cts → tagFactory-8qL9LCIx.d.cts} +58 -19
  83. package/dist/{tagFactory-DkaNVUNV.d.ts → tagFactory-BL2fymez.d.ts} +58 -19
  84. package/dist/testing.cjs +17 -4
  85. package/dist/testing.js +4 -4
  86. package/dist/types-CJFViL6Q.d.cts +26 -0
  87. package/dist/types-CJFViL6Q.d.ts +26 -0
  88. package/dist/ui.cjs +635 -254
  89. package/dist/ui.d.cts +3 -2
  90. package/dist/ui.d.ts +3 -2
  91. package/dist/ui.js +9 -8
  92. package/dist/widgets.cjs +22 -14
  93. package/dist/widgets.js +7 -7
  94. package/package.json +8 -5
@@ -1,15 +1,18 @@
1
1
  import {
2
2
  bindAttribute,
3
3
  setSafeAttribute
4
- } from "./chunk-47M47FOM.js";
4
+ } from "./chunk-O6TRVMJI.js";
5
+ import {
6
+ isBlockedElement
7
+ } from "./chunk-3ACAAQIN.js";
5
8
  import {
6
9
  isEventHandlerAttr,
7
- sanitizeCSSValue,
10
+ sanitizeCSSDeclaration,
8
11
  sanitizeStyleAttribute
9
- } from "./chunk-2INLLLMZ.js";
12
+ } from "./chunk-EXXSN3BW.js";
10
13
  import {
11
14
  reactiveBinding
12
- } from "./chunk-5Q4R7HCL.js";
15
+ } from "./chunk-TQQUN4WR.js";
13
16
  import {
14
17
  DEV,
15
18
  devWarn,
@@ -189,10 +192,6 @@ function bindChildNode(placeholder, getter) {
189
192
 
190
193
  // src/core/rendering/tagFactory.ts
191
194
  var SVG_NS = "http://www.w3.org/2000/svg";
192
- var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
193
- function isBlockedTag(tag) {
194
- return BLOCKED_TAGS.has(tag.toLowerCase());
195
- }
196
195
  var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
197
196
  "config",
198
197
  "location",
@@ -219,8 +218,35 @@ function toKebab(prop) {
219
218
  }
220
219
  function applyStyle(el, style) {
221
220
  if (typeof style === "function") {
221
+ const getter = style;
222
+ let written = [];
223
+ let wroteString = false;
222
224
  const teardown = reactiveBinding(() => {
223
- el.setAttribute("style", sanitizeStyleAttribute(String(style()), { element: el }));
225
+ const value = getter();
226
+ if (value === null || typeof value !== "object") {
227
+ written = [];
228
+ wroteString = true;
229
+ el.setAttribute("style", sanitizeStyleAttribute(String(value), { element: el }));
230
+ return;
231
+ }
232
+ const decl = el.style;
233
+ if (wroteString) {
234
+ el.removeAttribute("style");
235
+ wroteString = false;
236
+ }
237
+ const next = [];
238
+ for (const prop in value) {
239
+ if (!Object.hasOwn(value, prop)) continue;
240
+ const val = value[prop];
241
+ if (val == null) continue;
242
+ const name = toKebab(prop);
243
+ next.push(name);
244
+ decl.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
245
+ }
246
+ for (let i = 0; i < written.length; i++) {
247
+ if (next.indexOf(written[i]) === -1) decl.removeProperty(written[i]);
248
+ }
249
+ written = next;
224
250
  }, el);
225
251
  registerDisposer(el, teardown);
226
252
  return;
@@ -231,25 +257,27 @@ function applyStyle(el, style) {
231
257
  }
232
258
  const htmlEl = el;
233
259
  for (const prop in style) {
260
+ if (!Object.hasOwn(style, prop)) continue;
234
261
  const val = style[prop];
235
262
  const name = toKebab(prop);
236
263
  if (typeof val === "function") {
237
264
  const getter = val;
238
265
  const teardown = reactiveBinding(() => {
239
- htmlEl.style.setProperty(name, sanitizeCSSValue(String(getter()), { property: name, element: el }));
266
+ htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(getter()), { element: el }));
240
267
  }, el);
241
268
  registerDisposer(el, teardown);
242
269
  } else {
243
- htmlEl.style.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
270
+ htmlEl.style.setProperty(name, sanitizeCSSDeclaration(name, String(val), { element: el }));
244
271
  }
245
272
  }
246
273
  }
247
274
  function resolveClassValue(cls) {
248
275
  if (typeof cls === "string") return cls;
249
- if (typeof cls === "function") return cls();
276
+ if (typeof cls === "function") return cls() || "";
250
277
  if (!cls) return "";
251
278
  let out = "";
252
279
  for (const name in cls) {
280
+ if (!Object.hasOwn(cls, name)) continue;
253
281
  const val = cls[name];
254
282
  const active = typeof val === "function" ? val() : val;
255
283
  if (active) out = out ? `${out} ${name}` : name;
@@ -263,7 +291,9 @@ function applyClass(el, cls) {
263
291
  }
264
292
  if (typeof cls === "function") {
265
293
  const teardown = reactiveBinding(() => {
266
- el.setAttribute("class", cls());
294
+ const value = cls();
295
+ if (value == null || value === false) el.removeAttribute("class");
296
+ else el.setAttribute("class", value);
267
297
  }, el);
268
298
  registerDisposer(el, teardown);
269
299
  return;
@@ -272,6 +302,7 @@ function applyClass(el, cls) {
272
302
  let hasReactive = false;
273
303
  let result = "";
274
304
  for (const name in obj) {
305
+ if (!Object.hasOwn(obj, name)) continue;
275
306
  const val = obj[name];
276
307
  if (typeof val === "function") {
277
308
  hasReactive = true;
@@ -283,6 +314,7 @@ function applyClass(el, cls) {
283
314
  const update = () => {
284
315
  let r = "";
285
316
  for (const name in obj) {
317
+ if (!Object.hasOwn(obj, name)) continue;
286
318
  const val = obj[name];
287
319
  const active = typeof val === "function" ? val() : val;
288
320
  if (active) r = r ? `${r} ${name}` : name;
@@ -345,8 +377,8 @@ function appendChildren(el, nodes) {
345
377
  }
346
378
  }
347
379
  }
348
- var tagFactory = (tag, ns) => {
349
- const blocked = isBlockedTag(tag);
380
+ function tagFactory(tag, ns) {
381
+ const blocked = isBlockedElement(tag);
350
382
  return (first, second) => {
351
383
  if (blocked) {
352
384
  throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
@@ -394,7 +426,9 @@ var tagFactory = (tag, ns) => {
394
426
  const pClass = props.class;
395
427
  if (pClass != null) applyClass(el, pClass);
396
428
  const pId = props.id;
397
- if (pId != null) {
429
+ if (typeof pId === "function") {
430
+ registerDisposer(el, bindAttribute(el, "id", pId));
431
+ } else if (pId != null) {
398
432
  if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
399
433
  devWarn(
400
434
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
@@ -407,6 +441,7 @@ var tagFactory = (tag, ns) => {
407
441
  const pOn = props.on;
408
442
  if (pOn) {
409
443
  for (const ev in pOn) {
444
+ if (!Object.hasOwn(pOn, ev)) continue;
410
445
  const handler = pOn[ev];
411
446
  if (typeof handler === "function") {
412
447
  el.addEventListener(ev, handler);
@@ -433,6 +468,7 @@ var tagFactory = (tag, ns) => {
433
468
  continue;
434
469
  // already handled above / below
435
470
  default: {
471
+ if (!Object.hasOwn(props, key)) continue;
436
472
  const value = props[key];
437
473
  if (value == null) continue;
438
474
  if (isEventHandlerAttr(key)) continue;
@@ -444,12 +480,10 @@ var tagFactory = (tag, ns) => {
444
480
  }
445
481
  }
446
482
  }
447
- if (props.onElement && typeof props.onElement === "function") {
448
- props.onElement(el);
449
- }
483
+ if (typeof props.onElement === "function") props.onElement(el);
450
484
  return el;
451
485
  };
452
- };
486
+ }
453
487
 
454
488
  export {
455
489
  captureFocusWithin,
@@ -457,5 +491,6 @@ export {
457
491
  bindChildNode,
458
492
  SVG_NS,
459
493
  resolveClassValue,
494
+ appendChildren,
460
495
  tagFactory
461
496
  };
@@ -1,29 +1,33 @@
1
1
  import {
2
2
  domBinding
3
- } from "./chunk-3ISI6ACU.js";
3
+ } from "./chunk-C7AA2CZX.js";
4
4
  import {
5
5
  bindAttribute,
6
6
  setSafeAttribute
7
- } from "./chunk-47M47FOM.js";
7
+ } from "./chunk-O6TRVMJI.js";
8
8
  import {
9
- derived
10
- } from "./chunk-QE4TTDU3.js";
9
+ isBlockedElement
10
+ } from "./chunk-3ACAAQIN.js";
11
11
  import {
12
- isEventHandlerAttr
13
- } from "./chunk-2INLLLMZ.js";
12
+ derived
13
+ } from "./chunk-KJ3UKABJ.js";
14
14
  import {
15
15
  globalSingleton
16
16
  } from "./chunk-7ZHH77QA.js";
17
+ import {
18
+ isEventHandlerAttr,
19
+ sanitizeStylesheetText
20
+ } from "./chunk-EXXSN3BW.js";
17
21
  import {
18
22
  adoptThenable
19
23
  } from "./chunk-5HZXGZ6T.js";
20
24
  import {
21
25
  signal
22
- } from "./chunk-D33YTSX5.js";
26
+ } from "./chunk-DSID757X.js";
23
27
  import {
24
28
  reactiveBinding,
25
29
  track
26
- } from "./chunk-5Q4R7HCL.js";
30
+ } from "./chunk-TQQUN4WR.js";
27
31
  import {
28
32
  dispose,
29
33
  disposeNodeOwn,
@@ -745,31 +749,6 @@ function announce(message, priority = "polite") {
745
749
 
746
750
  // src/ui/scopedStyle.ts
747
751
  var _scope = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.scopedStyle.v1"), () => ({ n: 0 }));
748
- function decodeCssEscapes(css) {
749
- return css.replace(/\\([0-9a-f]{1,6})[ \t\n\r\f]?|\\([^\n])/gi, (_match, hex, ch) => {
750
- if (hex) {
751
- const code = Number.parseInt(hex, 16);
752
- if (Number.isFinite(code) && code > 0 && code <= 1114111) {
753
- try {
754
- return String.fromCodePoint(code);
755
- } catch {
756
- return "";
757
- }
758
- }
759
- return "";
760
- }
761
- return ch || "";
762
- });
763
- }
764
- function sanitizeCSS(css) {
765
- let sanitized = decodeCssEscapes(css);
766
- sanitized = sanitized.replace(/@import\s+[^;]+;/gi, "/* @import removed */");
767
- sanitized = sanitized.replace(/url\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* url() removed */");
768
- sanitized = sanitized.replace(/expression\s*\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)/gi, "/* expression() removed */");
769
- sanitized = sanitized.replace(/-moz-binding\s*:[^;]+;/gi, "/* -moz-binding removed */");
770
- sanitized = sanitized.replace(/behavior\s*:[^;]+;/gi, "/* behavior removed */");
771
- return sanitized;
772
- }
773
752
  function firstCompoundEnd(selector) {
774
753
  let parens = 0;
775
754
  let brackets = 0;
@@ -931,7 +910,7 @@ function scopeStylesheet(css, attr) {
931
910
  function scopedStyle(css) {
932
911
  const id = `sibu-s${_scope.n++}`;
933
912
  const attr = `data-${id}`;
934
- const safeCss = sanitizeCSS(css);
913
+ const safeCss = sanitizeStylesheetText(css);
935
914
  const scopedCSS = scopeStylesheet(safeCss, attr);
936
915
  if (typeof document !== "undefined") {
937
916
  const styleEl = document.createElement("style");
@@ -989,7 +968,7 @@ function bindBoolAttr(el, attr, getter) {
989
968
  reportError(err, { phase: "binding", name: "bindBoolAttr", node: el });
990
969
  return;
991
970
  }
992
- setSafeAttribute(el, attr, Boolean(value), { label: "bindBoolAttr" });
971
+ setSafeAttribute(el, attr, Boolean(value), { label: "bindBoolAttr", reactive: true });
993
972
  }
994
973
  return reactiveBinding(commit, el);
995
974
  }
@@ -1472,6 +1451,9 @@ function defineElement(name, component, options = {}) {
1472
1451
  customElements.define(name, SibuElement);
1473
1452
  }
1474
1453
  function svgElement(tag, props = {}, ...nodes) {
1454
+ if (isBlockedElement(tag)) {
1455
+ throw new Error(`svgElement: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
1456
+ }
1475
1457
  const el = document.createElementNS(SVG_NS, tag);
1476
1458
  for (const [key, value] of Object.entries(props)) {
1477
1459
  if (key === "nodes") continue;
@@ -1,8 +1,15 @@
1
+ import { C as Component } from './types-CJFViL6Q.js';
2
+
1
3
  /**
2
4
  * Higher-order component utilities for SibuJS.
3
5
  * These functions wrap or compose components to add behavior.
6
+ *
7
+ * Each helper is generic over the wrapped component's root type `R`, so a
8
+ * component returning `div()` keeps its `HTMLDivElement` root and an SVG
9
+ * component works as well. `R` defaults to `HTMLElement`, the type these
10
+ * helpers used before, for callers that pass the type arguments explicitly.
4
11
  */
5
- type Component<P = unknown> = (props: P) => HTMLElement;
12
+
6
13
  /**
7
14
  * Wraps a component with additional behavior that runs before/after rendering.
8
15
  *
@@ -18,7 +25,7 @@ type Component<P = unknown> = (props: P) => HTMLElement;
18
25
  * });
19
26
  * ```
20
27
  */
21
- declare function withWrapper<P>(WrappedComponent: Component<P>, wrapper: (component: Component<P>, props: P) => HTMLElement): Component<P>;
28
+ declare function withWrapper<P, R extends Node = HTMLElement, W extends Node = R>(WrappedComponent: Component<P, R>, wrapper: (component: Component<P, R>, props: P) => W): Component<P, W>;
22
29
  /**
23
30
  * Adds default props to a component. Missing props are filled from defaults.
24
31
  *
@@ -38,9 +45,9 @@ declare function withWrapper<P>(WrappedComponent: Component<P>, wrapper: (compon
38
45
  * optional status.
39
46
  */
40
47
  type WithDefaultsProps<P, D> = Omit<P, keyof D> & Partial<Pick<P, Extract<keyof P, keyof D>>>;
41
- declare function withDefaults<P extends object, const D extends Partial<P> = Partial<P>>(component: Component<P>, defaults: D & {
48
+ declare function withDefaults<P extends object, const D extends Partial<P> = Partial<P>, R extends Node = HTMLElement>(component: Component<P, R>, defaults: D & {
42
49
  [K in Exclude<keyof D, keyof P>]: never;
43
- }): Component<WithDefaultsProps<P, D>>;
50
+ }): Component<WithDefaultsProps<P, D>, R>;
44
51
  /**
45
52
  * Composes multiple HOC wrappers into a single wrapper.
46
53
  * Applied from right to left (like function composition).
@@ -54,7 +61,7 @@ declare function withDefaults<P extends object, const D extends Partial<P> = Par
54
61
  * const EnhancedPage = enhance(Page);
55
62
  * ```
56
63
  */
57
- declare function compose(...wrappers: Array<(component: Component) => Component>): (component: Component) => Component;
64
+ declare function compose<C extends Component<never, Node> = Component<unknown, HTMLElement>>(...wrappers: Array<(component: C) => C>): (component: C) => C;
58
65
 
59
66
  /**
60
67
  * RenderProp implements the render-prop pattern.
@@ -83,6 +90,7 @@ declare function createSlots(slots: Record<string, () => HTMLElement | HTMLEleme
83
90
  * Provides utilities to define typed components with prop defaults,
84
91
  * nodes slots, and prop mapping — all with full TypeScript inference.
85
92
  */
93
+
86
94
  /**
87
95
  * Extract the props type from a component defined with defineComponent.
88
96
  *
@@ -94,7 +102,7 @@ declare function createSlots(slots: Record<string, () => HTMLElement | HTMLEleme
94
102
  * type ButtonProps = ComponentProps<typeof Button>; // { label: string }
95
103
  * ```
96
104
  */
97
- type ComponentProps<T> = T extends (props: infer P) => HTMLElement ? P : never;
105
+ type ComponentProps<T> = T extends (props: infer P) => Node ? P : never;
98
106
  /**
99
107
  * Props that include an optional nodes slot.
100
108
  */
@@ -104,11 +112,14 @@ type WithNodes<Props> = Props & {
104
112
  /**
105
113
  * Define a typed component with props inference, defaults, and a setup function.
106
114
  *
107
- * The `setup` function receives merged props (defaults + provided) and must
108
- * return an HTMLElement. TypeScript infers the full props type from the generic.
115
+ * The `setup` function receives merged props (defaults + provided) and
116
+ * returns the component's root. TypeScript infers the full props type from the
117
+ * generic. `R` is the root type; it defaults to `HTMLElement` (every HTML tag
118
+ * factory's result fits) — pass it explicitly for an SVG root
119
+ * (`defineComponent<Props, SVGSVGElement>`).
109
120
  *
110
121
  * @param config Component configuration with optional defaults and a setup function
111
- * @returns A component function that accepts props and returns an HTMLElement
122
+ * @returns A component function that accepts props and returns the root
112
123
  *
113
124
  * @example
114
125
  * ```ts
@@ -125,10 +136,10 @@ type WithNodes<Props> = Props & {
125
136
  * // Usage: Button({ label: 'Click me' }) — TypeScript infers props
126
137
  * ```
127
138
  */
128
- declare function defineComponent<Props extends object>(config: {
139
+ declare function defineComponent<Props extends object, R extends Node = HTMLElement>(config: {
129
140
  defaults?: Partial<Props>;
130
- setup: (props: Props) => HTMLElement;
131
- }): (props: Props) => HTMLElement;
141
+ setup: (props: Props) => R;
142
+ }): Component<Props, R>;
132
143
  /**
133
144
  * Create a component with nodes slot support.
134
145
  *
@@ -137,7 +148,7 @@ declare function defineComponent<Props extends object>(config: {
137
148
  * wraps arbitrary child content.
138
149
  *
139
150
  * @param config Component configuration with optional defaults and a setup function
140
- * @returns A component function that accepts props (including nodes) and returns an HTMLElement
151
+ * @returns A component function that accepts props (including nodes) and returns the root
141
152
  *
142
153
  * @example
143
154
  * ```ts
@@ -156,10 +167,10 @@ declare function defineComponent<Props extends object>(config: {
156
167
  * // Usage: Card({ title: 'Hello', nodes: p('World') })
157
168
  * ```
158
169
  */
159
- declare function defineSlottedComponent<Props extends object>(config: {
170
+ declare function defineSlottedComponent<Props extends object, R extends Node = HTMLElement>(config: {
160
171
  defaults?: Partial<Props>;
161
- setup: (props: WithNodes<Props>) => HTMLElement;
162
- }): (props: WithNodes<Props>) => HTMLElement;
172
+ setup: (props: WithNodes<Props>) => R;
173
+ }): Component<WithNodes<Props>, R>;
163
174
  /**
164
175
  * Higher-order helper to create a component that maps outer props to inner props.
165
176
  *
@@ -185,7 +196,7 @@ declare function defineSlottedComponent<Props extends object>(config: {
185
196
  * // Usage: SmallIconButton({ icon: 'star', label: 'Favorite' })
186
197
  * ```
187
198
  */
188
- declare function withProps<OuterProps extends object, InnerProps extends object>(component: (props: InnerProps) => HTMLElement, mapProps: (outer: OuterProps) => InnerProps): (props: OuterProps) => HTMLElement;
199
+ declare function withProps<OuterProps extends object, InnerProps extends object, R extends Node = HTMLElement>(component: Component<InnerProps, R>, mapProps: (outer: OuterProps) => InnerProps): Component<OuterProps, R>;
189
200
 
190
201
  /**
191
202
  * Runtime prop validation and strict typing contracts for SibuJS.
@@ -1,8 +1,15 @@
1
+ import { C as Component } from './types-CJFViL6Q.cjs';
2
+
1
3
  /**
2
4
  * Higher-order component utilities for SibuJS.
3
5
  * These functions wrap or compose components to add behavior.
6
+ *
7
+ * Each helper is generic over the wrapped component's root type `R`, so a
8
+ * component returning `div()` keeps its `HTMLDivElement` root and an SVG
9
+ * component works as well. `R` defaults to `HTMLElement`, the type these
10
+ * helpers used before, for callers that pass the type arguments explicitly.
4
11
  */
5
- type Component<P = unknown> = (props: P) => HTMLElement;
12
+
6
13
  /**
7
14
  * Wraps a component with additional behavior that runs before/after rendering.
8
15
  *
@@ -18,7 +25,7 @@ type Component<P = unknown> = (props: P) => HTMLElement;
18
25
  * });
19
26
  * ```
20
27
  */
21
- declare function withWrapper<P>(WrappedComponent: Component<P>, wrapper: (component: Component<P>, props: P) => HTMLElement): Component<P>;
28
+ declare function withWrapper<P, R extends Node = HTMLElement, W extends Node = R>(WrappedComponent: Component<P, R>, wrapper: (component: Component<P, R>, props: P) => W): Component<P, W>;
22
29
  /**
23
30
  * Adds default props to a component. Missing props are filled from defaults.
24
31
  *
@@ -38,9 +45,9 @@ declare function withWrapper<P>(WrappedComponent: Component<P>, wrapper: (compon
38
45
  * optional status.
39
46
  */
40
47
  type WithDefaultsProps<P, D> = Omit<P, keyof D> & Partial<Pick<P, Extract<keyof P, keyof D>>>;
41
- declare function withDefaults<P extends object, const D extends Partial<P> = Partial<P>>(component: Component<P>, defaults: D & {
48
+ declare function withDefaults<P extends object, const D extends Partial<P> = Partial<P>, R extends Node = HTMLElement>(component: Component<P, R>, defaults: D & {
42
49
  [K in Exclude<keyof D, keyof P>]: never;
43
- }): Component<WithDefaultsProps<P, D>>;
50
+ }): Component<WithDefaultsProps<P, D>, R>;
44
51
  /**
45
52
  * Composes multiple HOC wrappers into a single wrapper.
46
53
  * Applied from right to left (like function composition).
@@ -54,7 +61,7 @@ declare function withDefaults<P extends object, const D extends Partial<P> = Par
54
61
  * const EnhancedPage = enhance(Page);
55
62
  * ```
56
63
  */
57
- declare function compose(...wrappers: Array<(component: Component) => Component>): (component: Component) => Component;
64
+ declare function compose<C extends Component<never, Node> = Component<unknown, HTMLElement>>(...wrappers: Array<(component: C) => C>): (component: C) => C;
58
65
 
59
66
  /**
60
67
  * RenderProp implements the render-prop pattern.
@@ -83,6 +90,7 @@ declare function createSlots(slots: Record<string, () => HTMLElement | HTMLEleme
83
90
  * Provides utilities to define typed components with prop defaults,
84
91
  * nodes slots, and prop mapping — all with full TypeScript inference.
85
92
  */
93
+
86
94
  /**
87
95
  * Extract the props type from a component defined with defineComponent.
88
96
  *
@@ -94,7 +102,7 @@ declare function createSlots(slots: Record<string, () => HTMLElement | HTMLEleme
94
102
  * type ButtonProps = ComponentProps<typeof Button>; // { label: string }
95
103
  * ```
96
104
  */
97
- type ComponentProps<T> = T extends (props: infer P) => HTMLElement ? P : never;
105
+ type ComponentProps<T> = T extends (props: infer P) => Node ? P : never;
98
106
  /**
99
107
  * Props that include an optional nodes slot.
100
108
  */
@@ -104,11 +112,14 @@ type WithNodes<Props> = Props & {
104
112
  /**
105
113
  * Define a typed component with props inference, defaults, and a setup function.
106
114
  *
107
- * The `setup` function receives merged props (defaults + provided) and must
108
- * return an HTMLElement. TypeScript infers the full props type from the generic.
115
+ * The `setup` function receives merged props (defaults + provided) and
116
+ * returns the component's root. TypeScript infers the full props type from the
117
+ * generic. `R` is the root type; it defaults to `HTMLElement` (every HTML tag
118
+ * factory's result fits) — pass it explicitly for an SVG root
119
+ * (`defineComponent<Props, SVGSVGElement>`).
109
120
  *
110
121
  * @param config Component configuration with optional defaults and a setup function
111
- * @returns A component function that accepts props and returns an HTMLElement
122
+ * @returns A component function that accepts props and returns the root
112
123
  *
113
124
  * @example
114
125
  * ```ts
@@ -125,10 +136,10 @@ type WithNodes<Props> = Props & {
125
136
  * // Usage: Button({ label: 'Click me' }) — TypeScript infers props
126
137
  * ```
127
138
  */
128
- declare function defineComponent<Props extends object>(config: {
139
+ declare function defineComponent<Props extends object, R extends Node = HTMLElement>(config: {
129
140
  defaults?: Partial<Props>;
130
- setup: (props: Props) => HTMLElement;
131
- }): (props: Props) => HTMLElement;
141
+ setup: (props: Props) => R;
142
+ }): Component<Props, R>;
132
143
  /**
133
144
  * Create a component with nodes slot support.
134
145
  *
@@ -137,7 +148,7 @@ declare function defineComponent<Props extends object>(config: {
137
148
  * wraps arbitrary child content.
138
149
  *
139
150
  * @param config Component configuration with optional defaults and a setup function
140
- * @returns A component function that accepts props (including nodes) and returns an HTMLElement
151
+ * @returns A component function that accepts props (including nodes) and returns the root
141
152
  *
142
153
  * @example
143
154
  * ```ts
@@ -156,10 +167,10 @@ declare function defineComponent<Props extends object>(config: {
156
167
  * // Usage: Card({ title: 'Hello', nodes: p('World') })
157
168
  * ```
158
169
  */
159
- declare function defineSlottedComponent<Props extends object>(config: {
170
+ declare function defineSlottedComponent<Props extends object, R extends Node = HTMLElement>(config: {
160
171
  defaults?: Partial<Props>;
161
- setup: (props: WithNodes<Props>) => HTMLElement;
162
- }): (props: WithNodes<Props>) => HTMLElement;
172
+ setup: (props: WithNodes<Props>) => R;
173
+ }): Component<WithNodes<Props>, R>;
163
174
  /**
164
175
  * Higher-order helper to create a component that maps outer props to inner props.
165
176
  *
@@ -185,7 +196,7 @@ declare function defineSlottedComponent<Props extends object>(config: {
185
196
  * // Usage: SmallIconButton({ icon: 'star', label: 'Favorite' })
186
197
  * ```
187
198
  */
188
- declare function withProps<OuterProps extends object, InnerProps extends object>(component: (props: InnerProps) => HTMLElement, mapProps: (outer: OuterProps) => InnerProps): (props: OuterProps) => HTMLElement;
199
+ declare function withProps<OuterProps extends object, InnerProps extends object, R extends Node = HTMLElement>(component: Component<InnerProps, R>, mapProps: (outer: OuterProps) => InnerProps): Component<OuterProps, R>;
189
200
 
190
201
  /**
191
202
  * Runtime prop validation and strict typing contracts for SibuJS.
@@ -277,9 +277,11 @@ declare function announce(message: string, priority?: "polite" | "assertive"): v
277
277
  * and prefixing all selectors.
278
278
  * Returns the scope attribute name and injects the CSS into the document.
279
279
  *
280
- * CSS is sanitized to remove dangerous patterns (`url()`, `@import`,
281
- * `expression()`, `-moz-binding`, `behavior`). If you need `url()` for
282
- * background images, use inline styles via the `style` prop instead.
280
+ * CSS is sanitized by the framework's stylesheet-text policy
281
+ * (`sanitizeStylesheetText`): `url()`, `image-set()`, `image()`, `src()`,
282
+ * `expression()`, `@import`, `behavior`, `-moz-binding` and `progid:` filters
283
+ * are removed. For a content image use an `<img>`; for a decorative one, a
284
+ * stylesheet you ship.
283
285
  */
284
286
  declare function scopedStyle(css: string): {
285
287
  scope: string;
@@ -484,6 +486,7 @@ declare function eventBus<T extends object>(): {
484
486
  interface CustomElementOptions {
485
487
  shadow?: boolean;
486
488
  mode?: "open" | "closed";
489
+ /** Stylesheet source for the element's shadow root, applied unsanitized — developer CSS, not runtime data. */
487
490
  styles?: string;
488
491
  observedAttributes?: string[];
489
492
  }
@@ -504,6 +507,11 @@ declare function defineElement(name: string, component: (props: Record<string, u
504
507
  *
505
508
  * Function-valued `on*` props keep their existing meaning — `addEventListener`,
506
509
  * never an attribute.
510
+ *
511
+ * The TAG is policed like a tag factory's, through the shared element policy:
512
+ * `svgElement("script", { href })` is refused. SVG has its own `<script>`, which
513
+ * the browser fetches and runs when it is inserted, so an unrestricted tag name
514
+ * here was a way around the tag factories' block on script elements.
507
515
  */
508
516
  declare function svgElement(tag: string, props?: Record<string, unknown>, ...nodes: (SVGElement | string)[]): SVGElement;
509
517
 
@@ -277,9 +277,11 @@ declare function announce(message: string, priority?: "polite" | "assertive"): v
277
277
  * and prefixing all selectors.
278
278
  * Returns the scope attribute name and injects the CSS into the document.
279
279
  *
280
- * CSS is sanitized to remove dangerous patterns (`url()`, `@import`,
281
- * `expression()`, `-moz-binding`, `behavior`). If you need `url()` for
282
- * background images, use inline styles via the `style` prop instead.
280
+ * CSS is sanitized by the framework's stylesheet-text policy
281
+ * (`sanitizeStylesheetText`): `url()`, `image-set()`, `image()`, `src()`,
282
+ * `expression()`, `@import`, `behavior`, `-moz-binding` and `progid:` filters
283
+ * are removed. For a content image use an `<img>`; for a decorative one, a
284
+ * stylesheet you ship.
283
285
  */
284
286
  declare function scopedStyle(css: string): {
285
287
  scope: string;
@@ -484,6 +486,7 @@ declare function eventBus<T extends object>(): {
484
486
  interface CustomElementOptions {
485
487
  shadow?: boolean;
486
488
  mode?: "open" | "closed";
489
+ /** Stylesheet source for the element's shadow root, applied unsanitized — developer CSS, not runtime data. */
487
490
  styles?: string;
488
491
  observedAttributes?: string[];
489
492
  }
@@ -504,6 +507,11 @@ declare function defineElement(name: string, component: (props: Record<string, u
504
507
  *
505
508
  * Function-valued `on*` props keep their existing meaning — `addEventListener`,
506
509
  * never an attribute.
510
+ *
511
+ * The TAG is policed like a tag factory's, through the shared element policy:
512
+ * `svgElement("script", { href })` is refused. SVG has its own `<script>`, which
513
+ * the browser fetches and runs when it is inserted, so an unrestricted tag name
514
+ * here was a way around the tag factories' block on script elements.
507
515
  */
508
516
  declare function svgElement(tag: string, props?: Record<string, unknown>, ...nodes: (SVGElement | string)[]): SVGElement;
509
517