@jack200714/mafw 4.5.1 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/README.md +5 -2
  2. package/bin/mafw.js +16 -14
  3. package/gateway/dist/index.js +52 -38
  4. package/gateway/dist/media/media-plugin-loader.js +0 -12
  5. package/gateway/dist/plugins/hub.js +153 -19
  6. package/gateway/dist/routes/plugins.js +15 -5
  7. package/gateway/dist/runtime/event-broadcast.js +33 -0
  8. package/gateway/dist/runtime/loader.js +23 -13
  9. package/gateway/dist/usage/builtin-plugins/gateway.js +25 -3
  10. package/gateway/dist/usage/plugin-loader.js +0 -11
  11. package/gateway/package.json +2 -2
  12. package/package.json +1 -7
  13. package/packages/tui/dist/cli.js +8 -3
  14. package/.opencode/mafw/.backup-v61/parametric/base-skill-manifest.yaml +0 -2
  15. package/.opencode/mafw/STATUS.md +0 -6
  16. package/.opencode/mafw/ledger.md +0 -20
  17. package/.opencode/mafw/memory/.harmonic_index.json +0 -28
  18. package/.opencode/mafw/memory/.review_queue.json +0 -1
  19. package/.opencode/mafw/memory/tier3/parametric.json +0 -13
  20. package/.opencode/mafw/memory/tier3/test-goal.json +0 -19
  21. package/.opencode/mafw/memory-index.json +0 -6
  22. package/.opencode/mafw/parametric/base-skill-manifest.yaml +0 -2
  23. package/.opencode/mafw/waves.json +0 -4
  24. package/.opencode/opencode.json +0 -3
  25. package/.opencode/plugins/mafw-plugin.ts +0 -8
  26. package/.opencode/skills/banner-design/SKILL.md +0 -196
  27. package/.opencode/skills/banner-design/references/banner-sizes-and-styles.md +0 -118
  28. package/.opencode/skills/brand/SKILL.md +0 -97
  29. package/.opencode/skills/brand/references/approval-checklist.md +0 -169
  30. package/.opencode/skills/brand/references/asset-organization.md +0 -157
  31. package/.opencode/skills/brand/references/brand-guideline-template.md +0 -140
  32. package/.opencode/skills/brand/references/color-palette-management.md +0 -186
  33. package/.opencode/skills/brand/references/consistency-checklist.md +0 -94
  34. package/.opencode/skills/brand/references/logo-usage-rules.md +0 -185
  35. package/.opencode/skills/brand/references/messaging-framework.md +0 -85
  36. package/.opencode/skills/brand/references/typography-specifications.md +0 -214
  37. package/.opencode/skills/brand/references/update.md +0 -118
  38. package/.opencode/skills/brand/references/visual-identity.md +0 -96
  39. package/.opencode/skills/brand/references/voice-framework.md +0 -88
  40. package/.opencode/skills/brand/scripts/extract-colors.cjs +0 -341
  41. package/.opencode/skills/brand/scripts/inject-brand-context.cjs +0 -349
  42. package/.opencode/skills/brand/scripts/sync-brand-to-tokens.cjs +0 -248
  43. package/.opencode/skills/brand/scripts/tests/test_sync_brand_to_tokens.py +0 -52
  44. package/.opencode/skills/brand/scripts/validate-asset.cjs +0 -387
  45. package/.opencode/skills/brand/templates/brand-guidelines-starter.md +0 -275
  46. package/.opencode/skills/design/SKILL.md +0 -313
  47. package/.opencode/skills/design/data/cip/deliverables.csv +0 -51
  48. package/.opencode/skills/design/data/cip/industries.csv +0 -21
  49. package/.opencode/skills/design/data/cip/mockup-contexts.csv +0 -21
  50. package/.opencode/skills/design/data/cip/styles.csv +0 -21
  51. package/.opencode/skills/design/data/icon/styles.csv +0 -16
  52. package/.opencode/skills/design/data/logo/colors.csv +0 -56
  53. package/.opencode/skills/design/data/logo/industries.csv +0 -56
  54. package/.opencode/skills/design/data/logo/styles.csv +0 -56
  55. package/.opencode/skills/design/references/banner-sizes-and-styles.md +0 -118
  56. package/.opencode/skills/design/references/cip-deliverable-guide.md +0 -95
  57. package/.opencode/skills/design/references/cip-design.md +0 -121
  58. package/.opencode/skills/design/references/cip-prompt-engineering.md +0 -84
  59. package/.opencode/skills/design/references/cip-style-guide.md +0 -68
  60. package/.opencode/skills/design/references/design-routing.md +0 -207
  61. package/.opencode/skills/design/references/icon-design.md +0 -122
  62. package/.opencode/skills/design/references/logo-color-psychology.md +0 -101
  63. package/.opencode/skills/design/references/logo-design.md +0 -92
  64. package/.opencode/skills/design/references/logo-prompt-engineering.md +0 -158
  65. package/.opencode/skills/design/references/logo-style-guide.md +0 -109
  66. package/.opencode/skills/design/references/slides-copywriting-formulas.md +0 -84
  67. package/.opencode/skills/design/references/slides-create.md +0 -4
  68. package/.opencode/skills/design/references/slides-html-template.md +0 -295
  69. package/.opencode/skills/design/references/slides-layout-patterns.md +0 -137
  70. package/.opencode/skills/design/references/slides-strategies.md +0 -94
  71. package/.opencode/skills/design/references/slides.md +0 -42
  72. package/.opencode/skills/design/references/social-photos-design.md +0 -329
  73. package/.opencode/skills/design/scripts/cip/core.py +0 -215
  74. package/.opencode/skills/design/scripts/cip/generate.py +0 -484
  75. package/.opencode/skills/design/scripts/cip/render-html.py +0 -424
  76. package/.opencode/skills/design/scripts/cip/search.py +0 -127
  77. package/.opencode/skills/design/scripts/icon/generate.py +0 -487
  78. package/.opencode/skills/design/scripts/logo/core.py +0 -175
  79. package/.opencode/skills/design/scripts/logo/generate.py +0 -362
  80. package/.opencode/skills/design/scripts/logo/search.py +0 -114
  81. package/.opencode/skills/design-system/SKILL.md +0 -244
  82. package/.opencode/skills/design-system/data/slide-backgrounds.csv +0 -11
  83. package/.opencode/skills/design-system/data/slide-charts.csv +0 -26
  84. package/.opencode/skills/design-system/data/slide-color-logic.csv +0 -14
  85. package/.opencode/skills/design-system/data/slide-copy.csv +0 -26
  86. package/.opencode/skills/design-system/data/slide-layout-logic.csv +0 -16
  87. package/.opencode/skills/design-system/data/slide-layouts.csv +0 -26
  88. package/.opencode/skills/design-system/data/slide-strategies.csv +0 -16
  89. package/.opencode/skills/design-system/data/slide-typography.csv +0 -15
  90. package/.opencode/skills/design-system/references/component-specs.md +0 -236
  91. package/.opencode/skills/design-system/references/component-tokens.md +0 -214
  92. package/.opencode/skills/design-system/references/primitive-tokens.md +0 -203
  93. package/.opencode/skills/design-system/references/semantic-tokens.md +0 -215
  94. package/.opencode/skills/design-system/references/states-and-variants.md +0 -241
  95. package/.opencode/skills/design-system/references/tailwind-integration.md +0 -251
  96. package/.opencode/skills/design-system/references/token-architecture.md +0 -224
  97. package/.opencode/skills/design-system/scripts/embed-tokens.cjs +0 -99
  98. package/.opencode/skills/design-system/scripts/fetch-background.py +0 -317
  99. package/.opencode/skills/design-system/scripts/generate-slide.py +0 -770
  100. package/.opencode/skills/design-system/scripts/generate-tokens.cjs +0 -205
  101. package/.opencode/skills/design-system/scripts/html-token-validator.py +0 -327
  102. package/.opencode/skills/design-system/scripts/search-slides.py +0 -218
  103. package/.opencode/skills/design-system/scripts/slide-token-validator.py +0 -35
  104. package/.opencode/skills/design-system/scripts/slide_search_core.py +0 -453
  105. package/.opencode/skills/design-system/scripts/tests/test_validate_tokens.py +0 -48
  106. package/.opencode/skills/design-system/scripts/validate-tokens.cjs +0 -246
  107. package/.opencode/skills/design-system/templates/design-tokens-starter.json +0 -143
  108. package/.opencode/skills/frontend-design/LICENSE.txt +0 -21
  109. package/.opencode/skills/frontend-design/SKILL.md +0 -115
  110. package/.opencode/skills/mafw-automation-interview/SKILL.md +0 -43
  111. package/.opencode/skills/mafw-cli-scanner/SKILL.md +0 -37
  112. package/.opencode/skills/mafw-compression-verifier/SKILL.md +0 -52
  113. package/.opencode/skills/mafw-desktop-inspector/SKILL.md +0 -170
  114. package/.opencode/skills/mafw-execute/SKILL.md +0 -62
  115. package/.opencode/skills/mafw-gateway-restart/SKILL.md +0 -87
  116. package/.opencode/skills/mafw-github-scanner/SKILL.md +0 -38
  117. package/.opencode/skills/mafw-goal/SKILL.md +0 -76
  118. package/.opencode/skills/mafw-interview/SKILL.md +0 -68
  119. package/.opencode/skills/mafw-memory-extractor/SKILL.md +0 -65
  120. package/.opencode/skills/mafw-plan/SKILL.md +0 -58
  121. package/.opencode/skills/mafw-review/SKILL.md +0 -85
  122. package/.opencode/skills/runtime-plugin-authoring/SKILL.md +0 -791
  123. package/.opencode/skills/slides/SKILL.md +0 -40
  124. package/.opencode/skills/slides/references/copywriting-formulas.md +0 -84
  125. package/.opencode/skills/slides/references/create.md +0 -4
  126. package/.opencode/skills/slides/references/html-template.md +0 -295
  127. package/.opencode/skills/slides/references/layout-patterns.md +0 -137
  128. package/.opencode/skills/slides/references/slide-strategies.md +0 -94
  129. package/.opencode/skills/ui-styling/LICENSE.txt +0 -202
  130. package/.opencode/skills/ui-styling/SKILL.md +0 -324
  131. package/.opencode/skills/ui-styling/references/canvas-design-system.md +0 -320
  132. package/.opencode/skills/ui-styling/references/shadcn-accessibility.md +0 -471
  133. package/.opencode/skills/ui-styling/references/shadcn-components.md +0 -424
  134. package/.opencode/skills/ui-styling/references/shadcn-theming.md +0 -373
  135. package/.opencode/skills/ui-styling/references/tailwind-customization.md +0 -483
  136. package/.opencode/skills/ui-styling/references/tailwind-responsive.md +0 -382
  137. package/.opencode/skills/ui-styling/references/tailwind-utilities.md +0 -455
  138. package/.opencode/skills/ui-styling/scripts/requirements.txt +0 -17
  139. package/.opencode/skills/ui-styling/scripts/shadcn_add.py +0 -308
  140. package/.opencode/skills/ui-styling/scripts/tailwind_config_gen.py +0 -473
  141. package/.opencode/skills/ui-styling/scripts/tests/coverage-ui.json +0 -1
  142. package/.opencode/skills/ui-styling/scripts/tests/requirements.txt +0 -3
  143. package/.opencode/skills/ui-styling/scripts/tests/test_shadcn_add.py +0 -266
  144. package/.opencode/skills/ui-styling/scripts/tests/test_tailwind_config_gen.py +0 -394
  145. package/.opencode/skills/ui-ux-pro-max/SKILL.md +0 -388
  146. package/.opencode/skills/ui-ux-pro-max/data/app-interface.csv +0 -31
  147. package/.opencode/skills/ui-ux-pro-max/data/charts.csv +0 -26
  148. package/.opencode/skills/ui-ux-pro-max/data/colors.csv +0 -193
  149. package/.opencode/skills/ui-ux-pro-max/data/google-fonts.csv +0 -1924
  150. package/.opencode/skills/ui-ux-pro-max/data/icons.csv +0 -106
  151. package/.opencode/skills/ui-ux-pro-max/data/landing.csv +0 -35
  152. package/.opencode/skills/ui-ux-pro-max/data/motion.csv +0 -17
  153. package/.opencode/skills/ui-ux-pro-max/data/products.csv +0 -193
  154. package/.opencode/skills/ui-ux-pro-max/data/react-performance.csv +0 -45
  155. package/.opencode/skills/ui-ux-pro-max/data/stacks/angular.csv +0 -51
  156. package/.opencode/skills/ui-ux-pro-max/data/stacks/astro.csv +0 -54
  157. package/.opencode/skills/ui-ux-pro-max/data/stacks/avalonia.csv +0 -57
  158. package/.opencode/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  159. package/.opencode/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  160. package/.opencode/skills/ui-ux-pro-max/data/stacks/javafx.csv +0 -76
  161. package/.opencode/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  162. package/.opencode/skills/ui-ux-pro-max/data/stacks/laravel.csv +0 -51
  163. package/.opencode/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  164. package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -71
  165. package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  166. package/.opencode/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  167. package/.opencode/skills/ui-ux-pro-max/data/stacks/react.csv +0 -54
  168. package/.opencode/skills/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  169. package/.opencode/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  170. package/.opencode/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  171. package/.opencode/skills/ui-ux-pro-max/data/stacks/threejs.csv +0 -54
  172. package/.opencode/skills/ui-ux-pro-max/data/stacks/uno.csv +0 -60
  173. package/.opencode/skills/ui-ux-pro-max/data/stacks/uwp.csv +0 -56
  174. package/.opencode/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  175. package/.opencode/skills/ui-ux-pro-max/data/stacks/winui.csv +0 -60
  176. package/.opencode/skills/ui-ux-pro-max/data/stacks/wpf.csv +0 -57
  177. package/.opencode/skills/ui-ux-pro-max/data/styles.csv +0 -85
  178. package/.opencode/skills/ui-ux-pro-max/data/typography.csv +0 -75
  179. package/.opencode/skills/ui-ux-pro-max/data/ui-reasoning.csv +0 -162
  180. package/.opencode/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  181. package/.opencode/skills/ui-ux-pro-max/scripts/core.py +0 -464
  182. package/.opencode/skills/ui-ux-pro-max/scripts/design_system.py +0 -1479
  183. package/.opencode/skills/ui-ux-pro-max/scripts/search.py +0 -162
  184. package/.opencode/skills/ui-ux-pro-max/scripts/tests/test_core.py +0 -134
  185. package/.opencode/skills/ui-ux-pro-max/scripts/tests/test_design_system_mode.py +0 -159
  186. package/.opencode/skills/ui-ux-pro-max/scripts/validate_data.py +0 -114
  187. package/dist/hooks/bash-python-guide.d.ts +0 -4
  188. package/dist/hooks/bash-python-guide.d.ts.map +0 -1
  189. package/dist/hooks/bash-python-guide.js +0 -67
  190. package/dist/hooks/bash-python-guide.js.map +0 -1
  191. package/dist/hooks/handoff.d.ts +0 -9
  192. package/dist/hooks/handoff.d.ts.map +0 -1
  193. package/dist/hooks/handoff.js +0 -8
  194. package/dist/hooks/handoff.js.map +0 -1
  195. package/dist/hooks/hook-manager.d.ts +0 -32
  196. package/dist/hooks/hook-manager.d.ts.map +0 -1
  197. package/dist/hooks/hook-manager.js +0 -91
  198. package/dist/hooks/hook-manager.js.map +0 -1
  199. package/dist/hooks/llm-after.d.ts +0 -8
  200. package/dist/hooks/llm-after.d.ts.map +0 -1
  201. package/dist/hooks/llm-after.js +0 -8
  202. package/dist/hooks/llm-after.js.map +0 -1
  203. package/dist/hooks/media-ingest.d.ts +0 -43
  204. package/dist/hooks/media-ingest.d.ts.map +0 -1
  205. package/dist/hooks/media-ingest.js +0 -269
  206. package/dist/hooks/media-ingest.js.map +0 -1
  207. package/dist/hooks/memory-guide.d.ts +0 -3
  208. package/dist/hooks/memory-guide.d.ts.map +0 -1
  209. package/dist/hooks/memory-guide.js +0 -47
  210. package/dist/hooks/memory-guide.js.map +0 -1
  211. package/dist/hooks/observation-capture.d.ts +0 -17
  212. package/dist/hooks/observation-capture.d.ts.map +0 -1
  213. package/dist/hooks/observation-capture.js +0 -20
  214. package/dist/hooks/observation-capture.js.map +0 -1
  215. package/dist/hooks/session-compacting.d.ts +0 -6
  216. package/dist/hooks/session-compacting.d.ts.map +0 -1
  217. package/dist/hooks/session-compacting.js +0 -6
  218. package/dist/hooks/session-compacting.js.map +0 -1
  219. package/dist/hooks/session-ending.d.ts +0 -20
  220. package/dist/hooks/session-ending.d.ts.map +0 -1
  221. package/dist/hooks/session-ending.js +0 -113
  222. package/dist/hooks/session-ending.js.map +0 -1
  223. package/dist/hooks/session-recall.d.ts +0 -2
  224. package/dist/hooks/session-recall.d.ts.map +0 -1
  225. package/dist/hooks/session-recall.js +0 -103
  226. package/dist/hooks/session-recall.js.map +0 -1
  227. package/dist/hooks/session-start.d.ts +0 -9
  228. package/dist/hooks/session-start.d.ts.map +0 -1
  229. package/dist/hooks/session-start.js +0 -42
  230. package/dist/hooks/session-start.js.map +0 -1
  231. package/dist/hooks/tool-before.d.ts +0 -10
  232. package/dist/hooks/tool-before.d.ts.map +0 -1
  233. package/dist/hooks/tool-before.js +0 -6
  234. package/dist/hooks/tool-before.js.map +0 -1
  235. package/dist/hooks/tool-executed.d.ts +0 -19
  236. package/dist/hooks/tool-executed.d.ts.map +0 -1
  237. package/dist/hooks/tool-executed.js +0 -12
  238. package/dist/hooks/tool-executed.js.map +0 -1
  239. package/dist/hooks/user-profile.d.ts +0 -2
  240. package/dist/hooks/user-profile.d.ts.map +0 -1
  241. package/dist/hooks/user-profile.js +0 -30
  242. package/dist/hooks/user-profile.js.map +0 -1
  243. package/dist/hooks/user-prompt.d.ts +0 -9
  244. package/dist/hooks/user-prompt.d.ts.map +0 -1
  245. package/dist/hooks/user-prompt.js +0 -8
  246. package/dist/hooks/user-prompt.js.map +0 -1
  247. package/dist/hooks/voice-guide.d.ts +0 -8
  248. package/dist/hooks/voice-guide.d.ts.map +0 -1
  249. package/dist/hooks/voice-guide.js +0 -101
  250. package/dist/hooks/voice-guide.js.map +0 -1
  251. package/dist/plugin.d.ts +0 -55
  252. package/dist/plugin.d.ts.map +0 -1
  253. package/dist/plugin.js +0 -342
  254. package/dist/plugin.js.map +0 -1
  255. package/dist/tools/add-memory.d.ts +0 -17
  256. package/dist/tools/add-memory.d.ts.map +0 -1
  257. package/dist/tools/add-memory.js +0 -60
  258. package/dist/tools/add-memory.js.map +0 -1
  259. package/dist/tools/media-ask.d.ts +0 -14
  260. package/dist/tools/media-ask.d.ts.map +0 -1
  261. package/dist/tools/media-ask.js +0 -224
  262. package/dist/tools/media-ask.js.map +0 -1
  263. package/dist/tools/media-speak.d.ts +0 -16
  264. package/dist/tools/media-speak.d.ts.map +0 -1
  265. package/dist/tools/media-speak.js +0 -78
  266. package/dist/tools/media-speak.js.map +0 -1
  267. package/dist/tools/media-upload.d.ts +0 -14
  268. package/dist/tools/media-upload.d.ts.map +0 -1
  269. package/dist/tools/media-upload.js +0 -155
  270. package/dist/tools/media-upload.js.map +0 -1
  271. package/dist/tools/python-exec.d.ts +0 -13
  272. package/dist/tools/python-exec.d.ts.map +0 -1
  273. package/dist/tools/python-exec.js +0 -99
  274. package/dist/tools/python-exec.js.map +0 -1
  275. package/dist/tools/python-restart.d.ts +0 -11
  276. package/dist/tools/python-restart.d.ts.map +0 -1
  277. package/dist/tools/python-restart.js +0 -33
  278. package/dist/tools/python-restart.js.map +0 -1
  279. package/dist/utils/circuit-breaker.d.ts +0 -23
  280. package/dist/utils/circuit-breaker.d.ts.map +0 -1
  281. package/dist/utils/circuit-breaker.js +0 -75
  282. package/dist/utils/circuit-breaker.js.map +0 -1
  283. package/dist/utils/config-loader.d.ts +0 -20
  284. package/dist/utils/config-loader.d.ts.map +0 -1
  285. package/dist/utils/config-loader.js +0 -194
  286. package/dist/utils/config-loader.js.map +0 -1
  287. package/dist/utils/fallback.d.ts +0 -7
  288. package/dist/utils/fallback.d.ts.map +0 -1
  289. package/dist/utils/fallback.js +0 -20
  290. package/dist/utils/fallback.js.map +0 -1
  291. package/dist/utils/git.d.ts +0 -24
  292. package/dist/utils/git.d.ts.map +0 -1
  293. package/dist/utils/git.js +0 -71
  294. package/dist/utils/git.js.map +0 -1
  295. package/dist/utils/github.d.ts +0 -37
  296. package/dist/utils/github.d.ts.map +0 -1
  297. package/dist/utils/github.js +0 -53
  298. package/dist/utils/github.js.map +0 -1
  299. package/dist/utils/global-path.d.ts +0 -2
  300. package/dist/utils/global-path.d.ts.map +0 -1
  301. package/dist/utils/global-path.js +0 -32
  302. package/dist/utils/global-path.js.map +0 -1
  303. package/dist/utils/logger.d.ts +0 -6
  304. package/dist/utils/logger.d.ts.map +0 -1
  305. package/dist/utils/logger.js +0 -69
  306. package/dist/utils/logger.js.map +0 -1
  307. package/dist/utils/obs-capture.d.ts +0 -7
  308. package/dist/utils/obs-capture.d.ts.map +0 -1
  309. package/dist/utils/obs-capture.js +0 -49
  310. package/dist/utils/obs-capture.js.map +0 -1
  311. package/dist/utils/retry.d.ts +0 -11
  312. package/dist/utils/retry.d.ts.map +0 -1
  313. package/dist/utils/retry.js +0 -45
  314. package/dist/utils/retry.js.map +0 -1
  315. package/dist/utils/self-wiring.d.ts +0 -13
  316. package/dist/utils/self-wiring.d.ts.map +0 -1
  317. package/dist/utils/self-wiring.js +0 -86
  318. package/dist/utils/self-wiring.js.map +0 -1
  319. package/dist/utils/state.d.ts +0 -106
  320. package/dist/utils/state.d.ts.map +0 -1
  321. package/dist/utils/state.js +0 -166
  322. package/dist/utils/state.js.map +0 -1
  323. package/dist/utils/status.d.ts +0 -47
  324. package/dist/utils/status.d.ts.map +0 -1
  325. package/dist/utils/status.js +0 -147
  326. package/dist/utils/status.js.map +0 -1
  327. package/dist/utils/ttl-map.d.ts +0 -17
  328. package/dist/utils/ttl-map.d.ts.map +0 -1
  329. package/dist/utils/ttl-map.js +0 -67
  330. package/dist/utils/ttl-map.js.map +0 -1
