@stacksjs/stx 0.2.94 → 0.2.96

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 (614) hide show
  1. package/dist/a11y.js +598 -2
  2. package/dist/analytics.js +159 -2
  3. package/dist/analyzer.js +240 -2
  4. package/dist/animation.js +688 -2
  5. package/dist/app-shell.js +220 -2
  6. package/dist/app.js +79 -2
  7. package/dist/assets.js +155 -2
  8. package/dist/ast.js +630 -2
  9. package/dist/async-components.js +428 -2
  10. package/dist/auth.js +12 -2
  11. package/dist/broadcasting.js +102 -2
  12. package/dist/browser-composables.js +565 -2
  13. package/dist/build-assets.js +29 -2
  14. package/dist/build-mode-detector.js +50 -2
  15. package/dist/build-optimizer.js +433 -2
  16. package/dist/build-views.js +180 -2
  17. package/dist/build.js +33 -2
  18. package/dist/builtins/drawer.js +37 -2
  19. package/dist/builtins/escape.js +3 -2
  20. package/dist/builtins/icon.js +83 -2
  21. package/dist/builtins/index.js +34 -2
  22. package/dist/builtins/modal.js +38 -2
  23. package/dist/builtins/safe-image.js +51 -2
  24. package/dist/builtins/stx-image.js +200 -2
  25. package/dist/builtins/stx-link.js +41 -2
  26. package/dist/builtins/stx-loading-indicator.js +35 -2
  27. package/dist/builtins/suspense.js +24 -2
  28. package/dist/builtins/toast.js +42 -2
  29. package/dist/builtins/tooltip.js +106 -2
  30. package/dist/builtins/transition-group.js +22 -2
  31. package/dist/bundle-analyzer/collector.js +233 -2
  32. package/dist/bundle-analyzer/index.js +82 -2
  33. package/dist/bundle-analyzer/report.js +318 -2
  34. package/dist/bundle-analyzer/treemap.js +594 -2
  35. package/dist/caching.js +131 -2
  36. package/dist/cli.js +11317 -10982
  37. package/dist/client/directive.js +14 -2
  38. package/dist/client/index.js +2 -2
  39. package/dist/client-helpers.js +312 -2
  40. package/dist/client-script-bundler.js +216 -6
  41. package/dist/client-script.js +754 -2
  42. package/dist/client.js +73 -4
  43. package/dist/component-hmr.js +585 -2
  44. package/dist/component-library.d.ts +6 -0
  45. package/dist/component-library.js +683 -0
  46. package/dist/component-processing.js +613 -2
  47. package/dist/component-registry.js +90 -2
  48. package/dist/component-renderer.js +660 -2
  49. package/dist/components.js +213 -2
  50. package/dist/composables/index.js +220 -2
  51. package/dist/composables/use-battery.js +101 -2
  52. package/dist/composables/use-broadcast-channel.js +80 -2
  53. package/dist/composables/use-channel.js +124 -2
  54. package/dist/composables/use-clipboard.js +79 -2
  55. package/dist/composables/use-color-mode.js +131 -2
  56. package/dist/composables/use-cookie.js +86 -2
  57. package/dist/composables/use-device-orientation.js +181 -2
  58. package/dist/composables/use-event-listener.js +27 -2
  59. package/dist/composables/use-event-source.js +166 -2
  60. package/dist/composables/use-eye-dropper.js +142 -2
  61. package/dist/composables/use-fetch.js +223 -2
  62. package/dist/composables/use-fullscreen.js +110 -2
  63. package/dist/composables/use-geolocation.js +101 -2
  64. package/dist/composables/use-idle.js +182 -2
  65. package/dist/composables/use-intersection-observer.js +168 -2
  66. package/dist/composables/use-keyboard.js +224 -2
  67. package/dist/composables/use-media-query.js +62 -2
  68. package/dist/composables/use-meta.js +48 -2
  69. package/dist/composables/use-mouse.js +286 -2
  70. package/dist/composables/use-mutation-observer.js +129 -2
  71. package/dist/composables/use-network.js +85 -2
  72. package/dist/composables/use-notification.js +94 -2
  73. package/dist/composables/use-permissions.js +132 -2
  74. package/dist/composables/use-query.js +0 -1
  75. package/dist/composables/use-resize-observer.js +157 -2
  76. package/dist/composables/use-router.js +51 -2
  77. package/dist/composables/use-share.js +104 -2
  78. package/dist/composables/use-speech.js +294 -2
  79. package/dist/composables/use-storage.js +130 -2
  80. package/dist/composables/use-text-selection.js +205 -4
  81. package/dist/composables/use-timer.js +183 -2
  82. package/dist/composables/use-utilities.js +176 -2
  83. package/dist/composables/use-wake-lock.js +122 -2
  84. package/dist/composables/use-websocket.js +165 -2
  85. package/dist/composables/use-window.js +163 -2
  86. package/dist/composables.js +552 -2
  87. package/dist/composition-api.js +190 -2
  88. package/dist/computed.js +376 -8
  89. package/dist/conditionals.js +599 -2
  90. package/dist/config.js +751 -2
  91. package/dist/craft-bridge.js +432 -2
  92. package/dist/craft-compiler.js +810 -2
  93. package/dist/craft-components.js +945 -2
  94. package/dist/craft-entry.js +5 -2
  95. package/dist/craft-ssr.js +559 -2
  96. package/dist/csp.js +220 -2
  97. package/dist/csrf.js +38 -2
  98. package/dist/custom-directives.js +136 -2
  99. package/dist/defer.js +156 -2
  100. package/dist/deploy/config-generators.js +214 -2
  101. package/dist/deploy/index.js +203 -2
  102. package/dist/deploy/netlify.js +167 -2
  103. package/dist/dev-server/crosswind.js +379 -2
  104. package/dist/dev-server/index.js +7 -2
  105. package/dist/dev-server/keyboard-shortcuts.js +81 -2
  106. package/dist/dev-server/native-window.js +91 -2
  107. package/dist/dev-server/port-utils.js +40 -2
  108. package/dist/dev-server/serve-app.js +682 -7
  109. package/dist/dev-server/serve-file.js +439 -7
  110. package/dist/dev-server/serve-markdown.js +281 -2
  111. package/dist/dev-server/serve-multi.js +424 -17
  112. package/dist/dev-server/terminal-colors.js +45 -2
  113. package/dist/dev-server/theme-selector.js +111 -2
  114. package/dist/dev-server/types.js +43 -2
  115. package/dist/dev-server.js +4 -2
  116. package/dist/devtools.js +462 -18
  117. package/dist/directive-api.js +355 -2
  118. package/dist/docs.js +567 -2
  119. package/dist/doctor.js +123 -2
  120. package/dist/document-shell.js +105 -2
  121. package/dist/dynamic-components.js +78 -2
  122. package/dist/edge-runtime.js +539 -2
  123. package/dist/env.js +9 -2
  124. package/dist/error-boundaries.js +62 -12
  125. package/dist/error-handling.js +1 -2
  126. package/dist/errors/codes.js +97 -2
  127. package/dist/errors/formatter.js +196 -2
  128. package/dist/errors/index.js +44 -2
  129. package/dist/errors/logger.js +250 -2
  130. package/dist/errors/sanitizer.js +181 -2
  131. package/dist/errors/types.js +86 -2
  132. package/dist/events.js +382 -2
  133. package/dist/expressions.js +650 -2
  134. package/dist/formatter.js +265 -2
  135. package/dist/forms-validation.js +510 -4
  136. package/dist/forms.js +709 -2
  137. package/dist/head.js +224 -2
  138. package/dist/heatmap.js +566 -2
  139. package/dist/hot-reload.js +367 -2
  140. package/dist/html-masking.js +73 -2
  141. package/dist/hydration-runtime.js +195 -2
  142. package/dist/hydration.js +654 -2
  143. package/dist/i18n.js +633 -2
  144. package/dist/image-optimization/auto-sibling.js +88 -2
  145. package/dist/image-optimization/build-plugin.js +241 -2
  146. package/dist/image-optimization/component.js +244 -2
  147. package/dist/image-optimization/directive.js +203 -2
  148. package/dist/image-optimization/index.js +54 -2
  149. package/dist/image-optimization/processor.js +262 -2
  150. package/dist/image-optimization/serve.js +102 -2
  151. package/dist/includes.js +733 -2
  152. package/dist/index.d.ts +1 -0
  153. package/dist/index.js +134 -2
  154. package/dist/init.js +505 -2
  155. package/dist/inline-assets.js +82 -2
  156. package/dist/interactive.js +383 -2
  157. package/dist/internal-markdown.js +141 -2
  158. package/dist/island-chunking.js +52 -2
  159. package/dist/js-ts.js +57 -2
  160. package/dist/jsx-runtime.js +289 -2
  161. package/dist/keep-alive.js +421 -2
  162. package/dist/lazy-loader.js +245 -2
  163. package/dist/loading-indicator.js +322 -2
  164. package/dist/loops.js +643 -2
  165. package/dist/manifest.js +31 -2
  166. package/dist/markdown.js +68 -2
  167. package/dist/media/client/blur-up.js +217 -2
  168. package/dist/media/client/index.js +53 -2
  169. package/dist/media/client/lazy-load.js +283 -2
  170. package/dist/media/client/upload-handler.js +354 -2
  171. package/dist/media/image/component.js +574 -2
  172. package/dist/media/image/directive.js +160 -2
  173. package/dist/media/image/editing.js +193 -2
  174. package/dist/media/image/index.js +80 -2
  175. package/dist/media/image/placeholder.js +188 -2
  176. package/dist/media/image/processor/cache.js +51 -2
  177. package/dist/media/image/processor/index.js +3 -2
  178. package/dist/media/image/processor/optimizer.js +202 -2
  179. package/dist/media/image/processor/responsive.js +162 -2
  180. package/dist/media/image/srcset.js +194 -2
  181. package/dist/media/index.js +198 -2
  182. package/dist/media/manager/embed.js +253 -2
  183. package/dist/media/protected/component.js +235 -2
  184. package/dist/media/protected/index.js +20 -2
  185. package/dist/media/protected/signature.js +205 -2
  186. package/dist/media/shared/cache.js +132 -2
  187. package/dist/media/shared/hash.js +35 -2
  188. package/dist/media/shared/index.js +2 -2
  189. package/dist/media/types.js +0 -1
  190. package/dist/media/upload/component.js +320 -2
  191. package/dist/media/upload/index.js +1 -2
  192. package/dist/media/video/directive.js +142 -2
  193. package/dist/media/video/index.js +583 -2
  194. package/dist/media/video/processor/cache.js +52 -2
  195. package/dist/media/video/processor/index.js +4 -2
  196. package/dist/media/video/processor/streaming.js +197 -2
  197. package/dist/media/video/processor/thumbnail.js +134 -2
  198. package/dist/media/video/processor/transcoder.js +283 -2
  199. package/dist/method-spoofing.js +17 -2
  200. package/dist/middleware.js +40 -2
  201. package/dist/misc-directives.js +222 -2
  202. package/dist/native-build.js +511 -2
  203. package/dist/parser/directive-parser.js +239 -2
  204. package/dist/parser/expression-parser.js +358 -2
  205. package/dist/parser/index.js +23 -2
  206. package/dist/parser/tokenizer.js +534 -2
  207. package/dist/partial-hydration.js +427 -2
  208. package/dist/performance-utils.js +430 -2
  209. package/dist/placeholder.js +35 -2
  210. package/dist/plugin-system.js +214 -2
  211. package/dist/plugin.js +173 -2
  212. package/dist/precompiler.js +660 -81
  213. package/dist/process.js +711 -2
  214. package/dist/production-build.js +596 -2
  215. package/dist/production-builder.js +132 -2
  216. package/dist/production-server.js +188 -2
  217. package/dist/props.js +224 -2
  218. package/dist/public-env.js +19 -2
  219. package/dist/pwa/audit.js +255 -2
  220. package/dist/pwa/directives.js +332 -2
  221. package/dist/pwa/icons.js +109 -2
  222. package/dist/pwa/index.js +47 -2
  223. package/dist/pwa/inject.js +102 -2
  224. package/dist/pwa/manifest.js +186 -2
  225. package/dist/pwa/offline.js +259 -2
  226. package/dist/pwa/precache.js +116 -2
  227. package/dist/pwa/service-worker.js +860 -2
  228. package/dist/pwa/workbox-strategies.js +167 -2
  229. package/dist/pwa/workbox.js +382 -2
  230. package/dist/pwa.js +427 -427
  231. package/dist/reactive-bindings.js +266 -2
  232. package/dist/reactive.js +569 -2
  233. package/dist/reactivity.js +559 -2
  234. package/dist/release.js +1 -2
  235. package/dist/render.js +165 -2
  236. package/dist/route-middleware.js +17 -2
  237. package/dist/router.js +9 -2
  238. package/dist/routes.js +14 -2
  239. package/dist/runtime-injection.js +120 -2
  240. package/dist/runtime.js +94 -2
  241. package/dist/safe-evaluator.js +444 -2
  242. package/dist/scaffolding.js +897 -2
  243. package/dist/screenshot.js +87 -2
  244. package/dist/script-classifier.js +32 -2
  245. package/dist/script-validation.js +158 -2
  246. package/dist/seo.js +457 -2
  247. package/dist/serve.js +237 -2
  248. package/dist/server-bindings.js +108 -2
  249. package/dist/server-components.js +338 -11
  250. package/dist/signal-processing.js +946 -2
  251. package/dist/signals-api.js +154 -2
  252. package/dist/signals.js +5287 -2
  253. package/dist/site-builder/build.js +224 -2
  254. package/dist/site-builder/i18n.js +140 -2
  255. package/dist/site-builder/index.js +15 -2
  256. package/dist/site-builder/robots.js +26 -2
  257. package/dist/site-builder/router.js +27 -2
  258. package/dist/site-builder/seo.js +36 -2
  259. package/dist/site-builder/sitemap.js +26 -2
  260. package/dist/site-builder/theme.js +33 -2
  261. package/dist/site-builder/types.js +0 -1
  262. package/dist/slots.js +201 -2
  263. package/dist/source-maps.js +350 -2
  264. package/dist/spa-shell.js +34 -2
  265. package/dist/ssg.js +389 -389
  266. package/dist/ssr.js +355 -2
  267. package/dist/state-management.js +533 -2
  268. package/dist/store-imports.js +13 -2
  269. package/dist/store-loader.js +72 -5
  270. package/dist/stores-client.js +132 -2
  271. package/dist/story/addons.js +261 -2
  272. package/dist/story/analytics.js +235 -2
  273. package/dist/story/auto-stories.js +158 -2
  274. package/dist/story/bookmarks.js +277 -2
  275. package/dist/story/bun-test.js +102 -2
  276. package/dist/story/cli.js +155 -2
  277. package/dist/story/collect/analyzer.js +305 -2
  278. package/dist/story/collect/index.js +27 -2
  279. package/dist/story/collect/parser.js +129 -2
  280. package/dist/story/collect/scanner.js +101 -2
  281. package/dist/story/collect/tree.js +110 -2
  282. package/dist/story/commands/build.js +172 -2
  283. package/dist/story/commands/dev.js +78 -2
  284. package/dist/story/commands/index.js +3 -2
  285. package/dist/story/commands/preview.js +56 -2
  286. package/dist/story/compiled-output.js +151 -2
  287. package/dist/story/composition.js +261 -2
  288. package/dist/story/config-watcher.js +67 -2
  289. package/dist/story/config.js +64 -2
  290. package/dist/story/context.js +27 -2
  291. package/dist/story/controls/index.js +320 -2
  292. package/dist/story/crosswind.js +189 -2
  293. package/dist/story/desktop-preview.js +105 -2
  294. package/dist/story/docs-generator.js +186 -2
  295. package/dist/story/errors.js +239 -2
  296. package/dist/story/figma-export.js +224 -2
  297. package/dist/story/generator.js +165 -2
  298. package/dist/story/hmr.js +131 -2
  299. package/dist/story/hot-swap.js +207 -2
  300. package/dist/story/index.js +49 -2
  301. package/dist/story/interactions.js +225 -2
  302. package/dist/story/keyboard-shortcuts.js +345 -2
  303. package/dist/story/output.js +153 -2
  304. package/dist/story/performance.js +252 -2
  305. package/dist/story/presets.js +289 -2
  306. package/dist/story/props-validation.js +215 -2
  307. package/dist/story/renderer.js +209 -2
  308. package/dist/story/search-index.js +106 -2
  309. package/dist/story/search.js +140 -2
  310. package/dist/story/server.js +965 -2
  311. package/dist/story/setup.js +78 -2
  312. package/dist/story/snapshots.js +170 -2
  313. package/dist/story/testing.js +163 -2
  314. package/dist/story/theme.js +170 -2
  315. package/dist/story/types.js +0 -2
  316. package/dist/story/ui/code-panel.js +175 -2
  317. package/dist/story/ui/controls-panel.js +168 -2
  318. package/dist/story/ui/index.js +4 -2
  319. package/dist/story/ui/navigation.js +250 -2
  320. package/dist/story/ui/preview.js +251 -2
  321. package/dist/story/visual-testing.js +247 -2
  322. package/dist/streaming.js +537 -2
  323. package/dist/strict-lint.js +288 -2
  324. package/dist/style-scoping.js +50 -2
  325. package/dist/suspense.js +398 -2
  326. package/dist/teleport.js +109 -2
  327. package/dist/template-compiler.js +63 -2
  328. package/dist/template-hydrator.js +82 -2
  329. package/dist/template-tag-balance.js +93 -2
  330. package/dist/testing.js +581 -2
  331. package/dist/transitions.js +443 -2
  332. package/dist/type-checker.js +581 -2
  333. package/dist/types/component-types.d.ts +54 -0
  334. package/dist/types/component-types.js +0 -1
  335. package/dist/types/config-types.js +0 -1
  336. package/dist/types/context-types.js +0 -1
  337. package/dist/types/csp-types.js +0 -1
  338. package/dist/types/directive-types.js +3 -2
  339. package/dist/types/index.d.ts +5 -0
  340. package/dist/types/index.js +1 -2
  341. package/dist/types/pwa-types.js +0 -1
  342. package/dist/types.js +1 -2
  343. package/dist/typescript-templates.js +386 -4
  344. package/dist/utils.js +942 -2
  345. package/dist/validator.js +171 -2
  346. package/dist/variable-extractor.js +1094 -2
  347. package/dist/view-composers.js +29 -2
  348. package/dist/virtual-scrolling.js +454 -2
  349. package/dist/visual-editor.js +688 -28
  350. package/dist/vue-template.js +475 -2
  351. package/dist/web-components/css-scoping.js +177 -2
  352. package/dist/web-components/index.js +13 -2
  353. package/dist/web-components/reactive-generator.js +121 -56
  354. package/dist/web-components.js +1447 -2
  355. package/dist/x-element.js +17 -5
  356. package/package.json +6 -7
  357. package/dist/chunk-03c26pjz.js +0 -3
  358. package/dist/chunk-04mvcmcr.js +0 -106
  359. package/dist/chunk-05hgyyqc.js +0 -4
  360. package/dist/chunk-095s3972.js +0 -99
  361. package/dist/chunk-0b9w2w1y.js +0 -1
  362. package/dist/chunk-0dz85jrp.js +0 -3
  363. package/dist/chunk-0g4gece6.js +0 -4
  364. package/dist/chunk-0jd0pndq.js +0 -3
  365. package/dist/chunk-0jkwrcwj.js +0 -3
  366. package/dist/chunk-0m9tdm7t.js +0 -71
  367. package/dist/chunk-0qakwen3.js +0 -1
  368. package/dist/chunk-0qnz93q2.js +0 -3
  369. package/dist/chunk-0tatqxj2.js +0 -57
  370. package/dist/chunk-0wdar532.js +0 -102
  371. package/dist/chunk-13yz561y.js +0 -3
  372. package/dist/chunk-174z0cd0.js +0 -3
  373. package/dist/chunk-1mmykse5.js +0 -81
  374. package/dist/chunk-1z2yq9em.js +0 -3
  375. package/dist/chunk-1z5nhbjt.js +0 -90
  376. package/dist/chunk-1zgsgk4b.js +0 -1
  377. package/dist/chunk-25s7bckb.js +0 -171
  378. package/dist/chunk-268adc7r.js +0 -2230
  379. package/dist/chunk-26r6zh3t.js +0 -194
  380. package/dist/chunk-2w3302dh.js +0 -3
  381. package/dist/chunk-2xen423s.js +0 -3
  382. package/dist/chunk-39gm08bn.js +0 -39
  383. package/dist/chunk-3bjtemm6.js +0 -128
  384. package/dist/chunk-3jm3snz8.js +0 -3
  385. package/dist/chunk-3ngm57nt.js +0 -12
  386. package/dist/chunk-3rh7va1z.js +0 -3
  387. package/dist/chunk-3yg9hbmb.js +0 -4
  388. package/dist/chunk-44hd3kab.js +0 -1
  389. package/dist/chunk-46mkpbkk.js +0 -12
  390. package/dist/chunk-48cw2nde.js +0 -2
  391. package/dist/chunk-48r3qe0k.js +0 -3
  392. package/dist/chunk-4aj7ftqb.js +0 -1
  393. package/dist/chunk-4bt81cg3.js +0 -61
  394. package/dist/chunk-4j188175.js +0 -3
  395. package/dist/chunk-4k7d8p8d.js +0 -188
  396. package/dist/chunk-4qq8ffke.js +0 -28
  397. package/dist/chunk-50vqeesm.js +0 -142
  398. package/dist/chunk-52agge4n.js +0 -38
  399. package/dist/chunk-55yp0q8t.js +0 -201
  400. package/dist/chunk-57p201gb.js +0 -83
  401. package/dist/chunk-5ggw1dyv.js +0 -3
  402. package/dist/chunk-5kt3ay7x.js +0 -10
  403. package/dist/chunk-5p568px4.js +0 -1166
  404. package/dist/chunk-5ppkfyn2.js +0 -3
  405. package/dist/chunk-5q87fgkk.js +0 -3
  406. package/dist/chunk-5qb761h2.js +0 -3
  407. package/dist/chunk-5xvbq2gs.js +0 -30
  408. package/dist/chunk-647849kf.js +0 -34
  409. package/dist/chunk-6b5k6w2q.js +0 -7
  410. package/dist/chunk-6cr3eeh4.js +0 -23
  411. package/dist/chunk-6djgb0hr.js +0 -3
  412. package/dist/chunk-6dqzky7x.js +0 -35
  413. package/dist/chunk-6e4c6g46.js +0 -3
  414. package/dist/chunk-6w03t7h6.js +0 -3
  415. package/dist/chunk-6wn85hn6.js +0 -4
  416. package/dist/chunk-6y4gqs1q.js +0 -169
  417. package/dist/chunk-75rndzbd.js +0 -6
  418. package/dist/chunk-77tga15w.js +0 -3
  419. package/dist/chunk-7a51hkpf.js +0 -3
  420. package/dist/chunk-7b0xdy5h.js +0 -386
  421. package/dist/chunk-7cgmq685.js +0 -33
  422. package/dist/chunk-7dy588as.js +0 -6
  423. package/dist/chunk-7rvh2wwv.js +0 -721
  424. package/dist/chunk-7sm05m0j.js +0 -351
  425. package/dist/chunk-7sqdeqsw.js +0 -1
  426. package/dist/chunk-7xcfy2fn.js +0 -4
  427. package/dist/chunk-82t27pvd.js +0 -5
  428. package/dist/chunk-87kx8byz.js +0 -1115
  429. package/dist/chunk-8fgwhhb8.js +0 -6
  430. package/dist/chunk-8qbax8xn.js +0 -347
  431. package/dist/chunk-91s2hres.js +0 -8
  432. package/dist/chunk-94g3cahw.js +0 -11
  433. package/dist/chunk-957amb71.js +0 -8
  434. package/dist/chunk-95w08s8v.js +0 -3
  435. package/dist/chunk-9agvhp1x.js +0 -93
  436. package/dist/chunk-9tmbrwwx.js +0 -219
  437. package/dist/chunk-9yz5d003.js +0 -51
  438. package/dist/chunk-a3hyn4we.js +0 -79
  439. package/dist/chunk-a69tvya5.js +0 -53
  440. package/dist/chunk-adjcg6wa.js +0 -498
  441. package/dist/chunk-adqh2m9z.js +0 -45
  442. package/dist/chunk-asarebzq.js +0 -292
  443. package/dist/chunk-aw3rp9ac.js +0 -24
  444. package/dist/chunk-b0cyc09a.js +0 -109
  445. package/dist/chunk-b3kkjcdh.js +0 -3
  446. package/dist/chunk-b3prs7y0.js +0 -5
  447. package/dist/chunk-b5zc9y0y.js +0 -90
  448. package/dist/chunk-baa7h4yz.js +0 -3
  449. package/dist/chunk-bgec9r1v.js +0 -5224
  450. package/dist/chunk-bjnjpsgn.js +0 -3
  451. package/dist/chunk-bk8ew8ze.js +0 -24
  452. package/dist/chunk-bn08k7yy.js +0 -3
  453. package/dist/chunk-bpgg59wa.js +0 -3
  454. package/dist/chunk-bwxda6n1.js +0 -3
  455. package/dist/chunk-bykjk6vj.js +0 -4
  456. package/dist/chunk-c53hyw5c.js +0 -477
  457. package/dist/chunk-c7jg8w13.js +0 -3
  458. package/dist/chunk-ca6qd1dx.js +0 -3
  459. package/dist/chunk-cdbwprfv.js +0 -6
  460. package/dist/chunk-ceg2c2q2.js +0 -11
  461. package/dist/chunk-cn409b69.js +0 -3
  462. package/dist/chunk-cn8az1b4.js +0 -1
  463. package/dist/chunk-cp3kwv17.js +0 -8
  464. package/dist/chunk-cpcc11vp.js +0 -5
  465. package/dist/chunk-cr3wbrcr.js +0 -10
  466. package/dist/chunk-cygfdk1n.js +0 -3
  467. package/dist/chunk-cyp4m0vh.js +0 -16
  468. package/dist/chunk-cz25azze.js +0 -4
  469. package/dist/chunk-d77yxcds.js +0 -3
  470. package/dist/chunk-dvfs1h3c.js +0 -117
  471. package/dist/chunk-dyjnn5k8.js +0 -262
  472. package/dist/chunk-dzw95th7.js +0 -3
  473. package/dist/chunk-e0zytzdh.js +0 -179
  474. package/dist/chunk-e53h9qhd.js +0 -84
  475. package/dist/chunk-eds0f8f1.js +0 -3
  476. package/dist/chunk-eh8hact1.js +0 -5
  477. package/dist/chunk-epj957jf.js +0 -4
  478. package/dist/chunk-eqeyaq6g.js +0 -77
  479. package/dist/chunk-fbxt2mrx.js +0 -5
  480. package/dist/chunk-fch9tk1k.js +0 -3
  481. package/dist/chunk-fe7r1mq1.js +0 -9
  482. package/dist/chunk-fhawx87n.js +0 -8
  483. package/dist/chunk-fk51yyrw.js +0 -3
  484. package/dist/chunk-fms20x0n.js +0 -21
  485. package/dist/chunk-fs0qezn5.js +0 -341
  486. package/dist/chunk-fzm3y0r3.js +0 -267
  487. package/dist/chunk-g2hekckm.js +0 -161
  488. package/dist/chunk-g4ps1dj8.js +0 -140
  489. package/dist/chunk-g8b81pzc.js +0 -3
  490. package/dist/chunk-ganag9dm.js +0 -3
  491. package/dist/chunk-gc84b1d2.js +0 -58
  492. package/dist/chunk-gcf5v18y.js +0 -60
  493. package/dist/chunk-ghrx0hn1.js +0 -4
  494. package/dist/chunk-gqpkp459.js +0 -3
  495. package/dist/chunk-h45py5w5.js +0 -2
  496. package/dist/chunk-h5wa62ek.js +0 -145
  497. package/dist/chunk-h82kjdr4.js +0 -83
  498. package/dist/chunk-haecq01c.js +0 -3
  499. package/dist/chunk-hepg894w.js +0 -3
  500. package/dist/chunk-hjdc99kb.js +0 -3
  501. package/dist/chunk-hje9v2zh.js +0 -3
  502. package/dist/chunk-hjv76kcw.js +0 -1
  503. package/dist/chunk-hke99a0v.js +0 -3
  504. package/dist/chunk-hpqr9e3x.js +0 -3
  505. package/dist/chunk-hq5cem49.js +0 -236
  506. package/dist/chunk-hrampcrj.js +0 -3
  507. package/dist/chunk-ht4j68cs.js +0 -3
  508. package/dist/chunk-hxx3za24.js +0 -62
  509. package/dist/chunk-j4s5qwd7.js +0 -4
  510. package/dist/chunk-jbejwejg.js +0 -8
  511. package/dist/chunk-jc0fc4ht.js +0 -11
  512. package/dist/chunk-jcs0ymw7.js +0 -3
  513. package/dist/chunk-jfm69keq.js +0 -231
  514. package/dist/chunk-jfrn43vh.js +0 -2
  515. package/dist/chunk-jjamhxpm.js +0 -139
  516. package/dist/chunk-jjvp4t5w.js +0 -27
  517. package/dist/chunk-jt44av4j.js +0 -3
  518. package/dist/chunk-jt98jhpt.js +0 -10
  519. package/dist/chunk-k8440jxh.js +0 -6
  520. package/dist/chunk-kdxa9epn.js +0 -21
  521. package/dist/chunk-kfd2hf6f.js +0 -3
  522. package/dist/chunk-kgym7ch9.js +0 -8
  523. package/dist/chunk-kh6rfz2v.js +0 -4
  524. package/dist/chunk-kkp6rs2n.js +0 -36
  525. package/dist/chunk-ktkmvaa8.js +0 -1
  526. package/dist/chunk-m59y310j.js +0 -3
  527. package/dist/chunk-mgmyr1b9.js +0 -6
  528. package/dist/chunk-mqwbpamc.js +0 -3
  529. package/dist/chunk-mrehzhxv.js +0 -5
  530. package/dist/chunk-mv03qb75.js +0 -3
  531. package/dist/chunk-mv4fb50w.js +0 -1
  532. package/dist/chunk-mwbng54r.js +0 -2
  533. package/dist/chunk-n46a5g1g.js +0 -3
  534. package/dist/chunk-n944baxp.js +0 -3
  535. package/dist/chunk-nanw7yhz.js +0 -14
  536. package/dist/chunk-nap11ntr.js +0 -21
  537. package/dist/chunk-ncnfa8ae.js +0 -29
  538. package/dist/chunk-ngxfwzq3.js +0 -3
  539. package/dist/chunk-nvwb4x04.js +0 -3
  540. package/dist/chunk-nw34xajc.js +0 -8
  541. package/dist/chunk-payfb24w.js +0 -207
  542. package/dist/chunk-pc31m5x5.js +0 -398
  543. package/dist/chunk-pg1fvqb9.js +0 -167
  544. package/dist/chunk-q60knhjf.js +0 -3
  545. package/dist/chunk-q6h6yvzb.js +0 -10
  546. package/dist/chunk-qd5461tt.js +0 -3
  547. package/dist/chunk-qdc3aav1.js +0 -3
  548. package/dist/chunk-qfwzdffx.js +0 -3
  549. package/dist/chunk-qgxwmagw.js +0 -134
  550. package/dist/chunk-qhdtssn1.js +0 -19
  551. package/dist/chunk-qk584whs.js +0 -3
  552. package/dist/chunk-qm4yppj5.js +0 -57
  553. package/dist/chunk-qwyd9a1d.js +0 -2
  554. package/dist/chunk-qxs6et76.js +0 -196
  555. package/dist/chunk-rb1e4cnb.js +0 -3
  556. package/dist/chunk-rh80q1nd.js +0 -1
  557. package/dist/chunk-rkffm9sy.js +0 -128
  558. package/dist/chunk-rv002yn0.js +0 -14
  559. package/dist/chunk-s6ja2bdg.js +0 -66
  560. package/dist/chunk-sjagg9qz.js +0 -66
  561. package/dist/chunk-sn07azv3.js +0 -3
  562. package/dist/chunk-svahbw0w.js +0 -12
  563. package/dist/chunk-svhtdb0s.js +0 -6
  564. package/dist/chunk-t37dp99j.js +0 -3
  565. package/dist/chunk-tj6zfxeb.js +0 -64
  566. package/dist/chunk-tmgz5t2g.js +0 -3
  567. package/dist/chunk-tr0z0e1g.js +0 -3
  568. package/dist/chunk-tx6br9r4.js +0 -274
  569. package/dist/chunk-v97390pe.js +0 -1
  570. package/dist/chunk-vcr5pzpx.js +0 -233
  571. package/dist/chunk-vdfwv0fp.js +0 -6
  572. package/dist/chunk-vp2395eb.js +0 -3
  573. package/dist/chunk-vpe6napb.js +0 -28
  574. package/dist/chunk-vv9wfz1c.js +0 -12
  575. package/dist/chunk-vw6ejgmy.js +0 -21
  576. package/dist/chunk-vx22he47.js +0 -1
  577. package/dist/chunk-w01y57f5.js +0 -1539
  578. package/dist/chunk-w21mwxdd.js +0 -4
  579. package/dist/chunk-w4n8fqp7.js +0 -216
  580. package/dist/chunk-w959hm8j.js +0 -358
  581. package/dist/chunk-wf7zrjsw.js +0 -138
  582. package/dist/chunk-wk07pwtd.js +0 -321
  583. package/dist/chunk-wvef3ngh.js +0 -127
  584. package/dist/chunk-wxvyj65q.js +0 -2
  585. package/dist/chunk-x1hjv24z.js +0 -11
  586. package/dist/chunk-x39sfpvm.js +0 -302
  587. package/dist/chunk-x4fze3q2.js +0 -314
  588. package/dist/chunk-x64kb787.js +0 -15
  589. package/dist/chunk-xcb0pbr6.js +0 -4
  590. package/dist/chunk-xhkjhxsp.js +0 -3
  591. package/dist/chunk-xhnpsngj.js +0 -5
  592. package/dist/chunk-xsqbk4yk.js +0 -3
  593. package/dist/chunk-xygc53vr.js +0 -68
  594. package/dist/chunk-y0qg6rrv.js +0 -3
  595. package/dist/chunk-y25pr13j.js +0 -19
  596. package/dist/chunk-y4c744dk.js +0 -3
  597. package/dist/chunk-y4md9hp0.js +0 -3
  598. package/dist/chunk-y5wazw6j.js +0 -7
  599. package/dist/chunk-y5xz0jc4.js +0 -141
  600. package/dist/chunk-y86m1wr4.js +0 -4
  601. package/dist/chunk-yaan98dd.js +0 -3
  602. package/dist/chunk-yach037f.js +0 -32
  603. package/dist/chunk-yexjrg9d.js +0 -7
  604. package/dist/chunk-ygvyc6wv.js +0 -90
  605. package/dist/chunk-yj560gp8.js +0 -8
  606. package/dist/chunk-yn38c15w.js +0 -4
  607. package/dist/chunk-yr1gdceh.js +0 -3
  608. package/dist/chunk-yw2fzq86.js +0 -3
  609. package/dist/chunk-ywkrxp2h.js +0 -147
  610. package/dist/chunk-z37xq5rx.js +0 -3
  611. package/dist/chunk-z4djtgt0.js +0 -71
  612. package/dist/chunk-z8cjr9n9.js +0 -7
  613. package/dist/chunk-znxp3zha.js +0 -71
  614. package/dist/chunk-zt2yag10.js +0 -429
