@sarjallab09/figma-intelligence 1.1.0 → 1.2.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 (297) hide show
  1. package/README.md +67 -36
  2. package/dist/bin/cli.js +2 -0
  3. package/dist/design-bridge/bridge.js +2 -0
  4. package/dist/figma-bridge-plugin/bridge-relay.js +2 -0
  5. package/dist/figma-bridge-plugin/code.js +1 -0
  6. package/{figma-bridge-plugin → dist/figma-bridge-plugin}/package-lock.json +0 -3
  7. package/dist/figma-bridge-plugin/ui.html +4970 -0
  8. package/dist/figma-intelligence-layer/dist/index.js +2 -0
  9. package/dist/scripts/clean-existing-chunks.js +2 -0
  10. package/dist/scripts/connect-ai-tool.js +2 -0
  11. package/dist/scripts/convert-hub-pdfs.js +2 -0
  12. package/dist/scripts/figma-mcp-status.js +2 -0
  13. package/dist/scripts/register-codex-mcp.js +2 -0
  14. package/dist/scripts/test-copilot-chat.js +2 -0
  15. package/package.json +11 -8
  16. package/bin/cli.js +0 -859
  17. package/design-bridge/bridge.js +0 -196
  18. package/design-bridge/lib/assets.js +0 -367
  19. package/design-bridge/lib/prompt.js +0 -85
  20. package/design-bridge/lib/server.js +0 -66
  21. package/design-bridge/lib/stitch.js +0 -37
  22. package/design-bridge/lib/tokens.js +0 -82
  23. package/design-bridge/package-lock.json +0 -579
  24. package/figma-bridge-plugin/README.md +0 -97
  25. package/figma-bridge-plugin/anthropic-chat-runner.js +0 -192
  26. package/figma-bridge-plugin/bridge-relay.js +0 -2505
  27. package/figma-bridge-plugin/chat-runner.js +0 -485
  28. package/figma-bridge-plugin/code.js +0 -1534
  29. package/figma-bridge-plugin/codex-runner.js +0 -505
  30. package/figma-bridge-plugin/component-schemas.js +0 -110
  31. package/figma-bridge-plugin/content-context.js +0 -869
  32. package/figma-bridge-plugin/create-button.js +0 -216
  33. package/figma-bridge-plugin/gemini-cli-runner.js +0 -291
  34. package/figma-bridge-plugin/gemini-runner.js +0 -187
  35. package/figma-bridge-plugin/html-to-figma.js +0 -927
  36. package/figma-bridge-plugin/knowledge-hub/.gitkeep +0 -0
  37. package/figma-bridge-plugin/knowledge-hub/uspec-references/anatomy-spec.md +0 -159
  38. package/figma-bridge-plugin/knowledge-hub/uspec-references/api-spec.md +0 -162
  39. package/figma-bridge-plugin/knowledge-hub/uspec-references/color-spec.md +0 -148
  40. package/figma-bridge-plugin/knowledge-hub/uspec-references/full-spec-template.md +0 -314
  41. package/figma-bridge-plugin/knowledge-hub/uspec-references/property-spec.md +0 -175
  42. package/figma-bridge-plugin/knowledge-hub/uspec-references/screen-reader-spec.md +0 -180
  43. package/figma-bridge-plugin/knowledge-hub/uspec-references/structure-spec.md +0 -165
  44. package/figma-bridge-plugin/perplexity-runner.js +0 -188
  45. package/figma-bridge-plugin/references/SKILL.md +0 -178
  46. package/figma-bridge-plugin/references/anatomy-spec.md +0 -159
  47. package/figma-bridge-plugin/references/api-spec.md +0 -162
  48. package/figma-bridge-plugin/references/color-spec.md +0 -148
  49. package/figma-bridge-plugin/references/full-spec-template.md +0 -314
  50. package/figma-bridge-plugin/references/property-spec.md +0 -175
  51. package/figma-bridge-plugin/references/screen-reader-spec.md +0 -180
  52. package/figma-bridge-plugin/references/structure-spec.md +0 -165
  53. package/figma-bridge-plugin/shared-prompt-config.js +0 -645
  54. package/figma-bridge-plugin/spec-helpers/build-table.js +0 -269
  55. package/figma-bridge-plugin/spec-helpers/classify-elements.js +0 -189
  56. package/figma-bridge-plugin/spec-helpers/index.js +0 -35
  57. package/figma-bridge-plugin/spec-helpers/parse-figma-link.js +0 -49
  58. package/figma-bridge-plugin/spec-helpers/position-markers.js +0 -158
  59. package/figma-bridge-plugin/stitch-auth.js +0 -322
  60. package/figma-bridge-plugin/stitch-runner.js +0 -1427
  61. package/figma-bridge-plugin/token-resolver.js +0 -107
  62. package/figma-bridge-plugin/ui.html +0 -4542
  63. package/figma-intelligence-layer/.env.example +0 -39
  64. package/figma-intelligence-layer/docs/local-image-generation.md +0 -60
  65. package/figma-intelligence-layer/examples/comfyui-workflow-template.example.json +0 -101
  66. package/figma-intelligence-layer/jest.config.js +0 -14
  67. package/figma-intelligence-layer/mcp-config.json +0 -19
  68. package/figma-intelligence-layer/package-lock.json +0 -5892
  69. package/figma-intelligence-layer/scripts/setup-comfyui-local.sh +0 -67
  70. package/figma-intelligence-layer/scripts/start-comfyui.sh +0 -33
  71. package/figma-intelligence-layer/src/index.ts +0 -2233
  72. package/figma-intelligence-layer/src/shared/auto-layout-validator.ts +0 -404
  73. package/figma-intelligence-layer/src/shared/cache.ts +0 -187
  74. package/figma-intelligence-layer/src/shared/color-operations.ts +0 -533
  75. package/figma-intelligence-layer/src/shared/color-utils.ts +0 -138
  76. package/figma-intelligence-layer/src/shared/component-script-builder.ts +0 -413
  77. package/figma-intelligence-layer/src/shared/component-templates.ts +0 -2767
  78. package/figma-intelligence-layer/src/shared/concept-taxonomy.ts +0 -694
  79. package/figma-intelligence-layer/src/shared/decision-log.ts +0 -128
  80. package/figma-intelligence-layer/src/shared/design-system-context.ts +0 -568
  81. package/figma-intelligence-layer/src/shared/design-system-intelligence.ts +0 -131
  82. package/figma-intelligence-layer/src/shared/design-system-matcher.ts +0 -184
  83. package/figma-intelligence-layer/src/shared/design-system-normalizers.ts +0 -196
  84. package/figma-intelligence-layer/src/shared/design-system-tokens.ts +0 -295
  85. package/figma-intelligence-layer/src/shared/dtcg-validator.ts +0 -530
  86. package/figma-intelligence-layer/src/shared/enrichment-pipeline.ts +0 -671
  87. package/figma-intelligence-layer/src/shared/figma-bridge.ts +0 -1418
  88. package/figma-intelligence-layer/src/shared/font-config.ts +0 -126
  89. package/figma-intelligence-layer/src/shared/icon-catalog.ts +0 -360
  90. package/figma-intelligence-layer/src/shared/icon-fetch.ts +0 -80
  91. package/figma-intelligence-layer/src/shared/prototype-script-builder.ts +0 -162
  92. package/figma-intelligence-layer/src/shared/response-compression.ts +0 -440
  93. package/figma-intelligence-layer/src/shared/semantic-token-catalog.ts +0 -324
  94. package/figma-intelligence-layer/src/shared/token-binder.ts +0 -505
  95. package/figma-intelligence-layer/src/shared/token-math.ts +0 -427
  96. package/figma-intelligence-layer/src/shared/token-naming.ts +0 -468
  97. package/figma-intelligence-layer/src/shared/token-utils.ts +0 -420
  98. package/figma-intelligence-layer/src/shared/types.ts +0 -346
  99. package/figma-intelligence-layer/src/shared/typography-presets.ts +0 -94
  100. package/figma-intelligence-layer/src/shared/unsplash.ts +0 -165
  101. package/figma-intelligence-layer/src/shared/vision-client.ts +0 -607
  102. package/figma-intelligence-layer/src/shared/vision-provider-anthropic.ts +0 -334
  103. package/figma-intelligence-layer/src/shared/vision-provider-openai.ts +0 -446
  104. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-handler.ts +0 -782
  105. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotate-renderer.ts +0 -496
  106. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/a11y-annotation-kit.ts +0 -230
  107. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/colorblind-sim.ts +0 -66
  108. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/index.ts +0 -810
  109. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-analyzer.ts +0 -1191
  110. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-figma-page.ts +0 -1346
  111. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/keyboard-sr-order-handler.ts +0 -148
  112. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-figma-page.ts +0 -499
  113. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/vpat-report.ts +0 -910
  114. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-checker.ts +0 -989
  115. package/figma-intelligence-layer/src/tools/phase1-vision/a11y-audit/wcag-criteria.ts +0 -1160
  116. package/figma-intelligence-layer/src/tools/phase1-vision/design-from-ref/index.ts +0 -424
  117. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/component-recognizer.ts +0 -38
  118. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/ds-matcher.ts +0 -111
  119. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/font-matcher.ts +0 -114
  120. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/icon-resolver.ts +0 -103
  121. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/index.ts +0 -1060
  122. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/layout-segmenter.ts +0 -18
  123. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/token-inferencer.ts +0 -39
  124. package/figma-intelligence-layer/src/tools/phase1-vision/screen-cloner/vision-pipeline.ts +0 -58
  125. package/figma-intelligence-layer/src/tools/phase1-vision/sketch-to-design/index.ts +0 -298
  126. package/figma-intelligence-layer/src/tools/phase1-vision/visual-audit/index.ts +0 -197
  127. package/figma-intelligence-layer/src/tools/phase2-accuracy/component-audit/index.ts +0 -494
  128. package/figma-intelligence-layer/src/tools/phase2-accuracy/intent-translator/index.ts +0 -356
  129. package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/container-patterns.ts +0 -123
  130. package/figma-intelligence-layer/src/tools/phase2-accuracy/layout-intelligence/index.ts +0 -663
  131. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/built-in-rules.yaml +0 -56
  132. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/index.ts +0 -614
  133. package/figma-intelligence-layer/src/tools/phase2-accuracy/lint-rules/rule-engine.ts +0 -113
  134. package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/color-theory.ts +0 -178
  135. package/figma-intelligence-layer/src/tools/phase2-accuracy/theme-generator/index.ts +0 -470
  136. package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/index.ts +0 -429
  137. package/figma-intelligence-layer/src/tools/phase2-accuracy/variant-expander/token-override-maps.ts +0 -226
  138. package/figma-intelligence-layer/src/tools/phase3-generation/ai-image-insert/index.ts +0 -535
  139. package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/index.ts +0 -660
  140. package/figma-intelligence-layer/src/tools/phase3-generation/component-archaeologist/pattern-fingerprints.ts +0 -209
  141. package/figma-intelligence-layer/src/tools/phase3-generation/composition-builder/index.ts +0 -540
  142. package/figma-intelligence-layer/src/tools/phase3-generation/figma-animated-build.ts +0 -391
  143. package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/index.ts +0 -2019
  144. package/figma-intelligence-layer/src/tools/phase3-generation/page-architect/screen-templates.ts +0 -131
  145. package/figma-intelligence-layer/src/tools/phase3-generation/prototype-map/index.ts +0 -381
  146. package/figma-intelligence-layer/src/tools/phase3-generation/prototype-wire/index.ts +0 -565
  147. package/figma-intelligence-layer/src/tools/phase3-generation/swarm-build/index.ts +0 -764
  148. package/figma-intelligence-layer/src/tools/phase3-generation/system-drift/index.ts +0 -535
  149. package/figma-intelligence-layer/src/tools/phase3-generation/unsplash-search/index.ts +0 -84
  150. package/figma-intelligence-layer/src/tools/phase3-generation/url-to-frame/index.ts +0 -401
  151. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/css-animations.ts +0 -68
  152. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/framer-motion.ts +0 -78
  153. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/code-generators/swift-animations.ts +0 -93
  154. package/figma-intelligence-layer/src/tools/phase4-sync/animation-specifier/index.ts +0 -596
  155. package/figma-intelligence-layer/src/tools/phase4-sync/ci-check/index.ts +0 -462
  156. package/figma-intelligence-layer/src/tools/phase4-sync/export-tokens/index.ts +0 -1470
  157. package/figma-intelligence-layer/src/tools/phase4-sync/generate-component-code/index.ts +0 -829
  158. package/figma-intelligence-layer/src/tools/phase4-sync/handoff-spec/index.ts +0 -702
  159. package/figma-intelligence-layer/src/tools/phase4-sync/icon-library-sync/index.ts +0 -483
  160. package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/index.ts +0 -501
  161. package/figma-intelligence-layer/src/tools/phase4-sync/sync-from-code/storybook-parser.ts +0 -106
  162. package/figma-intelligence-layer/src/tools/phase4-sync/watch-docs/index.ts +0 -676
  163. package/figma-intelligence-layer/src/tools/phase4-sync/webhook-listener/index.ts +0 -560
  164. package/figma-intelligence-layer/src/tools/phase5-governance/apg-doc/index.ts +0 -1043
  165. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/component-detection.ts +0 -620
  166. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/anatomy.ts +0 -331
  167. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/color-tokens.ts +0 -77
  168. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/properties.ts +0 -54
  169. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/snapshot.ts +0 -287
  170. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/spacing.ts +0 -71
  171. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/states.ts +0 -43
  172. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/extractors/typography.ts +0 -71
  173. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/index.ts +0 -221
  174. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/_default.ts +0 -166
  175. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/accordion.ts +0 -232
  176. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/alert.ts +0 -234
  177. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar-group.ts +0 -270
  178. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/avatar.ts +0 -249
  179. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/badge.ts +0 -231
  180. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/banner.ts +0 -293
  181. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/breadcrumb.ts +0 -240
  182. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/button.ts +0 -243
  183. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/calendar.ts +0 -307
  184. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/card.ts +0 -143
  185. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/checkbox.ts +0 -227
  186. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/chip.ts +0 -233
  187. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/combobox.ts +0 -282
  188. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/datepicker.ts +0 -276
  189. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/divider.ts +0 -223
  190. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/drawer.ts +0 -255
  191. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/dropdown-menu.ts +0 -289
  192. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/empty-state.ts +0 -261
  193. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/file-uploader.ts +0 -290
  194. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/form.ts +0 -265
  195. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/grid.ts +0 -238
  196. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/icon.ts +0 -255
  197. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/index.ts +0 -128
  198. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-edit.ts +0 -286
  199. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/inline-message.ts +0 -255
  200. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/input.ts +0 -330
  201. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/link.ts +0 -247
  202. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/list.ts +0 -250
  203. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/menu.ts +0 -247
  204. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/modal.ts +0 -144
  205. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navbar.ts +0 -264
  206. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/navigation.ts +0 -251
  207. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/number-input.ts +0 -261
  208. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/pagination.ts +0 -248
  209. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/popover.ts +0 -270
  210. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/progress.ts +0 -251
  211. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/radio.ts +0 -142
  212. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/range-slider.ts +0 -282
  213. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/rating.ts +0 -250
  214. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/search.ts +0 -258
  215. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/segmented-control.ts +0 -265
  216. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/select.ts +0 -319
  217. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/skeleton.ts +0 -256
  218. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/slider.ts +0 -232
  219. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/spinner.ts +0 -239
  220. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/status-dot.ts +0 -252
  221. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/stepper.ts +0 -270
  222. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/table.ts +0 -244
  223. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tabs.ts +0 -143
  224. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tag.ts +0 -243
  225. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/textarea.ts +0 -259
  226. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/time-picker.ts +0 -293
  227. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toast.ts +0 -144
  228. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toggle.ts +0 -289
  229. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/toolbar.ts +0 -267
  230. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/tooltip.ts +0 -232
  231. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/treeview.ts +0 -257
  232. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/knowledge/typography.ts +0 -319
  233. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/legacy-compat.ts +0 -121
  234. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/anatomy-diagram.ts +0 -430
  235. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/figma-page.ts +0 -312
  236. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/json.ts +0 -129
  237. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/markdown.ts +0 -78
  238. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/renderers/visual-doc.ts +0 -2333
  239. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/accessibility.ts +0 -100
  240. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/anatomy.ts +0 -32
  241. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/color-tokens.ts +0 -59
  242. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/content-guidance.ts +0 -18
  243. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/design-tokens.ts +0 -53
  244. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/interaction-rules.ts +0 -19
  245. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/overview.ts +0 -91
  246. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/properties-api.ts +0 -71
  247. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/qa-criteria.ts +0 -19
  248. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/related-components.ts +0 -110
  249. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/responsive.ts +0 -19
  250. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/size-specs.ts +0 -67
  251. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/spacing-structure.ts +0 -58
  252. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/state-specs.ts +0 -79
  253. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/states.ts +0 -50
  254. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/type-hierarchy.ts +0 -33
  255. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/typography.ts +0 -55
  256. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/usage-guidelines.ts +0 -73
  257. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/sections/variants.ts +0 -81
  258. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec/types.ts +0 -409
  259. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/index.ts +0 -198
  260. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/renderer.ts +0 -701
  261. package/figma-intelligence-layer/src/tools/phase5-governance/component-spec-sheet/types.ts +0 -88
  262. package/figma-intelligence-layer/src/tools/phase5-governance/decision-log/index.ts +0 -135
  263. package/figma-intelligence-layer/src/tools/phase5-governance/design-decision-log/index.ts +0 -491
  264. package/figma-intelligence-layer/src/tools/phase5-governance/ds-primitives/index.ts +0 -416
  265. package/figma-intelligence-layer/src/tools/phase5-governance/ds-scaffolder/index.ts +0 -722
  266. package/figma-intelligence-layer/src/tools/phase5-governance/ds-variables/index.ts +0 -449
  267. package/figma-intelligence-layer/src/tools/phase5-governance/health-report/index.ts +0 -393
  268. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/index.ts +0 -406
  269. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/figma-page.ts +0 -292
  270. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/json.ts +0 -24
  271. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/markdown.ts +0 -172
  272. package/figma-intelligence-layer/src/tools/phase5-governance/taxonomy-docs/renderers/naming-guide.ts +0 -409
  273. package/figma-intelligence-layer/src/tools/phase5-governance/token-analytics/index.ts +0 -594
  274. package/figma-intelligence-layer/src/tools/phase5-governance/token-docs/index.ts +0 -710
  275. package/figma-intelligence-layer/src/tools/phase5-governance/token-migrate/index.ts +0 -458
  276. package/figma-intelligence-layer/src/tools/phase5-governance/token-naming/index.ts +0 -134
  277. package/figma-intelligence-layer/tests/apg-doc.test.ts +0 -101
  278. package/figma-intelligence-layer/tests/design-system-context.test.ts +0 -152
  279. package/figma-intelligence-layer/tests/design-system-matcher.test.ts +0 -144
  280. package/figma-intelligence-layer/tests/figma-bridge.test.ts +0 -83
  281. package/figma-intelligence-layer/tests/generate-image-and-insert.test.ts +0 -56
  282. package/figma-intelligence-layer/tests/screen-cloner-regression.test.ts +0 -69
  283. package/figma-intelligence-layer/tests/smoke.test.ts +0 -174
  284. package/figma-intelligence-layer/tests/spec-generator.test.ts +0 -127
  285. package/figma-intelligence-layer/tests/token-migrate.test.ts +0 -21
  286. package/figma-intelligence-layer/tests/token-naming.test.ts +0 -30
  287. package/figma-intelligence-layer/tsconfig.json +0 -19
  288. package/scripts/clean-existing-chunks.js +0 -179
  289. package/scripts/connect-ai-tool.js +0 -490
  290. package/scripts/convert-hub-pdfs.js +0 -425
  291. package/scripts/figma-mcp-status.js +0 -349
  292. package/scripts/register-codex-mcp.js +0 -96
  293. /package/{design-bridge → dist/design-bridge}/.env.example +0 -0
  294. /package/{design-bridge → dist/design-bridge}/package.json +0 -0
  295. /package/{figma-bridge-plugin → dist/figma-bridge-plugin}/manifest.json +0 -0
  296. /package/{figma-bridge-plugin → dist/figma-bridge-plugin}/package.json +0 -0
  297. /package/{figma-intelligence-layer → dist/figma-intelligence-layer}/package.json +0 -0