@@ -1,471 +0,0 @@
1
- # shadcn/ui Accessibility Patterns
2
-
3
- ARIA patterns, keyboard navigation, screen reader support, and accessible component usage.
4
-
5
- ## Foundation: Radix UI Primitives
6
-
7
- shadcn/ui built on Radix UI primitives - unstyled, accessible components following WAI-ARIA design patterns.
8
-
9
- Benefits:
10
- - Keyboard navigation built-in
11
- - Screen reader announcements
12
- - Focus management
13
- - ARIA attributes automatically applied
14
- - Tested against accessibility standards
15
-
16
- ## Keyboard Navigation
17
-
18
- ### Focus Management
19
-
20
- **Focus visible states:**
21
- ```tsx
22
- <Button className="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
23
- Accessible Button
24
- </Button>
25
- ```
26
-
27
- **Skip to content:**
28
- ```tsx
29
- <a href="#main-content" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-50 focus:px-4 focus:py-2">
30
- Skip to content
31
- </a>
32
-
33
- <main id="main-content">
34
- {/* Content */}
35
- </main>
36
- ```
37
-
38
- ### Dialog/Modal Navigation
39
-
40
- Dialogs trap focus automatically via Radix Dialog primitive:
41
-
42
- ```tsx
43
- import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
44
-
45
- <Dialog>
46
- <DialogTrigger>Open</DialogTrigger>
47
- <DialogContent>
48
- {/* Focus trapped here */}
49
- <input /> {/* Auto-focused */}
50
- <Button>Action</Button>
51
- {/* Esc to close, Tab to navigate */}
52
- </DialogContent>
53
- </Dialog>
54
- ```
55
-
56
- Features:
57
- - Focus trapped within dialog
58
- - Esc key closes
59
- - Tab cycles through focusable elements
60
- - Focus returns to trigger on close
61
-
62
- ### Dropdown/Menu Navigation
63
-
64
- ```tsx
65
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
66
-
67
- <DropdownMenu>
68
- <DropdownMenuTrigger>Open</DropdownMenuTrigger>
69
- <DropdownMenuContent>
70
- <DropdownMenuItem>Profile</DropdownMenuItem>
71
- <DropdownMenuItem>Settings</DropdownMenuItem>
72
- <DropdownMenuItem>Logout</DropdownMenuItem>
73
- </DropdownMenuContent>
74
- </DropdownMenu>
75
- ```
76
-
77
- Keyboard shortcuts:
78
- - `Space/Enter`: Open menu
79
- - `Arrow Up/Down`: Navigate items
80
- - `Esc`: Close menu
81
- - `Tab`: Close and move focus
82
-
83
- ### Command Palette Navigation
84
-
85
- ```tsx
86
- import { Command } from "@/components/ui/command"
87
-
88
- <Command>
89
- <CommandInput placeholder="Search..." />
90
- <CommandList>
91
- <CommandGroup heading="Suggestions">
92
- <CommandItem>Calendar</CommandItem>
93
- <CommandItem>Search</CommandItem>
94
- </CommandGroup>
95
- </CommandList>
96
- </Command>
97
- ```
98
-
99
- Features:
100
- - Type to filter
101
- - Arrow keys to navigate
102
- - Enter to select
103
- - Esc to close
104
-
105
- ## Screen Reader Support
106
-
107
- ### Semantic HTML
108
-
109
- Use proper HTML elements:
110
-
111
- ```tsx
112
- // Good: Semantic HTML
113
- <button>Click me</button>
114
- <nav><a href="/">Home</a></nav>
115
-
116
- // Avoid: Div soup
117
- <div onClick={handler}>Click me</div>
118
- ```
119
-
120
- ### ARIA Labels
121
-
122
- **Label interactive elements:**
123
- ```tsx
124
- <Button aria-label="Close dialog">
125
- <X className="h-4 w-4" />
126
- </Button>
127
-
128
- <Input aria-label="Email address" type="email" />
129
- ```
130
-
131
- **Describe elements:**
132
- ```tsx
133
- <Button aria-describedby="delete-description">
134
- Delete Account
135
- </Button>
136
- <p id="delete-description" className="sr-only">
137
- This action permanently deletes your account and cannot be undone
138
- </p>
139
- ```
140
-
141
- ### Screen Reader Only Text
142
-
143
- Use `sr-only` class for screen reader only content:
144
-
145
- ```tsx
146
- <Button>
147
- <Trash className="h-4 w-4" />
148
- <span className="sr-only">Delete item</span>
149
- </Button>
150
-
151
- // CSS for sr-only
152
- .sr-only {
153
- position: absolute;
154
- width: 1px;
155
- height: 1px;
156
- padding: 0;
157
- margin: -1px;
158
- overflow: hidden;
159
- clip: rect(0, 0, 0, 0);
160
- white-space: nowrap;
161
- border-width: 0;
162
- }
163
- ```
164
-
165
- ### Live Regions
166
-
167
- Announce dynamic content:
168
-
169
- ```tsx
170
- <div aria-live="polite" aria-atomic="true">
171
- {message}
172
- </div>
173
-
174
- // For urgent updates
175
- <div aria-live="assertive">
176
- {error}
177
- </div>
178
- ```
179
-
180
- Toast component includes live region:
181
- ```tsx
182
- const { toast } = useToast()
183
-
184
- toast({
185
- title: "Success",
186
- description: "Profile updated"
187
- })
188
- // Announced to screen readers automatically
189
- ```
190
-
191
- ## Form Accessibility
192
-
193
- ### Labels and Descriptions
194
-
195
- **Always label inputs:**
196
- ```tsx
197
- import { Label } from "@/components/ui/label"
198
- import { Input } from "@/components/ui/input"
199
-
200
- <div>
201
- <Label htmlFor="email">Email</Label>
202
- <Input id="email" type="email" />
203
- </div>
204
- ```
205
-
206
- **Add descriptions:**
207
- ```tsx
208
- import { FormDescription, FormMessage } from "@/components/ui/form"
209
-
210
- <FormItem>
211
- <FormLabel>Username</FormLabel>
212
- <FormControl>
213
- <Input {...field} />
214
- </FormControl>
215
- <FormDescription>
216
- Your public display name
217
- </FormDescription>
218
- <FormMessage /> {/* Error messages */}
219
- </FormItem>
220
- ```
221
-
222
- ### Error Handling
223
-
224
- Announce errors to screen readers:
225
-
226
- ```tsx
227
- <FormField
228
- control={form.control}
229
- name="email"
230
- render={({ field, fieldState }) => (
231
- <FormItem>
232
- <FormLabel>Email</FormLabel>
233
- <FormControl>
234
- <Input
235
- {...field}
236
- aria-invalid={!!fieldState.error}
237
- aria-describedby={fieldState.error ? "email-error" : undefined}
238
- />
239
- </FormControl>
240
- <FormMessage id="email-error" />
241
- </FormItem>
242
- )}
243
- />
244
- ```
245
-
246
- ### Required Fields
247
-
248
- Indicate required fields:
249
-
250
- ```tsx
251
- <Label htmlFor="name">
252
- Name <span className="text-destructive">*</span>
253
- <span className="sr-only">(required)</span>
254
- </Label>
255
- <Input id="name" required />
256
- ```
257
-
258
- ### Fieldset and Legend
259
-
260
- Group related fields:
261
-
262
- ```tsx
263
- <fieldset>
264
- <legend className="text-lg font-semibold mb-4">
265
- Contact Information
266
- </legend>
267
- <div className="space-y-4">
268
- <FormField name="email" />
269
- <FormField name="phone" />
270
- </div>
271
- </fieldset>
272
- ```
273
-
274
- ## Component-Specific Patterns
275
-
276
- ### Accordion
277
-
278
- ```tsx
279
- import { Accordion } from "@/components/ui/accordion"
280
-
281
- <Accordion type="single" collapsible>
282
- <AccordionItem value="item-1">
283
- <AccordionTrigger>
284
- {/* Includes aria-expanded, aria-controls automatically */}
285
- Is it accessible?
286
- </AccordionTrigger>
287
- <AccordionContent>
288
- {/* Hidden when collapsed, announced when expanded */}
289
- Yes. Follows WAI-ARIA design pattern.
290
- </AccordionContent>
291
- </AccordionItem>
292
- </Accordion>
293
- ```
294
-
295
- ### Tabs
296
-
297
- ```tsx
298
- import { Tabs } from "@/components/ui/tabs"
299
-
300
- <Tabs defaultValue="account">
301
- <TabsList role="tablist">
302
- {/* Arrow keys navigate, Space/Enter activates */}
303
- <TabsTrigger value="account">Account</TabsTrigger>
304
- <TabsTrigger value="password">Password</TabsTrigger>
305
- </TabsList>
306
- <TabsContent value="account">
307
- {/* Hidden unless selected, aria-labelledby links to trigger */}
308
- Account content
309
- </TabsContent>
310
- </Tabs>
311
- ```
312
-
313
- ### Select
314
-
315
- ```tsx
316
- import { Select } from "@/components/ui/select"
317
-
318
- <Select>
319
- <SelectTrigger aria-label="Choose theme">
320
- <SelectValue placeholder="Theme" />
321
- </SelectTrigger>
322
- <SelectContent>
323
- {/* Keyboard navigable, announced to screen readers */}
324
- <SelectItem value="light">Light</SelectItem>
325
- <SelectItem value="dark">Dark</SelectItem>
326
- </SelectContent>
327
- </Select>
328
- ```
329
-
330
- ### Checkbox and Radio
331
-
332
- ```tsx
333
- import { Checkbox } from "@/components/ui/checkbox"
334
- import { Label } from "@/components/ui/label"
335
-
336
- <div className="flex items-center space-x-2">
337
- <Checkbox id="terms" aria-describedby="terms-description" />
338
- <Label htmlFor="terms">Accept terms</Label>
339
- </div>
340
- <p id="terms-description" className="text-sm text-muted-foreground">
341
- You agree to our Terms of Service and Privacy Policy
342
- </p>
343
- ```
344
-
345
- ### Alert
346
-
347
- ```tsx
348
- import { Alert } from "@/components/ui/alert"
349
-
350
- <Alert role="alert">
351
- {/* Announced immediately to screen readers */}
352
- <AlertTitle>Error</AlertTitle>
353
- <AlertDescription>
354
- Your session has expired
355
- </AlertDescription>
356
- </Alert>
357
- ```
358
-
359
- ## Color Contrast
360
-
361
- Ensure sufficient contrast between text and background.
362
-
363
- **WCAG Requirements:**
364
- - **AA**: 4.5:1 for normal text, 3:1 for large text
365
- - **AAA**: 7:1 for normal text, 4.5:1 for large text
366
-
367
- **Check defaults:**
368
- ```tsx
369
- // Good: High contrast
370
- <p className="text-gray-900 dark:text-gray-100">Text</p>
371
-
372
- // Avoid: Low contrast
373
- <p className="text-gray-400 dark:text-gray-600">Hard to read</p>
374
- ```
375
-
376
- **Muted text:**
377
- ```tsx
378
- // Use semantic muted foreground
379
- <p className="text-muted-foreground">
380
- Secondary text with accessible contrast
381
- </p>
382
- ```
383
-
384
- ## Focus Indicators
385
-
386
- Always provide visible focus indicators:
387
-
388
- **Default focus ring:**
389
- ```tsx
390
- <Button className="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2">
391
- Button
392
- </Button>
393
- ```
394
-
395
- **Custom focus styles:**
396
- ```tsx
397
- <a href="#" className="focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:underline">
398
- Link
399
- </a>
400
- ```
401
-
402
- **Don't remove focus styles:**
403
- ```tsx
404
- // Avoid
405
- <button className="focus:outline-none">Bad</button>
406
-
407
- // Use focus-visible instead
408
- <button className="focus-visible:ring-2">Good</button>
409
- ```
410
-
411
- ## Motion and Animation
412
-
413
- Respect reduced motion preference:
414
-
415
- ```css
416
- @media (prefers-reduced-motion: reduce) {
417
- * {
418
- animation-duration: 0.01ms !important;
419
- animation-iteration-count: 1 !important;
420
- transition-duration: 0.01ms !important;
421
- }
422
- }
423
- ```
424
-
425
- In components:
426
- ```tsx
427
- <div className="transition-all motion-reduce:transition-none">
428
- Respects user preference
429
- </div>
430
- ```
431
-
432
- ## Testing Checklist
433
-
434
- - [ ] All interactive elements keyboard accessible
435
- - [ ] Focus indicators visible
436
- - [ ] Screen reader announces all content correctly
437
- - [ ] Form errors announced and associated
438
- - [ ] Color contrast meets WCAG AA
439
- - [ ] Semantic HTML used
440
- - [ ] ARIA labels provided for icon-only buttons
441
- - [ ] Modal/dialog focus trap works
442
- - [ ] Dropdown/select keyboard navigable
443
- - [ ] Live regions announce updates
444
- - [ ] Respects reduced motion preference
445
- - [ ] Works with browser zoom up to 200%
446
- - [ ] Tab order logical
447
- - [ ] Skip links provided for navigation
448
-
449
- ## Tools
450
-
451
- **Testing tools:**
452
- - Lighthouse accessibility audit
453
- - axe DevTools browser extension
454
- - NVDA/JAWS screen readers
455
- - Keyboard-only navigation testing
456
- - Color contrast checkers (Contrast Ratio, WebAIM)
457
-
458
- **Automated testing:**
459
- ```bash
460
- npm install -D @axe-core/react
461
- ```
462
-
463
- ```tsx
464
- import { useEffect } from 'react'
465
-
466
- if (process.env.NODE_ENV === 'development') {
467
- import('@axe-core/react').then((axe) => {
468
- axe.default(React, ReactDOM, 1000)
469
- })
470
- }
471
- ```