@bquery/bquery 1.7.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/README.md +760 -716
  2. package/dist/{a11y-C5QOVvRn.js → a11y-DVBCy09c.js} +3 -3
  3. package/dist/a11y-DVBCy09c.js.map +1 -0
  4. package/dist/a11y.es.mjs +1 -1
  5. package/dist/component/library.d.ts.map +1 -1
  6. package/dist/{component-CuuTijA6.js → component-L3-JfOFz.js} +5 -5
  7. package/dist/component-L3-JfOFz.js.map +1 -0
  8. package/dist/component.es.mjs +1 -1
  9. package/dist/{config-BW35FKuA.js → config-DhT9auRm.js} +1 -1
  10. package/dist/{config-BW35FKuA.js.map → config-DhT9auRm.js.map} +1 -1
  11. package/dist/{constraints-3lV9yyBw.js → constraints-D5RHQLmP.js} +1 -1
  12. package/dist/constraints-D5RHQLmP.js.map +1 -0
  13. package/dist/core/collection.d.ts +86 -0
  14. package/dist/core/collection.d.ts.map +1 -1
  15. package/dist/core/element.d.ts +28 -0
  16. package/dist/core/element.d.ts.map +1 -1
  17. package/dist/core/shared.d.ts +6 -0
  18. package/dist/core/shared.d.ts.map +1 -1
  19. package/dist/core-DdtZHzsS.js +168 -0
  20. package/dist/core-DdtZHzsS.js.map +1 -0
  21. package/dist/{core-Cjl7GUu8.js → core-EMYSLzaT.js} +289 -259
  22. package/dist/core-EMYSLzaT.js.map +1 -0
  23. package/dist/core.es.mjs +48 -47
  24. package/dist/{custom-directives-7wAShnnd.js → custom-directives-Dr4C5lVV.js} +1 -1
  25. package/dist/custom-directives-Dr4C5lVV.js.map +1 -0
  26. package/dist/{devtools-D2fQLhDN.js → devtools-BhB2iDPT.js} +2 -2
  27. package/dist/devtools-BhB2iDPT.js.map +1 -0
  28. package/dist/devtools.es.mjs +1 -1
  29. package/dist/{dnd-B8EgyzaI.js → dnd-NwZBYh4l.js} +1 -1
  30. package/dist/dnd-NwZBYh4l.js.map +1 -0
  31. package/dist/dnd.es.mjs +1 -1
  32. package/dist/{env-NeVmr4Gf.js → env-CTdvLaH2.js} +1 -1
  33. package/dist/env-CTdvLaH2.js.map +1 -0
  34. package/dist/forms/create-form.d.ts.map +1 -1
  35. package/dist/forms/index.d.ts +3 -2
  36. package/dist/forms/index.d.ts.map +1 -1
  37. package/dist/forms/types.d.ts +46 -0
  38. package/dist/forms/types.d.ts.map +1 -1
  39. package/dist/forms/use-field.d.ts +34 -0
  40. package/dist/forms/use-field.d.ts.map +1 -0
  41. package/dist/forms/validators.d.ts +25 -0
  42. package/dist/forms/validators.d.ts.map +1 -1
  43. package/dist/forms-UcRHsYxC.js +227 -0
  44. package/dist/forms-UcRHsYxC.js.map +1 -0
  45. package/dist/forms.es.mjs +14 -12
  46. package/dist/full.d.ts +17 -26
  47. package/dist/full.d.ts.map +1 -1
  48. package/dist/full.es.mjs +206 -181
  49. package/dist/full.iife.js +33 -33
  50. package/dist/full.iife.js.map +1 -1
  51. package/dist/full.umd.js +33 -33
  52. package/dist/full.umd.js.map +1 -1
  53. package/dist/function-Cybd57JV.js +33 -0
  54. package/dist/function-Cybd57JV.js.map +1 -0
  55. package/dist/{i18n-BnnhTFOS.js → i18n-kuF6Ekj6.js} +3 -3
  56. package/dist/i18n-kuF6Ekj6.js.map +1 -0
  57. package/dist/i18n.es.mjs +1 -1
  58. package/dist/index.es.mjs +251 -228
  59. package/dist/media/breakpoints.d.ts.map +1 -1
  60. package/dist/media/types.d.ts +2 -2
  61. package/dist/media/types.d.ts.map +1 -1
  62. package/dist/{media-Di2Ta22s.js → media-i-fB5WxI.js} +3 -3
  63. package/dist/media-i-fB5WxI.js.map +1 -0
  64. package/dist/media.es.mjs +1 -1
  65. package/dist/{motion-qPj_TYGv.js → motion-BJsAuULb.js} +2 -2
  66. package/dist/motion-BJsAuULb.js.map +1 -0
  67. package/dist/motion.es.mjs +1 -1
  68. package/dist/{mount-SM07RUa6.js → mount-B4Y8bk8Z.js} +5 -5
  69. package/dist/mount-B4Y8bk8Z.js.map +1 -0
  70. package/dist/{platform-CPbCprb6.js → platform-Dw2gE3zI.js} +3 -3
  71. package/dist/{platform-CPbCprb6.js.map → platform-Dw2gE3zI.js.map} +1 -1
  72. package/dist/platform.es.mjs +2 -2
  73. package/dist/plugin/registry.d.ts.map +1 -1
  74. package/dist/{plugin-cPoOHFLY.js → plugin-C2WuC8SF.js} +20 -18
  75. package/dist/plugin-C2WuC8SF.js.map +1 -0
  76. package/dist/plugin.es.mjs +1 -1
  77. package/dist/reactive/async-data.d.ts +28 -3
  78. package/dist/reactive/async-data.d.ts.map +1 -1
  79. package/dist/reactive/computed.d.ts +3 -0
  80. package/dist/reactive/computed.d.ts.map +1 -1
  81. package/dist/reactive/effect.d.ts +3 -0
  82. package/dist/reactive/effect.d.ts.map +1 -1
  83. package/dist/reactive/http.d.ts +194 -0
  84. package/dist/reactive/http.d.ts.map +1 -0
  85. package/dist/reactive/index.d.ts +2 -2
  86. package/dist/reactive/index.d.ts.map +1 -1
  87. package/dist/reactive/pagination.d.ts +126 -0
  88. package/dist/reactive/pagination.d.ts.map +1 -0
  89. package/dist/reactive/polling.d.ts +55 -0
  90. package/dist/reactive/polling.d.ts.map +1 -0
  91. package/dist/reactive/readonly.d.ts +20 -1
  92. package/dist/reactive/readonly.d.ts.map +1 -1
  93. package/dist/reactive/rest.d.ts +293 -0
  94. package/dist/reactive/rest.d.ts.map +1 -0
  95. package/dist/reactive/scope.d.ts +140 -0
  96. package/dist/reactive/scope.d.ts.map +1 -0
  97. package/dist/reactive/signal.d.ts +16 -2
  98. package/dist/reactive/signal.d.ts.map +1 -1
  99. package/dist/reactive/to-value.d.ts +57 -0
  100. package/dist/reactive/to-value.d.ts.map +1 -0
  101. package/dist/reactive/websocket.d.ts +285 -0
  102. package/dist/reactive/websocket.d.ts.map +1 -0
  103. package/dist/reactive-DwkhUJfP.js +1148 -0
  104. package/dist/reactive-DwkhUJfP.js.map +1 -0
  105. package/dist/reactive.es.mjs +38 -19
  106. package/dist/{registry-CWf368tT.js → registry-B08iilIh.js} +1 -1
  107. package/dist/{registry-CWf368tT.js.map → registry-B08iilIh.js.map} +1 -1
  108. package/dist/router/constraints.d.ts.map +1 -1
  109. package/dist/router/index.d.ts +1 -1
  110. package/dist/router/index.d.ts.map +1 -1
  111. package/dist/router/router.d.ts.map +1 -1
  112. package/dist/router/state.d.ts +25 -2
  113. package/dist/router/state.d.ts.map +1 -1
  114. package/dist/router-CQikC9Ed.js +492 -0
  115. package/dist/router-CQikC9Ed.js.map +1 -0
  116. package/dist/router.es.mjs +9 -8
  117. package/dist/ssr/hydrate.d.ts.map +1 -1
  118. package/dist/{ssr-B2qd_WBB.js → ssr-_dAcGdzu.js} +4 -4
  119. package/dist/ssr-_dAcGdzu.js.map +1 -0
  120. package/dist/ssr.es.mjs +1 -1
  121. package/dist/store/persisted.d.ts.map +1 -1
  122. package/dist/{store-DWpyH6p5.js → store-Cb3gPRve.js} +7 -7
  123. package/dist/store-Cb3gPRve.js.map +1 -0
  124. package/dist/store.es.mjs +2 -2
  125. package/dist/storybook.es.mjs.map +1 -1
  126. package/dist/{testing-CsqjNUyy.js → testing-C5Sjfsna.js} +8 -8
  127. package/dist/testing-C5Sjfsna.js.map +1 -0
  128. package/dist/testing.es.mjs +1 -1
  129. package/dist/{type-guards-Do9DWgNp.js → type-guards-BMX2c0LP.js} +1 -1
  130. package/dist/{type-guards-Do9DWgNp.js.map → type-guards-BMX2c0LP.js.map} +1 -1
  131. package/dist/untrack-D0fnO5k2.js +36 -0
  132. package/dist/untrack-D0fnO5k2.js.map +1 -0
  133. package/dist/view/custom-directives.d.ts.map +1 -1
  134. package/dist/view.es.mjs +4 -4
  135. package/package.json +177 -177
  136. package/src/a11y/announce.ts +131 -131
  137. package/src/a11y/audit.ts +314 -314
  138. package/src/a11y/index.ts +68 -68
  139. package/src/a11y/media-preferences.ts +255 -255
  140. package/src/a11y/roving-tab-index.ts +164 -164
  141. package/src/a11y/skip-link.ts +255 -255
  142. package/src/a11y/trap-focus.ts +184 -184
  143. package/src/a11y/types.ts +183 -183
  144. package/src/component/component.ts +599 -599
  145. package/src/component/html.ts +153 -153
  146. package/src/component/index.ts +52 -52
  147. package/src/component/library.ts +540 -542
  148. package/src/component/scope.ts +212 -212
  149. package/src/component/types.ts +310 -310
  150. package/src/core/collection.ts +876 -707
  151. package/src/core/element.ts +1015 -981
  152. package/src/core/env.ts +60 -60
  153. package/src/core/index.ts +49 -49
  154. package/src/core/shared.ts +77 -62
  155. package/src/core/utils/index.ts +148 -148
  156. package/src/devtools/devtools.ts +410 -410
  157. package/src/devtools/index.ts +48 -48
  158. package/src/devtools/types.ts +104 -104
  159. package/src/dnd/draggable.ts +296 -296
  160. package/src/dnd/droppable.ts +228 -228
  161. package/src/dnd/index.ts +62 -62
  162. package/src/dnd/sortable.ts +307 -307
  163. package/src/dnd/types.ts +293 -293
  164. package/src/forms/create-form.ts +320 -278
  165. package/src/forms/index.ts +70 -65
  166. package/src/forms/types.ts +203 -154
  167. package/src/forms/use-field.ts +231 -0
  168. package/src/forms/validators.ts +294 -265
  169. package/src/full.ts +554 -480
  170. package/src/i18n/formatting.ts +67 -67
  171. package/src/i18n/i18n.ts +200 -200
  172. package/src/i18n/index.ts +67 -67
  173. package/src/i18n/translate.ts +182 -182
  174. package/src/i18n/types.ts +171 -171
  175. package/src/index.ts +108 -108
  176. package/src/media/battery.ts +116 -116
  177. package/src/media/breakpoints.ts +129 -131
  178. package/src/media/clipboard.ts +80 -80
  179. package/src/media/device-sensors.ts +158 -158
  180. package/src/media/geolocation.ts +119 -119
  181. package/src/media/index.ts +76 -76
  182. package/src/media/media-query.ts +92 -92
  183. package/src/media/network.ts +115 -115
  184. package/src/media/types.ts +177 -177
  185. package/src/media/viewport.ts +84 -84
  186. package/src/motion/index.ts +57 -57
  187. package/src/motion/morph.ts +151 -151
  188. package/src/motion/parallax.ts +120 -120
  189. package/src/motion/reduced-motion.ts +66 -66
  190. package/src/motion/types.ts +271 -271
  191. package/src/motion/typewriter.ts +164 -164
  192. package/src/plugin/index.ts +37 -37
  193. package/src/plugin/registry.ts +284 -269
  194. package/src/plugin/types.ts +137 -137
  195. package/src/reactive/async-data.ts +250 -29
  196. package/src/reactive/computed.ts +144 -130
  197. package/src/reactive/effect.ts +29 -6
  198. package/src/reactive/http.ts +790 -0
  199. package/src/reactive/index.ts +60 -0
  200. package/src/reactive/pagination.ts +317 -0
  201. package/src/reactive/polling.ts +179 -0
  202. package/src/reactive/readonly.ts +52 -8
  203. package/src/reactive/rest.ts +859 -0
  204. package/src/reactive/scope.ts +276 -0
  205. package/src/reactive/signal.ts +61 -1
  206. package/src/reactive/to-value.ts +71 -0
  207. package/src/reactive/websocket.ts +849 -0
  208. package/src/router/bq-link.ts +279 -279
  209. package/src/router/constraints.ts +204 -201
  210. package/src/router/index.ts +49 -49
  211. package/src/router/match.ts +312 -312
  212. package/src/router/path-pattern.ts +52 -52
  213. package/src/router/query.ts +38 -38
  214. package/src/router/router.ts +421 -402
  215. package/src/router/state.ts +51 -3
  216. package/src/router/types.ts +139 -139
  217. package/src/router/use-route.ts +68 -68
  218. package/src/router/utils.ts +157 -157
  219. package/src/security/index.ts +12 -12
  220. package/src/ssr/hydrate.ts +84 -82
  221. package/src/ssr/index.ts +70 -70
  222. package/src/ssr/render.ts +508 -508
  223. package/src/ssr/serialize.ts +296 -296
  224. package/src/ssr/types.ts +81 -81
  225. package/src/store/create-store.ts +467 -467
  226. package/src/store/index.ts +27 -27
  227. package/src/store/persisted.ts +245 -249
  228. package/src/store/types.ts +247 -247
  229. package/src/store/utils.ts +135 -135
  230. package/src/storybook/index.ts +480 -480
  231. package/src/testing/index.ts +42 -42
  232. package/src/testing/testing.ts +593 -593
  233. package/src/testing/types.ts +170 -170
  234. package/src/view/custom-directives.ts +28 -30
  235. package/src/view/evaluate.ts +292 -292
  236. package/src/view/process.ts +108 -108
  237. package/dist/a11y-C5QOVvRn.js.map +0 -1
  238. package/dist/component-CuuTijA6.js.map +0 -1
  239. package/dist/constraints-3lV9yyBw.js.map +0 -1
  240. package/dist/core-Cjl7GUu8.js.map +0 -1
  241. package/dist/core-DnlyjbF2.js +0 -112
  242. package/dist/core-DnlyjbF2.js.map +0 -1
  243. package/dist/custom-directives-7wAShnnd.js.map +0 -1
  244. package/dist/devtools-D2fQLhDN.js.map +0 -1
  245. package/dist/dnd-B8EgyzaI.js.map +0 -1
  246. package/dist/env-NeVmr4Gf.js.map +0 -1
  247. package/dist/forms-C3yovgH9.js +0 -141
  248. package/dist/forms-C3yovgH9.js.map +0 -1
  249. package/dist/i18n-BnnhTFOS.js.map +0 -1
  250. package/dist/media-Di2Ta22s.js.map +0 -1
  251. package/dist/motion-qPj_TYGv.js.map +0 -1
  252. package/dist/mount-SM07RUa6.js.map +0 -1
  253. package/dist/plugin-cPoOHFLY.js.map +0 -1
  254. package/dist/reactive-Cfv0RK6x.js +0 -233
  255. package/dist/reactive-Cfv0RK6x.js.map +0 -1
  256. package/dist/router-BrthaP_z.js +0 -473
  257. package/dist/router-BrthaP_z.js.map +0 -1
  258. package/dist/ssr-B2qd_WBB.js.map +0 -1
  259. package/dist/store-DWpyH6p5.js.map +0 -1
  260. package/dist/testing-CsqjNUyy.js.map +0 -1
  261. package/dist/untrack-DJVQQ2WM.js +0 -33
  262. package/dist/untrack-DJVQQ2WM.js.map +0 -1
