sibujs 1.4.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 (190) hide show
  1. package/README.md +105 -119
  2. package/dist/browser.cjs +288 -80
  3. package/dist/browser.d.cts +19 -9
  4. package/dist/browser.d.ts +19 -9
  5. package/dist/browser.js +6 -6
  6. package/dist/build.cjs +1019 -313
  7. package/dist/build.d.cts +1 -1
  8. package/dist/build.d.ts +1 -1
  9. package/dist/build.js +15 -13
  10. package/dist/cdn.global.js +17 -16
  11. package/dist/chunk-2RA7SHDA.js +65 -0
  12. package/dist/chunk-2UPRY23K.js +80 -0
  13. package/dist/chunk-3JHCYHWN.js +125 -0
  14. package/dist/{chunk-ZWKZCBO6.js → chunk-3LR7GLWQ.js} +154 -33
  15. package/dist/{chunk-3AIRKM3B.js → chunk-3NSGB5JN.js} +115 -34
  16. package/dist/{chunk-3ARAQO7B.js → chunk-52YJLLRO.js} +29 -6
  17. package/dist/chunk-54EDRCEF.js +93 -0
  18. package/dist/chunk-7JDB7I65.js +1327 -0
  19. package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
  20. package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
  21. package/dist/{chunk-WR5D4EGH.js → chunk-GTBNNBJ6.js} +14 -2
  22. package/dist/chunk-HB24TBAF.js +121 -0
  23. package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
  24. package/dist/{chunk-JAKHTMQU.js → chunk-JA6667UN.js} +206 -46
  25. package/dist/{chunk-77L6NL3X.js → chunk-JXMMDLBY.js} +306 -183
  26. package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
  27. package/dist/{chunk-F3FA4F32.js → chunk-KLRMB5ZS.js} +135 -79
  28. package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
  29. package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
  30. package/dist/{chunk-TSOKIX5Z.js → chunk-MIUAXB7K.js} +126 -74
  31. package/dist/{chunk-QWZG56ET.js → chunk-ND2664SF.js} +558 -190
  32. package/dist/{chunk-JCI5M6U6.js → chunk-O2MNQFLP.js} +261 -79
  33. package/dist/{chunk-EWFVA3TJ.js → chunk-R73P76YZ.js} +1 -1
  34. package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
  35. package/dist/chunk-UCS6AMJ7.js +79 -0
  36. package/dist/{chunk-ZD6OAMTH.js → chunk-VLPPXTYG.js} +90 -35
  37. package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
  38. package/dist/{contracts-xo5ckdRP.d.cts → contracts-ey_Qh8ef.d.cts} +7 -8
  39. package/dist/{contracts-xo5ckdRP.d.ts → contracts-ey_Qh8ef.d.ts} +7 -8
  40. package/dist/{customElement-D2DJp_xn.d.cts → customElement-CPfIrbvg.d.cts} +18 -9
  41. package/dist/{customElement-D2DJp_xn.d.ts → customElement-CPfIrbvg.d.ts} +18 -9
  42. package/dist/data.cjs +452 -100
  43. package/dist/data.d.cts +20 -2
  44. package/dist/data.d.ts +20 -2
  45. package/dist/data.js +11 -9
  46. package/dist/devtools.cjs +535 -247
  47. package/dist/devtools.d.cts +1 -1
  48. package/dist/devtools.d.ts +1 -1
  49. package/dist/devtools.js +34 -30
  50. package/dist/ecosystem.cjs +499 -143
  51. package/dist/ecosystem.d.cts +13 -11
  52. package/dist/ecosystem.d.ts +13 -11
  53. package/dist/ecosystem.js +12 -11
  54. package/dist/extras.cjs +3639 -1629
  55. package/dist/extras.d.cts +11 -11
  56. package/dist/extras.d.ts +11 -11
  57. package/dist/extras.js +58 -45
  58. package/dist/index.cjs +1023 -313
  59. package/dist/index.d.cts +128 -55
  60. package/dist/index.d.ts +128 -55
  61. package/dist/index.js +28 -16
  62. package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
  63. package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
  64. package/dist/motion.cjs +90 -36
  65. package/dist/motion.d.cts +1 -1
  66. package/dist/motion.d.ts +1 -1
  67. package/dist/motion.js +4 -4
  68. package/dist/patterns.cjs +414 -81
  69. package/dist/patterns.d.cts +53 -20
  70. package/dist/patterns.d.ts +53 -20
  71. package/dist/patterns.js +7 -7
  72. package/dist/performance.cjs +364 -108
  73. package/dist/performance.d.cts +29 -17
  74. package/dist/performance.d.ts +29 -17
  75. package/dist/performance.js +13 -6
  76. package/dist/plugin-D30wlGW5.d.cts +71 -0
  77. package/dist/plugin-D30wlGW5.d.ts +71 -0
  78. package/dist/plugins.cjs +652 -271
  79. package/dist/plugins.d.cts +13 -6
  80. package/dist/plugins.d.ts +13 -6
  81. package/dist/plugins.js +116 -50
  82. package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
  83. package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
  84. package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
  85. package/dist/ssr.cjs +648 -219
  86. package/dist/ssr.d.cts +27 -7
  87. package/dist/ssr.d.ts +27 -7
  88. package/dist/ssr.js +12 -11
  89. package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.cts} +9 -1
  90. package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.ts} +9 -1
  91. package/dist/testing.cjs +252 -63
  92. package/dist/testing.d.cts +17 -4
  93. package/dist/testing.d.ts +17 -4
  94. package/dist/testing.js +100 -44
  95. package/dist/ui.cjs +576 -168
  96. package/dist/ui.d.cts +13 -16
  97. package/dist/ui.d.ts +13 -16
  98. package/dist/ui.js +20 -17
  99. package/dist/widgets.cjs +1001 -93
  100. package/dist/widgets.d.cts +104 -2
  101. package/dist/widgets.d.ts +104 -2
  102. package/dist/widgets.js +9 -7
  103. package/package.json +8 -2
  104. package/dist/chunk-32DY64NT.js +0 -282
  105. package/dist/chunk-3CRQALYP.js +0 -877
  106. package/dist/chunk-4EI4AG32.js +0 -482
  107. package/dist/chunk-4MYMUBRS.js +0 -21
  108. package/dist/chunk-6HLLIF3K.js +0 -398
  109. package/dist/chunk-6LSNVCS2.js +0 -937
  110. package/dist/chunk-6SA3QQES.js +0 -61
  111. package/dist/chunk-7BF6TK55.js +0 -1097
  112. package/dist/chunk-7TQKR4PP.js +0 -294
  113. package/dist/chunk-7V26P53V.js +0 -712
  114. package/dist/chunk-AZ3ISID5.js +0 -298
  115. package/dist/chunk-B7SWRFUT.js +0 -332
  116. package/dist/chunk-BGN5ZMP4.js +0 -26
  117. package/dist/chunk-BTU3TJDS.js +0 -365
  118. package/dist/chunk-BW3WT46K.js +0 -937
  119. package/dist/chunk-C6KFWOFV.js +0 -616
  120. package/dist/chunk-CHF5OHIA.js +0 -61
  121. package/dist/chunk-CHJ27IGK.js +0 -26
  122. package/dist/chunk-CMBFNA7L.js +0 -27
  123. package/dist/chunk-DAHRH4ON.js +0 -331
  124. package/dist/chunk-DKOHBI74.js +0 -924
  125. package/dist/chunk-DTCOOBMX.js +0 -725
  126. package/dist/chunk-EBGIRKQY.js +0 -616
  127. package/dist/chunk-EUZND3CB.js +0 -27
  128. package/dist/chunk-EVCZO745.js +0 -365
  129. package/dist/chunk-FGOEVHY3.js +0 -60
  130. package/dist/chunk-G3BOQPVO.js +0 -365
  131. package/dist/chunk-GCOK2LC3.js +0 -282
  132. package/dist/chunk-HGMJFBC7.js +0 -654
  133. package/dist/chunk-K5ZUMYVS.js +0 -89
  134. package/dist/chunk-KQPDEVVS.js +0 -398
  135. package/dist/chunk-L6JRBDNS.js +0 -60
  136. package/dist/chunk-LA6KQEDU.js +0 -712
  137. package/dist/chunk-MDVXJWFN.js +0 -304
  138. package/dist/chunk-MEZVEBPN.js +0 -2008
  139. package/dist/chunk-MK4ERFYL.js +0 -2249
  140. package/dist/chunk-MLKGABMK.js +0 -9
  141. package/dist/chunk-MQ5GOYPH.js +0 -2249
  142. package/dist/chunk-N6IZB6KJ.js +0 -567
  143. package/dist/chunk-NEKUBFPT.js +0 -60
  144. package/dist/chunk-NHUC2QWH.js +0 -282
  145. package/dist/chunk-NMRUZALC.js +0 -1097
  146. package/dist/chunk-NYVAC6P5.js +0 -37
  147. package/dist/chunk-OF7UZIVB.js +0 -725
  148. package/dist/chunk-P6W3STU4.js +0 -2249
  149. package/dist/chunk-PBHF5WKN.js +0 -616
  150. package/dist/chunk-PTQJDMRT.js +0 -146
  151. package/dist/chunk-PZEGYCF5.js +0 -61
  152. package/dist/chunk-QBMDLBU2.js +0 -975
  153. package/dist/chunk-RQGQSLQK.js +0 -725
  154. package/dist/chunk-SDLZDHKP.js +0 -107
  155. package/dist/chunk-TNQWPPE6.js +0 -37
  156. package/dist/chunk-UHNL42EF.js +0 -2730
  157. package/dist/chunk-UNXCEF6S.js +0 -21
  158. package/dist/chunk-V2XTI523.js +0 -347
  159. package/dist/chunk-VAU366PN.js +0 -2241
  160. package/dist/chunk-VMVDTCXB.js +0 -712
  161. package/dist/chunk-VRW3FULF.js +0 -725
  162. package/dist/chunk-WADYRCO2.js +0 -304
  163. package/dist/chunk-WILQZRO4.js +0 -282
  164. package/dist/chunk-WUHJISPP.js +0 -298
  165. package/dist/chunk-XYU6TZOW.js +0 -182
  166. package/dist/chunk-Y6GP4QGG.js +0 -276
  167. package/dist/chunk-YECR7UIA.js +0 -347
  168. package/dist/chunk-YUTWTI4B.js +0 -654
  169. package/dist/chunk-Z65KYU7I.js +0 -26
  170. package/dist/chunk-Z6POF5YC.js +0 -975
  171. package/dist/chunk-ZBJP6WFL.js +0 -482
  172. package/dist/contracts-DDrwxvJ-.d.cts +0 -245
  173. package/dist/contracts-DDrwxvJ-.d.ts +0 -245
  174. package/dist/contracts-DOrhwbke.d.cts +0 -245
  175. package/dist/contracts-DOrhwbke.d.ts +0 -245
  176. package/dist/customElement-BKQfbSZQ.d.cts +0 -262
  177. package/dist/customElement-BKQfbSZQ.d.ts +0 -262
  178. package/dist/customElement-yz8uyk-0.d.cts +0 -308
  179. package/dist/customElement-yz8uyk-0.d.ts +0 -308
  180. package/dist/introspect-Cb0zgpi2.d.cts +0 -477
  181. package/dist/introspect-Y2xNXGSf.d.ts +0 -477
  182. package/dist/plugin-Bek4RhJY.d.cts +0 -43
  183. package/dist/plugin-Bek4RhJY.d.ts +0 -43
  184. package/dist/ssr-3RXHP5ES.js +0 -38
  185. package/dist/ssr-6GIMY5MX.js +0 -38
  186. package/dist/ssr-BA6sxxUd.d.cts +0 -135
  187. package/dist/ssr-BA6sxxUd.d.ts +0 -135
  188. package/dist/ssr-WKUPVSSK.js +0 -36
  189. package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
  190. package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