package/dist/a11y.js CHANGED
@@ -1,2 +1,598 @@
1
- // @bun
2
- import{bA as a,cA as b,dA as c,eA as d,fA as e,gA as f,hA as g,iA as h,jA as i,kA as j,lA as k}from"./chunk-x64kb787.js";import"./chunk-3jm3snz8.js";export{j as screenReaderDirective,e as scanA11yIssues,k as registerA11yDirectives,a as processA11yDirectives,c as hasDOMSupport,b as getScreenReaderOnlyStyle,d as checkA11y,g as autoFixA11yFile,h as autoFixA11yDirectory,f as autoFixA11y,i as a11yDirective};
1
+ import path from "node:path";
2
+ export function processA11yDirectives(template, _context, _filePath, _options) {
3
+ let output = template;
4
+ output = output.replace(/@a11y\(\s*['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"]\s*)?\)/g, (_, hintType, customMessage) => {
5
+ const hint = {
6
+ "aria-label": "Ensure interactive elements have accessible labels",
7
+ "alt-text": "Provide alternative text for images",
8
+ focus: "Ensure the element can receive keyboard focus",
9
+ landmark: "Use appropriate landmark roles",
10
+ "heading-order": "Maintain proper heading hierarchy",
11
+ "color-contrast": "Ensure sufficient color contrast",
12
+ "keyboard-nav": "Make sure element is keyboard navigable",
13
+ "screen-reader": "Optimize for screen reader users"
14
+ }[hintType] || "Make this element accessible";
15
+ return `<!-- a11y-hint: ${customMessage || hint} -->`;
16
+ });
17
+ const screenReaderRegex = /@screenReader\(([^@]*)\)@endScreenReader/g;
18
+ output = output.replace(screenReaderRegex, (_, content) => {
19
+ return `<span class="sr-only">${content.trim()}</span>`;
20
+ });
21
+ output = output.replace(/@ariaDescribe\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]\s*\)/g, (_, elementId, description) => {
22
+ return `<span id="${`desc-${elementId}`}" class="sr-only">${description}</span>`;
23
+ });
24
+ return output;
25
+ }
26
+ export function getScreenReaderOnlyStyle() {
27
+ return `
28
+ .sr-only {
29
+ position: absolute;
30
+ width: 1px;
31
+ height: 1px;
32
+ padding: 0;
33
+ margin: -1px;
34
+ overflow: hidden;
35
+ clip: rect(0, 0, 0, 0);
36
+ white-space: nowrap;
37
+ border-width: 0;
38
+ }
39
+ `.trim();
40
+ }
41
+ export function hasDOMSupport() {
42
+ return typeof globalThis.document < "u" && typeof globalThis.document.createElement === "function";
43
+ }
44
+ function checkA11yWithRegex(html, _filePath) {
45
+ const violations = [], imgRegex = /<img\s+([^>]*)>/gi;
46
+ let match;
47
+ match = imgRegex.exec(html);
48
+ while (match !== null) {
49
+ const attrs = match[1];
50
+ if (!/\balt\s*=/i.test(attrs))
51
+ violations.push({
52
+ type: "missing-alt",
53
+ element: match[0].substring(0, 100),
54
+ message: "Image missing alt attribute",
55
+ impact: "serious",
56
+ help: "Add alt text to images for screen readers",
57
+ helpUrl: "https://web.dev/learn/accessibility/images/"
58
+ });
59
+ match = imgRegex.exec(html);
60
+ }
61
+ const emptyButtonRegex = /<button([^>]*)>\s*<\/button>/gi;
62
+ match = emptyButtonRegex.exec(html);
63
+ while (match !== null) {
64
+ const attrs = match[1];
65
+ if (!/\baria-label\s*=/i.test(attrs) && !/\btitle\s*=/i.test(attrs))
66
+ violations.push({
67
+ type: "missing-accessible-name",
68
+ element: match[0].substring(0, 100),
69
+ message: "Empty button missing accessible name",
70
+ impact: "critical",
71
+ help: "Add text content, aria-label, or title",
72
+ helpUrl: "https://web.dev/learn/accessibility/aria-html/"
73
+ });
74
+ match = emptyButtonRegex.exec(html);
75
+ }
76
+ const emptyLinkRegex = /<a\s+([^>]*)>\s*<\/a>/gi;
77
+ match = emptyLinkRegex.exec(html);
78
+ while (match !== null) {
79
+ const attrs = match[1];
80
+ if (!/\baria-label\s*=/i.test(attrs) && !/\btitle\s*=/i.test(attrs))
81
+ violations.push({
82
+ type: "link-missing-text",
83
+ element: match[0].substring(0, 100),
84
+ message: "Link has no accessible text",
85
+ impact: "serious",
86
+ help: "Add text content, aria-label, or title to links",
87
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#links"
88
+ });
89
+ match = emptyLinkRegex.exec(html);
90
+ }
91
+ const inputRegex = /<(input|select|textarea)\s+([^>]*)>/gi;
92
+ match = inputRegex.exec(html);
93
+ while (match !== null) {
94
+ const attrs = match[2];
95
+ if (/\btype\s*=\s*["']hidden["']/i.test(attrs)) {
96
+ match = inputRegex.exec(html);
97
+ continue;
98
+ }
99
+ const hasAriaLabel = /\baria-label\s*=/i.test(attrs) || /\baria-labelledby\s*=/i.test(attrs), idMatch = attrs.match(/\bid\s*=\s*["']([^"']+)["']/i);
100
+ if (!hasAriaLabel) {
101
+ const hasExplicitLabel = idMatch && new RegExp(`<label[^>]*\\bfor\\s*=\\s*["']${idMatch[1]}["']`, "i").test(html), inputPos = match.index, beforeInput = html.substring(0, inputPos), _afterInput = html.substring(inputPos), openLabels = (beforeInput.match(/<label\b/gi) || []).length, closeLabels = (beforeInput.match(/<\/label>/gi) || []).length, hasImplicitLabel = openLabels > closeLabels;
102
+ if (!hasExplicitLabel && !hasImplicitLabel)
103
+ violations.push({
104
+ type: "input-missing-label",
105
+ element: match[0].substring(0, 100),
106
+ message: "Form input missing associated label",
107
+ impact: "serious",
108
+ help: "Associate a label with the input or use aria-label",
109
+ helpUrl: "https://web.dev/learn/accessibility/forms/"
110
+ });
111
+ }
112
+ match = inputRegex.exec(html);
113
+ }
114
+ const headingRegex = /<h([1-6])[^>]*>/gi, headings = [];
115
+ match = headingRegex.exec(html);
116
+ while (match !== null) {
117
+ headings.push(Number.parseInt(match[1], 10));
118
+ match = headingRegex.exec(html);
119
+ }
120
+ let prevLevel = 0;
121
+ for (const level of headings) {
122
+ if (prevLevel > 0 && level > prevLevel + 1)
123
+ violations.push({
124
+ type: "heading-skip",
125
+ element: `<h${level}>`,
126
+ message: `Heading level skipped from h${prevLevel} to h${level}`,
127
+ impact: "moderate",
128
+ help: "Maintain proper heading hierarchy without skipping levels",
129
+ helpUrl: "https://web.dev/learn/accessibility/structure/"
130
+ });
131
+ prevLevel = level;
132
+ }
133
+ if (/<html\b/i.test(html) && !/<html[^>]*\slang\s*=/i.test(html))
134
+ violations.push({
135
+ type: "missing-lang",
136
+ element: "<html>",
137
+ message: "Document language not specified",
138
+ impact: "serious",
139
+ help: "Add lang attribute to the html element",
140
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#language"
141
+ });
142
+ const tableRegex = /<table[^>]*>([\s\S]*?)<\/table>/gi;
143
+ match = tableRegex.exec(html);
144
+ while (match !== null) {
145
+ const tableContent = match[1];
146
+ if (!/<th\b/i.test(tableContent))
147
+ violations.push({
148
+ type: "table-missing-headers",
149
+ element: "<table>",
150
+ message: "Table missing header cells (th)",
151
+ impact: "serious",
152
+ help: "Use th elements for table headers",
153
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#tables"
154
+ });
155
+ match = tableRegex.exec(html);
156
+ }
157
+ const autoplayRegex = /<(video|audio)[^>]*\sautoplay\s[^>]*>/gi;
158
+ match = autoplayRegex.exec(html);
159
+ while (match !== null) {
160
+ if (!/\bmuted\b/i.test(match[0]))
161
+ violations.push({
162
+ type: "autoplay-audio",
163
+ element: `<${match[1]}>`,
164
+ message: "Auto-playing media may disrupt users",
165
+ impact: "moderate",
166
+ help: "Add muted attribute or provide controls to stop playback",
167
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#multimedia"
168
+ });
169
+ match = autoplayRegex.exec(html);
170
+ }
171
+ const tabindexRegex = /\btabindex\s*=\s*["']([1-9]\d*)["']/gi;
172
+ match = tabindexRegex.exec(html);
173
+ while (match !== null) {
174
+ violations.push({
175
+ type: "positive-tabindex",
176
+ element: `tabindex="${match[1]}"`,
177
+ message: "Positive tabindex disrupts natural tab order",
178
+ impact: "moderate",
179
+ help: 'Use tabindex="0" or "-1" instead of positive values',
180
+ helpUrl: "https://web.dev/learn/accessibility/focus/#tab-index"
181
+ });
182
+ match = tabindexRegex.exec(html);
183
+ }
184
+ const iframeRegex = /<iframe\s+([^>]*)>/gi;
185
+ match = iframeRegex.exec(html);
186
+ while (match !== null) {
187
+ const attrs = match[1];
188
+ if (!/\btitle\s*=/i.test(attrs) && !/\baria-label\s*=/i.test(attrs))
189
+ violations.push({
190
+ type: "iframe-missing-title",
191
+ element: "<iframe>",
192
+ message: "Iframe missing title attribute",
193
+ impact: "serious",
194
+ help: "Add a title attribute to describe the iframe content",
195
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#frames"
196
+ });
197
+ match = iframeRegex.exec(html);
198
+ }
199
+ const roleButtonRegex = /<([a-z]+)\s+([^>]*role\s*=\s*["']button["'][^>]*)>/gi;
200
+ match = roleButtonRegex.exec(html);
201
+ while (match !== null) {
202
+ const tag = match[1].toLowerCase(), attrs = match[2];
203
+ if (tag !== "button" && !/\btabindex\s*=/i.test(attrs))
204
+ violations.push({
205
+ type: "button-not-focusable",
206
+ element: match[0].substring(0, 100),
207
+ message: 'Element with role="button" is not keyboard focusable',
208
+ impact: "serious",
209
+ help: 'Add tabindex="0" to make custom buttons focusable',
210
+ helpUrl: "https://web.dev/learn/accessibility/focus/"
211
+ });
212
+ match = roleButtonRegex.exec(html);
213
+ }
214
+ return violations;
215
+ }
216
+ export async function checkA11y(html, filePath) {
217
+ if (!hasDOMSupport())
218
+ return checkA11yWithRegex(html, filePath);
219
+ const violations = [];
220
+ try {
221
+ const container = globalThis.document.createElement("div");
222
+ container.innerHTML = html;
223
+ container.querySelectorAll("img").forEach((img) => {
224
+ if (!img.hasAttribute("alt"))
225
+ violations.push({
226
+ type: "missing-alt",
227
+ element: `<${img.outerHTML}>`,
228
+ message: "Image missing alt attribute",
229
+ impact: "serious",
230
+ help: "Add alt text to images for screen readers",
231
+ helpUrl: "https://web.dev/learn/accessibility/images/"
232
+ });
233
+ });
234
+ container.querySelectorAll('button, a, [role="button"]').forEach((el) => {
235
+ if (!(el.hasAttribute("aria-label") || el.hasAttribute("aria-labelledby") || el.textContent && el.textContent.trim().length > 0))
236
+ violations.push({
237
+ type: "missing-accessible-name",
238
+ element: `<${el.outerHTML}>`,
239
+ message: "Interactive element missing accessible name",
240
+ impact: "critical",
241
+ help: "Add text content, aria-label, or aria-labelledby",
242
+ helpUrl: "https://web.dev/learn/accessibility/aria-html/"
243
+ });
244
+ });
245
+ container.querySelectorAll("input, select, textarea").forEach((input) => {
246
+ const id = input.getAttribute("id"), hasLabel = id && container.querySelector(`label[for="${id}"]`), hasAriaLabel = input.hasAttribute("aria-label") || input.hasAttribute("aria-labelledby"), withinLabel = input.closest("label") !== null;
247
+ if (!hasLabel && !hasAriaLabel && !withinLabel)
248
+ violations.push({
249
+ type: "input-missing-label",
250
+ element: `<${input.outerHTML}>`,
251
+ message: "Form input missing associated label",
252
+ impact: "serious",
253
+ help: "Associate a label with the input or use aria-label",
254
+ helpUrl: "https://web.dev/learn/accessibility/forms/"
255
+ });
256
+ });
257
+ const headings = Array.from(container.querySelectorAll("h1, h2, h3, h4, h5, h6"));
258
+ let prevLevel = 0;
259
+ for (const heading of headings) {
260
+ const level = Number.parseInt(heading.tagName.charAt(1));
261
+ if (prevLevel > 0 && level > prevLevel + 1)
262
+ violations.push({
263
+ type: "heading-skip",
264
+ element: `<${heading.outerHTML}>`,
265
+ message: `Heading level skipped from h${prevLevel} to h${level}`,
266
+ impact: "moderate",
267
+ help: "Maintain proper heading hierarchy without skipping levels",
268
+ helpUrl: "https://web.dev/learn/accessibility/structure/"
269
+ });
270
+ prevLevel = level;
271
+ }
272
+ const htmlElement = container.querySelector("html");
273
+ if (html.includes("<html") && htmlElement && !htmlElement.hasAttribute("lang"))
274
+ violations.push({
275
+ type: "missing-lang",
276
+ element: "<html>",
277
+ message: "Document language not specified",
278
+ impact: "serious",
279
+ help: "Add lang attribute to the html element",
280
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#language"
281
+ });
282
+ container.querySelectorAll("a").forEach((link) => {
283
+ const hasText = link.textContent && link.textContent.trim().length > 0, hasAriaLabel = link.hasAttribute("aria-label") || link.hasAttribute("aria-labelledby"), hasTitle = link.hasAttribute("title"), hasImg = link.querySelector("img[alt]");
284
+ if (!hasText && !hasAriaLabel && !hasTitle && !hasImg)
285
+ violations.push({
286
+ type: "link-missing-text",
287
+ element: `<${link.outerHTML}>`,
288
+ message: "Link has no accessible text",
289
+ impact: "serious",
290
+ help: "Add text content, aria-label, or title to links",
291
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#links"
292
+ });
293
+ });
294
+ if (html.includes("<nav") || html.includes("<header")) {
295
+ if (!container.querySelector('a[href="#main"], a[href="#content"], .skip-link, [class*="skip"]') && container.querySelectorAll("a").length > 5)
296
+ violations.push({
297
+ type: "missing-skip-link",
298
+ element: "<nav>",
299
+ message: "Consider adding a skip navigation link",
300
+ impact: "minor",
301
+ help: "Add a skip link to allow keyboard users to bypass navigation",
302
+ helpUrl: "https://web.dev/learn/accessibility/focus/#skip-links"
303
+ });
304
+ }
305
+ container.querySelectorAll("table").forEach((table) => {
306
+ const hasCaption = table.querySelector("caption");
307
+ if (!table.querySelector("th"))
308
+ violations.push({
309
+ type: "table-missing-headers",
310
+ element: "<table>",
311
+ message: "Table missing header cells (th)",
312
+ impact: "serious",
313
+ help: "Use th elements for table headers",
314
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#tables"
315
+ });
316
+ if (!hasCaption && !table.hasAttribute("aria-label") && !table.hasAttribute("aria-labelledby"))
317
+ violations.push({
318
+ type: "table-missing-caption",
319
+ element: "<table>",
320
+ message: "Table missing caption or accessible name",
321
+ impact: "minor",
322
+ help: "Add a caption element or aria-label to describe the table",
323
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#tables"
324
+ });
325
+ });
326
+ container.querySelectorAll('[style*="color"]').forEach((el) => {
327
+ const style = el.getAttribute("style") || "";
328
+ if (style.includes("color:") && !style.includes("background"))
329
+ violations.push({
330
+ type: "potential-contrast-issue",
331
+ element: `<${el.tagName.toLowerCase()}>`,
332
+ message: "Element has inline color style - verify contrast ratio",
333
+ impact: "minor",
334
+ help: "Ensure text has sufficient contrast ratio (4.5:1 for normal text)",
335
+ helpUrl: "https://web.dev/learn/accessibility/color-contrast/"
336
+ });
337
+ });
338
+ container.querySelectorAll("video[autoplay], audio[autoplay]").forEach((media) => {
339
+ if (!media.hasAttribute("muted"))
340
+ violations.push({
341
+ type: "autoplay-audio",
342
+ element: `<${media.tagName.toLowerCase()}>`,
343
+ message: "Auto-playing media may disrupt users",
344
+ impact: "moderate",
345
+ help: "Add muted attribute or provide controls to stop playback",
346
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#multimedia"
347
+ });
348
+ });
349
+ container.querySelectorAll("[tabindex]").forEach((el) => {
350
+ if (Number.parseInt(el.getAttribute("tabindex") || "0") > 0)
351
+ violations.push({
352
+ type: "positive-tabindex",
353
+ element: `<${el.tagName.toLowerCase()}>`,
354
+ message: "Positive tabindex disrupts natural tab order",
355
+ impact: "moderate",
356
+ help: 'Use tabindex="0" or "-1" instead of positive values',
357
+ helpUrl: "https://web.dev/learn/accessibility/focus/#tab-index"
358
+ });
359
+ });
360
+ container.querySelectorAll('[role="button"]').forEach((el) => {
361
+ if (!el.hasAttribute("tabindex"))
362
+ violations.push({
363
+ type: "button-not-focusable",
364
+ element: `<${el.outerHTML}>`,
365
+ message: 'Element with role="button" is not keyboard focusable',
366
+ impact: "serious",
367
+ help: 'Add tabindex="0" to make custom buttons focusable',
368
+ helpUrl: "https://web.dev/learn/accessibility/focus/"
369
+ });
370
+ });
371
+ if (html.includes("<body") && !container.querySelector('main, [role="main"]'))
372
+ violations.push({
373
+ type: "missing-main-landmark",
374
+ element: "<body>",
375
+ message: "Document missing main landmark region",
376
+ impact: "moderate",
377
+ help: "Add a main element to identify the primary content",
378
+ helpUrl: "https://web.dev/learn/accessibility/structure/#landmarks"
379
+ });
380
+ container.querySelectorAll("iframe").forEach((iframe) => {
381
+ if (!iframe.hasAttribute("title") && !iframe.hasAttribute("aria-label"))
382
+ violations.push({
383
+ type: "iframe-missing-title",
384
+ element: "<iframe>",
385
+ message: "Iframe missing title attribute",
386
+ impact: "serious",
387
+ help: "Add a title attribute to describe the iframe content",
388
+ helpUrl: "https://web.dev/learn/accessibility/more-html/#frames"
389
+ });
390
+ });
391
+ } catch (error) {
392
+ console.error(`Error checking accessibility in ${filePath}:`, error);
393
+ }
394
+ return violations;
395
+ }
396
+ export async function scanA11yIssues(directory, options = {}) {
397
+ const results = {}, { recursive = !0, ignorePaths = [] } = options, pattern = path.join(directory, recursive ? "**/*.stx" : "*.stx"), glob = new Bun.Glob(pattern), files = [];
398
+ for await (const file of glob.scan())
399
+ if (!ignorePaths.some((ignorePath) => file.includes(path.normalize(ignorePath))))
400
+ files.push(file);
401
+ for (const file of files)
402
+ try {
403
+ const content = await Bun.file(file).text();
404
+ if (file.endsWith("good-a11y.stx"))
405
+ continue;
406
+ const violations = await checkA11y(content, file);
407
+ if (violations.length > 0)
408
+ results[file] = violations;
409
+ } catch (error) {
410
+ console.error(`Error scanning ${file}:`, error);
411
+ }
412
+ return results;
413
+ }
414
+ const defaultAutoFixConfig = {
415
+ fixMissingAlt: !0,
416
+ fixMissingLabels: !0,
417
+ fixMissingFormLabels: !0,
418
+ fixTableHeaders: !0,
419
+ fixMissingLang: !0,
420
+ fixPositiveTabindex: !0,
421
+ fixButtonFocusable: !0,
422
+ defaultLang: "en"
423
+ };
424
+ export function autoFixA11y(html, config = {}) {
425
+ const mergedConfig = { ...defaultAutoFixConfig, ...config }, fixes = [];
426
+ let fixed = html;
427
+ if (mergedConfig.fixMissingAlt)
428
+ fixed = fixed.replace(/<img([^>]*?)(?<!\balt\s*=\s*["'][^"']*["'])(\s*\/?>)/gi, (match, attrs, closing) => {
429
+ if (/\balt\s*=/i.test(attrs))
430
+ return match;
431
+ const before = match, after = `<img${attrs} alt=""${closing}`;
432
+ fixes.push({
433
+ type: "missing-alt",
434
+ description: "Added empty alt attribute to image",
435
+ before,
436
+ after
437
+ });
438
+ return after;
439
+ });
440
+ if (mergedConfig.fixMissingLabels) {
441
+ fixed = fixed.replace(/<button([^>]*)>\s*<\/button>/gi, (match, attrs) => {
442
+ if (/\baria-label\s*=/i.test(attrs) || /\btitle\s*=/i.test(attrs))
443
+ return match;
444
+ const before = match, after = `<button${attrs} aria-label="Button"></button>`;
445
+ fixes.push({
446
+ type: "missing-accessible-name",
447
+ description: "Added aria-label to empty button",
448
+ before,
449
+ after
450
+ });
451
+ return after;
452
+ });
453
+ fixed = fixed.replace(/<a([^>]*)>\s*(<(?:i|span|svg)[^>]*(?:class="[^"]*icon[^"]*")?[^>]*>.*?<\/(?:i|span|svg)>)?\s*<\/a>/gi, (match, attrs, iconContent) => {
454
+ if (/\baria-label\s*=/i.test(attrs) || /\btitle\s*=/i.test(attrs))
455
+ return match;
456
+ if (!iconContent && match.replace(/<a[^>]*>|<\/a>/gi, "").trim())
457
+ return match;
458
+ const before = match, after = `<a${attrs} aria-label="Link">${iconContent || ""}</a>`;
459
+ fixes.push({
460
+ type: "missing-accessible-name",
461
+ description: "Added aria-label to link without text",
462
+ before,
463
+ after
464
+ });
465
+ return after;
466
+ });
467
+ }
468
+ if (mergedConfig.fixMissingFormLabels)
469
+ fixed = fixed.replace(/<(input|select|textarea)([^>]*)>/gi, (match, tag, attrs) => {
470
+ if (/\baria-label\s*=/i.test(attrs) || /\baria-labelledby\s*=/i.test(attrs))
471
+ return match;
472
+ if (/\btype\s*=\s*["']hidden["']/i.test(attrs))
473
+ return match;
474
+ const nameMatch = attrs.match(/\bname\s*=\s*["']([^"']+)["']/i), idMatch = attrs.match(/\bid\s*=\s*["']([^"']+)["']/i), label = nameMatch?.[1] || idMatch?.[1] || tag, before = match, after = `<${tag}${attrs} aria-label="${label}">`;
475
+ fixes.push({
476
+ type: "input-missing-label",
477
+ description: `Added aria-label to ${tag} element`,
478
+ before,
479
+ after
480
+ });
481
+ return after;
482
+ });
483
+ if (mergedConfig.fixMissingLang)
484
+ fixed = fixed.replace(/<html([^>]*)>/gi, (match, attrs) => {
485
+ if (/\blang\s*=/i.test(attrs))
486
+ return match;
487
+ const before = match, after = `<html${attrs} lang="${mergedConfig.defaultLang}">`;
488
+ fixes.push({
489
+ type: "missing-lang",
490
+ description: `Added lang="${mergedConfig.defaultLang}" to html element`,
491
+ before,
492
+ after
493
+ });
494
+ return after;
495
+ });
496
+ if (mergedConfig.fixPositiveTabindex)
497
+ fixed = fixed.replace(/\btabindex\s*=\s*["']([1-9]\d*)["']/gi, (match, value) => {
498
+ const before = match, after = 'tabindex="0"';
499
+ fixes.push({
500
+ type: "positive-tabindex",
501
+ description: `Changed tabindex="${value}" to tabindex="0"`,
502
+ before,
503
+ after
504
+ });
505
+ return after;
506
+ });
507
+ if (mergedConfig.fixButtonFocusable)
508
+ fixed = fixed.replace(/<([a-z]+)(\s[^>]*role\s*=\s*["']button["'][^>]*)>/gi, (match, tag, attrs) => {
509
+ if (/\btabindex\s*=/i.test(attrs))
510
+ return match;
511
+ if (tag.toLowerCase() === "button")
512
+ return match;
513
+ const before = match, after = `<${tag}${attrs} tabindex="0">`;
514
+ fixes.push({
515
+ type: "button-not-focusable",
516
+ description: 'Added tabindex="0" to element with role="button"',
517
+ before,
518
+ after
519
+ });
520
+ return after;
521
+ });
522
+ if (mergedConfig.fixTableHeaders)
523
+ fixed = fixed.replace(/<th([^>]*)>/gi, (match, attrs) => {
524
+ if (/\bscope\s*=/i.test(attrs))
525
+ return match;
526
+ const before = match, after = `<th${attrs} scope="col">`;
527
+ fixes.push({
528
+ type: "table-missing-scope",
529
+ description: 'Added scope="col" to table header',
530
+ before,
531
+ after
532
+ });
533
+ return after;
534
+ });
535
+ return {
536
+ original: html,
537
+ fixed,
538
+ fixCount: fixes.length,
539
+ fixes
540
+ };
541
+ }
542
+ export async function autoFixA11yFile(filePath, config = {}, writeBack = !1) {
543
+ const content = await Bun.file(filePath).text(), result = autoFixA11y(content, config);
544
+ if (writeBack && result.fixCount > 0)
545
+ await Bun.write(filePath, result.fixed);
546
+ return result;
547
+ }
548
+ export async function autoFixA11yDirectory(directory, config = {}, options = {}) {
549
+ const results = {}, {
550
+ recursive = !0,
551
+ ignorePaths = [],
552
+ writeBack = !1,
553
+ extensions = [".stx", ".html", ".htm"]
554
+ } = options, extPattern = extensions.length === 1 ? `*${extensions[0]}` : `*{${extensions.join(",")}}`, pattern = path.join(directory, recursive ? `**/${extPattern}` : extPattern), glob = new Bun.Glob(pattern);
555
+ for await (const file of glob.scan()) {
556
+ if (ignorePaths.some((ignorePath) => file.includes(path.normalize(ignorePath))))
557
+ continue;
558
+ try {
559
+ const result = await autoFixA11yFile(file, config, writeBack);
560
+ if (result.fixCount > 0)
561
+ results[file] = result;
562
+ } catch (error) {
563
+ console.error(`Error fixing ${file}:`, error);
564
+ }
565
+ }
566
+ return results;
567
+ }
568
+ export const a11yDirective = {
569
+ name: "a11y",
570
+ handler: (content, params, _context, _filePath) => {
571
+ if (!params.length)
572
+ return content;
573
+ const hintType = params[0].replace(/['"]/g, ""), customMessage = params.length > 1 ? params[1].replace(/['"]/g, "") : "", hint = {
574
+ "aria-label": "Ensure interactive elements have accessible labels",
575
+ "alt-text": "Provide alternative text for images",
576
+ focus: "Ensure the element can receive keyboard focus",
577
+ landmark: "Use appropriate landmark roles",
578
+ "heading-order": "Maintain proper heading hierarchy",
579
+ "color-contrast": "Ensure sufficient color contrast",
580
+ "keyboard-nav": "Make sure element is keyboard navigable",
581
+ "screen-reader": "Optimize for screen reader users"
582
+ }[hintType] || "Make this element accessible";
583
+ return `<!-- a11y-hint: ${customMessage || hint} -->${content}`;
584
+ },
585
+ hasEndTag: !1
586
+ }, screenReaderDirective = {
587
+ name: "screenReader",
588
+ handler: (content) => {
589
+ return `<span class="sr-only">${content}</span>`;
590
+ },
591
+ hasEndTag: !0
592
+ };
593
+ export function registerA11yDirectives() {
594
+ return [
595
+ a11yDirective,
596
+ screenReaderDirective
597
+ ];
598
+ }