@@ -1,1346 +0,0 @@
1
- /**
2
- * Keyboard & Screen Reader Order — Figma Page Renderer
3
- * Renders the full accessibility annotation as an enterprise-quality Figma page
4
- * with auto-layout tables, callout boxes, and structured sections.
5
- *
6
- * IMPORTANT Figma Plugin API pattern:
7
- * layoutSizingHorizontal = "FILL" only works AFTER the node is appended
8
- * to an auto-layout parent. Always: appendChild() first, then set sizing.
9
- */
10
-
11
- import type {
12
- A11yOrderAnalysis,
13
- TabOrderEntry,
14
- ReadingOrderNode,
15
- FocusAnnouncement,
16
- StateChangeRule,
17
- FocusRule,
18
- AriaReq,
19
- KBRule,
20
- Warning,
21
- AuditSummaryRow,
22
- } from "./keyboard-sr-order-analyzer.js";
23
-
24
- // ── Design Tokens ────────────────────────────────────────────────────────────
25
-
26
- const PAGE_W = 1200;
27
- const PAD = 50;
28
- const CONTENT_W = PAGE_W - PAD * 2;
29
-
30
- const C = {
31
- textMain: "{r:0.067,g:0.094,b:0.153}",
32
- textMuted: "{r:0.294,g:0.333,b:0.388}",
33
- textWhite: "{r:1,g:1,b:1}",
34
- bgPage: "{r:1,g:1,b:1}",
35
- bgHeader: "{r:0.067,g:0.094,b:0.153}",
36
- bgTableHeader: "{r:0.953,g:0.957,b:0.965}",
37
- border: "{r:0.898,g:0.906,b:0.922}",
38
- accent: "{r:0.2,g:0.45,b:0.9}",
39
- warnBg: "{r:1,g:0.95,b:0.95}",
40
- warnBorder: "{r:0.863,g:0.149,b:0.149}",
41
- warnAmberBg: "{r:1,g:0.98,b:0.93}",
42
- warnAmberBdr: "{r:0.918,g:0.576,b:0.051}",
43
- infoBg: "{r:0.94,g:0.96,b:1}",
44
- infoBorder: "{r:0.2,g:0.45,b:0.9}",
45
- green: "{r:0.086,g:0.639,b:0.290}",
46
- greenBg: "{r:0.863,g:0.965,b:0.898}",
47
- };
48
-
49
- type Bridge = {
50
- execute(code: string): Promise<{ success: boolean; result?: unknown; error?: string }>;
51
- };
52
-
53
- function esc(s: string): string { return JSON.stringify(s); }
54
-
55
- // ── Font Loader ──────────────────────────────────────────────────────────────
56
-
57
- const FL = `
58
- var F={};
59
- async function lf(k,a){for(var i=0;i<a.length;i++){try{await figma.loadFontAsync(a[i]);F[k]=a[i];return}catch(e){}}F[k]={family:"Arial",style:"Regular"};try{await figma.loadFontAsync(F[k])}catch(e){}}
60
- await lf("b",[{family:"Inter",style:"Bold"},{family:"Roboto",style:"Bold"}]);
61
- await lf("sb",[{family:"Inter",style:"SemiBold"},{family:"Inter",style:"Medium"},{family:"Roboto",style:"Medium"}]);
62
- await lf("r",[{family:"Inter",style:"Regular"},{family:"Roboto",style:"Regular"}]);
63
- await lf("mono",[{family:"Roboto Mono",style:"Regular"},{family:"Courier New",style:"Regular"}]);
64
- `;
65
-
66
- // ── Layout Helpers ───────────────────────────────────────────────────────────
67
-
68
- function spacerJS(h: number, parent: string = "m"): string {
69
- return `(function(){var sp=figma.createFrame();sp.resize(4,${h});sp.fills=[];${parent}.appendChild(sp);sp.layoutSizingHorizontal="FILL";})();`;
70
- }
71
-
72
- function dividerJS(parent: string = "m"): string {
73
- return `(function(){var dv=figma.createRectangle();dv.resize(4,2);dv.fills=[{type:"SOLID",color:${C.border}}];${parent}.appendChild(dv);dv.layoutSizingHorizontal="FILL";})();`;
74
- }
75
-
76
- function sectionHeadingJS(title: string, parent: string = "m"): string {
77
- return `(function(){
78
- var t=figma.createText();t.fontName=F.b;t.fontSize=22;
79
- t.lineHeight={unit:"PIXELS",value:30};
80
- t.characters=${esc(title)};
81
- t.fills=[{type:"SOLID",color:${C.textMain}}];
82
- t.textAutoResize="HEIGHT";
83
- ${parent}.appendChild(t);t.layoutSizingHorizontal="FILL";
84
- })();`;
85
- }
86
-
87
- function truncate(text: string, maxLen: number): string {
88
- if (text.length <= maxLen) return text;
89
- return text.slice(0, maxLen - 3) + "...";
90
- }
91
-
92
- // ── Main Renderer ────────────────────────────────────────────────────────────
93
-
94
- export async function renderKeyboardSrOrderPage(
95
- bridge: Bridge,
96
- analysis: A11yOrderAnalysis,
97
- customPageName?: string,
98
- ): Promise<{ pageId: string }> {
99
- const pageName =
100
- customPageName ||
101
- `A11y \u2014 Keyboard & SR Order \u2014 ${analysis.header.frameName} \u2014 ${analysis.header.date}`;
102
-
103
- // Step 1: Create page + master frame
104
- const initResult = await bridge.execute(`
105
- (async () => {
106
- await figma.loadAllPagesAsync();
107
- var nm=${esc(pageName)};
108
- var mm=figma.root.children.filter(function(p){return p.name===nm;});
109
- var pg;
110
- if(mm.length>0){pg=mm[0];for(var d=1;d<mm.length;d++)mm[d].remove();}
111
- else{pg=figma.createPage();}
112
- pg.name=nm;
113
- await figma.setCurrentPageAsync(pg);
114
- var ch=pg.children.slice();
115
- for(var i=0;i<ch.length;i++)ch[i].remove();
116
-
117
- var m=figma.createFrame();
118
- m.name="Keyboard & SR Order Annotation";
119
- m.layoutMode="VERTICAL";
120
- m.primaryAxisSizingMode="AUTO";
121
- m.counterAxisSizingMode="FIXED";
122
- m.resize(${PAGE_W},100);
123
- m.paddingTop=${PAD};m.paddingBottom=${PAD};
124
- m.paddingLeft=${PAD};m.paddingRight=${PAD};
125
- m.itemSpacing=0;
126
- m.fills=[{type:"SOLID",color:${C.bgPage}}];
127
- m.clipsContent=false;
128
- pg.appendChild(m);
129
- return {pageId:pg.id,mId:m.id};
130
- })();
131
- `);
132
- if (!initResult.success) throw new Error(`KSR init: ${initResult.error}`);
133
- const { pageId, mId } = initResult.result as { pageId: string; mId: string };
134
-
135
- // Step 2: Render header
136
- await renderHeader(bridge, mId, analysis);
137
-
138
- // Step 3: Scope & Assumptions
139
- await renderScopeAndAssumptions(bridge, mId, analysis);
140
-
141
- // Step 4: Keyboard Tab Order table
142
- await renderTabOrderTable(bridge, mId, analysis.keyboardTabOrder);
143
-
144
- // Step 5: Screen Reader Reading Order
145
- await renderReadingOrder(bridge, mId, analysis.screenReaderReadingOrder);
146
-
147
- // Step 6: Interaction Announcements
148
- await renderInteractionAnnouncements(bridge, mId, analysis);
149
-
150
- // Step 7: Focus Management
151
- await renderFocusManagement(bridge, mId, analysis.focusManagement);
152
-
153
- // Step 8: Implementation Notes
154
- await renderImplementationNotes(bridge, mId, analysis);
155
-
156
- // Step 9: Warnings
157
- await renderWarnings(bridge, mId, analysis.warnings);
158
-
159
- // Step 10: Audit Summary
160
- await renderAuditSummary(bridge, mId, analysis.auditSummary);
161
-
162
- // Final: Zoom to fit
163
- await bridge.execute(`
164
- (async () => {
165
- var m=await figma.getNodeByIdAsync(${esc(mId)});
166
- if(m)figma.viewport.scrollAndZoomIntoView([m]);
167
- return{ok:true};
168
- })();
169
- `);
170
-
171
- return { pageId };
172
- }
173
-
174
- // ── Section Renderers ───────────────────────────────────────────────────────
175
-
176
- async function renderHeader(
177
- bridge: Bridge,
178
- mId: string,
179
- analysis: A11yOrderAnalysis
180
- ): Promise<void> {
181
- const h = analysis.header;
182
- await bridge.execute(`
183
- (async () => {
184
- ${FL}
185
- var m=await figma.getNodeByIdAsync(${esc(mId)});
186
- if(!m)return{error:"no master"};
187
-
188
- var hdr=figma.createFrame();
189
- hdr.name="Header";
190
- hdr.layoutMode="VERTICAL";
191
- hdr.primaryAxisSizingMode="AUTO";
192
- hdr.counterAxisSizingMode="AUTO";
193
- hdr.paddingTop=40;hdr.paddingBottom=40;
194
- hdr.paddingLeft=40;hdr.paddingRight=40;
195
- hdr.itemSpacing=12;
196
- hdr.cornerRadius=12;
197
- hdr.fills=[{type:"SOLID",color:${C.bgHeader}}];
198
- m.appendChild(hdr);
199
- hdr.layoutSizingHorizontal="FILL";
200
-
201
- // Badge
202
- var badge=figma.createFrame();
203
- badge.name="Standard Badge";
204
- badge.layoutMode="HORIZONTAL";
205
- badge.primaryAxisSizingMode="AUTO";
206
- badge.counterAxisSizingMode="AUTO";
207
- badge.paddingTop=6;badge.paddingBottom=6;
208
- badge.paddingLeft=14;badge.paddingRight=14;
209
- badge.cornerRadius=6;
210
- badge.fills=[{type:"SOLID",color:${C.accent}}];
211
- hdr.appendChild(badge);
212
- var bt=figma.createText();bt.fontName=F.sb;bt.fontSize=13;
213
- bt.characters=${esc(h.standard)};
214
- bt.fills=[{type:"SOLID",color:${C.textWhite}}];
215
- badge.appendChild(bt);
216
-
217
- // Title
218
- var t1=figma.createText();t1.fontName=F.b;t1.fontSize=32;
219
- t1.lineHeight={unit:"PIXELS",value:40};
220
- t1.characters="Keyboard & Screen Reader Order";
221
- t1.fills=[{type:"SOLID",color:${C.textWhite}}];
222
- t1.textAutoResize="HEIGHT";
223
- hdr.appendChild(t1);t1.layoutSizingHorizontal="FILL";
224
-
225
- // Subtitle
226
- var sub=figma.createText();sub.fontName=F.r;sub.fontSize=15;
227
- sub.lineHeight={unit:"PIXELS",value:22};
228
- sub.characters=${esc(`${h.frameName} \u00b7 ${h.date} \u00b7 Node ${h.nodeId}`)};
229
- sub.fills=[{type:"SOLID",color:{r:0.7,g:0.75,b:0.82}}];
230
- sub.textAutoResize="HEIGHT";
231
- hdr.appendChild(sub);sub.layoutSizingHorizontal="FILL";
232
-
233
- // Subtitle line 2
234
- var sub2=figma.createText();sub2.fontName=F.r;sub2.fontSize=13;
235
- sub2.lineHeight={unit:"PIXELS",value:20};
236
- sub2.characters="Accessibility Annotation (Developer Handoff)";
237
- sub2.fills=[{type:"SOLID",color:{r:0.6,g:0.65,b:0.72}}];
238
- sub2.textAutoResize="HEIGHT";
239
- hdr.appendChild(sub2);sub2.layoutSizingHorizontal="FILL";
240
-
241
- return{ok:true};
242
- })();
243
- `);
244
- }
245
-
246
- async function renderScopeAndAssumptions(
247
- bridge: Bridge,
248
- mId: string,
249
- analysis: A11yOrderAnalysis
250
- ): Promise<void> {
251
- const assumptionsText = analysis.assumptions
252
- .map((a, i) => `\u2022 ${a}`)
253
- .join("\\n");
254
-
255
- await bridge.execute(`
256
- (async () => {
257
- ${FL}
258
- var m=await figma.getNodeByIdAsync(${esc(mId)});
259
- if(!m)return{error:"no master"};
260
-
261
- ${spacerJS(32)}
262
- ${sectionHeadingJS("Scope")}
263
- ${spacerJS(8)}
264
-
265
- var scope=figma.createText();scope.fontName=F.r;scope.fontSize=14;
266
- scope.lineHeight={unit:"PIXELS",value:22};
267
- scope.characters=${esc(analysis.scope)};
268
- scope.fills=[{type:"SOLID",color:${C.textMain}}];
269
- scope.textAutoResize="HEIGHT";
270
- m.appendChild(scope);scope.layoutSizingHorizontal="FILL";
271
-
272
- ${spacerJS(24)}
273
- ${sectionHeadingJS("Assumptions")}
274
- ${spacerJS(8)}
275
-
276
- var assumptions=figma.createText();assumptions.fontName=F.r;assumptions.fontSize=14;
277
- assumptions.lineHeight={unit:"PIXELS",value:22};
278
- assumptions.characters=${esc(analysis.assumptions.join("\n"))};
279
- assumptions.fills=[{type:"SOLID",color:${C.textMuted}}];
280
- assumptions.textAutoResize="HEIGHT";
281
- m.appendChild(assumptions);assumptions.layoutSizingHorizontal="FILL";
282
-
283
- ${spacerJS(16)}
284
- ${dividerJS()}
285
-
286
- return{ok:true};
287
- })();
288
- `);
289
- }
290
-
291
- async function renderTabOrderTable(
292
- bridge: Bridge,
293
- mId: string,
294
- tabOrder: TabOrderEntry[]
295
- ): Promise<void> {
296
- const BATCH_SIZE = 15;
297
- const COL = { num: 40, element: 220, role: 100, label: 300, notes: CONTENT_W - 40 - 220 - 100 - 300 - 32 };
298
-
299
- // Section heading + table frame + header row
300
- await bridge.execute(`
301
- (async () => {
302
- ${FL}
303
- var m=await figma.getNodeByIdAsync(${esc(mId)});
304
- if(!m)return{error:"no master"};
305
-
306
- ${spacerJS(32)}
307
- ${sectionHeadingJS("Keyboard Tab Order")}
308
- ${spacerJS(8)}
309
-
310
- var desc=figma.createText();desc.fontName=F.r;desc.fontSize=13;
311
- desc.lineHeight={unit:"PIXELS",value:20};
312
- desc.characters="Complete linear tab sequence for all focusable elements. Static text (prices, labels, headings) is excluded.";
313
- desc.fills=[{type:"SOLID",color:${C.textMuted}}];
314
- desc.textAutoResize="HEIGHT";
315
- m.appendChild(desc);desc.layoutSizingHorizontal="FILL";
316
-
317
- ${spacerJS(12)}
318
-
319
- var tbl=figma.createFrame();
320
- tbl.name="Tab Order Table";
321
- tbl.layoutMode="VERTICAL";
322
- tbl.primaryAxisSizingMode="AUTO";
323
- tbl.counterAxisSizingMode="AUTO";
324
- tbl.itemSpacing=0;
325
- tbl.fills=[{type:"SOLID",color:${C.bgPage}}];
326
- tbl.cornerRadius=8;
327
- tbl.strokes=[{type:"SOLID",color:${C.border}}];
328
- tbl.strokeWeight=1;tbl.strokeAlign="INSIDE";
329
- tbl.clipsContent=true;
330
- m.appendChild(tbl);
331
- tbl.layoutSizingHorizontal="FILL";
332
-
333
- // Header row
334
- var hdr=figma.createFrame();
335
- hdr.name="Header";
336
- hdr.layoutMode="HORIZONTAL";
337
- hdr.primaryAxisSizingMode="AUTO";
338
- hdr.counterAxisSizingMode="AUTO";
339
- hdr.itemSpacing=0;
340
- hdr.paddingTop=12;hdr.paddingBottom=12;
341
- hdr.paddingLeft=16;hdr.paddingRight=16;
342
- hdr.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
343
- hdr.counterAxisAlignItems="MIN";
344
- hdr.strokes=[{type:"SOLID",color:${C.border}}];
345
- hdr.strokeWeight=1;
346
- hdr.strokeTopWeight=0;hdr.strokeRightWeight=0;
347
- hdr.strokeBottomWeight=1;hdr.strokeLeftWeight=0;
348
- hdr.strokeAlign="INSIDE";
349
- tbl.appendChild(hdr);
350
- hdr.layoutSizingHorizontal="FILL";
351
-
352
- var hLabels=["#","Element","Role","Label","Notes"];
353
- var hWidths=[${COL.num},${COL.element},${COL.role},${COL.label},${COL.notes}];
354
- for(var c=0;c<hLabels.length;c++){
355
- var ht=figma.createText();ht.fontName=F.sb;ht.fontSize=12;
356
- ht.lineHeight={unit:"PIXELS",value:18};
357
- ht.characters=hLabels[c];
358
- ht.fills=[{type:"SOLID",color:${C.textMain}}];
359
- ht.textAutoResize="HEIGHT";
360
- ht.resize(hWidths[c],18);
361
- hdr.appendChild(ht);ht.layoutSizingHorizontal="FIXED";
362
- }
363
-
364
- return{tblId:tbl.id};
365
- })();
366
- `);
367
-
368
- // Render data rows in batches
369
- for (let i = 0; i < tabOrder.length; i += BATCH_SIZE) {
370
- const batch = tabOrder.slice(i, i + BATCH_SIZE);
371
- const rows = batch.map((r) => ({
372
- num: String(r.order),
373
- element: truncate(r.elementDescription, 50),
374
- role: r.role,
375
- label: truncate(r.label, 60),
376
- notes: truncate(r.notes, 80),
377
- }));
378
-
379
- await bridge.execute(`
380
- (async () => {
381
- ${FL}
382
- var m=await figma.getNodeByIdAsync(${esc(mId)});
383
- if(!m)return{error:"no master"};
384
- // Find the table frame
385
- var tbl=null;
386
- for(var i=0;i<m.children.length;i++){
387
- if(m.children[i].name==="Tab Order Table"){tbl=m.children[i];break;}
388
- }
389
- if(!tbl)return{error:"no table"};
390
-
391
- var rows=${JSON.stringify(rows)};
392
- var widths=[${COL.num},${COL.element},${COL.role},${COL.label},${COL.notes}];
393
- var keys=["num","element","role","label","notes"];
394
-
395
- for(var ri=0;ri<rows.length;ri++){
396
- var d=rows[ri];
397
- var row=figma.createFrame();
398
- row.name="Row "+(${i}+ri+1);
399
- row.layoutMode="HORIZONTAL";
400
- row.primaryAxisSizingMode="AUTO";
401
- row.counterAxisSizingMode="AUTO";
402
- row.itemSpacing=0;
403
- row.paddingTop=10;row.paddingBottom=10;
404
- row.paddingLeft=16;row.paddingRight=16;
405
- row.fills=[];
406
- row.counterAxisAlignItems="MIN";
407
- row.strokes=[{type:"SOLID",color:${C.border}}];
408
- row.strokeWeight=1;
409
- row.strokeTopWeight=0;row.strokeRightWeight=0;
410
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
411
- row.strokeAlign="INSIDE";
412
- tbl.appendChild(row);
413
- row.layoutSizingHorizontal="FILL";
414
-
415
- for(var c=0;c<keys.length;c++){
416
- var ct=figma.createText();
417
- ct.fontName=c===0?F.sb:(c===2?F.mono:F.r);
418
- ct.fontSize=12;
419
- ct.lineHeight={unit:"PIXELS",value:18};
420
- ct.characters=d[keys[c]]||"\\u2014";
421
- ct.fills=[{type:"SOLID",color:c===2?${C.accent}:${C.textMain}}];
422
- ct.textAutoResize="HEIGHT";
423
- ct.resize(widths[c],18);
424
- row.appendChild(ct);ct.layoutSizingHorizontal="FIXED";
425
- }
426
- }
427
-
428
- return{ok:true};
429
- })();
430
- `);
431
- }
432
- }
433
-
434
- async function renderReadingOrder(
435
- bridge: Bridge,
436
- mId: string,
437
- readingOrder: ReadingOrderNode[]
438
- ): Promise<void> {
439
- // Flatten reading order into numbered lines with indentation
440
- const lines: { text: string; indent: number }[] = [];
441
- let counter = 1;
442
-
443
- function flattenNodes(nodes: ReadingOrderNode[], depth: number): void {
444
- for (const node of nodes) {
445
- if (node.landmarkRole) {
446
- lines.push({
447
- text: `${counter++}. ${node.landmarkLabel || node.landmarkRole} region`,
448
- indent: depth,
449
- });
450
- if (node.children) flattenNodes(node.children, depth + 1);
451
- } else if (node.children && node.children.length > 0) {
452
- lines.push({
453
- text: `${counter++}. ${node.content}`,
454
- indent: depth,
455
- });
456
- flattenNodes(node.children, depth + 1);
457
- } else {
458
- const roleTag = node.role ? ` (${node.role})` : "";
459
- lines.push({
460
- text: `${counter++}. ${node.content}${roleTag}`,
461
- indent: depth,
462
- });
463
- }
464
- }
465
- }
466
-
467
- flattenNodes(readingOrder, 0);
468
-
469
- // Limit to keep script manageable
470
- const displayLines = lines.slice(0, 60);
471
-
472
- await bridge.execute(`
473
- (async () => {
474
- ${FL}
475
- var m=await figma.getNodeByIdAsync(${esc(mId)});
476
- if(!m)return{error:"no master"};
477
-
478
- ${spacerJS(32)}
479
- ${sectionHeadingJS("Screen Reader Reading Order")}
480
- ${spacerJS(8)}
481
-
482
- var desc=figma.createText();desc.fontName=F.r;desc.fontSize=13;
483
- desc.lineHeight={unit:"PIXELS",value:20};
484
- desc.characters="Virtual cursor (Browse mode) reading order, reflecting DOM order inferred from auto-layout hierarchy:";
485
- desc.fills=[{type:"SOLID",color:${C.textMuted}}];
486
- desc.textAutoResize="HEIGHT";
487
- m.appendChild(desc);desc.layoutSizingHorizontal="FILL";
488
-
489
- ${spacerJS(12)}
490
-
491
- var list=figma.createFrame();
492
- list.name="Reading Order List";
493
- list.layoutMode="VERTICAL";
494
- list.primaryAxisSizingMode="AUTO";
495
- list.counterAxisSizingMode="AUTO";
496
- list.itemSpacing=4;
497
- list.paddingTop=16;list.paddingBottom=16;
498
- list.paddingLeft=20;list.paddingRight=20;
499
- list.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
500
- list.cornerRadius=8;
501
- m.appendChild(list);
502
- list.layoutSizingHorizontal="FILL";
503
-
504
- var lines=${JSON.stringify(displayLines)};
505
- for(var i=0;i<lines.length;i++){
506
- var ln=lines[i];
507
- var row=figma.createFrame();
508
- row.name="Line "+(i+1);
509
- row.layoutMode="HORIZONTAL";
510
- row.primaryAxisSizingMode="AUTO";
511
- row.counterAxisSizingMode="AUTO";
512
- row.paddingLeft=ln.indent*24;
513
- row.fills=[];
514
- row.itemSpacing=0;
515
- list.appendChild(row);
516
- row.layoutSizingHorizontal="FILL";
517
-
518
- var txt=figma.createText();
519
- txt.fontName=ln.indent===0?F.sb:F.r;
520
- txt.fontSize=ln.indent===0?14:13;
521
- txt.lineHeight={unit:"PIXELS",value:ln.indent===0?22:20};
522
- txt.characters=ln.text;
523
- txt.fills=[{type:"SOLID",color:ln.indent===0?${C.textMain}:${C.textMuted}}];
524
- txt.textAutoResize="HEIGHT";
525
- row.appendChild(txt);txt.layoutSizingHorizontal="FILL";
526
- }
527
-
528
- ${spacerJS(16)}
529
- ${dividerJS()}
530
-
531
- return{ok:true};
532
- })();
533
- `);
534
- }
535
-
536
- async function renderInteractionAnnouncements(
537
- bridge: Bridge,
538
- mId: string,
539
- analysis: A11yOrderAnalysis
540
- ): Promise<void> {
541
- const focusRows = analysis.interactionAnnouncements.onFocus.map((f) => ({
542
- element: truncate(f.element, 50),
543
- announcement: truncate(f.announcement, 80),
544
- }));
545
- const stateRows = analysis.interactionAnnouncements.stateChanges.map(
546
- (s) => ({
547
- trigger: truncate(s.trigger, 50),
548
- behavior: truncate(s.behavior, 100),
549
- })
550
- );
551
-
552
- // Limit focus rows for rendering
553
- const displayFocusRows = focusRows.slice(0, 25);
554
-
555
- const COL_FOCUS = { element: 320, announcement: CONTENT_W - 320 - 32 };
556
- const COL_STATE = { trigger: 320, behavior: CONTENT_W - 320 - 32 };
557
-
558
- await bridge.execute(`
559
- (async () => {
560
- ${FL}
561
- var m=await figma.getNodeByIdAsync(${esc(mId)});
562
- if(!m)return{error:"no master"};
563
-
564
- ${spacerJS(32)}
565
- ${sectionHeadingJS("Screen Reader Interaction Announcements")}
566
- ${spacerJS(16)}
567
-
568
- // Sub-heading: On Focus
569
- var sh1=figma.createText();sh1.fontName=F.sb;sh1.fontSize=16;
570
- sh1.lineHeight={unit:"PIXELS",value:24};
571
- sh1.characters="On Focus";
572
- sh1.fills=[{type:"SOLID",color:${C.textMain}}];
573
- sh1.textAutoResize="HEIGHT";
574
- m.appendChild(sh1);sh1.layoutSizingHorizontal="FILL";
575
-
576
- ${spacerJS(8)}
577
-
578
- // Focus announcements table
579
- var tbl1=figma.createFrame();
580
- tbl1.name="Focus Announcements";
581
- tbl1.layoutMode="VERTICAL";
582
- tbl1.primaryAxisSizingMode="AUTO";
583
- tbl1.counterAxisSizingMode="AUTO";
584
- tbl1.itemSpacing=0;
585
- tbl1.fills=[{type:"SOLID",color:${C.bgPage}}];
586
- tbl1.cornerRadius=8;
587
- tbl1.strokes=[{type:"SOLID",color:${C.border}}];
588
- tbl1.strokeWeight=1;tbl1.strokeAlign="INSIDE";
589
- tbl1.clipsContent=true;
590
- m.appendChild(tbl1);
591
- tbl1.layoutSizingHorizontal="FILL";
592
-
593
- // Header
594
- var hdr1=figma.createFrame();
595
- hdr1.name="Header";
596
- hdr1.layoutMode="HORIZONTAL";
597
- hdr1.primaryAxisSizingMode="AUTO";
598
- hdr1.counterAxisSizingMode="AUTO";
599
- hdr1.itemSpacing=0;
600
- hdr1.paddingTop=12;hdr1.paddingBottom=12;
601
- hdr1.paddingLeft=16;hdr1.paddingRight=16;
602
- hdr1.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
603
- hdr1.counterAxisAlignItems="MIN";
604
- hdr1.strokes=[{type:"SOLID",color:${C.border}}];
605
- hdr1.strokeWeight=1;
606
- hdr1.strokeTopWeight=0;hdr1.strokeRightWeight=0;
607
- hdr1.strokeBottomWeight=1;hdr1.strokeLeftWeight=0;
608
- hdr1.strokeAlign="INSIDE";
609
- tbl1.appendChild(hdr1);
610
- hdr1.layoutSizingHorizontal="FILL";
611
-
612
- var h1a=figma.createText();h1a.fontName=F.sb;h1a.fontSize=12;
613
- h1a.lineHeight={unit:"PIXELS",value:18};h1a.characters="Element";
614
- h1a.fills=[{type:"SOLID",color:${C.textMain}}];
615
- h1a.textAutoResize="HEIGHT";h1a.resize(${COL_FOCUS.element},18);
616
- hdr1.appendChild(h1a);h1a.layoutSizingHorizontal="FIXED";
617
-
618
- var h1b=figma.createText();h1b.fontName=F.sb;h1b.fontSize=12;
619
- h1b.lineHeight={unit:"PIXELS",value:18};h1b.characters="Announcement";
620
- h1b.fills=[{type:"SOLID",color:${C.textMain}}];
621
- h1b.textAutoResize="HEIGHT";h1b.resize(${COL_FOCUS.announcement},18);
622
- hdr1.appendChild(h1b);h1b.layoutSizingHorizontal="FIXED";
623
-
624
- // Focus rows
625
- var fRows=${JSON.stringify(displayFocusRows)};
626
- for(var i=0;i<fRows.length;i++){
627
- var r=fRows[i];
628
- var row=figma.createFrame();
629
- row.name="Row "+(i+1);
630
- row.layoutMode="HORIZONTAL";
631
- row.primaryAxisSizingMode="AUTO";
632
- row.counterAxisSizingMode="AUTO";
633
- row.itemSpacing=0;
634
- row.paddingTop=10;row.paddingBottom=10;
635
- row.paddingLeft=16;row.paddingRight=16;
636
- row.fills=[];
637
- row.counterAxisAlignItems="MIN";
638
- if(i<fRows.length-1){
639
- row.strokes=[{type:"SOLID",color:${C.border}}];
640
- row.strokeWeight=1;
641
- row.strokeTopWeight=0;row.strokeRightWeight=0;
642
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
643
- row.strokeAlign="INSIDE";
644
- }
645
- tbl1.appendChild(row);
646
- row.layoutSizingHorizontal="FILL";
647
-
648
- var c1=figma.createText();c1.fontName=F.sb;c1.fontSize=12;
649
- c1.lineHeight={unit:"PIXELS",value:18};c1.characters=r.element;
650
- c1.fills=[{type:"SOLID",color:${C.textMain}}];
651
- c1.textAutoResize="HEIGHT";c1.resize(${COL_FOCUS.element},18);
652
- row.appendChild(c1);c1.layoutSizingHorizontal="FIXED";
653
-
654
- var c2=figma.createText();c2.fontName=F.r;c2.fontSize=12;
655
- c2.lineHeight={unit:"PIXELS",value:18};c2.characters=r.announcement;
656
- c2.fills=[{type:"SOLID",color:${C.textMuted}}];
657
- c2.textAutoResize="HEIGHT";c2.resize(${COL_FOCUS.announcement},18);
658
- row.appendChild(c2);c2.layoutSizingHorizontal="FIXED";
659
- }
660
-
661
- ${spacerJS(24)}
662
-
663
- // Sub-heading: State Changes
664
- var sh2=figma.createText();sh2.fontName=F.sb;sh2.fontSize=16;
665
- sh2.lineHeight={unit:"PIXELS",value:24};
666
- sh2.characters="On State Change";
667
- sh2.fills=[{type:"SOLID",color:${C.textMain}}];
668
- sh2.textAutoResize="HEIGHT";
669
- m.appendChild(sh2);sh2.layoutSizingHorizontal="FILL";
670
-
671
- ${spacerJS(8)}
672
-
673
- // State changes table
674
- var tbl2=figma.createFrame();
675
- tbl2.name="State Changes";
676
- tbl2.layoutMode="VERTICAL";
677
- tbl2.primaryAxisSizingMode="AUTO";
678
- tbl2.counterAxisSizingMode="AUTO";
679
- tbl2.itemSpacing=0;
680
- tbl2.fills=[{type:"SOLID",color:${C.bgPage}}];
681
- tbl2.cornerRadius=8;
682
- tbl2.strokes=[{type:"SOLID",color:${C.border}}];
683
- tbl2.strokeWeight=1;tbl2.strokeAlign="INSIDE";
684
- tbl2.clipsContent=true;
685
- m.appendChild(tbl2);
686
- tbl2.layoutSizingHorizontal="FILL";
687
-
688
- // Header
689
- var hdr2=figma.createFrame();
690
- hdr2.name="Header";
691
- hdr2.layoutMode="HORIZONTAL";
692
- hdr2.primaryAxisSizingMode="AUTO";
693
- hdr2.counterAxisSizingMode="AUTO";
694
- hdr2.itemSpacing=0;
695
- hdr2.paddingTop=12;hdr2.paddingBottom=12;
696
- hdr2.paddingLeft=16;hdr2.paddingRight=16;
697
- hdr2.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
698
- hdr2.counterAxisAlignItems="MIN";
699
- hdr2.strokes=[{type:"SOLID",color:${C.border}}];
700
- hdr2.strokeWeight=1;
701
- hdr2.strokeTopWeight=0;hdr2.strokeRightWeight=0;
702
- hdr2.strokeBottomWeight=1;hdr2.strokeLeftWeight=0;
703
- hdr2.strokeAlign="INSIDE";
704
- tbl2.appendChild(hdr2);
705
- hdr2.layoutSizingHorizontal="FILL";
706
-
707
- var h2a=figma.createText();h2a.fontName=F.sb;h2a.fontSize=12;
708
- h2a.lineHeight={unit:"PIXELS",value:18};h2a.characters="Trigger";
709
- h2a.fills=[{type:"SOLID",color:${C.textMain}}];
710
- h2a.textAutoResize="HEIGHT";h2a.resize(${COL_STATE.trigger},18);
711
- hdr2.appendChild(h2a);h2a.layoutSizingHorizontal="FIXED";
712
-
713
- var h2b=figma.createText();h2b.fontName=F.sb;h2b.fontSize=12;
714
- h2b.lineHeight={unit:"PIXELS",value:18};h2b.characters="Behavior";
715
- h2b.fills=[{type:"SOLID",color:${C.textMain}}];
716
- h2b.textAutoResize="HEIGHT";h2b.resize(${COL_STATE.behavior},18);
717
- hdr2.appendChild(h2b);h2b.layoutSizingHorizontal="FIXED";
718
-
719
- var sRows=${JSON.stringify(stateRows)};
720
- for(var i=0;i<sRows.length;i++){
721
- var r=sRows[i];
722
- var row=figma.createFrame();
723
- row.name="Row "+(i+1);
724
- row.layoutMode="HORIZONTAL";
725
- row.primaryAxisSizingMode="AUTO";
726
- row.counterAxisSizingMode="AUTO";
727
- row.itemSpacing=0;
728
- row.paddingTop=10;row.paddingBottom=10;
729
- row.paddingLeft=16;row.paddingRight=16;
730
- row.fills=[];
731
- row.counterAxisAlignItems="MIN";
732
- if(i<sRows.length-1){
733
- row.strokes=[{type:"SOLID",color:${C.border}}];
734
- row.strokeWeight=1;
735
- row.strokeTopWeight=0;row.strokeRightWeight=0;
736
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
737
- row.strokeAlign="INSIDE";
738
- }
739
- tbl2.appendChild(row);
740
- row.layoutSizingHorizontal="FILL";
741
-
742
- var c1=figma.createText();c1.fontName=F.sb;c1.fontSize=12;
743
- c1.lineHeight={unit:"PIXELS",value:18};c1.characters=r.trigger;
744
- c1.fills=[{type:"SOLID",color:${C.textMain}}];
745
- c1.textAutoResize="HEIGHT";c1.resize(${COL_STATE.trigger},18);
746
- row.appendChild(c1);c1.layoutSizingHorizontal="FIXED";
747
-
748
- var c2=figma.createText();c2.fontName=F.r;c2.fontSize=12;
749
- c2.lineHeight={unit:"PIXELS",value:18};c2.characters=r.behavior;
750
- c2.fills=[{type:"SOLID",color:${C.textMuted}}];
751
- c2.textAutoResize="HEIGHT";c2.resize(${COL_STATE.behavior},18);
752
- row.appendChild(c2);c2.layoutSizingHorizontal="FIXED";
753
- }
754
-
755
- ${spacerJS(16)}
756
- ${dividerJS()}
757
-
758
- return{ok:true};
759
- })();
760
- `);
761
- }
762
-
763
- async function renderFocusManagement(
764
- bridge: Bridge,
765
- mId: string,
766
- rules: FocusRule[]
767
- ): Promise<void> {
768
- const ruleItems = rules.map((r) => ({
769
- scenario: r.scenario,
770
- rule: r.rule,
771
- }));
772
-
773
- await bridge.execute(`
774
- (async () => {
775
- ${FL}
776
- var m=await figma.getNodeByIdAsync(${esc(mId)});
777
- if(!m)return{error:"no master"};
778
-
779
- ${spacerJS(32)}
780
- ${sectionHeadingJS("Focus Management & State Changes")}
781
- ${spacerJS(12)}
782
-
783
- var items=${JSON.stringify(ruleItems)};
784
- for(var i=0;i<items.length;i++){
785
- var item=items[i];
786
-
787
- var card=figma.createFrame();
788
- card.name="Focus Rule "+(i+1);
789
- card.layoutMode="VERTICAL";
790
- card.primaryAxisSizingMode="AUTO";
791
- card.counterAxisSizingMode="AUTO";
792
- card.paddingTop=12;card.paddingBottom=12;
793
- card.paddingLeft=16;card.paddingRight=16;
794
- card.itemSpacing=4;
795
- card.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
796
- card.cornerRadius=8;
797
- m.appendChild(card);
798
- card.layoutSizingHorizontal="FILL";
799
-
800
- var title=figma.createText();title.fontName=F.sb;title.fontSize=13;
801
- title.lineHeight={unit:"PIXELS",value:20};
802
- title.characters=item.scenario;
803
- title.fills=[{type:"SOLID",color:${C.textMain}}];
804
- title.textAutoResize="HEIGHT";
805
- card.appendChild(title);title.layoutSizingHorizontal="FILL";
806
-
807
- var body=figma.createText();body.fontName=F.r;body.fontSize=13;
808
- body.lineHeight={unit:"PIXELS",value:20};
809
- body.characters=item.rule;
810
- body.fills=[{type:"SOLID",color:${C.textMuted}}];
811
- body.textAutoResize="HEIGHT";
812
- card.appendChild(body);body.layoutSizingHorizontal="FILL";
813
-
814
- ${spacerJS(8)}
815
- }
816
-
817
- ${spacerJS(16)}
818
- ${dividerJS()}
819
-
820
- return{ok:true};
821
- })();
822
- `);
823
- }
824
-
825
- async function renderImplementationNotes(
826
- bridge: Bridge,
827
- mId: string,
828
- analysis: A11yOrderAnalysis
829
- ): Promise<void> {
830
- const notes = analysis.implementationNotes;
831
-
832
- // ARIA table
833
- const ariaRows = notes.ariaTable.map((a) => ({
834
- element: truncate(a.element, 40),
835
- attribute: a.attribute,
836
- value: a.value,
837
- }));
838
- const displayAriaRows = ariaRows.slice(0, 25);
839
-
840
- // KB behavior table
841
- const kbRows = notes.keyboardBehavior.map((k) => ({
842
- component: k.component,
843
- key: k.key,
844
- action: k.action,
845
- }));
846
-
847
- const COL_ARIA = { element: 280, attribute: 180, value: CONTENT_W - 280 - 180 - 32 };
848
- const COL_KB = { component: 200, key: 220, action: CONTENT_W - 200 - 220 - 32 };
849
-
850
- await bridge.execute(`
851
- (async () => {
852
- ${FL}
853
- var m=await figma.getNodeByIdAsync(${esc(mId)});
854
- if(!m)return{error:"no master"};
855
-
856
- ${spacerJS(32)}
857
- ${sectionHeadingJS("Implementation Notes for Developers")}
858
- ${spacerJS(16)}
859
-
860
- // Sub-heading: Required ARIA
861
- var sh1=figma.createText();sh1.fontName=F.sb;sh1.fontSize=16;
862
- sh1.lineHeight={unit:"PIXELS",value:24};
863
- sh1.characters="Required ARIA (only where native HTML is insufficient)";
864
- sh1.fills=[{type:"SOLID",color:${C.textMain}}];
865
- sh1.textAutoResize="HEIGHT";
866
- m.appendChild(sh1);sh1.layoutSizingHorizontal="FILL";
867
-
868
- ${spacerJS(8)}
869
-
870
- // ARIA table
871
- var tbl1=figma.createFrame();
872
- tbl1.name="ARIA Table";
873
- tbl1.layoutMode="VERTICAL";
874
- tbl1.primaryAxisSizingMode="AUTO";
875
- tbl1.counterAxisSizingMode="AUTO";
876
- tbl1.itemSpacing=0;
877
- tbl1.fills=[{type:"SOLID",color:${C.bgPage}}];
878
- tbl1.cornerRadius=8;
879
- tbl1.strokes=[{type:"SOLID",color:${C.border}}];
880
- tbl1.strokeWeight=1;tbl1.strokeAlign="INSIDE";
881
- tbl1.clipsContent=true;
882
- m.appendChild(tbl1);
883
- tbl1.layoutSizingHorizontal="FILL";
884
-
885
- // Header
886
- var hdr1=figma.createFrame();
887
- hdr1.name="Header";
888
- hdr1.layoutMode="HORIZONTAL";
889
- hdr1.primaryAxisSizingMode="AUTO";
890
- hdr1.counterAxisSizingMode="AUTO";
891
- hdr1.itemSpacing=0;
892
- hdr1.paddingTop=12;hdr1.paddingBottom=12;
893
- hdr1.paddingLeft=16;hdr1.paddingRight=16;
894
- hdr1.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
895
- hdr1.counterAxisAlignItems="MIN";
896
- hdr1.strokes=[{type:"SOLID",color:${C.border}}];
897
- hdr1.strokeWeight=1;
898
- hdr1.strokeTopWeight=0;hdr1.strokeRightWeight=0;
899
- hdr1.strokeBottomWeight=1;hdr1.strokeLeftWeight=0;
900
- hdr1.strokeAlign="INSIDE";
901
- tbl1.appendChild(hdr1);
902
- hdr1.layoutSizingHorizontal="FILL";
903
-
904
- var h1Labels=["Element","Attribute","Value"];
905
- var h1Widths=[${COL_ARIA.element},${COL_ARIA.attribute},${COL_ARIA.value}];
906
- for(var c=0;c<h1Labels.length;c++){
907
- var ht=figma.createText();ht.fontName=F.sb;ht.fontSize=12;
908
- ht.lineHeight={unit:"PIXELS",value:18};ht.characters=h1Labels[c];
909
- ht.fills=[{type:"SOLID",color:${C.textMain}}];
910
- ht.textAutoResize="HEIGHT";ht.resize(h1Widths[c],18);
911
- hdr1.appendChild(ht);ht.layoutSizingHorizontal="FIXED";
912
- }
913
-
914
- var aRows=${JSON.stringify(displayAriaRows)};
915
- for(var i=0;i<aRows.length;i++){
916
- var d=aRows[i];
917
- var row=figma.createFrame();
918
- row.name="Row "+(i+1);
919
- row.layoutMode="HORIZONTAL";
920
- row.primaryAxisSizingMode="AUTO";
921
- row.counterAxisSizingMode="AUTO";
922
- row.itemSpacing=0;
923
- row.paddingTop=10;row.paddingBottom=10;
924
- row.paddingLeft=16;row.paddingRight=16;
925
- row.fills=[];
926
- row.counterAxisAlignItems="MIN";
927
- if(i<aRows.length-1){
928
- row.strokes=[{type:"SOLID",color:${C.border}}];
929
- row.strokeWeight=1;
930
- row.strokeTopWeight=0;row.strokeRightWeight=0;
931
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
932
- row.strokeAlign="INSIDE";
933
- }
934
- tbl1.appendChild(row);
935
- row.layoutSizingHorizontal="FILL";
936
-
937
- var vals=[d.element,d.attribute,d.value];
938
- var fonts=[F.r,F.mono,F.mono];
939
- var colors=[${C.textMain},${C.accent},${C.textMuted}];
940
- var ws=[${COL_ARIA.element},${COL_ARIA.attribute},${COL_ARIA.value}];
941
- for(var c=0;c<3;c++){
942
- var ct=figma.createText();ct.fontName=fonts[c];ct.fontSize=12;
943
- ct.lineHeight={unit:"PIXELS",value:18};ct.characters=vals[c];
944
- ct.fills=[{type:"SOLID",color:colors[c]}];
945
- ct.textAutoResize="HEIGHT";ct.resize(ws[c],18);
946
- row.appendChild(ct);ct.layoutSizingHorizontal="FIXED";
947
- }
948
- }
949
-
950
- return{ok:true};
951
- })();
952
- `);
953
-
954
- // Keyboard behavior table
955
- await bridge.execute(`
956
- (async () => {
957
- ${FL}
958
- var m=await figma.getNodeByIdAsync(${esc(mId)});
959
- if(!m)return{error:"no master"};
960
-
961
- ${spacerJS(24)}
962
-
963
- var sh2=figma.createText();sh2.fontName=F.sb;sh2.fontSize=16;
964
- sh2.lineHeight={unit:"PIXELS",value:24};
965
- sh2.characters="Keyboard Behaviour Expectations";
966
- sh2.fills=[{type:"SOLID",color:${C.textMain}}];
967
- sh2.textAutoResize="HEIGHT";
968
- m.appendChild(sh2);sh2.layoutSizingHorizontal="FILL";
969
-
970
- ${spacerJS(8)}
971
-
972
- var tbl2=figma.createFrame();
973
- tbl2.name="Keyboard Behavior";
974
- tbl2.layoutMode="VERTICAL";
975
- tbl2.primaryAxisSizingMode="AUTO";
976
- tbl2.counterAxisSizingMode="AUTO";
977
- tbl2.itemSpacing=0;
978
- tbl2.fills=[{type:"SOLID",color:${C.bgPage}}];
979
- tbl2.cornerRadius=8;
980
- tbl2.strokes=[{type:"SOLID",color:${C.border}}];
981
- tbl2.strokeWeight=1;tbl2.strokeAlign="INSIDE";
982
- tbl2.clipsContent=true;
983
- m.appendChild(tbl2);
984
- tbl2.layoutSizingHorizontal="FILL";
985
-
986
- var hdr2=figma.createFrame();
987
- hdr2.name="Header";
988
- hdr2.layoutMode="HORIZONTAL";
989
- hdr2.primaryAxisSizingMode="AUTO";
990
- hdr2.counterAxisSizingMode="AUTO";
991
- hdr2.itemSpacing=0;
992
- hdr2.paddingTop=12;hdr2.paddingBottom=12;
993
- hdr2.paddingLeft=16;hdr2.paddingRight=16;
994
- hdr2.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
995
- hdr2.counterAxisAlignItems="MIN";
996
- hdr2.strokes=[{type:"SOLID",color:${C.border}}];
997
- hdr2.strokeWeight=1;
998
- hdr2.strokeTopWeight=0;hdr2.strokeRightWeight=0;
999
- hdr2.strokeBottomWeight=1;hdr2.strokeLeftWeight=0;
1000
- hdr2.strokeAlign="INSIDE";
1001
- tbl2.appendChild(hdr2);
1002
- hdr2.layoutSizingHorizontal="FILL";
1003
-
1004
- var h2Labels=["Component","Key","Action"];
1005
- var h2Widths=[${COL_KB.component},${COL_KB.key},${COL_KB.action}];
1006
- for(var c=0;c<h2Labels.length;c++){
1007
- var ht=figma.createText();ht.fontName=F.sb;ht.fontSize=12;
1008
- ht.lineHeight={unit:"PIXELS",value:18};ht.characters=h2Labels[c];
1009
- ht.fills=[{type:"SOLID",color:${C.textMain}}];
1010
- ht.textAutoResize="HEIGHT";ht.resize(h2Widths[c],18);
1011
- hdr2.appendChild(ht);ht.layoutSizingHorizontal="FIXED";
1012
- }
1013
-
1014
- var kRows=${JSON.stringify(kbRows)};
1015
- for(var i=0;i<kRows.length;i++){
1016
- var d=kRows[i];
1017
- var row=figma.createFrame();
1018
- row.name="Row "+(i+1);
1019
- row.layoutMode="HORIZONTAL";
1020
- row.primaryAxisSizingMode="AUTO";
1021
- row.counterAxisSizingMode="AUTO";
1022
- row.itemSpacing=0;
1023
- row.paddingTop=10;row.paddingBottom=10;
1024
- row.paddingLeft=16;row.paddingRight=16;
1025
- row.fills=[];
1026
- row.counterAxisAlignItems="MIN";
1027
- if(i<kRows.length-1){
1028
- row.strokes=[{type:"SOLID",color:${C.border}}];
1029
- row.strokeWeight=1;
1030
- row.strokeTopWeight=0;row.strokeRightWeight=0;
1031
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
1032
- row.strokeAlign="INSIDE";
1033
- }
1034
- tbl2.appendChild(row);
1035
- row.layoutSizingHorizontal="FILL";
1036
-
1037
- var vals=[d.component,d.key,d.action];
1038
- var fonts=[F.r,F.mono,F.r];
1039
- var colors=[${C.textMain},${C.accent},${C.textMuted}];
1040
- var ws=[${COL_KB.component},${COL_KB.key},${COL_KB.action}];
1041
- for(var c=0;c<3;c++){
1042
- var ct=figma.createText();ct.fontName=fonts[c];ct.fontSize=12;
1043
- ct.lineHeight={unit:"PIXELS",value:18};ct.characters=vals[c];
1044
- ct.fills=[{type:"SOLID",color:colors[c]}];
1045
- ct.textAutoResize="HEIGHT";ct.resize(ws[c],18);
1046
- row.appendChild(ct);ct.layoutSizingHorizontal="FIXED";
1047
- }
1048
- }
1049
-
1050
- return{ok:true};
1051
- })();
1052
- `);
1053
-
1054
- // Do/Don't rules
1055
- const doRules = notes.dosDonts.filter((r) => r.startsWith("Do:"));
1056
- const dontRules = notes.dosDonts.filter((r) => r.startsWith("Don't:"));
1057
-
1058
- await bridge.execute(`
1059
- (async () => {
1060
- ${FL}
1061
- var m=await figma.getNodeByIdAsync(${esc(mId)});
1062
- if(!m)return{error:"no master"};
1063
-
1064
- ${spacerJS(24)}
1065
-
1066
- var sh3=figma.createText();sh3.fontName=F.sb;sh3.fontSize=16;
1067
- sh3.lineHeight={unit:"PIXELS",value:24};
1068
- sh3.characters="Do / Don't Rules";
1069
- sh3.fills=[{type:"SOLID",color:${C.textMain}}];
1070
- sh3.textAutoResize="HEIGHT";
1071
- m.appendChild(sh3);sh3.layoutSizingHorizontal="FILL";
1072
-
1073
- ${spacerJS(8)}
1074
-
1075
- // Two-column layout
1076
- var cols=figma.createFrame();
1077
- cols.name="Do Dont Columns";
1078
- cols.layoutMode="HORIZONTAL";
1079
- cols.primaryAxisSizingMode="AUTO";
1080
- cols.counterAxisSizingMode="AUTO";
1081
- cols.itemSpacing=16;
1082
- cols.fills=[];
1083
- m.appendChild(cols);
1084
- cols.layoutSizingHorizontal="FILL";
1085
-
1086
- // Do column
1087
- var doCol=figma.createFrame();
1088
- doCol.name="Do";
1089
- doCol.layoutMode="VERTICAL";
1090
- doCol.primaryAxisSizingMode="AUTO";
1091
- doCol.counterAxisSizingMode="AUTO";
1092
- doCol.paddingTop=16;doCol.paddingBottom=16;
1093
- doCol.paddingLeft=16;doCol.paddingRight=16;
1094
- doCol.itemSpacing=8;
1095
- doCol.cornerRadius=8;
1096
- doCol.fills=[{type:"SOLID",color:${C.greenBg}}];
1097
- cols.appendChild(doCol);
1098
- doCol.layoutSizingHorizontal="FILL";
1099
-
1100
- var doTitle=figma.createText();doTitle.fontName=F.sb;doTitle.fontSize=14;
1101
- doTitle.characters="\\u2705 Do";
1102
- doTitle.fills=[{type:"SOLID",color:${C.green}}];
1103
- doCol.appendChild(doTitle);doTitle.layoutSizingHorizontal="FILL";
1104
-
1105
- var doRules=${JSON.stringify(doRules)};
1106
- for(var i=0;i<doRules.length;i++){
1107
- var dt=figma.createText();dt.fontName=F.r;dt.fontSize=12;
1108
- dt.lineHeight={unit:"PIXELS",value:18};
1109
- dt.characters=doRules[i].replace(/^Do: /,"\\u2022 ");
1110
- dt.fills=[{type:"SOLID",color:${C.textMain}}];
1111
- dt.textAutoResize="HEIGHT";
1112
- doCol.appendChild(dt);dt.layoutSizingHorizontal="FILL";
1113
- }
1114
-
1115
- // Don't column
1116
- var dontCol=figma.createFrame();
1117
- dontCol.name="Don't";
1118
- dontCol.layoutMode="VERTICAL";
1119
- dontCol.primaryAxisSizingMode="AUTO";
1120
- dontCol.counterAxisSizingMode="AUTO";
1121
- dontCol.paddingTop=16;dontCol.paddingBottom=16;
1122
- dontCol.paddingLeft=16;dontCol.paddingRight=16;
1123
- dontCol.itemSpacing=8;
1124
- dontCol.cornerRadius=8;
1125
- dontCol.fills=[{type:"SOLID",color:${C.warnBg}}];
1126
- cols.appendChild(dontCol);
1127
- dontCol.layoutSizingHorizontal="FILL";
1128
-
1129
- var dontTitle=figma.createText();dontTitle.fontName=F.sb;dontTitle.fontSize=14;
1130
- dontTitle.characters="\\u274c Don't";
1131
- dontTitle.fills=[{type:"SOLID",color:${C.warnBorder}}];
1132
- dontCol.appendChild(dontTitle);dontTitle.layoutSizingHorizontal="FILL";
1133
-
1134
- var dontRules=${JSON.stringify(dontRules)};
1135
- for(var i=0;i<dontRules.length;i++){
1136
- var dt=figma.createText();dt.fontName=F.r;dt.fontSize=12;
1137
- dt.lineHeight={unit:"PIXELS",value:18};
1138
- dt.characters=dontRules[i].replace(/^Don't: /,"\\u2022 ");
1139
- dt.fills=[{type:"SOLID",color:${C.textMain}}];
1140
- dt.textAutoResize="HEIGHT";
1141
- dontCol.appendChild(dt);dt.layoutSizingHorizontal="FILL";
1142
- }
1143
-
1144
- ${spacerJS(16)}
1145
- ${dividerJS()}
1146
-
1147
- return{ok:true};
1148
- })();
1149
- `);
1150
- }
1151
-
1152
- async function renderWarnings(
1153
- bridge: Bridge,
1154
- mId: string,
1155
- warnings: Warning[]
1156
- ): Promise<void> {
1157
- if (warnings.length === 0) return;
1158
-
1159
- const warningData = warnings.map((w) => ({
1160
- id: w.id,
1161
- severity: w.severity,
1162
- title: w.title,
1163
- description: w.description,
1164
- }));
1165
-
1166
- await bridge.execute(`
1167
- (async () => {
1168
- ${FL}
1169
- var m=await figma.getNodeByIdAsync(${esc(mId)});
1170
- if(!m)return{error:"no master"};
1171
-
1172
- ${spacerJS(32)}
1173
- ${sectionHeadingJS("Warnings")}
1174
- ${spacerJS(12)}
1175
-
1176
- var warnings=${JSON.stringify(warningData)};
1177
- var sevColors={
1178
- "Critical":{bg:${C.warnBg},border:${C.warnBorder},text:${C.warnBorder}},
1179
- "Warning":{bg:${C.warnAmberBg},border:${C.warnAmberBdr},text:${C.warnAmberBdr}},
1180
- "Info":{bg:${C.infoBg},border:${C.infoBorder},text:${C.infoBorder}}
1181
- };
1182
-
1183
- for(var i=0;i<warnings.length;i++){
1184
- var w=warnings[i];
1185
- var sc=sevColors[w.severity]||sevColors["Info"];
1186
-
1187
- var card=figma.createFrame();
1188
- card.name="Warning "+(i+1);
1189
- card.layoutMode="VERTICAL";
1190
- card.primaryAxisSizingMode="AUTO";
1191
- card.counterAxisSizingMode="AUTO";
1192
- card.paddingTop=16;card.paddingBottom=16;
1193
- card.paddingLeft=20;card.paddingRight=16;
1194
- card.itemSpacing=6;
1195
- card.cornerRadius=8;
1196
- card.fills=[{type:"SOLID",color:sc.bg}];
1197
- card.strokes=[{type:"SOLID",color:sc.border}];
1198
- card.strokeWeight=2;
1199
- card.strokeLeftWeight=4;
1200
- card.strokeAlign="INSIDE";
1201
- m.appendChild(card);
1202
- card.layoutSizingHorizontal="FILL";
1203
-
1204
- // Severity + Title
1205
- var title=figma.createText();title.fontName=F.sb;title.fontSize=14;
1206
- title.lineHeight={unit:"PIXELS",value:22};
1207
- title.characters=w.id+". ["+w.severity+"] "+w.title;
1208
- title.fills=[{type:"SOLID",color:sc.text}];
1209
- title.textAutoResize="HEIGHT";
1210
- card.appendChild(title);title.layoutSizingHorizontal="FILL";
1211
-
1212
- // Description
1213
- var desc=figma.createText();desc.fontName=F.r;desc.fontSize=13;
1214
- desc.lineHeight={unit:"PIXELS",value:20};
1215
- desc.characters=w.description;
1216
- desc.fills=[{type:"SOLID",color:${C.textMain}}];
1217
- desc.textAutoResize="HEIGHT";
1218
- card.appendChild(desc);desc.layoutSizingHorizontal="FILL";
1219
-
1220
- ${spacerJS(8)}
1221
- }
1222
-
1223
- ${spacerJS(16)}
1224
- ${dividerJS()}
1225
-
1226
- return{ok:true};
1227
- })();
1228
- `);
1229
- }
1230
-
1231
- async function renderAuditSummary(
1232
- bridge: Bridge,
1233
- mId: string,
1234
- summary: AuditSummaryRow[]
1235
- ): Promise<void> {
1236
- const COL_SUM = { severity: 120, count: 80, category: CONTENT_W - 120 - 80 - 32 };
1237
-
1238
- await bridge.execute(`
1239
- (async () => {
1240
- ${FL}
1241
- var m=await figma.getNodeByIdAsync(${esc(mId)});
1242
- if(!m)return{error:"no master"};
1243
-
1244
- ${spacerJS(32)}
1245
- ${sectionHeadingJS("A11y Audit Summary")}
1246
- ${spacerJS(12)}
1247
-
1248
- var tbl=figma.createFrame();
1249
- tbl.name="Audit Summary";
1250
- tbl.layoutMode="VERTICAL";
1251
- tbl.primaryAxisSizingMode="AUTO";
1252
- tbl.counterAxisSizingMode="AUTO";
1253
- tbl.itemSpacing=0;
1254
- tbl.fills=[{type:"SOLID",color:${C.bgPage}}];
1255
- tbl.cornerRadius=8;
1256
- tbl.strokes=[{type:"SOLID",color:${C.border}}];
1257
- tbl.strokeWeight=1;tbl.strokeAlign="INSIDE";
1258
- tbl.clipsContent=true;
1259
- m.appendChild(tbl);
1260
- tbl.layoutSizingHorizontal="FILL";
1261
-
1262
- // Header
1263
- var hdr=figma.createFrame();
1264
- hdr.name="Header";
1265
- hdr.layoutMode="HORIZONTAL";
1266
- hdr.primaryAxisSizingMode="AUTO";
1267
- hdr.counterAxisSizingMode="AUTO";
1268
- hdr.itemSpacing=0;
1269
- hdr.paddingTop=12;hdr.paddingBottom=12;
1270
- hdr.paddingLeft=16;hdr.paddingRight=16;
1271
- hdr.fills=[{type:"SOLID",color:${C.bgTableHeader}}];
1272
- hdr.counterAxisAlignItems="MIN";
1273
- hdr.strokes=[{type:"SOLID",color:${C.border}}];
1274
- hdr.strokeWeight=1;
1275
- hdr.strokeTopWeight=0;hdr.strokeRightWeight=0;
1276
- hdr.strokeBottomWeight=1;hdr.strokeLeftWeight=0;
1277
- hdr.strokeAlign="INSIDE";
1278
- tbl.appendChild(hdr);
1279
- hdr.layoutSizingHorizontal="FILL";
1280
-
1281
- var hLabels=["Severity","Count","Category"];
1282
- var hWidths=[${COL_SUM.severity},${COL_SUM.count},${COL_SUM.category}];
1283
- for(var c=0;c<hLabels.length;c++){
1284
- var ht=figma.createText();ht.fontName=F.sb;ht.fontSize=12;
1285
- ht.lineHeight={unit:"PIXELS",value:18};ht.characters=hLabels[c];
1286
- ht.fills=[{type:"SOLID",color:${C.textMain}}];
1287
- ht.textAutoResize="HEIGHT";ht.resize(hWidths[c],18);
1288
- hdr.appendChild(ht);ht.layoutSizingHorizontal="FIXED";
1289
- }
1290
-
1291
- var sevColorMap={
1292
- "Error":${C.warnBorder},
1293
- "Warning":${C.warnAmberBdr},
1294
- "Suggestion":${C.accent},
1295
- "Total":${C.textMain}
1296
- };
1297
-
1298
- var rows=${JSON.stringify(summary)};
1299
- for(var i=0;i<rows.length;i++){
1300
- var d=rows[i];
1301
- var row=figma.createFrame();
1302
- row.name="Row "+(i+1);
1303
- row.layoutMode="HORIZONTAL";
1304
- row.primaryAxisSizingMode="AUTO";
1305
- row.counterAxisSizingMode="AUTO";
1306
- row.itemSpacing=0;
1307
- row.paddingTop=10;row.paddingBottom=10;
1308
- row.paddingLeft=16;row.paddingRight=16;
1309
- row.fills=[];
1310
- row.counterAxisAlignItems="MIN";
1311
- if(i<rows.length-1){
1312
- row.strokes=[{type:"SOLID",color:${C.border}}];
1313
- row.strokeWeight=1;
1314
- row.strokeTopWeight=0;row.strokeRightWeight=0;
1315
- row.strokeBottomWeight=1;row.strokeLeftWeight=0;
1316
- row.strokeAlign="INSIDE";
1317
- }
1318
- tbl.appendChild(row);
1319
- row.layoutSizingHorizontal="FILL";
1320
-
1321
- var sc=sevColorMap[d.severity]||${C.textMain};
1322
- var isTotal=d.severity==="Total";
1323
-
1324
- var c0=figma.createText();c0.fontName=isTotal?F.b:F.sb;c0.fontSize=12;
1325
- c0.lineHeight={unit:"PIXELS",value:18};c0.characters=d.severity;
1326
- c0.fills=[{type:"SOLID",color:sc}];
1327
- c0.textAutoResize="HEIGHT";c0.resize(${COL_SUM.severity},18);
1328
- row.appendChild(c0);c0.layoutSizingHorizontal="FIXED";
1329
-
1330
- var c1=figma.createText();c1.fontName=isTotal?F.b:F.sb;c1.fontSize=12;
1331
- c1.lineHeight={unit:"PIXELS",value:18};c1.characters=String(d.count);
1332
- c1.fills=[{type:"SOLID",color:sc}];
1333
- c1.textAutoResize="HEIGHT";c1.resize(${COL_SUM.count},18);
1334
- row.appendChild(c1);c1.layoutSizingHorizontal="FIXED";
1335
-
1336
- var c2=figma.createText();c2.fontName=F.r;c2.fontSize=12;
1337
- c2.lineHeight={unit:"PIXELS",value:18};c2.characters=d.category;
1338
- c2.fills=[{type:"SOLID",color:${C.textMuted}}];
1339
- c2.textAutoResize="HEIGHT";c2.resize(${COL_SUM.category},18);
1340
- row.appendChild(c2);c2.layoutSizingHorizontal="FIXED";
1341
- }
1342
-
1343
- return{ok:true};
1344
- })();
1345
- `);
1346
- }