@@ -16,6 +16,14 @@ declare function combobox<T>(options: ComboboxOptions<T>): {
16
16
  isOpen: () => boolean;
17
17
  open: () => void;
18
18
  close: () => void;
19
+ /** WAI-ARIA Combobox 1.2 wiring: `role=combobox` on input,
20
+ * `aria-expanded`/`aria-controls`/`aria-activedescendant`, listbox option
21
+ * ids, Down/Up/Enter/Escape/Home/End. Returns dispose. */
22
+ bind: (els: {
23
+ input: HTMLInputElement;
24
+ listbox: HTMLElement;
25
+ option: (item: T, index: number) => HTMLElement | null;
26
+ }) => () => void;
19
27
  };
20
28
 
21
29
  interface TabsOptions {
@@ -26,6 +34,15 @@ interface TabsOptions {
26
34
  }>;
27
35
  defaultTab?: string;
28
36
  }
37
+ interface TabsAriaBinding {
38
+ /** WAI-ARIA Tabs pattern — wires `role`/`aria-*` and arrow/Home/End keys
39
+ * to the provided tablist + per-tab elements. Returns dispose. */
40
+ bind: (els: {
41
+ tablist: HTMLElement;
42
+ tabs: Record<string, HTMLElement>;
43
+ panels?: Record<string, HTMLElement>;
44
+ }) => () => void;
45
+ }
29
46
  declare function tabs(options: TabsOptions): {
30
47
  activeTab: () => string;
31
48
  setActiveTab: (id: string) => void;
@@ -38,6 +55,7 @@ declare function tabs(options: TabsOptions): {
38
55
  nextTab: () => void;
39
56
  prevTab: () => void;
40
57
  isActive: (id: string) => boolean;
58
+ bind: TabsAriaBinding["bind"];
41
59
  };
42
60
 
43
61
  interface AccordionOptions {
@@ -48,6 +66,18 @@ interface AccordionOptions {
48
66
  multiple?: boolean;
49
67
  defaultExpanded?: string[];
50
68
  }
69
+ interface AccordionAriaBinding {
70
+ /** WAI-ARIA Accordion pattern — wires `aria-expanded`/`aria-controls`,
71
+ * Enter/Space toggle, and panel `role=region`. Returns dispose.
72
+ * Pass `root` (any stable container element) to anchor the WeakMap
73
+ * idempotency key — without it, double-bind detection falls back to
74
+ * the first trigger and breaks if items re-render. */
75
+ bind: (els: {
76
+ root?: HTMLElement;
77
+ triggers: Record<string, HTMLElement>;
78
+ panels: Record<string, HTMLElement>;
79
+ }) => () => void;
80
+ }
51
81
  declare function accordion(options: AccordionOptions): {
52
82
  items: () => Array<{
53
83
  id: string;
@@ -60,6 +90,7 @@ declare function accordion(options: AccordionOptions): {
60
90
  expandAll: () => void;
61
91
  collapseAll: () => void;
62
92
  isExpanded: (id: string) => boolean;
93
+ bind: AccordionAriaBinding["bind"];
63
94
  };
64
95
 
65
96
  /**
@@ -71,12 +102,22 @@ declare function popover(): {
71
102
  open: () => void;
72
103
  close: () => void;
73
104
  toggle: () => void;
105
+ /** WAI-ARIA non-modal dialog wiring: `role=dialog`, `aria-expanded` on
106
+ * trigger, Escape closes, click-outside closes. Returns dispose. */
107
+ bind: (els: {
108
+ trigger: HTMLElement;
109
+ popover: HTMLElement;
110
+ labelledBy?: HTMLElement;
111
+ }) => () => void;
74
112
  };
75
113
 
76
114
  interface SelectOptions<T> {
77
115
  items: T[];
78
116
  multiple?: boolean;
79
117
  itemToString?: (item: T) => string;
118
+ /** Optional predicate marking items as disabled — such items are skipped
119
+ * by `highlightNext`/`highlightPrev`/typeahead and rejected by `select`. */
120
+ isDisabled?: (item: T) => boolean;
80
121
  }
81
122
  declare function select<T>(options: SelectOptions<T>): {
82
123
  selectedItems: () => T[];
@@ -93,6 +134,14 @@ declare function select<T>(options: SelectOptions<T>): {
93
134
  highlightPrev: () => void;
94
135
  selectHighlighted: () => void;
95
136
  clear: () => void;
137
+ /** WAI-ARIA Listbox wiring: `role=listbox`, `aria-multiselectable`,
138
+ * `aria-selected`/`aria-activedescendant`, arrow + Home/End/Enter/Space
139
+ * + typeahead. Returns dispose. */
140
+ bind: (els: {
141
+ listbox: HTMLElement;
142
+ option: (item: T, index: number) => HTMLElement | null;
143
+ itemToString?: (item: T) => string;
144
+ }) => () => void;
96
145
  };
97
146
 
98
147
  /**
@@ -101,12 +150,19 @@ declare function select<T>(options: SelectOptions<T>): {
101
150
  */
102
151
  declare function tooltip(options?: {
103
152
  delay?: number;
153
+ hideDelay?: number;
104
154
  }): {
105
155
  isVisible: () => boolean;
106
156
  show: () => void;
107
157
  hide: () => void;
108
158
  content: () => string;
109
159
  setContent: (text: string) => void;
160
+ /** WAI-ARIA Tooltip pattern — wires `role=tooltip`, `aria-describedby`,
161
+ * Escape-to-dismiss, and pointer hover-grace per WCAG 1.4.13. */
162
+ bind: (els: {
163
+ trigger: HTMLElement;
164
+ tooltip: HTMLElement;
165
+ }) => () => void;
110
166
  };
111
167
 
112
168
  interface FileUploadOptions {
@@ -123,8 +179,37 @@ declare function fileUpload(options?: FileUploadOptions): {
123
179
  errors: () => string[];
124
180
  isDragOver: () => boolean;
125
181
  setDragOver: (v: boolean) => void;
182
+ /** Wires native file input + drop zone with proper labeling, hint
183
+ * description, and keyboard activation. Returns dispose. */
184
+ bind: (els: {
185
+ input: HTMLInputElement;
186
+ dropZone?: HTMLElement;
187
+ hint?: HTMLElement;
188
+ errorRegion?: HTMLElement;
189
+ }) => () => void;
126
190
  };
127
191
 
192
+ /**
193
+ * Options for `setContent`.
194
+ *
195
+ * WARNING: passing `sanitize: false` bypasses the built-in protection and
196
+ * requires the caller to guarantee the HTML has already been sanitized with
197
+ * a trusted library. Any untrusted input that reaches `setContent` with
198
+ * `sanitize: false` is an XSS vector.
199
+ */
200
+ interface SetContentOptions {
201
+ /** Raw HTML to assign. Sanitized by default (tags are stripped). */
202
+ html?: string;
203
+ /** Plain text. Always safe — assigned via `textContent`. */
204
+ text?: string;
205
+ /**
206
+ * When true (default), `html` is run through the framework's HTML
207
+ * stripper before assignment — tags are removed, only text content is
208
+ * preserved. Set to `false` ONLY when `html` has already been sanitized
209
+ * with a dedicated library (e.g. DOMPurify).
210
+ */
211
+ sanitize?: boolean;
212
+ }
128
213
  /**
129
214
  * contentEditable provides reactive binding for contenteditable elements.
130
215
  *
@@ -134,7 +219,18 @@ declare function fileUpload(options?: FileUploadOptions): {
134
219
  */
135
220
  declare function contentEditable(): {
136
221
  content: () => string;
137
- setContent: (html: string) => void;
222
+ /**
223
+ * Update the reactive content value.
224
+ *
225
+ * - `setContent("<b>x</b>")` — LEGACY: treated as `{ html, sanitize: true }`.
226
+ * The HTML is stripped to text by default to prevent XSS. Prefer the
227
+ * options form below.
228
+ * - `setContent({ text: "hello" })` — plain text, always safe.
229
+ * - `setContent({ html, sanitize: true })` — sanitized HTML (default).
230
+ * - `setContent({ html, sanitize: false })` — raw HTML; the caller MUST
231
+ * have pre-sanitized it with a trusted library (e.g. DOMPurify).
232
+ */
233
+ setContent: (input: string | SetContentOptions) => void;
138
234
  isFocused: () => boolean;
139
235
  setFocused: (v: boolean) => void;
140
236
  bold: () => void;
@@ -165,6 +261,12 @@ declare function datePicker(options?: DatePickerOptions): {
165
261
  }>;
166
262
  isDateDisabled: (date: Date) => boolean;
167
263
  isSelected: (date: Date) => boolean;
264
+ /** WAI-ARIA Date Picker dialog grid wiring: `role=grid`, arrow nav,
265
+ * PageUp/Down (month), Shift+PageUp/Down (year), Home/End. */
266
+ bind: (els: {
267
+ grid: HTMLElement;
268
+ cell: (date: Date) => HTMLElement | null;
269
+ }) => () => void;
168
270
  };
169
271
 
170
- export { type AccordionOptions, type ComboboxOptions, type DatePickerOptions, type FileUploadOptions, type SelectOptions, type TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip };
272
+ export { type AccordionAriaBinding, type AccordionOptions, type ComboboxOptions, type DatePickerOptions, type FileUploadOptions, type SelectOptions, type SetContentOptions, type TabsAriaBinding, type TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip };
package/dist/widgets.d.ts CHANGED
@@ -16,6 +16,14 @@ declare function combobox<T>(options: ComboboxOptions<T>): {
16
16
  isOpen: () => boolean;
17
17
  open: () => void;
18
18
  close: () => void;
19
+ /** WAI-ARIA Combobox 1.2 wiring: `role=combobox` on input,
20
+ * `aria-expanded`/`aria-controls`/`aria-activedescendant`, listbox option
21
+ * ids, Down/Up/Enter/Escape/Home/End. Returns dispose. */
22
+ bind: (els: {
23
+ input: HTMLInputElement;
24
+ listbox: HTMLElement;
25
+ option: (item: T, index: number) => HTMLElement | null;
26
+ }) => () => void;
19
27
  };
20
28
 
21
29
  interface TabsOptions {
@@ -26,6 +34,15 @@ interface TabsOptions {
26
34
  }>;
27
35
  defaultTab?: string;
28
36
  }
37
+ interface TabsAriaBinding {
38
+ /** WAI-ARIA Tabs pattern — wires `role`/`aria-*` and arrow/Home/End keys
39
+ * to the provided tablist + per-tab elements. Returns dispose. */
40
+ bind: (els: {
41
+ tablist: HTMLElement;
42
+ tabs: Record<string, HTMLElement>;
43
+ panels?: Record<string, HTMLElement>;
44
+ }) => () => void;
45
+ }
29
46
  declare function tabs(options: TabsOptions): {
30
47
  activeTab: () => string;
31
48
  setActiveTab: (id: string) => void;
@@ -38,6 +55,7 @@ declare function tabs(options: TabsOptions): {
38
55
  nextTab: () => void;
39
56
  prevTab: () => void;
40
57
  isActive: (id: string) => boolean;
58
+ bind: TabsAriaBinding["bind"];
41
59
  };
42
60
 
43
61
  interface AccordionOptions {
@@ -48,6 +66,18 @@ interface AccordionOptions {
48
66
  multiple?: boolean;
49
67
  defaultExpanded?: string[];
50
68
  }
69
+ interface AccordionAriaBinding {
70
+ /** WAI-ARIA Accordion pattern — wires `aria-expanded`/`aria-controls`,
71
+ * Enter/Space toggle, and panel `role=region`. Returns dispose.
72
+ * Pass `root` (any stable container element) to anchor the WeakMap
73
+ * idempotency key — without it, double-bind detection falls back to
74
+ * the first trigger and breaks if items re-render. */
75
+ bind: (els: {
76
+ root?: HTMLElement;
77
+ triggers: Record<string, HTMLElement>;
78
+ panels: Record<string, HTMLElement>;
79
+ }) => () => void;
80
+ }
51
81
  declare function accordion(options: AccordionOptions): {
52
82
  items: () => Array<{
53
83
  id: string;
@@ -60,6 +90,7 @@ declare function accordion(options: AccordionOptions): {
60
90
  expandAll: () => void;
61
91
  collapseAll: () => void;
62
92
  isExpanded: (id: string) => boolean;
93
+ bind: AccordionAriaBinding["bind"];
63
94
  };
64
95
 
65
96
  /**
@@ -71,12 +102,22 @@ declare function popover(): {
71
102
  open: () => void;
72
103
  close: () => void;
73
104
  toggle: () => void;
105
+ /** WAI-ARIA non-modal dialog wiring: `role=dialog`, `aria-expanded` on
106
+ * trigger, Escape closes, click-outside closes. Returns dispose. */
107
+ bind: (els: {
108
+ trigger: HTMLElement;
109
+ popover: HTMLElement;
110
+ labelledBy?: HTMLElement;
111
+ }) => () => void;
74
112
  };
75
113
 
76
114
  interface SelectOptions<T> {
77
115
  items: T[];
78
116
  multiple?: boolean;
79
117
  itemToString?: (item: T) => string;
118
+ /** Optional predicate marking items as disabled — such items are skipped
119
+ * by `highlightNext`/`highlightPrev`/typeahead and rejected by `select`. */
120
+ isDisabled?: (item: T) => boolean;
80
121
  }
81
122
  declare function select<T>(options: SelectOptions<T>): {
82
123
  selectedItems: () => T[];
@@ -93,6 +134,14 @@ declare function select<T>(options: SelectOptions<T>): {
93
134
  highlightPrev: () => void;
94
135
  selectHighlighted: () => void;
95
136
  clear: () => void;
137
+ /** WAI-ARIA Listbox wiring: `role=listbox`, `aria-multiselectable`,
138
+ * `aria-selected`/`aria-activedescendant`, arrow + Home/End/Enter/Space
139
+ * + typeahead. Returns dispose. */
140
+ bind: (els: {
141
+ listbox: HTMLElement;
142
+ option: (item: T, index: number) => HTMLElement | null;
143
+ itemToString?: (item: T) => string;
144
+ }) => () => void;
96
145
  };
97
146
 
98
147
  /**
@@ -101,12 +150,19 @@ declare function select<T>(options: SelectOptions<T>): {
101
150
  */
102
151
  declare function tooltip(options?: {
103
152
  delay?: number;
153
+ hideDelay?: number;
104
154
  }): {
105
155
  isVisible: () => boolean;
106
156
  show: () => void;
107
157
  hide: () => void;
108
158
  content: () => string;
109
159
  setContent: (text: string) => void;
160
+ /** WAI-ARIA Tooltip pattern — wires `role=tooltip`, `aria-describedby`,
161
+ * Escape-to-dismiss, and pointer hover-grace per WCAG 1.4.13. */
162
+ bind: (els: {
163
+ trigger: HTMLElement;
164
+ tooltip: HTMLElement;
165
+ }) => () => void;
110
166
  };
111
167
 
112
168
  interface FileUploadOptions {
@@ -123,8 +179,37 @@ declare function fileUpload(options?: FileUploadOptions): {
123
179
  errors: () => string[];
124
180
  isDragOver: () => boolean;
125
181
  setDragOver: (v: boolean) => void;
182
+ /** Wires native file input + drop zone with proper labeling, hint
183
+ * description, and keyboard activation. Returns dispose. */
184
+ bind: (els: {
185
+ input: HTMLInputElement;
186
+ dropZone?: HTMLElement;
187
+ hint?: HTMLElement;
188
+ errorRegion?: HTMLElement;
189
+ }) => () => void;
126
190
  };
127
191
 
192
+ /**
193
+ * Options for `setContent`.
194
+ *
195
+ * WARNING: passing `sanitize: false` bypasses the built-in protection and
196
+ * requires the caller to guarantee the HTML has already been sanitized with
197
+ * a trusted library. Any untrusted input that reaches `setContent` with
198
+ * `sanitize: false` is an XSS vector.
199
+ */
200
+ interface SetContentOptions {
201
+ /** Raw HTML to assign. Sanitized by default (tags are stripped). */
202
+ html?: string;
203
+ /** Plain text. Always safe — assigned via `textContent`. */
204
+ text?: string;
205
+ /**
206
+ * When true (default), `html` is run through the framework's HTML
207
+ * stripper before assignment — tags are removed, only text content is
208
+ * preserved. Set to `false` ONLY when `html` has already been sanitized
209
+ * with a dedicated library (e.g. DOMPurify).
210
+ */
211
+ sanitize?: boolean;
212
+ }
128
213
  /**
129
214
  * contentEditable provides reactive binding for contenteditable elements.
130
215
  *
@@ -134,7 +219,18 @@ declare function fileUpload(options?: FileUploadOptions): {
134
219
  */
135
220
  declare function contentEditable(): {
136
221
  content: () => string;
137
- setContent: (html: string) => void;
222
+ /**
223
+ * Update the reactive content value.
224
+ *
225
+ * - `setContent("<b>x</b>")` — LEGACY: treated as `{ html, sanitize: true }`.
226
+ * The HTML is stripped to text by default to prevent XSS. Prefer the
227
+ * options form below.
228
+ * - `setContent({ text: "hello" })` — plain text, always safe.
229
+ * - `setContent({ html, sanitize: true })` — sanitized HTML (default).
230
+ * - `setContent({ html, sanitize: false })` — raw HTML; the caller MUST
231
+ * have pre-sanitized it with a trusted library (e.g. DOMPurify).
232
+ */
233
+ setContent: (input: string | SetContentOptions) => void;
138
234
  isFocused: () => boolean;
139
235
  setFocused: (v: boolean) => void;
140
236
  bold: () => void;
@@ -165,6 +261,12 @@ declare function datePicker(options?: DatePickerOptions): {
165
261
  }>;
166
262
  isDateDisabled: (date: Date) => boolean;
167
263
  isSelected: (date: Date) => boolean;
264
+ /** WAI-ARIA Date Picker dialog grid wiring: `role=grid`, arrow nav,
265
+ * PageUp/Down (month), Shift+PageUp/Down (year), Home/End. */
266
+ bind: (els: {
267
+ grid: HTMLElement;
268
+ cell: (date: Date) => HTMLElement | null;
269
+ }) => () => void;
168
270
  };
169
271
 
170
- export { type AccordionOptions, type ComboboxOptions, type DatePickerOptions, type FileUploadOptions, type SelectOptions, type TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip };
272
+ export { type AccordionAriaBinding, type AccordionOptions, type ComboboxOptions, type DatePickerOptions, type FileUploadOptions, type SelectOptions, type SetContentOptions, type TabsAriaBinding, type TabsOptions, accordion, combobox, contentEditable, datePicker, fileUpload, popover, select, tabs, tooltip };
package/dist/widgets.js CHANGED
@@ -8,13 +8,15 @@ import {
8
8
  select,
9
9
  tabs,
10
10
  tooltip
11
- } from "./chunk-EBGIRKQY.js";
12
- import "./chunk-NYVAC6P5.js";
13
- import "./chunk-NEKUBFPT.js";
14
- import "./chunk-EUZND3CB.js";
15
- import "./chunk-WZSPOOER.js";
16
- import "./chunk-ZD6OAMTH.js";
17
- import "./chunk-5X6PP2UK.js";
11
+ } from "./chunk-7JDB7I65.js";
12
+ import "./chunk-ITX6OO3F.js";
13
+ import "./chunk-54EDRCEF.js";
14
+ import "./chunk-UCS6AMJ7.js";
15
+ import "./chunk-HB24TBAF.js";
16
+ import "./chunk-2RA7SHDA.js";
17
+ import "./chunk-CC65Y57T.js";
18
+ import "./chunk-VLPPXTYG.js";
19
+ import "./chunk-LMLD24FC.js";
18
20
  export {
19
21
  accordion,
20
22
  combobox,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sibujs",
3
- "version": "1.4.0",
3
+ "version": "2.0.0",
4
4
  "description": "A lightweight, function-based frontend framework that combines the best of React, Svelte, and Vue — with zero VDOM and maximum simplicity. Designed for developers who want fine-grained reactivity and full control without compilation or magic.",
5
5
  "keywords": [
6
6
  "frontend",
@@ -33,7 +33,7 @@
33
33
  "format": "biome format --write src/ tests/",
34
34
  "test": "vitest",
35
35
  "test:ui": "vitest --ui",
36
- "build": "tsup index.ts data.ts browser.ts patterns.ts motion.ts ui.ts widgets.ts ssr.ts devtools.ts performance.ts ecosystem.ts plugins.ts build.ts testing.ts extras.ts --dts --format esm,cjs --out-dir dist && tsup cdn.ts --format iife --globalName Sibu --out-dir dist --no-dts --minify",
36
+ "build": "tsup index.ts data.ts browser.ts patterns.ts motion.ts ui.ts widgets.ts ssr.ts devtools.ts performance.ts ecosystem.ts plugins.ts build.ts testing.ts extras.ts --dts --format esm,cjs --out-dir dist --clean && tsup cdn.ts --format iife --globalName Sibu --out-dir dist --no-dts --minify",
37
37
  "bench": "node bench.mjs",
38
38
  "bench:save": "node bench.mjs --save",
39
39
  "bench:check": "node bench.mjs --compare",
@@ -116,8 +116,14 @@
116
116
  "types": "./dist/extras.d.ts",
117
117
  "import": "./dist/extras.js",
118
118
  "require": "./dist/extras.cjs"
119
+ },
120
+ "./cdn": {
121
+ "default": "./dist/cdn.global.js"
119
122
  }
120
123
  },
124
+ "publishConfig": {
125
+ "access": "public"
126
+ },
121
127
  "browserslist": [
122
128
  "Chrome >= 80",
123
129
  "Firefox >= 78",