@@ -1,5 +1,5 @@
1
- import { n as E } from "./core-DnlyjbF2.js";
2
- import { i as I } from "./reactive-Cfv0RK6x.js";
1
+ import { n as E } from "./core-DdtZHzsS.js";
2
+ import { m as I } from "./reactive-DwkhUJfP.js";
3
3
  var w = /* @__PURE__ */ new Map(), A = /* @__PURE__ */ new Map(), q = 50, M = (e) => {
4
4
  const t = w.get(e);
5
5
  if (t && t.isConnected) return t;
@@ -418,4 +418,4 @@ export {
418
418
  G as u
419
419
  };
420
420
 
421
- //# sourceMappingURL=a11y-C5QOVvRn.js.map
421
+ //# sourceMappingURL=a11y-DVBCy09c.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a11y-DVBCy09c.js","names":[],"sources":["../src/a11y/announce.ts","../src/a11y/audit.ts","../src/a11y/media-preferences.ts","../src/a11y/roving-tab-index.ts","../src/a11y/skip-link.ts","../src/a11y/trap-focus.ts"],"sourcesContent":["/**\n * Screen reader announcement utility using ARIA live regions.\n *\n * Creates and manages off-screen live regions to announce dynamic\n * content changes to assistive technologies.\n *\n * @module bquery/a11y\n */\n\nimport type { AnnouncePriority } from './types';\n\n/** Cache for live region containers, keyed by priority. */\nconst liveRegions = new Map<AnnouncePriority, HTMLElement>();\nconst pendingAnnouncements = new Map<AnnouncePriority, ReturnType<typeof setTimeout>>();\n\n/**\n * Delay in milliseconds before updating the live region text.\n * This ensures screen readers detect the content change even when\n * the same message is announced consecutively — clearing first and\n * setting after a short timer delay forces a new live-region mutation event.\n * @internal\n */\nconst ANNOUNCEMENT_DELAY_MS = 50;\n\n/**\n * Gets or creates a visually-hidden ARIA live region for the given priority.\n *\n * @param priority - The aria-live priority level\n * @returns The live region element\n * @internal\n */\nconst getOrCreateLiveRegion = (priority: AnnouncePriority): HTMLElement => {\n const existing = liveRegions.get(priority);\n if (existing && existing.isConnected) {\n return existing;\n }\n\n const el = document.createElement('div');\n el.setAttribute('aria-live', priority);\n el.setAttribute('aria-atomic', 'true');\n el.setAttribute('role', priority === 'assertive' ? 'alert' : 'status');\n\n // Visually hidden but accessible to screen readers\n Object.assign(el.style, {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0, 0, 0, 0)',\n whiteSpace: 'nowrap',\n border: '0',\n });\n\n document.body.appendChild(el);\n liveRegions.set(priority, el);\n\n return el;\n};\n\n/**\n * Announces a message to screen readers via an ARIA live region.\n *\n * The message is injected into a visually-hidden live region element.\n * Screen readers will pick up the change and announce it to the user.\n *\n * @param message - The text message to announce\n * @param priority - The urgency level: `'polite'` (default) or `'assertive'`\n *\n * @example\n * ```ts\n * import { announceToScreenReader } from '@bquery/bquery/a11y';\n *\n * // Polite announcement (waits for idle)\n * announceToScreenReader('3 search results found');\n *\n * // Assertive announcement (interrupts current speech)\n * announceToScreenReader('Error: Please fix the form', 'assertive');\n * ```\n */\nexport const announceToScreenReader = (\n message: string,\n priority: AnnouncePriority = 'polite'\n): void => {\n if (!message) return;\n if (typeof document === 'undefined' || !document.body) return;\n\n const region = getOrCreateLiveRegion(priority);\n const pendingTimeout = pendingAnnouncements.get(priority);\n if (pendingTimeout !== undefined) {\n clearTimeout(pendingTimeout);\n }\n\n // Clear first, then set after a short timer delay to ensure screen readers\n // detect the change even if the same message is announced twice.\n region.textContent = '';\n\n // Use setTimeout to ensure the DOM update triggers a live region change event\n const timeout = setTimeout(() => {\n pendingAnnouncements.delete(priority);\n if (region.isConnected) {\n region.textContent = message;\n }\n }, ANNOUNCEMENT_DELAY_MS);\n\n pendingAnnouncements.set(priority, timeout);\n};\n\n/**\n * Removes all live region elements created by `announceToScreenReader`.\n * Useful for cleanup in tests or when unmounting an application.\n *\n * @example\n * ```ts\n * import { clearAnnouncements } from '@bquery/bquery/a11y';\n *\n * clearAnnouncements();\n * ```\n */\nexport const clearAnnouncements = (): void => {\n for (const timeout of pendingAnnouncements.values()) {\n clearTimeout(timeout);\n }\n pendingAnnouncements.clear();\n\n for (const [, el] of liveRegions) {\n el.remove();\n }\n liveRegions.clear();\n};\n","/**\n * Development-time accessibility audit utility.\n *\n * Scans DOM elements for common accessibility issues such as missing\n * alt text on images, missing labels on form inputs, empty links/buttons,\n * and incorrect ARIA usage.\n *\n * @module bquery/a11y\n */\n\nimport type { AuditFinding, AuditResult, AuditSeverity } from './types';\n\n/**\n * Creates a finding object.\n * @internal\n */\nconst finding = (\n severity: AuditSeverity,\n message: string,\n element: Element,\n rule: string\n): AuditFinding => ({\n severity,\n message,\n element,\n rule,\n});\n\n/**\n * Checks images for missing alt attributes.\n * @internal\n */\nconst auditImages = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n const images = container.querySelectorAll('img');\n\n for (const img of images) {\n if (!img.hasAttribute('alt')) {\n findings.push(\n finding(\n 'error',\n 'Image is missing an alt attribute. Add alt=\"\" for decorative images or a descriptive alt text.',\n img,\n 'img-alt'\n )\n );\n } else if (img.getAttribute('alt') === '' && !img.hasAttribute('role')) {\n findings.push(\n finding(\n 'info',\n 'Image has empty alt text. Consider adding role=\"presentation\" if decorative.',\n img,\n 'img-decorative'\n )\n );\n }\n }\n\n return findings;\n};\n\n/**\n * Checks form inputs for missing labels.\n * @internal\n */\nconst auditFormInputs = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n const inputs = container.querySelectorAll('input, select, textarea');\n\n for (const input of inputs) {\n const type = input.getAttribute('type');\n\n // Hidden, submit, and button inputs don't need labels\n if (type === 'hidden' || type === 'submit' || type === 'button' || type === 'reset') {\n continue;\n }\n\n const id = input.getAttribute('id');\n const hasLabel = id ? !!container.querySelector(`label[for=\"${id}\"]`) : false;\n const hasAriaLabel = input.hasAttribute('aria-label') || input.hasAttribute('aria-labelledby');\n const hasTitle = input.hasAttribute('title');\n const isWrappedInLabel = input.closest('label') !== null;\n\n if (!hasLabel && !hasAriaLabel && !hasTitle && !isWrappedInLabel) {\n findings.push(\n finding(\n 'error',\n `Form input is missing a label. Add a <label for=\"id\">, aria-label, or aria-labelledby attribute.`,\n input,\n 'input-label'\n )\n );\n }\n }\n\n return findings;\n};\n\n/**\n * Checks for empty interactive elements (buttons, links).\n * @internal\n */\nconst auditInteractiveElements = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n\n // Check buttons\n const buttons = container.querySelectorAll('button');\n for (const btn of buttons) {\n const hasText = (btn.textContent ?? '').trim().length > 0;\n const hasAriaLabel = btn.hasAttribute('aria-label') || btn.hasAttribute('aria-labelledby');\n const hasTitle = btn.hasAttribute('title');\n\n if (!hasText && !hasAriaLabel && !hasTitle) {\n findings.push(\n finding(\n 'error',\n 'Button has no accessible name. Add text content, aria-label, or title.',\n btn,\n 'button-name'\n )\n );\n }\n }\n\n // Check links\n const links = container.querySelectorAll('a[href]');\n for (const link of links) {\n const hasText = (link.textContent ?? '').trim().length > 0;\n const hasAriaLabel = link.hasAttribute('aria-label') || link.hasAttribute('aria-labelledby');\n const hasTitle = link.hasAttribute('title');\n const hasImage = link.querySelector('img[alt]') !== null;\n\n if (!hasText && !hasAriaLabel && !hasTitle && !hasImage) {\n findings.push(\n finding(\n 'error',\n 'Link has no accessible name. Add text content, aria-label, or title.',\n link,\n 'link-name'\n )\n );\n }\n }\n\n return findings;\n};\n\n/**\n * Checks heading hierarchy for skipped levels.\n * @internal\n */\nconst auditHeadings = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n const headings = container.querySelectorAll('h1, h2, h3, h4, h5, h6');\n\n let previousLevel = 0;\n\n for (const heading of headings) {\n const level = parseInt(heading.tagName.charAt(1), 10);\n\n if (previousLevel > 0 && level > previousLevel + 1) {\n findings.push(\n finding(\n 'warning',\n `Heading level skipped: <${heading.tagName.toLowerCase()}> follows <h${previousLevel}>. Don't skip heading levels.`,\n heading,\n 'heading-order'\n )\n );\n }\n\n if ((heading.textContent ?? '').trim().length === 0) {\n findings.push(finding('warning', 'Heading element is empty.', heading, 'heading-empty'));\n }\n\n previousLevel = level;\n }\n\n return findings;\n};\n\n/**\n * Checks for valid ARIA attribute usage.\n * @internal\n */\nconst auditAria = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n\n // Check aria-labelledby references exist\n const labelled = container.querySelectorAll('[aria-labelledby]');\n for (const el of labelled) {\n const ids = (el.getAttribute('aria-labelledby') ?? '').split(/\\s+/);\n for (const id of ids) {\n if (id && !document.getElementById(id)) {\n findings.push(\n finding(\n 'error',\n `aria-labelledby references \"${id}\" which does not exist in the document.`,\n el,\n 'aria-labelledby-ref'\n )\n );\n }\n }\n }\n\n // Check aria-describedby references exist\n const described = container.querySelectorAll('[aria-describedby]');\n for (const el of described) {\n const ids = (el.getAttribute('aria-describedby') ?? '').split(/\\s+/);\n for (const id of ids) {\n if (id && !document.getElementById(id)) {\n findings.push(\n finding(\n 'error',\n `aria-describedby references \"${id}\" which does not exist in the document.`,\n el,\n 'aria-describedby-ref'\n )\n );\n }\n }\n }\n\n return findings;\n};\n\n/**\n * Checks for sufficient document landmarks.\n * @internal\n */\nconst auditLandmarks = (container: Element): AuditFinding[] => {\n const findings: AuditFinding[] = [];\n\n // Only audit the document body or top-level container\n if (container === document.body || container === document.documentElement) {\n const hasMain = !!container.querySelector('main') || !!container.querySelector('[role=\"main\"]');\n\n if (!hasMain) {\n findings.push(\n finding(\n 'warning',\n 'Page is missing a <main> landmark. Add <main> or role=\"main\" to the primary content area.',\n container,\n 'landmark-main'\n )\n );\n }\n }\n\n return findings;\n};\n\n/**\n * Runs a development-time accessibility audit on a container element.\n *\n * Checks for common accessibility issues including:\n * - Missing alt text on images\n * - Missing labels on form inputs\n * - Empty buttons and links\n * - Heading hierarchy issues\n * - Invalid ARIA references\n * - Missing document landmarks\n *\n * This is intended as a development tool — not a replacement for\n * manual testing or professional accessibility audits.\n *\n * @param container - The element to audit (defaults to `document.body`)\n * @returns An audit result with findings, counts, and pass/fail status\n *\n * @example\n * ```ts\n * import { auditA11y } from '@bquery/bquery/a11y';\n *\n * const result = auditA11y();\n * if (!result.passed) {\n * console.warn(`Found ${result.errors} accessibility errors:`);\n * for (const f of result.findings) {\n * console.warn(`[${f.severity}] ${f.message}`, f.element);\n * }\n * }\n * ```\n */\nexport const auditA11y = (container?: Element): AuditResult => {\n if (typeof document === 'undefined' || !document.body) {\n return {\n findings: [],\n errors: 0,\n warnings: 0,\n passed: true,\n };\n }\n\n const target = container ?? document.body;\n\n const allFindings: AuditFinding[] = [\n ...auditImages(target),\n ...auditFormInputs(target),\n ...auditInteractiveElements(target),\n ...auditHeadings(target),\n ...auditAria(target),\n ...auditLandmarks(target),\n ];\n\n const errors = allFindings.filter((f) => f.severity === 'error').length;\n const warnings = allFindings.filter((f) => f.severity === 'warning').length;\n\n return {\n findings: allFindings,\n errors,\n warnings,\n passed: errors === 0,\n };\n};\n","/**\n * Reactive media preference signals for accessibility.\n *\n * Provides reactive signals that track the user's system-level\n * accessibility preferences (reduced motion, color scheme, contrast).\n *\n * @module bquery/a11y\n */\n\nimport { readonly, signal, type ReadonlySignal } from '../reactive/index';\nimport type { ColorScheme, ContrastPreference, MediaPreferenceSignal } from './types';\n\ntype LegacyMediaQueryList = MediaQueryList & {\n addListener?: (listener: (event: MediaQueryListEvent | MediaQueryList) => void) => void;\n removeListener?: (listener: (event: MediaQueryListEvent | MediaQueryList) => void) => void;\n};\n\nconst bindMediaQueryListener = (\n mql: MediaQueryList,\n handler: (event: MediaQueryListEvent | MediaQueryList) => void\n): (() => void) | undefined => {\n if (typeof mql.addEventListener === 'function') {\n mql.addEventListener('change', handler);\n return (): void => {\n mql.removeEventListener('change', handler);\n };\n }\n\n const legacyMql = mql as LegacyMediaQueryList;\n if (typeof legacyMql.addListener === 'function') {\n legacyMql.addListener(handler);\n return (): void => {\n legacyMql.removeListener?.(handler);\n };\n }\n\n return undefined;\n};\n\nconst withDestroy = <T>(\n signalHandle: ReadonlySignal<T>,\n cleanup: () => void\n): MediaPreferenceSignal<T> => {\n let destroyImpl = cleanup;\n const handle = signalHandle as MediaPreferenceSignal<T>;\n Object.defineProperty(handle, 'destroy', {\n configurable: true,\n enumerable: false,\n value: (): void => {\n const currentDestroy = destroyImpl;\n // Make cleanup idempotent so repeated destroy() calls from user code stay safe.\n destroyImpl = (): void => {};\n currentDestroy();\n },\n });\n return handle;\n};\n\n/**\n * Creates a reactive signal that tracks a CSS media query.\n *\n * @param query - The media query string\n * @param initialValue - Fallback value when `matchMedia` is unavailable\n * @returns A readonly signal handle that updates when the query match changes\n * @internal\n */\nconst createMediaSignal = (\n query: string,\n initialValue: boolean\n): MediaPreferenceSignal<boolean> => {\n const s = signal(initialValue);\n let destroy = (): void => {\n s.dispose();\n };\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n try {\n const mql = window.matchMedia(query);\n s.value = mql.matches;\n\n const handler = (e: MediaQueryListEvent | MediaQueryList): void => {\n s.value = e.matches;\n };\n\n const cleanupMql = bindMediaQueryListener(mql, handler);\n if (cleanupMql) {\n destroy = (): void => {\n cleanupMql();\n s.dispose();\n };\n }\n } catch {\n // matchMedia may throw in non-browser environments\n }\n }\n\n return withDestroy(readonly(s), destroy);\n};\n\n/**\n * Returns a reactive signal indicating whether the user prefers reduced motion.\n *\n * Tracks the `(prefers-reduced-motion: reduce)` media query. Returns `true`\n * when the user has requested reduced motion in their system settings.\n *\n * @returns A readonly reactive signal handle. Call `destroy()` to remove listeners.\n *\n * @example\n * ```ts\n * import { prefersReducedMotion } from '@bquery/bquery/a11y';\n * import { effect } from '@bquery/bquery/reactive';\n *\n * const reduced = prefersReducedMotion();\n * effect(() => {\n * if (reduced.value) {\n * console.log('User prefers reduced motion');\n * }\n * });\n * ```\n */\nexport const prefersReducedMotion = (): MediaPreferenceSignal<boolean> => {\n return createMediaSignal('(prefers-reduced-motion: reduce)', false);\n};\n\n/**\n * Returns a reactive signal tracking the user's preferred color scheme.\n *\n * Tracks the `(prefers-color-scheme: dark)` media query. Returns `'dark'`\n * when the user prefers a dark color scheme, `'light'` otherwise.\n *\n * @returns A readonly reactive signal handle with `'light'` or `'dark'`\n *\n * @example\n * ```ts\n * import { prefersColorScheme } from '@bquery/bquery/a11y';\n * import { effect } from '@bquery/bquery/reactive';\n *\n * const scheme = prefersColorScheme();\n * effect(() => {\n * document.body.dataset.theme = scheme.value;\n * });\n * ```\n */\nexport const prefersColorScheme = (): MediaPreferenceSignal<ColorScheme> => {\n const s = signal<ColorScheme>('light');\n let destroy = (): void => {\n s.dispose();\n };\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n try {\n const mql = window.matchMedia('(prefers-color-scheme: dark)');\n s.value = mql.matches ? 'dark' : 'light';\n\n const handler = (e: MediaQueryListEvent | MediaQueryList): void => {\n s.value = e.matches ? 'dark' : 'light';\n };\n\n const cleanupMql = bindMediaQueryListener(mql, handler);\n if (cleanupMql) {\n destroy = (): void => {\n cleanupMql();\n s.dispose();\n };\n }\n } catch {\n // matchMedia may throw in non-browser environments\n }\n }\n\n return withDestroy(readonly(s), destroy);\n};\n\n/**\n * Returns a reactive signal tracking the user's contrast preference.\n *\n * Tracks the `(prefers-contrast)` media query. Returns:\n * - `'more'` — user prefers higher contrast\n * - `'less'` — user prefers lower contrast\n * - `'custom'` — user has set a custom contrast level\n * - `'no-preference'` — no explicit preference\n *\n * @returns A readonly reactive signal handle\n *\n * @example\n * ```ts\n * import { prefersContrast } from '@bquery/bquery/a11y';\n * import { effect } from '@bquery/bquery/reactive';\n *\n * const contrast = prefersContrast();\n * effect(() => {\n * if (contrast.value === 'more') {\n * document.body.classList.add('high-contrast');\n * }\n * });\n * ```\n */\nexport const prefersContrast = (): MediaPreferenceSignal<ContrastPreference> => {\n const s = signal<ContrastPreference>('no-preference');\n let destroy = (): void => {\n s.dispose();\n };\n\n if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {\n let mql: MediaQueryList | undefined;\n let mqlLess: MediaQueryList | undefined;\n let mqlCustom: MediaQueryList | undefined;\n\n const update = (): void => {\n // Defensive guard for environments where matchMedia setup fails before\n // listeners are attached; update() is only expected to run after init.\n if (!mql || !mqlLess || !mqlCustom) {\n return;\n }\n\n if (mql.matches) {\n s.value = 'more';\n } else if (mqlLess.matches) {\n s.value = 'less';\n } else if (mqlCustom.matches) {\n s.value = 'custom';\n } else {\n s.value = 'no-preference';\n }\n };\n\n // Listen for changes on the contrast preference variants\n try {\n mql = window.matchMedia('(prefers-contrast: more)');\n mqlLess = window.matchMedia('(prefers-contrast: less)');\n mqlCustom = window.matchMedia('(prefers-contrast: custom)');\n update();\n const cleanupFns = [mql, mqlLess, mqlCustom]\n .map((entry) =>\n bindMediaQueryListener(entry, () => {\n update();\n })\n )\n .filter((cleanup): cleanup is () => void => cleanup !== undefined);\n\n if (cleanupFns.length > 0) {\n destroy = (): void => {\n for (const cleanup of cleanupFns) {\n cleanup();\n }\n s.dispose();\n };\n }\n } catch {\n // matchMedia may throw in non-browser environments\n }\n }\n\n return withDestroy(readonly(s), destroy);\n};\n","/**\n * Roving tab index utility for arrow-key navigation within groups.\n *\n * Implements the WAI-ARIA roving tabindex pattern: only one item\n * in the group has tabindex=\"0\" (the active item), while all others\n * have tabindex=\"-1\". Arrow keys move focus between items.\n *\n * @module bquery/a11y\n */\n\nimport type { RovingTabIndexHandle, RovingTabIndexOptions } from './types';\n\n/**\n * Sets up roving tab index navigation for a group of elements.\n *\n * Only the active item receives `tabindex=\"0\"`, making it the only\n * tabbable element in the group. Arrow keys move focus between items,\n * and Home/End jump to the first/last item.\n *\n * @param container - The parent element containing the navigable items\n * @param itemSelector - CSS selector for the navigable items within the container\n * @param options - Configuration options\n * @returns A handle with `destroy()`, `focusItem()`, and `activeIndex()`\n *\n * @example\n * ```ts\n * import { rovingTabIndex } from '@bquery/bquery/a11y';\n *\n * const toolbar = document.querySelector('[role=\"toolbar\"]');\n * const handle = rovingTabIndex(toolbar, 'button', {\n * orientation: 'horizontal',\n * wrap: true,\n * });\n *\n * // Later, clean up\n * handle.destroy();\n * ```\n */\nexport const rovingTabIndex = (\n container: HTMLElement,\n itemSelector: string,\n options: RovingTabIndexOptions = {}\n): RovingTabIndexHandle => {\n const { wrap = true, orientation = 'vertical', onActivate } = options;\n\n let currentIndex = 0;\n const originalTabIndexes = new Map<HTMLElement, string | null>();\n\n const getItems = (): HTMLElement[] => {\n return Array.from(container.querySelectorAll(itemSelector)) as HTMLElement[];\n };\n\n const trackItems = (items: HTMLElement[]): void => {\n for (const item of items) {\n if (!originalTabIndexes.has(item)) {\n originalTabIndexes.set(item, item.getAttribute('tabindex'));\n }\n }\n };\n\n const setActiveItem = (index: number): void => {\n const items = getItems();\n if (items.length === 0) return;\n trackItems(items);\n\n // Clamp index\n const clampedIndex = Math.max(0, Math.min(index, items.length - 1));\n\n // Update tabindex on all items\n for (let i = 0; i < items.length; i++) {\n items[i].setAttribute('tabindex', i === clampedIndex ? '0' : '-1');\n }\n\n currentIndex = clampedIndex;\n items[clampedIndex].focus();\n onActivate?.(items[clampedIndex], clampedIndex);\n };\n\n const isRelevantKey = (key: string): boolean => {\n if (key === 'Home' || key === 'End') return true;\n\n switch (orientation) {\n case 'horizontal':\n return key === 'ArrowLeft' || key === 'ArrowRight';\n case 'vertical':\n return key === 'ArrowUp' || key === 'ArrowDown';\n case 'both':\n return (\n key === 'ArrowLeft' || key === 'ArrowRight' || key === 'ArrowUp' || key === 'ArrowDown'\n );\n default:\n return false;\n }\n };\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (!isRelevantKey(event.key)) return;\n\n const items = getItems();\n if (items.length === 0) return;\n\n event.preventDefault();\n\n let nextIndex = currentIndex;\n\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowRight':\n nextIndex = currentIndex + 1;\n if (nextIndex >= items.length) {\n nextIndex = wrap ? 0 : items.length - 1;\n }\n break;\n\n case 'ArrowUp':\n case 'ArrowLeft':\n nextIndex = currentIndex - 1;\n if (nextIndex < 0) {\n nextIndex = wrap ? items.length - 1 : 0;\n }\n break;\n\n case 'Home':\n nextIndex = 0;\n break;\n\n case 'End':\n nextIndex = items.length - 1;\n break;\n }\n\n setActiveItem(nextIndex);\n };\n\n // Initialize: set tabindex on all items\n const items = getItems();\n trackItems(items);\n for (let i = 0; i < items.length; i++) {\n items[i].setAttribute('tabindex', i === 0 ? '0' : '-1');\n }\n\n container.addEventListener('keydown', handleKeyDown);\n\n return {\n destroy: () => {\n container.removeEventListener('keydown', handleKeyDown);\n // Restore original tabindex values\n for (const [item, originalTabIndex] of originalTabIndexes) {\n if (originalTabIndex === null) {\n item.removeAttribute('tabindex');\n } else {\n item.setAttribute('tabindex', originalTabIndex);\n }\n }\n originalTabIndexes.clear();\n },\n\n focusItem: (index: number) => {\n setActiveItem(index);\n },\n\n activeIndex: () => currentIndex,\n };\n};\n","/**\n * Auto-generated skip navigation link utility.\n *\n * Creates a visually-hidden (but keyboard-focusable) \"Skip to content\"\n * link that becomes visible on focus, letting keyboard users bypass\n * repeated navigation.\n *\n * @module bquery/a11y\n */\n\nimport type { SkipLinkHandle, SkipLinkOptions } from './types';\n\n/** Default CSS for the skip link — visually hidden until focused. */\nconst DEFAULT_STYLES = `\n position: absolute;\n top: -9999px;\n left: -9999px;\n z-index: 999999;\n padding: 0.5em 1em;\n background: #000;\n color: #fff;\n font-size: 1rem;\n text-decoration: none;\n border-radius: 0 0 4px 0;\n outline: 2px solid #4A90D9;\n outline-offset: 2px;\n`;\n\nconst FOCUSED_STYLES = `\n top: 0;\n left: 0;\n`;\n\nlet skipTargetIdCounter = 0;\nconst generatedSkipTargetRefs = new Map<string, { count: number; target: HTMLElement }>();\n\nconst hasSkipLinkEnvironment = (): boolean => {\n if (typeof document === 'undefined') {\n return false;\n }\n\n return (\n typeof document.createElement === 'function' &&\n typeof document.querySelector === 'function' &&\n typeof document.getElementById === 'function' &&\n document.body !== null &&\n document.body !== undefined\n );\n};\n\nconst createNoopSkipLinkHandle = (): SkipLinkHandle => ({\n destroy: () => {},\n element: null,\n});\n\n/**\n * Creates a skip navigation link that jumps to the specified target.\n *\n * The link is visually hidden by default and becomes visible when\n * it receives keyboard focus. This follows the WCAG 2.4.1 \"Bypass Blocks\"\n * success criterion.\n *\n * @param targetSelector - CSS selector for the main content area (e.g. `'#main'`, `'main'`)\n * @param options - Configuration options\n * @returns A handle with `destroy()` method and reference to the created element\n *\n * @example\n * ```ts\n * import { skipLink } from '@bquery/bquery/a11y';\n *\n * // Creates a \"Skip to main content\" link pointing to <main>\n * const handle = skipLink('#main-content');\n *\n * // Custom text\n * const handle2 = skipLink('#content', { text: 'Jump to content' });\n *\n * // Remove when no longer needed\n * handle.destroy();\n * ```\n */\nexport const skipLink = (targetSelector: string, options: SkipLinkOptions = {}): SkipLinkHandle => {\n if (!hasSkipLinkEnvironment()) {\n return createNoopSkipLinkHandle();\n }\n\n const { text = 'Skip to main content', className = 'bq-skip-link' } = options;\n let trackedGeneratedTargetId: string | undefined;\n let trackedFocusTarget:\n | { target: HTMLElement; hadTabIndex: boolean; previousTabIndex: string | null }\n | undefined;\n const safeQuerySelector = (selector: string): HTMLElement | null => {\n try {\n return document.querySelector(selector) as HTMLElement | null;\n } catch {\n return null;\n }\n };\n const releaseTrackedGeneratedTargetId = (): void => {\n if (!trackedGeneratedTargetId) return;\n\n const entry = generatedSkipTargetRefs.get(trackedGeneratedTargetId);\n const remainingRefs = (entry?.count ?? 0) - 1;\n if (remainingRefs <= 0) {\n generatedSkipTargetRefs.delete(trackedGeneratedTargetId);\n if (entry?.target.isConnected && entry.target.id === trackedGeneratedTargetId) {\n entry.target.removeAttribute('id');\n }\n } else {\n generatedSkipTargetRefs.set(trackedGeneratedTargetId, {\n count: remainingRefs,\n target: entry!.target,\n });\n }\n\n trackedGeneratedTargetId = undefined;\n };\n const restoreTrackedFocusTarget = (): void => {\n if (!trackedFocusTarget) return;\n\n const { target, hadTabIndex, previousTabIndex } = trackedFocusTarget;\n if (target.isConnected) {\n if (hadTabIndex) {\n target.setAttribute('tabindex', previousTabIndex ?? '');\n } else {\n target.removeAttribute('tabindex');\n }\n }\n\n trackedFocusTarget = undefined;\n };\n const ensureTargetFocusable = (target: HTMLElement): void => {\n if (trackedFocusTarget?.target === target) {\n return;\n }\n\n restoreTrackedFocusTarget();\n\n if (target.hasAttribute('tabindex')) {\n trackedFocusTarget = {\n target,\n hadTabIndex: true,\n previousTabIndex: target.getAttribute('tabindex'),\n };\n return;\n }\n\n if (target.tabIndex !== -1) {\n return;\n }\n\n trackedFocusTarget = {\n target,\n hadTabIndex: false,\n previousTabIndex: null,\n };\n target.setAttribute('tabindex', '-1');\n };\n const trackGeneratedTargetId = (target: HTMLElement, id: string): void => {\n if (trackedGeneratedTargetId === id) return;\n releaseTrackedGeneratedTargetId();\n const entry = generatedSkipTargetRefs.get(id);\n generatedSkipTargetRefs.set(id, {\n count: (entry?.count ?? 0) + 1,\n target,\n });\n trackedGeneratedTargetId = id;\n };\n const resolveTarget = (): HTMLElement | null => {\n if (targetSelector.startsWith('#')) {\n const id = targetSelector.slice(1);\n const byId = id ? (document.getElementById(id) as HTMLElement | null) : null;\n if (byId) {\n return byId;\n }\n\n return safeQuerySelector(targetSelector);\n }\n\n const byId = document.getElementById(targetSelector) as HTMLElement | null;\n if (byId) {\n return byId;\n }\n\n return safeQuerySelector(targetSelector);\n };\n\n const ensureTargetId = (target: HTMLElement): string => {\n if (target.id) {\n const generatedTarget = generatedSkipTargetRefs.get(target.id);\n if (generatedTarget?.target === target) {\n trackGeneratedTargetId(target, target.id);\n }\n return target.id;\n }\n\n let generatedTargetId: string;\n do {\n skipTargetIdCounter += 1;\n generatedTargetId = `bq-skip-target-${skipTargetIdCounter}`;\n } while (document.getElementById(generatedTargetId) !== null);\n\n target.id = generatedTargetId;\n trackGeneratedTargetId(target, generatedTargetId);\n return generatedTargetId;\n };\n\n const link = document.createElement('a');\n const initialTarget = resolveTarget();\n link.href = targetSelector.startsWith('#')\n ? targetSelector\n : initialTarget\n ? `#${ensureTargetId(initialTarget)}`\n : `#${targetSelector}`;\n link.textContent = text;\n link.className = className;\n link.setAttribute('style', DEFAULT_STYLES);\n\n link.addEventListener('focus', () => {\n link.setAttribute('style', DEFAULT_STYLES + FOCUSED_STYLES);\n });\n\n link.addEventListener('blur', () => {\n link.setAttribute('style', DEFAULT_STYLES);\n });\n\n link.addEventListener('click', (e) => {\n e.preventDefault();\n\n const target = resolveTarget();\n if (!target) {\n return;\n }\n\n link.href = `#${ensureTargetId(target)}`;\n // Make the target focusable if it isn't already\n ensureTargetFocusable(target);\n target.focus();\n });\n\n // Insert as the first child of <body>\n if (document.body.firstChild) {\n document.body.insertBefore(link, document.body.firstChild);\n } else {\n document.body.appendChild(link);\n }\n\n return {\n destroy: () => {\n restoreTrackedFocusTarget();\n releaseTrackedGeneratedTargetId();\n link.remove();\n },\n element: link,\n };\n};\n","/**\n * Focus trapping utility for modals, dialogs, and popover content.\n *\n * Constrains keyboard focus within a container so that Tab and Shift+Tab\n * cycle only through the container's focusable elements.\n *\n * @module bquery/a11y\n */\n\nimport type { FocusTrapHandle, TrapFocusOptions } from './types';\n\n/** Selector for elements that can receive focus. */\nconst FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n 'details > summary',\n 'audio[controls]',\n 'video[controls]',\n].join(', ');\n\n/**\n * Gets all focusable elements within a container.\n *\n * @param container - The container element\n * @returns Array of focusable elements\n * @internal\n */\nexport const getFocusableElements = (container: Element): HTMLElement[] => {\n const elements = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR)) as HTMLElement[];\n return elements.filter(\n (el) => !el.hasAttribute('disabled') && el.tabIndex !== -1 && el.getClientRects().length > 0\n );\n};\n\n/**\n * Resolves an element from a string selector or returns the element directly.\n * @internal\n */\nconst resolveElement = (\n target: HTMLElement | string | undefined,\n container: Element\n): HTMLElement | null => {\n if (!target) return null;\n if (typeof target === 'string') {\n return container.querySelector(target) as HTMLElement | null;\n }\n return target;\n};\n\n/**\n * Traps keyboard focus within a container element.\n *\n * When activated, Tab and Shift+Tab will cycle only through focusable\n * elements within the container. Useful for modals, dialogs, and\n * dropdown menus.\n *\n * @param container - The DOM element to trap focus within\n * @param options - Configuration options\n * @returns A handle with a `release()` method to deactivate the trap\n *\n * @example\n * ```ts\n * import { trapFocus } from '@bquery/bquery/a11y';\n *\n * const dialog = document.querySelector('#my-dialog');\n * const trap = trapFocus(dialog, { escapeDeactivates: true });\n *\n * // Later, release the trap\n * trap.release();\n * ```\n */\nexport const trapFocus = (\n container: HTMLElement,\n options: TrapFocusOptions = {}\n): FocusTrapHandle => {\n const { escapeDeactivates = true, onEscape, initialFocus, returnFocus } = options;\n\n if (\n typeof document === 'undefined' ||\n typeof document.addEventListener !== 'function' ||\n typeof document.removeEventListener !== 'function'\n ) {\n let active = false;\n return {\n get active() {\n return active;\n },\n release: () => {\n active = false;\n },\n };\n }\n\n const previouslyFocused = document.activeElement as HTMLElement | null;\n let active = true;\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (!active) return;\n\n if (event.key === 'Escape' && escapeDeactivates) {\n event.preventDefault();\n handle.release();\n onEscape?.();\n return;\n }\n\n if (event.key !== 'Tab') return;\n\n const focusable = getFocusableElements(container);\n if (focusable.length === 0) {\n event.preventDefault();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (event.shiftKey) {\n // Shift+Tab: if at first element, wrap to last\n if (document.activeElement === first || !container.contains(document.activeElement)) {\n event.preventDefault();\n last.focus();\n }\n } else {\n // Tab: if at last element, wrap to first\n if (document.activeElement === last || !container.contains(document.activeElement)) {\n event.preventDefault();\n first.focus();\n }\n }\n };\n\n // Attach the event listener\n document.addEventListener('keydown', handleKeyDown, true);\n\n // Set initial focus\n const initialEl = resolveElement(initialFocus, container);\n if (initialEl) {\n initialEl.focus();\n } else {\n const focusable = getFocusableElements(container);\n if (focusable.length > 0) {\n focusable[0].focus();\n }\n }\n\n const handle: FocusTrapHandle = {\n get active() {\n return active;\n },\n\n release: () => {\n if (!active) return;\n active = false;\n document.removeEventListener('keydown', handleKeyDown, true);\n\n // Return focus\n const returnEl = resolveElement(returnFocus, document.body);\n if (returnEl) {\n returnEl.focus();\n } else if (previouslyFocused && previouslyFocused.focus) {\n previouslyFocused.focus();\n }\n },\n };\n\n return handle;\n};\n\n/**\n * Releases a focus trap handle.\n * This is a convenience function — in most cases, use the `release()`\n * method on the individual trap handle directly.\n *\n * @deprecated Prefer using the handle returned by `trapFocus()` directly.\n */\nexport const releaseFocus = (handle: FocusTrapHandle): void => {\n handle.release();\n};\n"],"mappings":"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"}
package/dist/a11y.es.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as s, c as a, d as r, i as o, l as n, n as t, o as c, r as u, s as i, t as p, u as d } from "./a11y-C5QOVvRn.js";
1
+ import { a as s, c as a, d as r, i as o, l as n, n as t, o as c, r as u, s as i, t as p, u as d } from "./a11y-DVBCy09c.js";
2
2
  export {
3
3
  d as announceToScreenReader,
4
4
  n as auditA11y,
@@ -1 +1 @@
1
- {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/component/library.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,6DAA6D;AAC7D,MAAM,WAAW,8BAA8B;IAC7C,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,2BAA2B;IAC1C,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AA8LD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,UAAS,8BAAmC,KAC3C,2BAuTF,CAAC"}
1
+ {"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/component/library.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,6DAA6D;AAC7D,MAAM,WAAW,8BAA8B;IAC7C,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,2BAA2B;IAC1C,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,QAAQ,EAAE,MAAM,CAAC;CAClB;AA4LD;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GACpC,UAAS,8BAAmC,KAC3C,2BAuTF,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import { f as L, l as N, n as I, t as j, u as D } from "./sanitize-B1V4JswB.js";
2
- import { n as Q, r as q } from "./core-DnlyjbF2.js";
3
- import { n as U } from "./config-BW35FKuA.js";
4
- import { r as W, t as w } from "./untrack-DJVQQ2WM.js";
5
- import { t as J } from "./env-NeVmr4Gf.js";
2
+ import { n as Q, r as q } from "./core-DdtZHzsS.js";
3
+ import { n as U } from "./config-DhT9auRm.js";
4
+ import { r as W, t as w } from "./untrack-D0fnO5k2.js";
5
+ import { t as J } from "./env-CTdvLaH2.js";
6
6
  var F = (r, e) => {
7
7
  const { type: o } = e;
8
8
  if (o === String) return r;
@@ -681,4 +681,4 @@ export {
681
681
  fe as t
682
682
  };
683
683
 
684
- //# sourceMappingURL=component-CuuTijA6.js.map
684
+ //# sourceMappingURL=component-L3-JfOFz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-L3-JfOFz.js","names":[],"sources":["../src/component/props.ts","../src/component/scope.ts","../src/component/component.ts","../src/component/html.ts","../src/component/library.ts"],"sourcesContent":["/**\n * Prop coercion utilities.\n *\n * @module bquery/component\n */\n\nimport type { PropDefinition } from './types';\n\n/**\n * Coerces a string attribute value into a typed prop value.\n * Supports String, Number, Boolean, Object, Array, and custom converters.\n *\n * @internal\n * @template T - The target type\n * @param rawValue - The raw string value from the attribute\n * @param config - The prop definition with type information\n * @returns The coerced value of type T\n */\nexport const coercePropValue = <T>(rawValue: string, config: PropDefinition<T>): T => {\n const { type } = config;\n\n if (type === String) return rawValue as T;\n\n if (type === Number) {\n return Number(rawValue) as T;\n }\n\n if (type === Boolean) {\n const normalized = rawValue.trim().toLowerCase();\n if (normalized === '' || normalized === 'true' || normalized === '1') {\n return true as T;\n }\n if (normalized === 'false' || normalized === '0') {\n return false as T;\n }\n return Boolean(rawValue) as T;\n }\n\n if (type === Object || type === Array) {\n try {\n return JSON.parse(rawValue) as T;\n } catch {\n return rawValue as T;\n }\n }\n\n if (typeof type === 'function') {\n const callable = type as (value: unknown) => T;\n const constructable = type as new (value: unknown) => T;\n\n // Explicit construct mode takes precedence\n if (config.construct === true) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n if (config.construct === false) {\n return callable(rawValue);\n }\n\n // Auto-detect: Check if type is constructable\n // A function is considered constructable if:\n // 1. It has a prototype with properties beyond just constructor, OR\n // 2. Its prototype.constructor is not itself (inherited), OR\n // 3. It's a class (toString starts with \"class\")\n const hasPrototype = type.prototype !== undefined && type.prototype !== null;\n const prototypeProps = hasPrototype ? Object.getOwnPropertyNames(type.prototype) : [];\n const hasPrototypeMethods = prototypeProps.length > 1;\n const hasInheritedConstructor = hasPrototype && type.prototype.constructor !== type;\n const isClassSyntax = /^class\\s/.test(Function.prototype.toString.call(type));\n\n const isConstructable = hasPrototypeMethods || hasInheritedConstructor || isClassSyntax;\n\n // For constructable types (e.g. Date, custom classes), prefer `new` to avoid\n // silent wrong-type returns (Date() returns string, new Date() returns Date)\n if (isConstructable) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Fall back to calling as function if construction fails\n return callable(rawValue);\n }\n }\n\n // For non-constructable types (arrow functions, plain functions), call directly\n // but fall back to constructor if result is undefined (common for function constructors)\n try {\n const result = callable(rawValue);\n\n // If calling without `new` returned undefined and the function has a prototype,\n // it's likely a function constructor that should be called with `new`\n if (result === undefined && hasPrototype) {\n try {\n return Reflect.construct(constructable, [rawValue]) as T;\n } catch {\n // Construction also failed, return the undefined\n return result as T;\n }\n }\n\n return result as T;\n } catch (error) {\n // Fall back to constructor if error indicates 'new' is required\n const isNewRequired =\n error instanceof TypeError &&\n /cannot be invoked without 'new'|is not a function/i.test(error.message);\n\n if (isNewRequired) {\n return Reflect.construct(constructable, [rawValue]) as T;\n }\n\n // Rethrow original error for non-constructable converters\n throw error;\n }\n }\n\n return rawValue as T;\n};\n","/**\n * Component-scoped reactive primitives.\n *\n * Provides `useSignal`, `useComputed`, and `useEffect` that automatically\n * dispose when their owning component disconnects from the DOM.\n *\n * @module bquery/component\n */\n\nimport type { Computed } from '../reactive/computed';\nimport { computed } from '../reactive/computed';\nimport { detectDevEnvironment } from '../core/env';\nimport type { Signal } from '../reactive/core';\nimport { signal } from '../reactive/core';\nimport { effect } from '../reactive/effect';\nimport type { CleanupFn } from '../reactive/index';\n\n/**\n * Holds disposable resources created inside a component scope.\n * All registered disposers run when the component disconnects.\n * @internal\n */\nexport interface ComponentScope {\n /** Register a cleanup function to run on dispose */\n addDisposer(fn: CleanupFn): void;\n /** Dispose all registered resources */\n dispose(): void;\n}\n\n/** Currently active component scope. @internal */\nlet currentScope: ComponentScope | undefined;\n\n/**\n * Sets the active component scope.\n * @internal\n */\nexport function setCurrentScope(scope: ComponentScope | undefined): ComponentScope | undefined {\n const previousScope = currentScope;\n currentScope = scope;\n return previousScope;\n}\n\n/**\n * Returns the active component scope, or undefined if none.\n * @internal\n */\nexport function getCurrentScope(): ComponentScope | undefined {\n return currentScope;\n}\n\n/**\n * Creates a new component scope that tracks disposable resources.\n * @internal\n */\nexport function createComponentScope(): ComponentScope {\n const disposers: CleanupFn[] = [];\n\n return {\n addDisposer(fn: CleanupFn): void {\n disposers.push(fn);\n },\n dispose(): void {\n for (const fn of disposers) {\n try {\n fn();\n } catch (error) {\n if (\n detectDevEnvironment() &&\n typeof console !== 'undefined' &&\n typeof console.error === 'function'\n ) {\n console.error('bQuery component: Error disposing scoped resource', error);\n }\n }\n }\n disposers.length = 0;\n },\n };\n}\n\n/**\n * Creates a reactive signal scoped to the current component.\n *\n * The signal is automatically disposed when the component disconnects\n * from the DOM, removing all subscribers and preventing memory leaks.\n *\n * Must be called during a component lifecycle hook such as `connected`,\n * `beforeMount`, `onAdopted`, or `onAttributeChanged`.\n *\n * Do not create scoped primitives from `render()`. Repeated renders can\n * accumulate render-scoped resources until disconnect; prefer lifecycle hooks.\n *\n * @template T - The type of the signal value\n * @param initialValue - The initial value of the signal\n * @returns A new Signal instance that auto-disposes with the component\n * @throws {Error} If called outside a component scope\n *\n * @example\n * ```ts\n * import { component, html, useSignal } from '@bquery/bquery/component';\n *\n * component('my-counter', {\n * connected() {\n * const count = useSignal(0);\n * // count.dispose() is called automatically on disconnect\n * },\n * render({ state }) {\n * return html`<span>${state.count}</span>`;\n * },\n * });\n * ```\n */\nexport function useSignal<T>(initialValue: T): Signal<T> {\n const scope = currentScope;\n if (!scope) {\n throw new Error(\n 'bQuery component: useSignal() must be called inside a component lifecycle hook. Avoid calling it directly from render()'\n );\n }\n const s = signal(initialValue);\n scope.addDisposer(() => s.dispose());\n return s;\n}\n\n/**\n * Creates a computed value scoped to the current component.\n *\n * The computed value's internal effect is automatically cleaned up\n * when the component disconnects from the DOM.\n *\n * Must be called during a component lifecycle hook such as `connected`,\n * `beforeMount`, `onAdopted`, or `onAttributeChanged`.\n *\n * Do not create scoped primitives from `render()`. Repeated renders can\n * accumulate render-scoped resources until disconnect; prefer lifecycle hooks.\n *\n * @template T - The type of the computed value\n * @param fn - Derivation function that reads reactive sources\n * @returns A new Computed instance that auto-cleans-up with the component\n * @throws {Error} If called outside a component scope\n *\n * @example\n * ```ts\n * import { component, html, useSignal, useComputed } from '@bquery/bquery/component';\n *\n * component('my-doubler', {\n * connected() {\n * const count = useSignal(1);\n * const doubled = useComputed(() => count.value * 2);\n * },\n * render({ state }) {\n * return html`<span>${state.doubled}</span>`;\n * },\n * });\n * ```\n */\nexport function useComputed<T>(fn: () => T): Computed<T> {\n const scope = currentScope;\n if (!scope) {\n throw new Error(\n 'bQuery component: useComputed() must be called inside a component lifecycle hook. Avoid calling it directly from render()'\n );\n }\n const c = computed(fn);\n scope.addDisposer(() => c.dispose());\n return c;\n}\n\n/**\n * Creates a side effect scoped to the current component.\n *\n * The effect runs immediately and re-runs when its reactive dependencies\n * change. It is automatically disposed when the component disconnects\n * from the DOM.\n *\n * Must be called during a component lifecycle hook such as `connected`,\n * `beforeMount`, `onAdopted`, or `onAttributeChanged`.\n *\n * Do not create scoped primitives from `render()`. Repeated renders can\n * accumulate render-scoped resources until disconnect; prefer lifecycle hooks.\n *\n * @param fn - The effect function; may return a cleanup function\n * @returns A cleanup function to manually stop the effect early\n * @throws {Error} If called outside a component scope\n *\n * @example\n * ```ts\n * import { component, useSignal, useEffect } from '@bquery/bquery/component';\n *\n * component('my-logger', {\n * connected() {\n * const count = useSignal(0);\n * useEffect(() => {\n * console.log('Count changed:', count.value);\n * return () => console.log('Cleanup');\n * });\n * },\n * render() { return '<p>Logger</p>'; },\n * });\n * ```\n */\nexport function useEffect(fn: () => void | CleanupFn): CleanupFn {\n const scope = currentScope;\n if (!scope) {\n throw new Error(\n 'bQuery component: useEffect() must be called inside a component lifecycle hook. Avoid calling it directly from render()'\n );\n }\n const cleanup = effect(fn);\n scope.addDisposer(cleanup);\n return cleanup;\n}\n","/**\n * Web Component factory and registry.\n *\n * @module bquery/component\n */\n\nimport type { CleanupFn } from '../reactive/signal';\nimport { effect, untrack } from '../reactive/signal';\nimport { sanitizeHtml } from '../security/sanitize';\nimport { coercePropValue } from './props';\nimport { createComponentScope, setCurrentScope, type ComponentScope } from './scope';\nimport type {\n AttributeChange,\n ComponentClass,\n ComponentDefinition,\n ComponentSignalLike,\n ComponentSignals,\n ComponentStateShape,\n PropDefinition,\n ShadowMode,\n} from './types';\n\n/**\n * Base extra tags preserved for component shadow DOM renders in addition to the\n * global sanitizer defaults. `slot` must remain allowed here because shadow DOM\n * content projection depends on authored `<slot>` elements in component render\n * output.\n */\nconst COMPONENT_ALLOWED_TAGS = ['slot'];\n\n/**\n * Base extra attributes preserved for component shadow DOM renders in addition\n * to the global sanitizer defaults.\n */\nconst COMPONENT_ALLOWED_ATTRIBUTES = [\n 'part',\n // Standard form attributes required by interactive shadow DOM content\n 'disabled',\n 'checked',\n 'placeholder',\n 'value',\n 'rows',\n 'cols',\n 'readonly',\n 'required',\n 'maxlength',\n 'minlength',\n 'max',\n 'min',\n 'step',\n 'pattern',\n 'autocomplete',\n 'autofocus',\n 'for',\n 'multiple',\n 'selected',\n 'wrap',\n];\n\n/**\n * Creates a custom element class for a component definition.\n *\n * This is useful when you want to extend or register the class manually\n * (e.g. with different tag names in tests or custom registries).\n *\n * @template TProps - Type of the component's props\n * @param tagName - The custom element tag name (used for diagnostics)\n * @param definition - The component configuration\n */\nconst createComponentClass = <\n TProps extends Record<string, unknown>,\n TState extends Record<string, unknown> | undefined = undefined,\n TSignals extends ComponentSignals = Record<string, never>,\n>(\n tagName: string,\n definition: ComponentDefinition<TProps, TState, TSignals>\n): ComponentClass<TState> => {\n const componentAllowedTags = [\n ...COMPONENT_ALLOWED_TAGS,\n ...(definition.sanitize?.allowTags ?? []),\n ];\n const componentAllowedAttributes = [\n ...COMPONENT_ALLOWED_ATTRIBUTES,\n ...(definition.sanitize?.allowAttributes ?? []),\n ];\n const signalSources = Object.values(definition.signals ?? {}) as ComponentSignalLike<unknown>[];\n\n /** Resolve the Shadow DOM mode from the `shadow` option. */\n const resolveShadowMode = (option: ShadowMode | undefined): 'open' | 'closed' | false => {\n if (option === false) return false;\n if (option === 'closed') return 'closed';\n // true, 'open', or undefined all resolve to 'open'\n return 'open';\n };\n const shadowMode = resolveShadowMode(definition.shadow);\n\n /**\n * Merges prop-derived observed attributes with any extra attributes from\n * `observeAttributes`, deduplicating to avoid redundant callbacks.\n */\n const observedAttrs = Array.from(\n new Set([...Object.keys(definition.props ?? {}), ...(definition.observeAttributes ?? [])])\n );\n\n class BQueryComponent extends HTMLElement {\n /** Internal state object for the component */\n private readonly state: ComponentStateShape<TState> = {\n ...(definition.state ?? {}),\n } as ComponentStateShape<TState>;\n /** Typed props object populated from attributes */\n private props = {} as TProps;\n /** Tracks missing required props for validation during connectedCallback */\n private missingRequiredProps = new Set<string>();\n /** Tracks whether the component has completed its initial mount */\n private hasMounted = false;\n /** Cleanup for external signal subscriptions */\n private signalEffectCleanup?: CleanupFn;\n /** Component-scoped reactive resource tracker */\n private scope?: ComponentScope;\n /** Render target for open/closed shadow roots or the host element when shadow DOM is disabled */\n private readonly renderRootNode: HTMLElement | ShadowRoot;\n\n constructor() {\n super();\n if (shadowMode !== false) {\n this.renderRootNode = this.attachShadow({ mode: shadowMode });\n } else {\n this.renderRootNode = this;\n }\n this.syncProps();\n }\n\n /**\n * Returns the list of attributes to observe for changes.\n */\n static get observedAttributes(): string[] {\n return observedAttrs;\n }\n\n /**\n * Called when the element is added to the DOM.\n */\n connectedCallback(): void {\n try {\n // Defer only the initial mount until all required props are present.\n // Already-mounted components must still reconnect their signal\n // subscriptions so reactive updates can resume after reattachment.\n if (!this.hasMounted && this.missingRequiredProps.size > 0) {\n // Component will mount once all required props are satisfied\n // via attributeChangedCallback\n return;\n }\n if (this.hasMounted) {\n // Recreate scope for reconnected component\n this.scope = createComponentScope();\n const previousScope = setCurrentScope(this.scope);\n try {\n definition.connected?.call(this);\n } catch (error) {\n this.handleError(error as Error);\n } finally {\n setCurrentScope(previousScope);\n }\n this.setupSignalSubscriptions(true);\n return;\n }\n this.mount();\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Performs the initial mount of the component.\n * Called when the element is connected and all required props are present.\n * @internal\n */\n private mount(): void {\n if (this.hasMounted) return;\n const previousScope = setCurrentScope(this.ensureScope());\n let hookError = false;\n try {\n definition.beforeMount?.call(this);\n definition.connected?.call(this);\n } catch (error) {\n hookError = true;\n this.handleError(error as Error);\n } finally {\n setCurrentScope(previousScope);\n }\n if (hookError) {\n this.scope?.dispose();\n this.scope = undefined;\n return;\n }\n this.render();\n this.setupSignalSubscriptions();\n this.hasMounted = true;\n }\n\n /**\n * Called when the element is removed from the DOM.\n */\n disconnectedCallback(): void {\n try {\n this.signalEffectCleanup?.();\n this.signalEffectCleanup = undefined;\n // Dispose all scoped reactive resources (useSignal, useComputed, useEffect)\n this.scope?.dispose();\n this.scope = undefined;\n definition.disconnected?.call(this);\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Called when an observed attribute changes.\n */\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n try {\n const previousProps = this.cloneProps();\n this.syncProps();\n\n // Fire the user-facing onAttributeChanged hook for every observed attribute change\n if (definition.onAttributeChanged) {\n const previousScope = setCurrentScope(this.ensureScope());\n try {\n definition.onAttributeChanged.call(this, name, oldValue, newValue);\n } finally {\n setCurrentScope(previousScope);\n }\n }\n\n if (this.hasMounted) {\n // Component already mounted - trigger update render\n this.render(true, previousProps, { name, oldValue, newValue });\n } else if (this.isConnected && this.missingRequiredProps.size === 0) {\n // All required props are now satisfied and element is connected\n // Trigger the deferred initial mount\n this.mount();\n }\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n\n /**\n * Called when the element is moved to a new document (e.g. via `document.adoptNode`).\n */\n adoptedCallback(): void {\n if (!definition.onAdopted) {\n return;\n }\n\n const previousScope = setCurrentScope(this.ensureScope());\n try {\n definition.onAdopted.call(this);\n } catch (error) {\n this.handleError(error as Error);\n } finally {\n setCurrentScope(previousScope);\n }\n }\n\n /**\n * Handles errors during component lifecycle.\n * @internal\n */\n private handleError(error: Error): void {\n if (definition.onError) {\n definition.onError.call(this, error);\n } else {\n console.error(`bQuery component error in <${tagName}>:`, error);\n }\n }\n\n /**\n * Ensures the component has an active scope for scoped reactive primitives.\n * @internal\n */\n private ensureScope(): ComponentScope {\n return (this.scope ??= createComponentScope());\n }\n\n /**\n * Updates a state property and triggers a re-render.\n *\n * @param key - The state property key\n * @param value - The new value\n */\n setState<TKey extends keyof ComponentStateShape<TState>>(\n key: TKey,\n value: ComponentStateShape<TState>[TKey]\n ): void {\n this.state[key] = value;\n this.render(true, this.cloneProps(), undefined, false);\n }\n\n /**\n * Gets a state property value.\n *\n * @param key - The state property key\n * @returns The current value\n */\n getState<TKey extends keyof ComponentStateShape<TState>>(\n key: TKey\n ): ComponentStateShape<TState>[TKey];\n getState<TResult = unknown>(key: string): TResult;\n getState(key: string): unknown {\n return (this.state as Record<string, unknown>)[key];\n }\n\n /**\n * Subscribes to declared reactive sources and re-renders on change.\n *\n * @param renderOnInitialRun - When true, immediately re-renders after\n * re-subscribing so detached components resync with any signal changes\n * that happened while they were disconnected.\n * @internal\n */\n private setupSignalSubscriptions(renderOnInitialRun = false): void {\n if (this.signalEffectCleanup || signalSources.length === 0) return;\n\n let isInitialRun = true;\n this.signalEffectCleanup = effect(() => {\n try {\n for (const source of signalSources) {\n // Intentionally read each source to register this effect as a subscriber.\n void source.value;\n }\n\n if (isInitialRun) {\n isInitialRun = false;\n if (renderOnInitialRun && this.hasMounted && this.isConnected) {\n // Signal-driven reconnect renders do not change props, so the\n // previous-props snapshot is the current prop set at reconnect time.\n const previousProps = this.cloneProps();\n untrack(() => {\n this.render(true, previousProps, undefined, false);\n });\n }\n return;\n }\n\n if (!this.hasMounted || !this.isConnected) return;\n\n // Signal updates leave props unchanged, so cloning the current props\n // provides the previous-props snapshot expected by beforeUpdate().\n const previousProps = this.cloneProps();\n untrack(() => {\n this.render(true, previousProps, undefined, false);\n });\n } catch (error) {\n this.handleError(error as Error);\n }\n });\n }\n\n /**\n * Synchronizes props from attributes.\n * @internal\n */\n private syncProps(): void {\n const props = definition.props ?? {};\n for (const [key, config] of Object.entries(props) as [string, PropDefinition][]) {\n const attrValue = this.getAttribute(key);\n let value: unknown;\n\n if (attrValue == null) {\n if (config.required && config.default === undefined) {\n // Mark as missing instead of throwing - validate during connectedCallback\n this.missingRequiredProps.add(key);\n value = undefined;\n } else {\n value = config.default ?? undefined;\n }\n } else {\n // Attribute is present, remove from missing set if it was there\n if (this.missingRequiredProps.has(key)) {\n this.missingRequiredProps.delete(key);\n }\n value = coercePropValue(attrValue, config);\n }\n\n if (config.validator && value !== undefined) {\n const isValid = config.validator(value);\n if (!isValid) {\n throw new Error(\n `bQuery component: validation failed for prop \"${key}\" with value ${JSON.stringify(value)}`\n );\n }\n }\n\n (this.props as Record<string, unknown>)[key] = value;\n }\n }\n\n /**\n * Creates a shallow snapshot of the current props for lifecycle diffing.\n * A shallow copy is sufficient because component props are re-derived from\n * reflected attributes on each update, so nested object mutation is not\n * tracked as part of this lifecycle diff.\n * @internal\n */\n private cloneProps(): TProps {\n return { ...(this.props as Record<string, unknown>) } as TProps;\n }\n\n /**\n * Renders the component to its shadow root or host element.\n * @internal\n */\n private render(): void;\n private render(triggerUpdated: true, oldProps: TProps, change?: AttributeChange): void;\n private render(\n triggerUpdated: true,\n oldProps: TProps,\n change: AttributeChange | undefined,\n runBeforeUpdate: boolean\n ): void;\n private render(\n triggerUpdated = false,\n oldProps?: TProps,\n change?: AttributeChange,\n runBeforeUpdate = true\n ): void {\n try {\n if (triggerUpdated && runBeforeUpdate && definition.beforeUpdate) {\n if (!oldProps) {\n throw new Error('bQuery component: previous props are required for update renders');\n }\n const shouldUpdate = definition.beforeUpdate.call(this, this.props, oldProps);\n if (shouldUpdate === false) return;\n }\n\n const emit = (event: string, detail?: unknown): void => {\n this.dispatchEvent(new CustomEvent(event, { detail, bubbles: true, composed: true }));\n };\n\n const renderRoot = this.renderRootNode;\n\n const markup = definition.render({\n props: this.props,\n state: this.state,\n signals: (definition.signals ?? {}) as TSignals,\n emit,\n });\n\n // Component render output is authored by the component definition itself,\n // so we can explicitly preserve shadow-DOM-specific markup such as <slot>,\n // the stylistic `part` attribute, and standard form/input attributes without\n // relaxing the global DOM sanitization rules.\n const sanitizedMarkup = sanitizeHtml(markup, {\n allowTags: componentAllowedTags,\n allowAttributes: componentAllowedAttributes,\n });\n let existingStyleElement: HTMLStyleElement | null = null;\n if (definition.styles) {\n existingStyleElement = renderRoot.querySelector<HTMLStyleElement>(\n 'style[data-bquery-component-style]'\n );\n }\n\n renderRoot.innerHTML = sanitizedMarkup;\n\n if (definition.styles) {\n const styleElement = existingStyleElement ?? document.createElement('style');\n if (!existingStyleElement) {\n styleElement.setAttribute('data-bquery-component-style', '');\n }\n styleElement.textContent = definition.styles;\n renderRoot.prepend(styleElement);\n }\n\n if (triggerUpdated) {\n definition.updated?.call(this, change);\n }\n } catch (error) {\n this.handleError(error as Error);\n }\n }\n }\n\n return BQueryComponent as ComponentClass<TState>;\n};\n\n/**\n * Creates a custom element class for a component definition.\n *\n * This is useful when you want to extend or register the class manually\n * (e.g. with different tag names in tests or custom registries).\n *\n * @template TProps - Type of the component's props\n * @template TState - Type of the component's internal state. When provided,\n * `definition.state` is required, `render({ state })` is strongly typed, and\n * returned instances expose typed `getState()` / `setState()` helpers.\n * @param tagName - The custom element tag name (used for diagnostics)\n * @param definition - The component configuration\n */\nexport function defineComponent<\n TProps extends Record<string, unknown>,\n TSignals extends ComponentSignals = Record<string, never>,\n>(\n tagName: string,\n definition: ComponentDefinition<TProps, undefined, TSignals>\n): ComponentClass<undefined>;\nexport function defineComponent<\n TProps extends Record<string, unknown>,\n TState extends Record<string, unknown>,\n TSignals extends ComponentSignals = Record<string, never>,\n>(\n tagName: string,\n definition: ComponentDefinition<TProps, TState, TSignals>\n): ComponentClass<TState>;\nexport function defineComponent<\n TProps extends Record<string, unknown>,\n TState extends Record<string, unknown> | undefined = undefined,\n TSignals extends ComponentSignals = Record<string, never>,\n>(\n tagName: string,\n definition: ComponentDefinition<TProps, TState, TSignals>\n): ComponentClass<TState> {\n return createComponentClass(tagName, definition);\n}\n\n/**\n * Defines and registers a custom Web Component.\n *\n * This function creates a new custom element with the given tag name\n * and configuration. The component uses Shadow DOM for encapsulation\n * and automatically re-renders when observed attributes change.\n *\n * @template TProps - Type of the component's props\n * @template TState - Type of the component's internal state. When provided,\n * `definition.state` is required and lifecycle hooks receive typed state\n * helpers via `this.getState()` / `this.setState()`.\n * @param tagName - The custom element tag name (must contain a hyphen)\n * @param definition - The component configuration\n *\n * @example\n * ```ts\n * component<{ start: number }, { count: number }>('counter-button', {\n * props: {\n * start: { type: Number, default: 0 },\n * },\n * state: { count: 0 },\n * styles: `\n * button { padding: 0.5rem 1rem; }\n * `,\n * connected() {\n * // Use event delegation on shadow root so handler survives re-renders\n * const handleClick = (event: Event) => {\n * const target = event.target as HTMLElement | null;\n * if (target?.matches('button')) {\n * this.setState('count', this.getState('count') + 1);\n * }\n * };\n * this.shadowRoot?.addEventListener('click', handleClick);\n * // Store handler for cleanup\n * (this as any)._handleClick = handleClick;\n * },\n * disconnected() {\n * // Clean up event listener to prevent memory leaks\n * const handleClick = (this as any)._handleClick;\n * if (handleClick) {\n * this.shadowRoot?.removeEventListener('click', handleClick);\n * }\n * },\n * render({ props, state }) {\n * return html`\n * <button>\n * Count: ${state.count}\n * </button>\n * `;\n * },\n * });\n * ```\n */\nexport function component<\n TProps extends Record<string, unknown>,\n TSignals extends ComponentSignals = Record<string, never>,\n>(tagName: string, definition: ComponentDefinition<TProps, undefined, TSignals>): void;\nexport function component<\n TProps extends Record<string, unknown>,\n TState extends Record<string, unknown>,\n TSignals extends ComponentSignals = Record<string, never>,\n>(tagName: string, definition: ComponentDefinition<TProps, TState, TSignals>): void;\nexport function component<\n TProps extends Record<string, unknown>,\n TState extends Record<string, unknown> | undefined = undefined,\n TSignals extends ComponentSignals = Record<string, never>,\n>(tagName: string, definition: ComponentDefinition<TProps, TState, TSignals>): void {\n const elementClass = createComponentClass(tagName, definition);\n\n if (!customElements.get(tagName)) {\n customElements.define(tagName, elementClass);\n }\n}\n","import {\n isTrustedHtml,\n type SanitizedHtml,\n toSanitizedHtml,\n unwrapTrustedHtml,\n} from '../security/trusted-html';\nconst BOOLEAN_ATTRIBUTE_MARKER: unique symbol = Symbol('bquery.booleanAttribute');\nconst BOOLEAN_ATTRIBUTE_NAME = /^[^\\0-\\x20\"'/>=]+$/;\n\n/**\n * Public shape of a boolean HTML attribute created by {@link bool}.\n *\n * This type is returned from {@link bool} and can be interpolated into\n * {@link html} / {@link safeHtml} templates to conditionally include or omit\n * an attribute by name. The internal marker property used for runtime checks\n * remains private and is not part of the public API.\n *\n * @example\n * ```ts\n * const disabled = bool('disabled', isDisabled);\n * const button = html`<button ${disabled}>Click</button>`;\n * ```\n */\nexport interface BooleanAttribute {\n readonly enabled: boolean;\n readonly name: string;\n}\n\ninterface BooleanAttributeValue extends BooleanAttribute {\n readonly [BOOLEAN_ATTRIBUTE_MARKER]: true;\n}\n\nconst isBooleanAttributeValue = (value: unknown): value is BooleanAttributeValue => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as Partial<BooleanAttributeValue>;\n return (\n candidate[BOOLEAN_ATTRIBUTE_MARKER] === true &&\n typeof candidate.enabled === 'boolean' &&\n typeof candidate.name === 'string'\n );\n};\n\nconst stringifyTemplateValue = (value: unknown): string => {\n if (isBooleanAttributeValue(value)) {\n return value.enabled ? value.name : '';\n }\n\n return String(value ?? '');\n};\n\nconst escapeMap: Record<string, string> = {\n '&': '&amp;',\n '<': '&lt;',\n '>': '&gt;',\n '\"': '&quot;',\n \"'\": '&#x27;',\n '`': '&#x60;',\n};\n\nconst escapeTemplateValue = (value: unknown): string => {\n if (isBooleanAttributeValue(value)) {\n return value.enabled ? value.name : '';\n }\n\n return stringifyTemplateValue(value).replace(/[&<>\"'`]/g, (char) => escapeMap[char]);\n};\n\n/**\n * Creates a boolean-attribute marker for the {@link html} and {@link safeHtml} template tags.\n *\n * When the condition is truthy, the attribute name is rendered without a value.\n * When the condition is falsy, an empty string is rendered and any surrounding\n * template-literal whitespace is preserved.\n *\n * @param name - HTML attribute name to emit\n * @param enabled - Whether the boolean attribute should be present\n * @returns Internal marker consumed by template tags\n *\n * @example\n * ```ts\n * html`<button ${bool('disabled', isDisabled)}>Save</button>`;\n * // Result when isDisabled = true: '<button disabled>Save</button>'\n * ```\n */\nexport const bool = (name: string, enabled: unknown): BooleanAttribute => {\n if (!BOOLEAN_ATTRIBUTE_NAME.test(name)) {\n throw new TypeError(`Invalid boolean attribute name: ${name}`);\n }\n\n const attribute: BooleanAttributeValue = {\n [BOOLEAN_ATTRIBUTE_MARKER]: true,\n enabled: Boolean(enabled),\n name,\n };\n\n return Object.freeze(attribute);\n};\n\n/**\n * Tagged template literal for creating HTML strings.\n *\n * This function handles interpolation of values into HTML templates,\n * converting null/undefined to empty strings.\n *\n * @param strings - Template literal string parts\n * @param values - Interpolated values\n * @returns Combined HTML string\n *\n * @example\n * ```ts\n * const name = 'World';\n * const greeting = html`<h1>Hello, ${name}!</h1>`;\n * // Result: '<h1>Hello, World!</h1>'\n * ```\n */\nexport const html = (strings: TemplateStringsArray, ...values: unknown[]): string => {\n return strings.reduce(\n (acc, part, index) => `${acc}${part}${stringifyTemplateValue(values[index])}`,\n ''\n );\n};\n\n/**\n * Escapes HTML entities in interpolated values for XSS prevention.\n * Use this when you need to safely embed user content in templates.\n *\n * @param strings - Template literal string parts\n * @param values - Interpolated values to escape\n * @returns Branded escaped HTML string safe for bQuery template composition\n *\n * @example\n * ```ts\n * const userInput = '<script>alert(\"xss\")</script>';\n * const safe = safeHtml`<div>${userInput}</div>`;\n * // Result: '<div>&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;</div>'\n * ```\n */\nexport const safeHtml = (strings: TemplateStringsArray, ...values: unknown[]): SanitizedHtml => {\n const escape = (value: unknown): string => {\n if (isTrustedHtml(value)) return unwrapTrustedHtml(value);\n return escapeTemplateValue(value);\n };\n\n return toSanitizedHtml(\n strings.reduce(\n (acc, part, index) => `${acc}${part}${index < values.length ? escape(values[index]) : ''}`,\n ''\n )\n );\n};\n","/**\n * Default component library based on native Web Components.\n *\n * @module bquery/component\n */\n\nimport { getBqueryConfig } from '../platform/config';\nimport { escapeHtml } from '../security';\nimport { component } from './component';\nimport { html } from './html';\n\n/** Options for registering the default component library. */\nexport interface DefaultComponentLibraryOptions {\n /** Prefix used for all registered component tags. Defaults to `bq`. */\n prefix?: string;\n}\n\n/** Tag names returned by registerDefaultComponents(). */\nexport interface RegisteredDefaultComponents {\n /** Button component tag name. */\n button: string;\n /** Card component tag name. */\n card: string;\n /** Input component tag name. */\n input: string;\n /** Textarea component tag name. */\n textarea: string;\n /** Checkbox component tag name. */\n checkbox: string;\n}\n\nconst baseStyles = `\n :host {\n color: inherit;\n font: inherit;\n }\n`;\n\nconst controlStyles = `\n ${baseStyles}\n .field {\n display: inline-flex;\n flex-direction: column;\n gap: 0.375rem;\n width: 100%;\n }\n .label {\n color: #334155;\n font-size: 0.875rem;\n font-weight: 600;\n }\n .control {\n border: 1px solid #cbd5e1;\n border-radius: 0.75rem;\n box-sizing: border-box;\n font: inherit;\n min-height: 2.75rem;\n outline: none;\n padding: 0.75rem 0.875rem;\n width: 100%;\n background: #fff;\n color: #0f172a;\n transition: border-color 160ms ease, box-shadow 160ms ease;\n }\n .control:focus {\n border-color: #2563eb;\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.15);\n }\n .control:disabled {\n background: #f8fafc;\n color: #94a3b8;\n cursor: not-allowed;\n }\n`;\n\nconst escapeProp = (value: string): string => escapeHtml(value);\n\nconst handlerStore = new WeakMap<HTMLElement, Record<string, EventListener>>();\n\nconst readHandler = (element: HTMLElement, key: string): EventListener | undefined => {\n return handlerStore.get(element)?.[key];\n};\n\nconst storeHandler = (element: HTMLElement, key: string, value: EventListener): void => {\n const handlers = handlerStore.get(element) ?? {};\n handlers[key] = value;\n handlerStore.set(element, handlers);\n};\n\n/**\n * Detect a value-only input update, patch the live control in place, and\n * return whether the component can skip a full shadow DOM re-render.\n *\n * @param element - The host custom element whose shadow DOM is being updated\n * @param newProps - The next reflected input props for the pending update\n * @param oldProps - The previous reflected input props from the last render\n */\nconst canSkipInputRender = (\n element: HTMLElement,\n newProps: {\n label: string;\n type: string;\n value: string;\n placeholder: string;\n name: string;\n disabled: boolean;\n },\n oldProps: {\n label: string;\n type: string;\n value: string;\n placeholder: string;\n name: string;\n disabled: boolean;\n }\n): boolean => {\n if (oldProps.label !== newProps.label) return false;\n if (oldProps.type !== newProps.type) return false;\n if (oldProps.placeholder !== newProps.placeholder) return false;\n if (oldProps.name !== newProps.name) return false;\n if (oldProps.disabled !== newProps.disabled) return false;\n\n // Verify shadow DOM still matches expected non-value props before skipping re-render\n const shadowRoot = element.shadowRoot;\n if (!shadowRoot) return false;\n\n const labelEl = shadowRoot.querySelector('.label');\n if ((labelEl?.textContent ?? '') !== newProps.label) return false;\n\n const control = shadowRoot.querySelector('input.control') as HTMLInputElement | null;\n if (!control) return false;\n\n if (control.type !== newProps.type) return false;\n if (control.placeholder !== newProps.placeholder) return false;\n if (control.name !== newProps.name) return false;\n if (control.disabled !== newProps.disabled) return false;\n\n if (control.value !== newProps.value) {\n control.value = newProps.value;\n }\n\n return true;\n};\n\n/**\n * Detect a value-only textarea update, patch the live control in place, and\n * return whether the component can skip a full shadow DOM re-render.\n *\n * @param element - The host custom element whose shadow DOM is being updated\n * @param newProps - The next reflected textarea props for the pending update\n * @param oldProps - The previous reflected textarea props from the last render\n */\nconst canSkipTextareaRender = (\n element: HTMLElement,\n newProps: {\n label: string;\n value: string;\n placeholder: string;\n name: string;\n rows: number;\n disabled: boolean;\n },\n oldProps: {\n label: string;\n value: string;\n placeholder: string;\n name: string;\n rows: number;\n disabled: boolean;\n }\n): boolean => {\n if (oldProps.label !== newProps.label) return false;\n if (oldProps.placeholder !== newProps.placeholder) return false;\n if (oldProps.name !== newProps.name) return false;\n if (oldProps.rows !== newProps.rows) return false;\n if (oldProps.disabled !== newProps.disabled) return false;\n\n // Verify shadow DOM still matches expected non-value props before skipping re-render\n const shadowRoot = element.shadowRoot;\n if (!shadowRoot) return false;\n\n const labelEl = shadowRoot.querySelector('.label');\n if ((labelEl?.textContent ?? '') !== newProps.label) return false;\n\n const control = shadowRoot.querySelector('textarea.control') as HTMLTextAreaElement | null;\n if (!control) return false;\n\n if (control.placeholder !== newProps.placeholder) return false;\n if (control.name !== newProps.name) return false;\n if (Number(control.rows) !== newProps.rows) return false;\n if (control.disabled !== newProps.disabled) return false;\n\n if (control.value !== newProps.value) {\n control.value = newProps.value;\n }\n return true;\n};\n\nconst renderTextareaControl = (props: {\n value: string;\n placeholder: string;\n name: string;\n rows: number;\n disabled: boolean;\n}): string => {\n return [\n '<textarea',\n ' part=\"control\"',\n ' class=\"control\"',\n ` placeholder=\"${escapeProp(props.placeholder)}\"`,\n ` name=\"${escapeProp(props.name)}\"`,\n ` rows=\"${props.rows}\"`,\n props.disabled ? ' disabled' : '',\n `>${escapeProp(props.value)}</textarea>`,\n ].join('');\n};\n\n/**\n * Register a default set of foundational UI components.\n *\n * The library is intentionally small and dependency-free, providing common\n * primitives that can be themed via shadow parts and CSS custom properties.\n *\n * @param options - Optional registration settings such as a custom tag prefix\n * @returns The registered tag names for each component\n */\nexport const registerDefaultComponents = (\n options: DefaultComponentLibraryOptions = {}\n): RegisteredDefaultComponents => {\n const prefix = options.prefix ?? getBqueryConfig().components?.prefix ?? 'bq';\n const tags: RegisteredDefaultComponents = {\n button: `${prefix}-button`,\n card: `${prefix}-card`,\n input: `${prefix}-input`,\n textarea: `${prefix}-textarea`,\n checkbox: `${prefix}-checkbox`,\n };\n\n component<{\n label: string;\n variant: string;\n size: string;\n type: string;\n disabled: boolean;\n }>(tags.button, {\n props: {\n label: { type: String, default: '' },\n variant: { type: String, default: 'primary' },\n size: { type: String, default: 'md' },\n type: { type: String, default: 'button' },\n disabled: { type: Boolean, default: false },\n },\n styles: `\n ${baseStyles}\n button {\n appearance: none;\n border: 0;\n border-radius: 999px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font: inherit;\n font-weight: 600;\n gap: 0.5rem;\n min-height: 2.5rem;\n padding: 0.65rem 1rem;\n transition: transform 160ms ease, opacity 160ms ease, background 160ms ease;\n background: #2563eb;\n color: #fff;\n }\n button[data-variant='secondary'] {\n background: #e2e8f0;\n color: #0f172a;\n }\n button[data-size='sm'] {\n min-height: 2.125rem;\n padding: 0.5rem 0.875rem;\n }\n button[data-size='lg'] {\n min-height: 3rem;\n padding: 0.875rem 1.25rem;\n }\n button:hover:not(:disabled) {\n transform: translateY(-1px);\n }\n button:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n `,\n render: ({ props }) => html`\n <button\n part=\"button\"\n type=\"${escapeProp(props.type)}\"\n data-variant=\"${escapeProp(props.variant)}\"\n data-size=\"${escapeProp(props.size)}\"\n ${props.disabled ? 'disabled' : ''}\n >\n <slot>${escapeProp(props.label)}</slot>\n </button>\n `,\n });\n\n component<{ title: string; footer: string; elevated: boolean }>(tags.card, {\n props: {\n title: { type: String, default: '' },\n footer: { type: String, default: '' },\n elevated: { type: Boolean, default: true },\n },\n styles: `\n ${baseStyles}\n article {\n background: #fff;\n border: 1px solid #e2e8f0;\n border-radius: 1rem;\n box-shadow: 0 10px 25px rgba(15, 23, 42, 0.08);\n color: #0f172a;\n display: block;\n padding: 1rem;\n }\n article[data-elevated='false'] {\n box-shadow: none;\n }\n header, footer {\n color: #475569;\n font-size: 0.95rem;\n font-weight: 600;\n }\n header {\n margin-bottom: 0.75rem;\n }\n footer {\n margin-top: 0.75rem;\n }\n `,\n render: ({ props }) => html`\n <article part=\"card\" data-elevated=\"${String(props.elevated)}\">\n ${props.title ? `<header part=\"header\">${escapeProp(props.title)}</header>` : ''}\n <section part=\"body\"><slot></slot></section>\n ${props.footer ? `<footer part=\"footer\">${escapeProp(props.footer)}</footer>` : ''}\n </article>\n `,\n });\n\n component<{\n label: string;\n type: string;\n value: string;\n placeholder: string;\n name: string;\n disabled: boolean;\n }>(tags.input, {\n props: {\n label: { type: String, default: '' },\n type: { type: String, default: 'text' },\n value: { type: String, default: '' },\n placeholder: { type: String, default: '' },\n name: { type: String, default: '' },\n disabled: { type: Boolean, default: false },\n },\n styles: controlStyles,\n /**\n * Skip the full shadow DOM re-render when only the reflected input value\n * changed, because the live control has already been patched in place.\n */\n beforeUpdate(newProps, oldProps) {\n if (canSkipInputRender(this, newProps, oldProps)) {\n return false;\n }\n return true;\n },\n connected() {\n const handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement | null;\n if (!target?.matches('input')) return;\n event.stopPropagation();\n this.setAttribute('value', target.value);\n this.dispatchEvent(\n new CustomEvent('input', {\n detail: { value: target.value },\n bubbles: true,\n composed: true,\n })\n );\n };\n storeHandler(this, '__bqueryInputHandler', handleInput);\n this.shadowRoot?.addEventListener('input', handleInput);\n },\n disconnected() {\n const handleInput = readHandler(this, '__bqueryInputHandler');\n if (handleInput) {\n this.shadowRoot?.removeEventListener('input', handleInput);\n }\n },\n render: ({ props }) => html`\n <label part=\"field\" class=\"field\">\n ${props.label ? `<span part=\"label\" class=\"label\">${escapeProp(props.label)}</span>` : ''}\n <input\n part=\"control\"\n class=\"control\"\n type=\"${escapeProp(props.type)}\"\n value=\"${escapeProp(props.value)}\"\n placeholder=\"${escapeProp(props.placeholder)}\"\n name=\"${escapeProp(props.name)}\"\n ${props.disabled ? 'disabled' : ''}\n />\n </label>\n `,\n });\n\n component<{\n label: string;\n value: string;\n placeholder: string;\n name: string;\n rows: number;\n disabled: boolean;\n }>(tags.textarea, {\n props: {\n label: { type: String, default: '' },\n value: { type: String, default: '' },\n placeholder: { type: String, default: '' },\n name: { type: String, default: '' },\n rows: { type: Number, default: 4 },\n disabled: { type: Boolean, default: false },\n },\n styles: `${controlStyles}\n textarea.control {\n min-height: 6rem;\n resize: vertical;\n }\n `,\n /**\n * Skip the full shadow DOM re-render when only the reflected textarea value\n * changed, because the live control has already been patched in place.\n */\n beforeUpdate(newProps, oldProps) {\n if (canSkipTextareaRender(this, newProps, oldProps)) {\n return false;\n }\n return true;\n },\n connected() {\n const handleInput = (event: Event) => {\n const target = event.target as HTMLTextAreaElement | null;\n if (!target?.matches('textarea')) return;\n event.stopPropagation();\n this.setAttribute('value', target.value);\n this.dispatchEvent(\n new CustomEvent('input', {\n detail: { value: target.value },\n bubbles: true,\n composed: true,\n })\n );\n };\n storeHandler(this, '__bqueryTextareaHandler', handleInput);\n this.shadowRoot?.addEventListener('input', handleInput);\n },\n disconnected() {\n const handleInput = readHandler(this, '__bqueryTextareaHandler');\n if (handleInput) {\n this.shadowRoot?.removeEventListener('input', handleInput);\n }\n },\n render: ({ props }) => html`\n <label part=\"field\" class=\"field\">\n ${props.label ? `<span part=\"label\" class=\"label\">${escapeProp(props.label)}</span>` : ''}\n ${renderTextareaControl(props)}\n </label>\n `,\n });\n\n component<{ label: string; checked: boolean; disabled: boolean }>(tags.checkbox, {\n props: {\n label: { type: String, default: '' },\n checked: { type: Boolean, default: false },\n disabled: { type: Boolean, default: false },\n },\n styles: `\n ${baseStyles}\n label {\n align-items: center;\n color: #0f172a;\n cursor: pointer;\n display: inline-flex;\n gap: 0.625rem;\n }\n input {\n accent-color: #2563eb;\n block-size: 1rem;\n inline-size: 1rem;\n }\n input:disabled {\n cursor: not-allowed;\n }\n `,\n connected() {\n const handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement | null;\n if (!target?.matches('input[type=\"checkbox\"]')) return;\n event.stopPropagation();\n if (target.checked) {\n this.setAttribute('checked', 'true');\n } else {\n this.removeAttribute('checked');\n }\n this.dispatchEvent(\n new CustomEvent('change', {\n detail: { checked: target.checked },\n bubbles: true,\n composed: true,\n })\n );\n };\n storeHandler(this, '__bqueryCheckboxHandler', handleChange);\n this.shadowRoot?.addEventListener('change', handleChange);\n },\n disconnected() {\n const handleChange = readHandler(this, '__bqueryCheckboxHandler');\n if (handleChange) {\n this.shadowRoot?.removeEventListener('change', handleChange);\n }\n },\n render: ({ props }) => html`\n <label part=\"label\">\n <input\n part=\"control\"\n type=\"checkbox\"\n ${props.checked ? 'checked' : ''}\n ${props.disabled ? 'disabled' : ''}\n />\n <span part=\"text\"><slot>${escapeProp(props.label)}</slot></span>\n </label>\n `,\n });\n\n return tags;\n};\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { a as e, c as a, i as o, l as t, n, o as m, r as f, s as l, t as p } from "./component-CuuTijA6.js";
1
+ import { a as e, c as a, i as o, l as t, n, o as m, r as f, s as l, t as p } from "./component-L3-JfOFz.js";
2
2
  export {
3
3
  n as bool,
4
4
  e as component,
@@ -37,4 +37,4 @@ export {
37
37
  d as t
38
38
  };
39
39
 
40
- //# sourceMappingURL=config-BW35FKuA.js.map
40
+ //# sourceMappingURL=config-DhT9auRm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config-BW35FKuA.js","names":[],"sources":["../src/platform/config.ts"],"sourcesContent":["/**\n * Global bQuery configuration helpers.\n *\n * @module bquery/platform\n */\n\nimport { isPlainObject, merge } from '../core/utils/object';\n\n/** Supported response parsing strategies for fetch composables. */\nexport type BqueryFetchParseAs = 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData' | 'response';\n\n/** Global fetch defaults used by useFetch(). */\nexport interface BqueryFetchConfig {\n /** Optional base URL prepended to relative request URLs. */\n baseUrl?: string;\n /** Default request headers. */\n headers?: HeadersInit;\n /** Default response parser. */\n parseAs?: BqueryFetchParseAs;\n}\n\n/** Global cookie defaults used by useCookie(). */\nexport interface BqueryCookieConfig {\n /** Default cookie path. */\n path?: string;\n /** Default SameSite mode. */\n sameSite?: 'Strict' | 'Lax' | 'None';\n /** Whether cookies should be marked secure by default. */\n secure?: boolean;\n}\n\n/** Global announcer defaults used by useAnnouncer(). */\nexport interface BqueryAnnouncerConfig {\n /** Default politeness level. */\n politeness?: 'polite' | 'assertive';\n /** Whether announcements should be treated atomically. */\n atomic?: boolean;\n /** Delay before writing the message into the live region. */\n delay?: number;\n /** Delay after which the live region is cleared automatically. */\n clearDelay?: number;\n}\n\n/** Global page meta defaults used by definePageMeta(). */\nexport interface BqueryPageMetaConfig {\n /** Optional title template function. */\n titleTemplate?: (title: string) => string;\n}\n\n/** Global motion defaults used by transition(). */\nexport interface BqueryTransitionConfig {\n /** Skip transitions when reduced motion is preferred. */\n skipOnReducedMotion?: boolean;\n /** Classes applied to the root element during transitions. */\n classes?: string[];\n /** Transition type identifiers added when supported by the browser. */\n types?: string[];\n}\n\n/** Global default component library configuration. */\nexport interface BqueryComponentLibraryConfig {\n /** Prefix used by registerDefaultComponents(). */\n prefix?: string;\n}\n\n/** Complete global bQuery configuration object. */\nexport interface BqueryConfig {\n /** Fetch composable defaults. */\n fetch?: BqueryFetchConfig;\n /** Cookie composable defaults. */\n cookies?: BqueryCookieConfig;\n /** Announcer composable defaults. */\n announcer?: BqueryAnnouncerConfig;\n /** Page metadata defaults. */\n pageMeta?: BqueryPageMetaConfig;\n /** View transition defaults. */\n transitions?: BqueryTransitionConfig;\n /** Default component library options. */\n components?: BqueryComponentLibraryConfig;\n}\n\nconst defaultConfig: BqueryConfig = {\n fetch: {\n headers: {},\n parseAs: 'json',\n },\n cookies: {\n path: '/',\n sameSite: 'Lax',\n secure: false,\n },\n announcer: {\n politeness: 'polite',\n atomic: true,\n delay: 16,\n clearDelay: 1000,\n },\n pageMeta: {},\n transitions: {\n skipOnReducedMotion: false,\n classes: [],\n types: [],\n },\n components: {\n prefix: 'bq',\n },\n};\n\nconst cloneConfigValue = <T>(value: T): T => {\n if (typeof Headers !== 'undefined' && value instanceof Headers) {\n return new Headers(value) as T;\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => cloneConfigValue(entry)) as T;\n }\n\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = cloneConfigValue(entry);\n }\n return result as T;\n }\n\n return value;\n};\n\nlet currentConfig: BqueryConfig = cloneConfigValue(defaultConfig);\n\n/**\n * Define or extend the global bQuery configuration.\n *\n * @param config - Partial configuration values to merge into the current config\n * @returns The resolved configuration after merging\n *\n * @example\n * ```ts\n * defineBqueryConfig({\n * fetch: { baseUrl: 'https://api.example.com' },\n * components: { prefix: 'ui' },\n * });\n * ```\n */\nexport const defineBqueryConfig = (config: BqueryConfig): BqueryConfig => {\n currentConfig = cloneConfigValue(\n merge(\n defaultConfig as Record<string, unknown>,\n currentConfig as Record<string, unknown>,\n config as Record<string, unknown>\n ) as BqueryConfig\n );\n return getBqueryConfig();\n};\n\n/**\n * Get the currently resolved bQuery configuration.\n *\n * @returns A cloned snapshot of the active configuration\n */\nexport const getBqueryConfig = (): BqueryConfig => {\n return cloneConfigValue(currentConfig);\n};\n"],"mappings":";AAiFA,IAAM,IAA8B;AAAA,EAClC,OAAO;AAAA,IACL,SAAS,CAAA;AAAA,IACT,SAAS;AAAA;EAEX,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA;EAEV,WAAW;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA;EAEd,UAAU,CAAA;AAAA,EACV,aAAa;AAAA,IACX,qBAAqB;AAAA,IACrB,SAAS,CAAA;AAAA,IACT,OAAO,CAAA;AAAA;EAET,YAAY,EACV,QAAQ,KAAA;GAIN,IAAA,CAAuB,MAAgB;AAC3C,MAAI,OAAO,UAAY,OAAe,aAAiB,QACrD,QAAO,IAAI,QAAQ,CAAA;AAGrB,MAAI,MAAM,QAAQ,CAAA,EAChB,QAAO,EAAM,IAAA,CAAK,MAAU,EAAiB,CAAA,CAAM;AAGrD,MAAI,EAAc,CAAA,GAAQ;AACxB,UAAM,IAAkC,CAAA;AACxC,eAAW,CAAC,GAAK,CAAA,KAAU,OAAO,QAAQ,CAAA,EACxC,CAAA,EAAO,CAAA,IAAO,EAAiB,CAAA;AAEjC,WAAO;AAAA;AAGT,SAAO;GAGL,IAA8B,EAAiB,CAAA,GAgBtC,IAAA,CAAsB,OACjC,IAAgB,EACd,EACE,GACA,GACA,CAAA,CACD,GAEI,EAAA,IAQI,IAAA,MACJ,EAAiB,CAAA"}
1
+ {"version":3,"file":"config-DhT9auRm.js","names":[],"sources":["../src/platform/config.ts"],"sourcesContent":["/**\n * Global bQuery configuration helpers.\n *\n * @module bquery/platform\n */\n\nimport { isPlainObject, merge } from '../core/utils/object';\n\n/** Supported response parsing strategies for fetch composables. */\nexport type BqueryFetchParseAs = 'json' | 'text' | 'blob' | 'arrayBuffer' | 'formData' | 'response';\n\n/** Global fetch defaults used by useFetch(). */\nexport interface BqueryFetchConfig {\n /** Optional base URL prepended to relative request URLs. */\n baseUrl?: string;\n /** Default request headers. */\n headers?: HeadersInit;\n /** Default response parser. */\n parseAs?: BqueryFetchParseAs;\n}\n\n/** Global cookie defaults used by useCookie(). */\nexport interface BqueryCookieConfig {\n /** Default cookie path. */\n path?: string;\n /** Default SameSite mode. */\n sameSite?: 'Strict' | 'Lax' | 'None';\n /** Whether cookies should be marked secure by default. */\n secure?: boolean;\n}\n\n/** Global announcer defaults used by useAnnouncer(). */\nexport interface BqueryAnnouncerConfig {\n /** Default politeness level. */\n politeness?: 'polite' | 'assertive';\n /** Whether announcements should be treated atomically. */\n atomic?: boolean;\n /** Delay before writing the message into the live region. */\n delay?: number;\n /** Delay after which the live region is cleared automatically. */\n clearDelay?: number;\n}\n\n/** Global page meta defaults used by definePageMeta(). */\nexport interface BqueryPageMetaConfig {\n /** Optional title template function. */\n titleTemplate?: (title: string) => string;\n}\n\n/** Global motion defaults used by transition(). */\nexport interface BqueryTransitionConfig {\n /** Skip transitions when reduced motion is preferred. */\n skipOnReducedMotion?: boolean;\n /** Classes applied to the root element during transitions. */\n classes?: string[];\n /** Transition type identifiers added when supported by the browser. */\n types?: string[];\n}\n\n/** Global default component library configuration. */\nexport interface BqueryComponentLibraryConfig {\n /** Prefix used by registerDefaultComponents(). */\n prefix?: string;\n}\n\n/** Complete global bQuery configuration object. */\nexport interface BqueryConfig {\n /** Fetch composable defaults. */\n fetch?: BqueryFetchConfig;\n /** Cookie composable defaults. */\n cookies?: BqueryCookieConfig;\n /** Announcer composable defaults. */\n announcer?: BqueryAnnouncerConfig;\n /** Page metadata defaults. */\n pageMeta?: BqueryPageMetaConfig;\n /** View transition defaults. */\n transitions?: BqueryTransitionConfig;\n /** Default component library options. */\n components?: BqueryComponentLibraryConfig;\n}\n\nconst defaultConfig: BqueryConfig = {\n fetch: {\n headers: {},\n parseAs: 'json',\n },\n cookies: {\n path: '/',\n sameSite: 'Lax',\n secure: false,\n },\n announcer: {\n politeness: 'polite',\n atomic: true,\n delay: 16,\n clearDelay: 1000,\n },\n pageMeta: {},\n transitions: {\n skipOnReducedMotion: false,\n classes: [],\n types: [],\n },\n components: {\n prefix: 'bq',\n },\n};\n\nconst cloneConfigValue = <T>(value: T): T => {\n if (typeof Headers !== 'undefined' && value instanceof Headers) {\n return new Headers(value) as T;\n }\n\n if (Array.isArray(value)) {\n return value.map((entry) => cloneConfigValue(entry)) as T;\n }\n\n if (isPlainObject(value)) {\n const result: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value)) {\n result[key] = cloneConfigValue(entry);\n }\n return result as T;\n }\n\n return value;\n};\n\nlet currentConfig: BqueryConfig = cloneConfigValue(defaultConfig);\n\n/**\n * Define or extend the global bQuery configuration.\n *\n * @param config - Partial configuration values to merge into the current config\n * @returns The resolved configuration after merging\n *\n * @example\n * ```ts\n * defineBqueryConfig({\n * fetch: { baseUrl: 'https://api.example.com' },\n * components: { prefix: 'ui' },\n * });\n * ```\n */\nexport const defineBqueryConfig = (config: BqueryConfig): BqueryConfig => {\n currentConfig = cloneConfigValue(\n merge(\n defaultConfig as Record<string, unknown>,\n currentConfig as Record<string, unknown>,\n config as Record<string, unknown>\n ) as BqueryConfig\n );\n return getBqueryConfig();\n};\n\n/**\n * Get the currently resolved bQuery configuration.\n *\n * @returns A cloned snapshot of the active configuration\n */\nexport const getBqueryConfig = (): BqueryConfig => {\n return cloneConfigValue(currentConfig);\n};\n"],"mappings":";AAiFA,IAAM,IAA8B;AAAA,EAClC,OAAO;AAAA,IACL,SAAS,CAAA;AAAA,IACT,SAAS;AAAA;EAEX,SAAS;AAAA,IACP,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA;EAEV,WAAW;AAAA,IACT,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA;EAEd,UAAU,CAAA;AAAA,EACV,aAAa;AAAA,IACX,qBAAqB;AAAA,IACrB,SAAS,CAAA;AAAA,IACT,OAAO,CAAA;AAAA;EAET,YAAY,EACV,QAAQ,KAAA;GAIN,IAAA,CAAuB,MAAgB;AAC3C,MAAI,OAAO,UAAY,OAAe,aAAiB,QACrD,QAAO,IAAI,QAAQ,CAAA;AAGrB,MAAI,MAAM,QAAQ,CAAA,EAChB,QAAO,EAAM,IAAA,CAAK,MAAU,EAAiB,CAAA,CAAM;AAGrD,MAAI,EAAc,CAAA,GAAQ;AACxB,UAAM,IAAkC,CAAA;AACxC,eAAW,CAAC,GAAK,CAAA,KAAU,OAAO,QAAQ,CAAA,EACxC,CAAA,EAAO,CAAA,IAAO,EAAiB,CAAA;AAEjC,WAAO;AAAA;AAGT,SAAO;GAGL,IAA8B,EAAiB,CAAA,GAgBtC,IAAA,CAAsB,OACjC,IAAgB,EACd,EACE,GACA,GACA,CAAA,CACD,GAEI,EAAA,IAQI,IAAA,MACJ,EAAiB,CAAA"}
@@ -97,4 +97,4 @@ export {
97
97
  h as t
98
98
  };
99
99
 
100
- //# sourceMappingURL=constraints-3lV9yyBw.js.map
100
+ //# sourceMappingURL=constraints-D5RHQLmP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints-D5RHQLmP.js","names":[],"sources":["../src/router/constraints.ts"],"sourcesContent":["/**\n * Shared helpers for validating and normalizing route param constraints.\n * @internal\n */\n\nconst MAX_ROUTE_CONSTRAINT_CACHE_SIZE = 128;\nconst normalizedConstraintCache = new Map<string, string>();\nconst compiledConstraintRegexCache = new Map<string, RegExp>();\n\nconst setBoundedCacheEntry = <T>(cache: Map<string, T>, key: string, value: T): void => {\n if (cache.has(key)) {\n cache.delete(key);\n }\n\n cache.set(key, value);\n\n if (cache.size <= MAX_ROUTE_CONSTRAINT_CACHE_SIZE) {\n return;\n }\n\n const oldestKey = cache.keys().next().value;\n if (oldestKey !== undefined) {\n cache.delete(oldestKey);\n }\n};\n\n/**\n * Detects potentially super-linear (ReDoS) patterns caused by quantified\n * groups that already contain inner quantifiers, such as `(a+)+` or `(a*)*`.\n * @internal\n */\nconst hasNestedQuantifier = (pattern: string): boolean => {\n const groupQuantifierStack: boolean[] = [];\n let inCharClass = false;\n\n for (let i = 0; i < pattern.length; i++) {\n const ch = pattern[i];\n\n if (ch === '\\\\' && i + 1 < pattern.length) {\n i++;\n continue;\n }\n\n if (ch === '[' && !inCharClass) {\n inCharClass = true;\n continue;\n }\n if (ch === ']' && inCharClass) {\n inCharClass = false;\n continue;\n }\n if (inCharClass) continue;\n\n if (ch === '(') {\n groupQuantifierStack.push(false);\n continue;\n }\n\n if (ch === ')') {\n const groupHasInnerQuantifier = groupQuantifierStack.pop() ?? false;\n // Check if the closing paren is followed by a quantifier\n const next = pattern[i + 1];\n if (\n groupHasInnerQuantifier &&\n (next === '+' || next === '*' || next === '?' || next === '{')\n ) {\n return true;\n }\n if (groupHasInnerQuantifier && groupQuantifierStack.length > 0) {\n groupQuantifierStack[groupQuantifierStack.length - 1] = true;\n }\n continue;\n }\n\n if (groupQuantifierStack.length > 0) {\n if (ch === '?' && i > 0 && pattern[i - 1] === '(') {\n continue;\n }\n\n if (ch === '+' || ch === '*' || ch === '?' || ch === '{') {\n groupQuantifierStack[groupQuantifierStack.length - 1] = true;\n }\n }\n }\n\n return false;\n};\n\nconst normalizeConstraintCaptures = (constraint: string): string => {\n let normalized = '';\n let inCharacterClass = false;\n\n for (let i = 0; i < constraint.length; i++) {\n const char = constraint[i];\n\n if (char === '\\\\' && i + 1 < constraint.length) {\n if (!inCharacterClass && constraint[i + 1] >= '1' && constraint[i + 1] <= '9') {\n throw new Error(\n `bQuery router: Route constraints cannot use backreferences: \"${constraint}\".`\n );\n }\n\n if (!inCharacterClass && constraint[i + 1] === 'k' && constraint[i + 2] === '<') {\n throw new Error(\n `bQuery router: Route constraints cannot use backreferences: \"${constraint}\".`\n );\n }\n\n normalized += char + constraint[i + 1];\n i++;\n continue;\n }\n\n if (char === '[' && !inCharacterClass) {\n inCharacterClass = true;\n normalized += char;\n continue;\n }\n\n if (char === ']' && inCharacterClass) {\n inCharacterClass = false;\n normalized += char;\n continue;\n }\n\n if (!inCharacterClass && char === '(') {\n if (i + 1 < constraint.length && constraint[i + 1] === '?') {\n if (constraint[i + 2] === '<') {\n if (constraint[i + 3] === '=' || constraint[i + 3] === '!') {\n normalized += '(';\n continue;\n }\n\n const namedCaptureEnd = constraint.indexOf('>', i + 3);\n if (namedCaptureEnd === -1) {\n throw new Error(\n `bQuery router: Invalid route constraint named capture group: \"${constraint}\".`\n );\n }\n normalized += '(?:';\n i = namedCaptureEnd;\n continue;\n }\n\n normalized += '(';\n continue;\n }\n\n normalized += '(?:';\n continue;\n }\n\n normalized += char;\n }\n\n return normalized;\n};\n\nexport const getNormalizedRouteConstraint = (constraint: string): string => {\n const cached = normalizedConstraintCache.get(constraint);\n if (cached !== undefined) {\n return cached;\n }\n\n const normalized = normalizeConstraintCaptures(constraint);\n setBoundedCacheEntry(normalizedConstraintCache, constraint, normalized);\n return normalized;\n};\n\nexport const getRouteConstraintRegex = (constraint: string): RegExp => {\n const normalizedConstraint = getNormalizedRouteConstraint(constraint);\n const cached = compiledConstraintRegexCache.get(normalizedConstraint);\n if (cached) {\n return cached;\n }\n\n if (hasNestedQuantifier(normalizedConstraint)) {\n throw new Error(\n `bQuery router: Route constraint contains a potentially catastrophic (ReDoS) pattern. Nested quantifiers are not allowed: \"${constraint}\".`\n );\n }\n\n try {\n const compiled = new RegExp(`^(?:${normalizedConstraint})$`);\n setBoundedCacheEntry(compiledConstraintRegexCache, normalizedConstraint, compiled);\n return compiled;\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error(\n `bQuery router: Invalid route constraint regex \"${constraint}\": ${error.message}`\n );\n }\n throw error;\n }\n};\n\nexport const routeConstraintMatches = (constraint: string, value: string): boolean => {\n return getRouteConstraintRegex(constraint).test(value);\n};\n\nexport const clearRouteConstraintCache = (): void => {\n normalizedConstraintCache.clear();\n compiledConstraintRegexCache.clear();\n};\n"],"mappings":"AAKA,IAAM,IAAkC,KAClC,IAA4B,oBAAI,IAAA,GAChC,IAA+B,oBAAI,IAAA,GAEnC,IAAA,CAA2B,GAAuB,GAAa,MAAmB;AAOtF,MANI,EAAM,IAAI,CAAA,KACZ,EAAM,OAAO,CAAA,GAGf,EAAM,IAAI,GAAK,CAAA,GAEX,EAAM,QAAQ,EAChB;AAGF,QAAM,IAAY,EAAM,KAAA,EAAO,KAAA,EAAO;AACtC,EAAI,MAAc,UAChB,EAAM,OAAO,CAAA;GASX,IAAA,CAAuB,MAA6B;AACxD,QAAM,IAAkC,CAAA;AACxC,MAAI,IAAc;AAElB,WAAS,IAAI,GAAG,IAAI,EAAQ,QAAQ,KAAK;AACvC,UAAM,IAAK,EAAQ,CAAA;AAEnB,QAAI,MAAO,QAAQ,IAAI,IAAI,EAAQ,QAAQ;AACzC,MAAA;AACA;AAAA;AAGF,QAAI,MAAO,OAAO,CAAC,GAAa;AAC9B,MAAA,IAAc;AACd;AAAA;AAEF,QAAI,MAAO,OAAO,GAAa;AAC7B,MAAA,IAAc;AACd;AAAA;AAEF,QAAI,CAAA,GAEJ;AAAA,UAAI,MAAO,KAAK;AACd,QAAA,EAAqB,KAAK,EAAA;AAC1B;AAAA;AAGF,UAAI,MAAO,KAAK;AACd,cAAM,IAA0B,EAAqB,IAAA,KAAS,IAExD,IAAO,EAAQ,IAAI,CAAA;AACzB,YACE,MACC,MAAS,OAAO,MAAS,OAAO,MAAS,OAAO,MAAS,KAE1D,QAAO;AAET,QAAI,KAA2B,EAAqB,SAAS,MAC3D,EAAqB,EAAqB,SAAS,CAAA,IAAK;AAE1D;AAAA;AAGF,UAAI,EAAqB,SAAS,GAAG;AACnC,YAAI,MAAO,OAAO,IAAI,KAAK,EAAQ,IAAI,CAAA,MAAO,IAC5C;AAGF,SAAI,MAAO,OAAO,MAAO,OAAO,MAAO,OAAO,MAAO,SACnD,EAAqB,EAAqB,SAAS,CAAA,IAAK;AAAA;;;AAK9D,SAAO;GAGH,IAAA,CAA+B,MAA+B;AAClE,MAAI,IAAa,IACb,IAAmB;AAEvB,WAAS,IAAI,GAAG,IAAI,EAAW,QAAQ,KAAK;AAC1C,UAAM,IAAO,EAAW,CAAA;AAExB,QAAI,MAAS,QAAQ,IAAI,IAAI,EAAW,QAAQ;AAC9C,UAAI,CAAC,KAAoB,EAAW,IAAI,CAAA,KAAM,OAAO,EAAW,IAAI,CAAA,KAAM,IACxE,OAAM,IAAI,MACR,gEAAgE,CAAA,IAAW;AAI/E,UAAI,CAAC,KAAoB,EAAW,IAAI,CAAA,MAAO,OAAO,EAAW,IAAI,CAAA,MAAO,IAC1E,OAAM,IAAI,MACR,gEAAgE,CAAA,IAAW;AAI/E,MAAA,KAAc,IAAO,EAAW,IAAI,CAAA,GACpC;AACA;AAAA;AAGF,QAAI,MAAS,OAAO,CAAC,GAAkB;AACrC,MAAA,IAAmB,IACnB,KAAc;AACd;AAAA;AAGF,QAAI,MAAS,OAAO,GAAkB;AACpC,MAAA,IAAmB,IACnB,KAAc;AACd;AAAA;AAGF,QAAI,CAAC,KAAoB,MAAS,KAAK;AACrC,UAAI,IAAI,IAAI,EAAW,UAAU,EAAW,IAAI,CAAA,MAAO,KAAK;AAC1D,YAAI,EAAW,IAAI,CAAA,MAAO,KAAK;AAC7B,cAAI,EAAW,IAAI,CAAA,MAAO,OAAO,EAAW,IAAI,CAAA,MAAO,KAAK;AAC1D,YAAA,KAAc;AACd;AAAA;AAGF,gBAAM,IAAkB,EAAW,QAAQ,KAAK,IAAI,CAAA;AACpD,cAAI,MAAoB,GACtB,OAAM,IAAI,MACR,iEAAiE,CAAA,IAAW;AAGhF,UAAA,KAAc,OACd,IAAI;AACJ;AAAA;AAGF,QAAA,KAAc;AACd;AAAA;AAGF,MAAA,KAAc;AACd;AAAA;AAGF,IAAA,KAAc;AAAA;AAGhB,SAAO;GAGI,IAAA,CAAgC,MAA+B;AAC1E,QAAM,IAAS,EAA0B,IAAI,CAAA;AAC7C,MAAI,MAAW,OACb,QAAO;AAGT,QAAM,IAAa,EAA4B,CAAA;AAC/C,SAAA,EAAqB,GAA2B,GAAY,CAAA,GACrD;GAGI,IAAA,CAA2B,MAA+B;AACrE,QAAM,IAAuB,EAA6B,CAAA,GACpD,IAAS,EAA6B,IAAI,CAAA;AAChD,MAAI,EACF,QAAO;AAGT,MAAI,EAAoB,CAAA,EACtB,OAAM,IAAI,MACR,6HAA6H,CAAA,IAAW;AAI5I,MAAI;AACF,UAAM,IAAW,IAAI,OAAO,OAAO,CAAA,IAAqB;AACxD,WAAA,EAAqB,GAA8B,GAAsB,CAAA,GAClE;AAAA,WACA,GAAO;AACd,UAAI,aAAiB,cACb,IAAI,MACR,kDAAkD,CAAA,MAAgB,EAAM,OAAA,EAAA,IAGtE;AAAA"}
@@ -215,6 +215,18 @@ export declare class BQueryCollection {
215
215
  top: number;
216
216
  left: number;
217
217
  };
218
+ /**
219
+ * Gets the inner width of the first element (content + padding, excluding border).
220
+ *
221
+ * @returns Inner width in pixels, or 0 when the collection is empty
222
+ */
223
+ innerWidth(): number;
224
+ /**
225
+ * Gets the inner height of the first element (content + padding, excluding border).
226
+ *
227
+ * @returns Inner height in pixels, or 0 when the collection is empty
228
+ */
229
+ innerHeight(): number;
218
230
  /**
219
231
  * Gets the outer width of the first element, optionally including margins.
220
232
  *
@@ -326,6 +338,80 @@ export declare class BQueryCollection {
326
338
  * ```
327
339
  */
328
340
  find(selector: string): BQueryCollection;
341
+ /**
342
+ * Gets the closest element or ancestor matching a selector for each element in
343
+ * the collection, including the element itself. Duplicates are removed from the
344
+ * result.
345
+ *
346
+ * @param selector - CSS selector to match
347
+ * @returns A new BQueryCollection with matching elements or ancestors
348
+ *
349
+ * @example
350
+ * ```ts
351
+ * $$('.item').closest('.container');
352
+ * ```
353
+ */
354
+ closest(selector: string): BQueryCollection;
355
+ /**
356
+ * Gets the parent element of each element in the collection.
357
+ * Duplicates are removed (e.g. siblings sharing a parent).
358
+ *
359
+ * @returns A new BQueryCollection with unique parent elements
360
+ *
361
+ * @example
362
+ * ```ts
363
+ * $$('.item').parent().addClass('has-items');
364
+ * ```
365
+ */
366
+ parent(): BQueryCollection;
367
+ /**
368
+ * Gets the direct children of every element in the collection.
369
+ * Duplicates are removed from the result.
370
+ *
371
+ * @returns A new BQueryCollection with child elements
372
+ *
373
+ * @example
374
+ * ```ts
375
+ * $$('.list').children().addClass('child');
376
+ * ```
377
+ */
378
+ children(): BQueryCollection;
379
+ /**
380
+ * Gets all siblings of every element in the collection (excluding the
381
+ * elements themselves). Duplicates are removed.
382
+ *
383
+ * @returns A new BQueryCollection with sibling elements
384
+ *
385
+ * @example
386
+ * ```ts
387
+ * $$('.active').siblings().removeClass('active');
388
+ * ```
389
+ */
390
+ siblings(): BQueryCollection;
391
+ /**
392
+ * Gets the next sibling element of each element in the collection.
393
+ * Elements without a next sibling are skipped.
394
+ *
395
+ * @returns A new BQueryCollection with next sibling elements
396
+ *
397
+ * @example
398
+ * ```ts
399
+ * $$('.current').next().addClass('upcoming');
400
+ * ```
401
+ */
402
+ next(): BQueryCollection;
403
+ /**
404
+ * Gets the previous sibling element of each element in the collection.
405
+ * Elements without a previous sibling are skipped.
406
+ *
407
+ * @returns A new BQueryCollection with previous sibling elements
408
+ *
409
+ * @example
410
+ * ```ts
411
+ * $$('.current').prev().addClass('previous');
412
+ * ```
413
+ */
414
+ prev(): BQueryCollection;
329
415
  /**
330
416
  * Removes all elements from the DOM.
331
417
  *
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/core/collection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../../src/core/collection.ts"],"names":[],"mappings":"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"}
@@ -216,6 +216,34 @@ export declare class BQueryElement {
216
216
  top: number;
217
217
  left: number;
218
218
  };
219
+ /**
220
+ * Gets the inner width of the element (content + padding, excluding border).
221
+ *
222
+ * This corresponds to the element's `clientWidth` and mirrors jQuery's
223
+ * `innerWidth()` method.
224
+ *
225
+ * @returns Inner width in pixels, or 0 for non-HTML elements
226
+ *
227
+ * @example
228
+ * ```ts
229
+ * const innerW = $('#panel').innerWidth();
230
+ * ```
231
+ */
232
+ innerWidth(): number;
233
+ /**
234
+ * Gets the inner height of the element (content + padding, excluding border).
235
+ *
236
+ * This corresponds to the element's `clientHeight` and mirrors jQuery's
237
+ * `innerHeight()` method.
238
+ *
239
+ * @returns Inner height in pixels, or 0 for non-HTML elements
240
+ *
241
+ * @example
242
+ * ```ts
243
+ * const innerH = $('#panel').innerHeight();
244
+ * ```
245
+ */
246
+ innerHeight(): number;
219
247
  /**
220
248
  * Gets the outer width of the element, optionally including margins.
221
249
  *
@@ -1 +1 @@
1
- {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/core/element.ts"],"names":[],"mappings":"AAsHA,qBAAa,aAAa;IAYZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IAXpC;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA2D;IAE7F;;;OAGG;gBAC0B,OAAO,EAAE,OAAO;IAE7C;;;OAGG;IACH,IAAI,GAAG,IAAI,OAAO,CAEjB;IAED;;;OAGG;IACH,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAKvC,kCAAkC;IAClC,WAAW,CAAC,GAAG,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI;IAK1C,8BAA8B;IAC9B,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAKrD,+BAA+B;IAC/B,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQjD,2BAA2B;IAC3B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK9B,kCAAkC;IAClC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAW/C,6BAA6B;IAC7B,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAQ7E,kDAAkD;IAClD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASjD,+BAA+B;IAC/B,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAQnC,iDAAiD;IACjD;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzB;;;;;;;;OAQG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK/B;;;;;;;;;;;;;;;;;;OAkBG;IACH,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAC7B,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAC1C,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAoB3C;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI;IAKnD;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI;IAKpD;;;;;OAKG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI;IAKnD;;;;;OAKG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,GAAG,IAAI;IAKlD;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAOrC;;;;;;;;;;;;;;;;OAgBG;IACH,MAAM,IAAI,IAAI;IASd;;;;;;;;;;OAUG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,aAAa;IAMrD;;;;;;;;;;;OAWG;IACH,MAAM,IAAI,IAAI;IAId;;;;;;;;;OASG;IACH,KAAK,IAAI,MAAM;IAQf;;;;;;;;;OASG;IACH,QAAQ,IAAI,SAAS,EAAE;IAIvB;;;;;;;;;OASG;IACH,YAAY,IAAI,OAAO,GAAG,IAAI;IAI9B;;;;;;;;;OASG;IACH,QAAQ,IAAI;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAYzC;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAIlD;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAInD;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,OAAO,GAAE,qBAAqB,GAAG,OAAgC,GAAG,IAAI;IAKjF;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAKd;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAKb;;;;;OAKG;IACH,KAAK,CAAC,IAAI,GAAE,OAAc,GAAG,aAAa;IAI1C;;;;;OAKG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE;IAIjC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAIzC;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI;IAIzC;;;;OAIG;IACH,MAAM,IAAI,OAAO,GAAG,IAAI;IAIxB;;;;OAIG;IACH,QAAQ,IAAI,OAAO,EAAE;IAIrB;;;;OAIG;IACH,QAAQ,IAAI,OAAO,EAAE;IAMrB;;;;OAIG;IACH,IAAI,IAAI,OAAO,GAAG,IAAI;IAItB;;;;OAIG;IACH,IAAI,IAAI,OAAO,GAAG,IAAI;IAItB;;;;;;OAMG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI;IAKpE;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAKjD;;;;;;OAMG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,kCAAkC,GAAG,IAAI;IAKrE;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAK9C;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,QAAQ,CACN,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAC/C,IAAI;IAmBP;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,GAC/C,IAAI;IAoBP;;;;;OAKG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIlC;;;;;;;;;;;;OAYG;IACH,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI7B;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC;;;;;OAKG;IACH,IAAI,CAAC,OAAO,GAAE,MAAW,GAAG,IAAI;IAMhC;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAKZ;;;;;OAKG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI;IAM7B;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAKb;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAKZ;;;;;OAKG;IACH,GAAG,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASrC;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAyB9C;;;;;;;;;;OAUG;IACH,eAAe,IAAI,MAAM;IAezB;;;;OAIG;IACH,IAAI,IAAI,OAAO;IAIf;;;;OAIG;IACH,MAAM,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAUtE;;;OAGG;IACH,OAAO,CAAC,aAAa;CAGtB"}
1
+ {"version":3,"file":"element.d.ts","sourceRoot":"","sources":["../../src/core/element.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,12 @@ export declare const toElementList: (input: Element | ElementList) => ElementLis
6
6
  export declare const applyAll: (elements: ElementList, action: (el: Element) => void) => void;
7
7
  /** @internal */
8
8
  export declare const isHTMLElement: (element: Element | null | undefined) => element is HTMLElement;
9
+ /**
10
+ * Gets an element's inner size (content + padding, excluding border and margin).
11
+ *
12
+ * @internal
13
+ */
14
+ export declare const getInnerSize: (element: Element | null | undefined, dimension: "width" | "height") => number;
9
15
  /**
10
16
  * Gets an element's outer size, optionally including margins.
11
17
  *