@ethlete/cli 3.0.0-next.25 → 3.0.0-next.27

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 (592) hide show
  1. package/CHANGELOG.md +417 -0
  2. package/build-info.json +1 -0
  3. package/design/define-call.ts +99 -31
  4. package/design/define-part.ts +50 -3
  5. package/design/icon-sheet.ts +1 -1
  6. package/design/interaction-rows.ts +13 -6
  7. package/design/logo-sheet.ts +52 -0
  8. package/design/mark-part.ts +51 -1
  9. package/design/motion-drive.ts +215 -0
  10. package/design/motion-runtime.ts +14 -2
  11. package/design/motion-tokens.ts +177 -0
  12. package/design/token-sheet.ts +1 -1
  13. package/design/web/frame-fill.ts +4 -0
  14. package/design/web/frame-fit.ts +7 -0
  15. package/design/web/frame-scheme.ts +44 -0
  16. package/design/web/frame-surfaces.ts +294 -0
  17. package/design/web/frame.ts +162 -43
  18. package/design/web/surface-interactive.css +42 -0
  19. package/design/with-action.ts +29 -0
  20. package/package.json +3 -1
  21. package/src/index.js +9 -1
  22. package/src/index.js.map +1 -1
  23. package/src/lib/design/asset-shot.js +2 -2
  24. package/src/lib/design/asset-shot.js.map +1 -1
  25. package/src/lib/design/build-watch.d.ts +26 -0
  26. package/src/lib/design/build-watch.js +138 -0
  27. package/src/lib/design/build-watch.js.map +1 -0
  28. package/src/lib/design/calls-tsconfig.d.ts +2 -0
  29. package/src/lib/design/calls-tsconfig.js +10 -3
  30. package/src/lib/design/calls-tsconfig.js.map +1 -1
  31. package/src/lib/design/check.d.ts +1 -0
  32. package/src/lib/design/check.js +195 -13
  33. package/src/lib/design/check.js.map +1 -1
  34. package/src/lib/design/commit-hunks.d.ts +22 -0
  35. package/src/lib/design/commit-hunks.js +173 -0
  36. package/src/lib/design/commit-hunks.js.map +1 -0
  37. package/src/lib/design/contact-sheet.d.ts +9 -0
  38. package/src/lib/design/contact-sheet.js +38 -4
  39. package/src/lib/design/contact-sheet.js.map +1 -1
  40. package/src/lib/design/design-command.d.ts +2 -0
  41. package/src/lib/design/design-command.js +183 -15
  42. package/src/lib/design/design-command.js.map +1 -1
  43. package/src/lib/design/draw-ledger.d.ts +36 -0
  44. package/src/lib/design/draw-ledger.js +52 -0
  45. package/src/lib/design/draw-ledger.js.map +1 -0
  46. package/src/lib/design/force-interactions.d.ts +1 -1
  47. package/src/lib/design/force-interactions.js +4 -2
  48. package/src/lib/design/force-interactions.js.map +1 -1
  49. package/src/lib/design/inbox-command.js +9 -5
  50. package/src/lib/design/inbox-command.js.map +1 -1
  51. package/src/lib/design/mcp-command.d.ts +28 -3
  52. package/src/lib/design/mcp-command.js +134 -21
  53. package/src/lib/design/mcp-command.js.map +1 -1
  54. package/src/lib/design/merge-compare.d.ts +10 -2
  55. package/src/lib/design/merge-compare.js +63 -11
  56. package/src/lib/design/merge-compare.js.map +1 -1
  57. package/src/lib/design/motion-command.js +10 -16
  58. package/src/lib/design/motion-command.js.map +1 -1
  59. package/src/lib/design/motion-shot.js +3 -2
  60. package/src/lib/design/motion-shot.js.map +1 -1
  61. package/src/lib/design/new-call.js +19 -10
  62. package/src/lib/design/new-call.js.map +1 -1
  63. package/src/lib/design/part-marks.d.ts +3 -2
  64. package/src/lib/design/part-marks.js +13 -5
  65. package/src/lib/design/part-marks.js.map +1 -1
  66. package/src/lib/design/paths.d.ts +42 -0
  67. package/src/lib/design/paths.js +50 -1
  68. package/src/lib/design/paths.js.map +1 -1
  69. package/src/lib/design/product-command.d.ts +1 -1
  70. package/src/lib/design/product-command.js +12 -14
  71. package/src/lib/design/product-command.js.map +1 -1
  72. package/src/lib/design/ready-shots.d.ts +29 -3
  73. package/src/lib/design/ready-shots.js +105 -5
  74. package/src/lib/design/ready-shots.js.map +1 -1
  75. package/src/lib/design/render-packages.d.ts +9 -17
  76. package/src/lib/design/render-packages.js +25 -63
  77. package/src/lib/design/render-packages.js.map +1 -1
  78. package/src/lib/design/render-worker.js +2 -3
  79. package/src/lib/design/render-worker.js.map +1 -1
  80. package/src/lib/design/render.d.ts +2 -0
  81. package/src/lib/design/render.js +32 -7
  82. package/src/lib/design/render.js.map +1 -1
  83. package/src/lib/design/serve.d.ts +23 -3
  84. package/src/lib/design/serve.js +288 -35
  85. package/src/lib/design/serve.js.map +1 -1
  86. package/src/lib/design/server-identity.d.ts +36 -0
  87. package/src/lib/design/server-identity.js +68 -0
  88. package/src/lib/design/server-identity.js.map +1 -0
  89. package/src/lib/design/settle-frames.d.ts +4 -0
  90. package/src/lib/design/settle-frames.js +22 -0
  91. package/src/lib/design/settle-frames.js.map +1 -0
  92. package/src/lib/design/shot-command.d.ts +30 -6
  93. package/src/lib/design/shot-command.js +144 -56
  94. package/src/lib/design/shot-command.js.map +1 -1
  95. package/src/lib/design/shot-store.d.ts +24 -0
  96. package/src/lib/design/shot-store.js +120 -0
  97. package/src/lib/design/shot-store.js.map +1 -0
  98. package/src/lib/design/shot.d.ts +71 -1
  99. package/src/lib/design/shot.js +253 -40
  100. package/src/lib/design/shot.js.map +1 -1
  101. package/src/lib/design/sketch-command.d.ts +6 -1
  102. package/src/lib/design/sketch-command.js +452 -136
  103. package/src/lib/design/sketch-command.js.map +1 -1
  104. package/src/lib/design/ssr-shims.d.ts +2 -0
  105. package/src/lib/design/ssr-shims.js +12 -1
  106. package/src/lib/design/ssr-shims.js.map +1 -1
  107. package/src/lib/design/stale-cli-dist.d.ts +11 -0
  108. package/src/lib/design/stale-cli-dist.js +56 -0
  109. package/src/lib/design/stale-cli-dist.js.map +1 -0
  110. package/src/lib/design/stamp.d.ts +18 -1
  111. package/src/lib/design/stamp.js +53 -7
  112. package/src/lib/design/stamp.js.map +1 -1
  113. package/src/lib/design/started-by-studio.d.ts +1 -0
  114. package/src/lib/design/started-by-studio.js +6 -0
  115. package/src/lib/design/started-by-studio.js.map +1 -0
  116. package/src/lib/design/studio-api.d.ts +35 -4
  117. package/src/lib/design/studio-api.js +312 -41
  118. package/src/lib/design/studio-api.js.map +1 -1
  119. package/src/lib/design/system/accept-command.d.ts +39 -5
  120. package/src/lib/design/system/accept-command.js +109 -25
  121. package/src/lib/design/system/accept-command.js.map +1 -1
  122. package/src/lib/design/system/accepted-pictures.d.ts +83 -0
  123. package/src/lib/design/system/accepted-pictures.js +324 -0
  124. package/src/lib/design/system/accepted-pictures.js.map +1 -0
  125. package/src/lib/design/system/action-lost.d.ts +59 -0
  126. package/src/lib/design/system/action-lost.js +120 -0
  127. package/src/lib/design/system/action-lost.js.map +1 -0
  128. package/src/lib/design/system/action-press.d.ts +23 -0
  129. package/src/lib/design/system/action-press.js +76 -0
  130. package/src/lib/design/system/action-press.js.map +1 -0
  131. package/src/lib/design/system/action-undeclared.d.ts +34 -0
  132. package/src/lib/design/system/action-undeclared.js +81 -0
  133. package/src/lib/design/system/action-undeclared.js.map +1 -0
  134. package/src/lib/design/system/actions-command.d.ts +101 -0
  135. package/src/lib/design/system/actions-command.js +695 -0
  136. package/src/lib/design/system/actions-command.js.map +1 -0
  137. package/src/lib/design/system/actions.d.ts +158 -0
  138. package/src/lib/design/system/actions.js +295 -0
  139. package/src/lib/design/system/actions.js.map +1 -0
  140. package/src/lib/design/system/app-files.d.ts +10 -0
  141. package/src/lib/design/system/app-files.js +159 -0
  142. package/src/lib/design/system/app-files.js.map +1 -0
  143. package/src/lib/design/system/bespoke-controls.d.ts +30 -0
  144. package/src/lib/design/system/bespoke-controls.js +147 -0
  145. package/src/lib/design/system/bespoke-controls.js.map +1 -0
  146. package/src/lib/design/system/build-ready-contract.d.ts +27 -0
  147. package/src/lib/design/system/build-ready-contract.js +12 -0
  148. package/src/lib/design/system/build-ready-contract.js.map +1 -0
  149. package/src/lib/design/system/check-rules.d.ts +1 -0
  150. package/src/lib/design/system/check-rules.js +82 -0
  151. package/src/lib/design/system/check-rules.js.map +1 -0
  152. package/src/lib/design/system/check-system.d.ts +62 -3
  153. package/src/lib/design/system/check-system.js +527 -34
  154. package/src/lib/design/system/check-system.js.map +1 -1
  155. package/src/lib/design/system/colour.d.ts +4 -1
  156. package/src/lib/design/system/colour.js +54 -2
  157. package/src/lib/design/system/colour.js.map +1 -1
  158. package/src/lib/design/system/comments/comment.d.ts +4 -1
  159. package/src/lib/design/system/comments/comment.js +13 -4
  160. package/src/lib/design/system/comments/comment.js.map +1 -1
  161. package/src/lib/design/system/comments/inbox.js +2 -2
  162. package/src/lib/design/system/comments/inbox.js.map +1 -1
  163. package/src/lib/design/system/compare-command.d.ts +119 -0
  164. package/src/lib/design/system/compare-command.js +558 -0
  165. package/src/lib/design/system/compare-command.js.map +1 -0
  166. package/src/lib/design/system/complete-command.js +7 -3
  167. package/src/lib/design/system/complete-command.js.map +1 -1
  168. package/src/lib/design/system/complete.d.ts +99 -3
  169. package/src/lib/design/system/complete.js +358 -88
  170. package/src/lib/design/system/complete.js.map +1 -1
  171. package/src/lib/design/system/component-outputs.d.ts +20 -0
  172. package/src/lib/design/system/component-outputs.js +86 -0
  173. package/src/lib/design/system/component-outputs.js.map +1 -0
  174. package/src/lib/design/system/contrast-check.d.ts +6 -1
  175. package/src/lib/design/system/contrast-check.js +179 -13
  176. package/src/lib/design/system/contrast-check.js.map +1 -1
  177. package/src/lib/design/system/demo-backdrop.d.ts +11 -0
  178. package/src/lib/design/system/demo-backdrop.js +41 -0
  179. package/src/lib/design/system/demo-backdrop.js.map +1 -0
  180. package/src/lib/design/system/design-hash.d.ts +31 -0
  181. package/src/lib/design/system/design-hash.js +73 -0
  182. package/src/lib/design/system/design-hash.js.map +1 -0
  183. package/src/lib/design/system/disabled-interaction.d.ts +8 -0
  184. package/src/lib/design/system/disabled-interaction.js +37 -0
  185. package/src/lib/design/system/disabled-interaction.js.map +1 -0
  186. package/src/lib/design/system/dom-command.d.ts +36 -0
  187. package/src/lib/design/system/dom-command.js +175 -0
  188. package/src/lib/design/system/dom-command.js.map +1 -0
  189. package/src/lib/design/system/drawn-open-points.d.ts +38 -0
  190. package/src/lib/design/system/drawn-open-points.js +94 -0
  191. package/src/lib/design/system/drawn-open-points.js.map +1 -0
  192. package/src/lib/design/system/dropped-props.d.ts +25 -0
  193. package/src/lib/design/system/dropped-props.js +159 -0
  194. package/src/lib/design/system/dropped-props.js.map +1 -0
  195. package/src/lib/design/system/embedded-actions.d.ts +21 -0
  196. package/src/lib/design/system/embedded-actions.js +37 -0
  197. package/src/lib/design/system/embedded-actions.js.map +1 -0
  198. package/src/lib/design/system/exceptions.js +2 -1
  199. package/src/lib/design/system/exceptions.js.map +1 -1
  200. package/src/lib/design/system/flows/flow.js +2 -1
  201. package/src/lib/design/system/flows/flow.js.map +1 -1
  202. package/src/lib/design/system/frozen-animations.d.ts +13 -0
  203. package/src/lib/design/system/frozen-animations.js +51 -0
  204. package/src/lib/design/system/frozen-animations.js.map +1 -0
  205. package/src/lib/design/system/go-batch.d.ts +24 -0
  206. package/src/lib/design/system/go-batch.js +110 -0
  207. package/src/lib/design/system/go-batch.js.map +1 -0
  208. package/src/lib/design/system/go-command.d.ts +4 -0
  209. package/src/lib/design/system/go-command.js +64 -0
  210. package/src/lib/design/system/go-command.js.map +1 -0
  211. package/src/lib/design/system/go-guard.d.ts +26 -0
  212. package/src/lib/design/system/go-guard.js +70 -0
  213. package/src/lib/design/system/go-guard.js.map +1 -0
  214. package/src/lib/design/system/go-step.d.ts +13 -0
  215. package/src/lib/design/system/go-step.js +84 -0
  216. package/src/lib/design/system/go-step.js.map +1 -0
  217. package/src/lib/design/system/handoff.js +2 -1
  218. package/src/lib/design/system/handoff.js.map +1 -1
  219. package/src/lib/design/system/harness-build-cache.d.ts +35 -0
  220. package/src/lib/design/system/harness-build-cache.js +175 -0
  221. package/src/lib/design/system/harness-build-cache.js.map +1 -0
  222. package/src/lib/design/system/harness-command.d.ts +7 -0
  223. package/src/lib/design/system/harness-command.js +51 -0
  224. package/src/lib/design/system/harness-command.js.map +1 -0
  225. package/src/lib/design/system/harness-config.d.ts +9 -0
  226. package/src/lib/design/system/harness-config.js +65 -0
  227. package/src/lib/design/system/harness-config.js.map +1 -0
  228. package/src/lib/design/system/harness-map.d.ts +44 -0
  229. package/src/lib/design/system/harness-map.js +126 -0
  230. package/src/lib/design/system/harness-map.js.map +1 -0
  231. package/src/lib/design/system/harness-samples.d.ts +20 -0
  232. package/src/lib/design/system/harness-samples.js +92 -0
  233. package/src/lib/design/system/harness-samples.js.map +1 -0
  234. package/src/lib/design/system/harness-server.d.ts +40 -0
  235. package/src/lib/design/system/harness-server.js +296 -0
  236. package/src/lib/design/system/harness-server.js.map +1 -0
  237. package/src/lib/design/system/imports.js +14 -1
  238. package/src/lib/design/system/imports.js.map +1 -1
  239. package/src/lib/design/system/in-order-at-once.d.ts +6 -0
  240. package/src/lib/design/system/in-order-at-once.js +28 -0
  241. package/src/lib/design/system/in-order-at-once.js.map +1 -0
  242. package/src/lib/design/system/inventory-approval.js +2 -1
  243. package/src/lib/design/system/inventory-approval.js.map +1 -1
  244. package/src/lib/design/system/inventory.d.ts +13 -4
  245. package/src/lib/design/system/inventory.js +36 -7
  246. package/src/lib/design/system/inventory.js.map +1 -1
  247. package/src/lib/design/system/list-system.d.ts +8 -1
  248. package/src/lib/design/system/list-system.js +13 -3
  249. package/src/lib/design/system/list-system.js.map +1 -1
  250. package/src/lib/design/system/live-actions.d.ts +121 -0
  251. package/src/lib/design/system/live-actions.js +665 -0
  252. package/src/lib/design/system/live-actions.js.map +1 -0
  253. package/src/lib/design/system/live-compare.d.ts +136 -0
  254. package/src/lib/design/system/live-compare.js +441 -0
  255. package/src/lib/design/system/live-compare.js.map +1 -0
  256. package/src/lib/design/system/live-uncovered.d.ts +40 -0
  257. package/src/lib/design/system/live-uncovered.js +123 -0
  258. package/src/lib/design/system/live-uncovered.js.map +1 -0
  259. package/src/lib/design/system/nested-scroll.d.ts +7 -0
  260. package/src/lib/design/system/nested-scroll.js +25 -0
  261. package/src/lib/design/system/nested-scroll.js.map +1 -0
  262. package/src/lib/design/system/notes/note.js +2 -1
  263. package/src/lib/design/system/notes/note.js.map +1 -1
  264. package/src/lib/design/system/occluded.d.ts +13 -0
  265. package/src/lib/design/system/occluded.js +111 -0
  266. package/src/lib/design/system/occluded.js.map +1 -0
  267. package/src/lib/design/system/open-points.d.ts +119 -0
  268. package/src/lib/design/system/open-points.js +185 -0
  269. package/src/lib/design/system/open-points.js.map +1 -0
  270. package/src/lib/design/system/part-build-ready.d.ts +39 -0
  271. package/src/lib/design/system/part-build-ready.js +107 -0
  272. package/src/lib/design/system/part-build-ready.js.map +1 -0
  273. package/src/lib/design/system/part-command.js +2 -9
  274. package/src/lib/design/system/part-command.js.map +1 -1
  275. package/src/lib/design/system/part-compare.d.ts +123 -0
  276. package/src/lib/design/system/part-compare.js +396 -0
  277. package/src/lib/design/system/part-compare.js.map +1 -0
  278. package/src/lib/design/system/part-go.d.ts +70 -0
  279. package/src/lib/design/system/part-go.js +94 -0
  280. package/src/lib/design/system/part-go.js.map +1 -0
  281. package/src/lib/design/system/part-ready.d.ts +90 -0
  282. package/src/lib/design/system/part-ready.js +172 -0
  283. package/src/lib/design/system/part-ready.js.map +1 -0
  284. package/src/lib/design/system/part-task.d.ts +147 -0
  285. package/src/lib/design/system/part-task.js +285 -0
  286. package/src/lib/design/system/part-task.js.map +1 -0
  287. package/src/lib/design/system/pointer-focus.d.ts +81 -0
  288. package/src/lib/design/system/pointer-focus.js +152 -0
  289. package/src/lib/design/system/pointer-focus.js.map +1 -0
  290. package/src/lib/design/system/prettier.d.ts +10 -0
  291. package/src/lib/design/system/prettier.js +36 -0
  292. package/src/lib/design/system/prettier.js.map +1 -0
  293. package/src/lib/design/system/reach.d.ts +12 -0
  294. package/src/lib/design/system/reach.js +186 -0
  295. package/src/lib/design/system/reach.js.map +1 -0
  296. package/src/lib/design/system/reachable-controls.d.ts +6 -0
  297. package/src/lib/design/system/reachable-controls.js +19 -0
  298. package/src/lib/design/system/reachable-controls.js.map +1 -0
  299. package/src/lib/design/system/reachable-files.d.ts +14 -0
  300. package/src/lib/design/system/reachable-files.js +101 -0
  301. package/src/lib/design/system/reachable-files.js.map +1 -0
  302. package/src/lib/design/system/reached-state.d.ts +23 -0
  303. package/src/lib/design/system/reached-state.js +53 -0
  304. package/src/lib/design/system/reached-state.js.map +1 -0
  305. package/src/lib/design/system/read-open-points.d.ts +33 -0
  306. package/src/lib/design/system/read-open-points.js +110 -0
  307. package/src/lib/design/system/read-open-points.js.map +1 -0
  308. package/src/lib/design/system/ready-command.d.ts +11 -0
  309. package/src/lib/design/system/ready-command.js +82 -0
  310. package/src/lib/design/system/ready-command.js.map +1 -0
  311. package/src/lib/design/system/render-check.d.ts +52 -0
  312. package/src/lib/design/system/render-check.js +479 -60
  313. package/src/lib/design/system/render-check.js.map +1 -1
  314. package/src/lib/design/system/resolve-product.d.ts +2 -1
  315. package/src/lib/design/system/resolve-product.js +25 -3
  316. package/src/lib/design/system/resolve-product.js.map +1 -1
  317. package/src/lib/design/system/rules/app-spec.d.ts +30 -0
  318. package/src/lib/design/system/rules/app-spec.js +87 -0
  319. package/src/lib/design/system/rules/app-spec.js.map +1 -0
  320. package/src/lib/design/system/rules/canonical-class.d.ts +2 -0
  321. package/src/lib/design/system/rules/canonical-class.js +36 -110
  322. package/src/lib/design/system/rules/canonical-class.js.map +1 -1
  323. package/src/lib/design/system/rules/capability-place.d.ts +44 -0
  324. package/src/lib/design/system/rules/capability-place.js +116 -0
  325. package/src/lib/design/system/rules/capability-place.js.map +1 -0
  326. package/src/lib/design/system/rules/denied-class.d.ts +9 -0
  327. package/src/lib/design/system/rules/denied-class.js +121 -0
  328. package/src/lib/design/system/rules/denied-class.js.map +1 -0
  329. package/src/lib/design/system/rules/exemptions.d.ts +18 -0
  330. package/src/lib/design/system/rules/exemptions.js +18 -0
  331. package/src/lib/design/system/rules/exemptions.js.map +1 -0
  332. package/src/lib/design/system/rules/flow.js +1 -1
  333. package/src/lib/design/system/rules/flow.js.map +1 -1
  334. package/src/lib/design/system/rules/glued-interpolation.d.ts +8 -0
  335. package/src/lib/design/system/rules/glued-interpolation.js +61 -0
  336. package/src/lib/design/system/rules/glued-interpolation.js.map +1 -0
  337. package/src/lib/design/system/rules/hard-coded-colour.js +2 -1
  338. package/src/lib/design/system/rules/hard-coded-colour.js.map +1 -1
  339. package/src/lib/design/system/rules/implemented-components.d.ts +22 -0
  340. package/src/lib/design/system/rules/implemented-components.js +45 -0
  341. package/src/lib/design/system/rules/implemented-components.js.map +1 -0
  342. package/src/lib/design/system/rules/implements.d.ts +8 -0
  343. package/src/lib/design/system/rules/implements.js +48 -0
  344. package/src/lib/design/system/rules/implements.js.map +1 -0
  345. package/src/lib/design/system/rules/inline-svg.js +4 -1
  346. package/src/lib/design/system/rules/inline-svg.js.map +1 -1
  347. package/src/lib/design/system/rules/inline-ui-in-page-open.d.ts +13 -0
  348. package/src/lib/design/system/rules/inline-ui-in-page-open.js +5 -0
  349. package/src/lib/design/system/rules/inline-ui-in-page-open.js.map +1 -0
  350. package/src/lib/design/system/rules/inline-ui-in-page.d.ts +18 -0
  351. package/src/lib/design/system/rules/inline-ui-in-page.js +123 -0
  352. package/src/lib/design/system/rules/inline-ui-in-page.js.map +1 -0
  353. package/src/lib/design/system/rules/inline-ui.d.ts +16 -0
  354. package/src/lib/design/system/rules/inline-ui.js +100 -0
  355. package/src/lib/design/system/rules/inline-ui.js.map +1 -0
  356. package/src/lib/design/system/rules/motion.d.ts +2 -0
  357. package/src/lib/design/system/rules/motion.js +35 -2
  358. package/src/lib/design/system/rules/motion.js.map +1 -1
  359. package/src/lib/design/system/rules/native-title.d.ts +7 -0
  360. package/src/lib/design/system/rules/native-title.js +64 -0
  361. package/src/lib/design/system/rules/native-title.js.map +1 -0
  362. package/src/lib/design/system/rules/option-values.d.ts +15 -0
  363. package/src/lib/design/system/rules/option-values.js +145 -0
  364. package/src/lib/design/system/rules/option-values.js.map +1 -0
  365. package/src/lib/design/system/rules/orphan-endpoint-known.d.ts +12 -0
  366. package/src/lib/design/system/rules/orphan-endpoint-known.js +20 -0
  367. package/src/lib/design/system/rules/orphan-endpoint-known.js.map +1 -0
  368. package/src/lib/design/system/rules/orphan-endpoint.d.ts +23 -0
  369. package/src/lib/design/system/rules/orphan-endpoint.js +166 -0
  370. package/src/lib/design/system/rules/orphan-endpoint.js.map +1 -0
  371. package/src/lib/design/system/rules/part-rewrite.d.ts +13 -0
  372. package/src/lib/design/system/rules/part-rewrite.js +125 -0
  373. package/src/lib/design/system/rules/part-rewrite.js.map +1 -0
  374. package/src/lib/design/system/rules/sample-default-known.d.ts +5 -0
  375. package/src/lib/design/system/rules/sample-default-known.js +17 -0
  376. package/src/lib/design/system/rules/sample-default-known.js.map +1 -0
  377. package/src/lib/design/system/rules/sample-default.d.ts +22 -0
  378. package/src/lib/design/system/rules/sample-default.js +92 -0
  379. package/src/lib/design/system/rules/sample-default.js.map +1 -0
  380. package/src/lib/design/system/rules/stale-replace.js +45 -3
  381. package/src/lib/design/system/rules/stale-replace.js.map +1 -1
  382. package/src/lib/design/system/rules/state-in-component.d.ts +16 -0
  383. package/src/lib/design/system/rules/state-in-component.js +101 -0
  384. package/src/lib/design/system/rules/state-in-component.js.map +1 -0
  385. package/src/lib/design/system/rules/tailwind-classes.d.ts +51 -0
  386. package/src/lib/design/system/rules/tailwind-classes.js +232 -0
  387. package/src/lib/design/system/rules/tailwind-classes.js.map +1 -0
  388. package/src/lib/design/system/rules/top-level-await.d.ts +9 -0
  389. package/src/lib/design/system/rules/top-level-await.js +62 -0
  390. package/src/lib/design/system/rules/top-level-await.js.map +1 -0
  391. package/src/lib/design/system/rules/unbound-input-known.d.ts +5 -0
  392. package/src/lib/design/system/rules/unbound-input-known.js +47 -0
  393. package/src/lib/design/system/rules/unbound-input-known.js.map +1 -0
  394. package/src/lib/design/system/rules/unbound-input.d.ts +22 -0
  395. package/src/lib/design/system/rules/unbound-input.js +61 -0
  396. package/src/lib/design/system/rules/unbound-input.js.map +1 -0
  397. package/src/lib/design/system/rules/uncovered-region.d.ts +13 -0
  398. package/src/lib/design/system/rules/uncovered-region.js +36 -0
  399. package/src/lib/design/system/rules/uncovered-region.js.map +1 -0
  400. package/src/lib/design/system/rules/undefined-class.d.ts +9 -0
  401. package/src/lib/design/system/rules/undefined-class.js +32 -0
  402. package/src/lib/design/system/rules/undefined-class.js.map +1 -0
  403. package/src/lib/design/system/rules/undefined-token.d.ts +1 -1
  404. package/src/lib/design/system/rules/undefined-token.js +7 -61
  405. package/src/lib/design/system/rules/undefined-token.js.map +1 -1
  406. package/src/lib/design/system/rules/utility-css.d.ts +2 -1
  407. package/src/lib/design/system/rules/utility-css.js +29 -14
  408. package/src/lib/design/system/rules/utility-css.js.map +1 -1
  409. package/src/lib/design/system/rules/view-coverage.d.ts +8 -0
  410. package/src/lib/design/system/rules/view-coverage.js +51 -0
  411. package/src/lib/design/system/rules/view-coverage.js.map +1 -0
  412. package/src/lib/design/system/rules/visible-change.d.ts +20 -0
  413. package/src/lib/design/system/rules/visible-change.js +48 -0
  414. package/src/lib/design/system/rules/visible-change.js.map +1 -0
  415. package/src/lib/design/system/sdk-errors.d.ts +14 -0
  416. package/src/lib/design/system/sdk-errors.js +38 -0
  417. package/src/lib/design/system/sdk-errors.js.map +1 -0
  418. package/src/lib/design/system/see-through.d.ts +12 -0
  419. package/src/lib/design/system/see-through.js +112 -0
  420. package/src/lib/design/system/see-through.js.map +1 -0
  421. package/src/lib/design/system/settled-panes.d.ts +18 -0
  422. package/src/lib/design/system/settled-panes.js +70 -0
  423. package/src/lib/design/system/settled-panes.js.map +1 -0
  424. package/src/lib/design/system/sketch/after-merge.d.ts +11 -0
  425. package/src/lib/design/system/sketch/after-merge.js +51 -0
  426. package/src/lib/design/system/sketch/after-merge.js.map +1 -0
  427. package/src/lib/design/system/sketch/aktuell-placeholders.d.ts +30 -0
  428. package/src/lib/design/system/sketch/aktuell-placeholders.js +87 -0
  429. package/src/lib/design/system/sketch/aktuell-placeholders.js.map +1 -0
  430. package/src/lib/design/system/sketch/baseline.d.ts +29 -2
  431. package/src/lib/design/system/sketch/baseline.js +33 -9
  432. package/src/lib/design/system/sketch/baseline.js.map +1 -1
  433. package/src/lib/design/system/sketch/check-sketches.d.ts +11 -0
  434. package/src/lib/design/system/sketch/check-sketches.js +54 -6
  435. package/src/lib/design/system/sketch/check-sketches.js.map +1 -1
  436. package/src/lib/design/system/sketch/cli-args.d.ts +12 -2
  437. package/src/lib/design/system/sketch/cli-args.js +18 -3
  438. package/src/lib/design/system/sketch/cli-args.js.map +1 -1
  439. package/src/lib/design/system/sketch/edit-sketch.d.ts +21 -0
  440. package/src/lib/design/system/sketch/edit-sketch.js +117 -0
  441. package/src/lib/design/system/sketch/edit-sketch.js.map +1 -0
  442. package/src/lib/design/system/sketch/frame-budget.d.ts +24 -0
  443. package/src/lib/design/system/sketch/frame-budget.js +23 -0
  444. package/src/lib/design/system/sketch/frame-budget.js.map +1 -0
  445. package/src/lib/design/system/sketch/identical-renders.d.ts +31 -0
  446. package/src/lib/design/system/sketch/identical-renders.js +137 -0
  447. package/src/lib/design/system/sketch/identical-renders.js.map +1 -0
  448. package/src/lib/design/system/sketch/merge-shared.d.ts +2 -0
  449. package/src/lib/design/system/sketch/merge-shared.js +7 -10
  450. package/src/lib/design/system/sketch/merge-shared.js.map +1 -1
  451. package/src/lib/design/system/sketch/merge-step.d.ts +35 -0
  452. package/src/lib/design/system/sketch/merge-step.js +98 -0
  453. package/src/lib/design/system/sketch/merge-step.js.map +1 -0
  454. package/src/lib/design/system/sketch/merge.d.ts +10 -3
  455. package/src/lib/design/system/sketch/merge.js +122 -17
  456. package/src/lib/design/system/sketch/merge.js.map +1 -1
  457. package/src/lib/design/system/sketch/merged-layout.d.ts +17 -0
  458. package/src/lib/design/system/sketch/merged-layout.js +57 -0
  459. package/src/lib/design/system/sketch/merged-layout.js.map +1 -0
  460. package/src/lib/design/system/sketch/merged-parts.d.ts +41 -11
  461. package/src/lib/design/system/sketch/merged-parts.js +113 -50
  462. package/src/lib/design/system/sketch/merged-parts.js.map +1 -1
  463. package/src/lib/design/system/sketch/no-visible-change.d.ts +10 -0
  464. package/src/lib/design/system/sketch/no-visible-change.js +16 -6
  465. package/src/lib/design/system/sketch/no-visible-change.js.map +1 -1
  466. package/src/lib/design/system/sketch/part-definition.d.ts +56 -0
  467. package/src/lib/design/system/sketch/part-definition.js +129 -13
  468. package/src/lib/design/system/sketch/part-definition.js.map +1 -1
  469. package/src/lib/design/system/sketch/rebase-port.d.ts +24 -0
  470. package/src/lib/design/system/sketch/rebase-port.js +170 -0
  471. package/src/lib/design/system/sketch/rebase-port.js.map +1 -0
  472. package/src/lib/design/system/sketch/sample-mark-drift.d.ts +33 -0
  473. package/src/lib/design/system/sketch/sample-mark-drift.js +88 -0
  474. package/src/lib/design/system/sketch/sample-mark-drift.js.map +1 -0
  475. package/src/lib/design/system/sketch/sketch-check-worker.d.ts +1 -0
  476. package/src/lib/design/system/sketch/sketch-check-worker.js +27 -0
  477. package/src/lib/design/system/sketch/sketch-check-worker.js.map +1 -0
  478. package/src/lib/design/system/sketch/sketch-checker.d.ts +27 -0
  479. package/src/lib/design/system/sketch/sketch-checker.js +99 -0
  480. package/src/lib/design/system/sketch/sketch-checker.js.map +1 -0
  481. package/src/lib/design/system/sketch/sketch.d.ts +78 -2
  482. package/src/lib/design/system/sketch/sketch.js +247 -54
  483. package/src/lib/design/system/sketch/sketch.js.map +1 -1
  484. package/src/lib/design/system/sketch/stale-base.d.ts +22 -0
  485. package/src/lib/design/system/sketch/stale-base.js +56 -0
  486. package/src/lib/design/system/sketch/stale-base.js.map +1 -0
  487. package/src/lib/design/system/sketch/unchanged-states.d.ts +36 -1
  488. package/src/lib/design/system/sketch/unchanged-states.js +60 -17
  489. package/src/lib/design/system/sketch/unchanged-states.js.map +1 -1
  490. package/src/lib/design/system/sketch/unused-closure.js +26 -4
  491. package/src/lib/design/system/sketch/unused-closure.js.map +1 -1
  492. package/src/lib/design/system/sketch/unused-files.d.ts +1 -1
  493. package/src/lib/design/system/sketch/unused-files.js +6 -3
  494. package/src/lib/design/system/sketch/unused-files.js.map +1 -1
  495. package/src/lib/design/system/sketch/viewed-shots.d.ts +24 -0
  496. package/src/lib/design/system/sketch/viewed-shots.js +61 -0
  497. package/src/lib/design/system/sketch/viewed-shots.js.map +1 -0
  498. package/src/lib/design/system/slow-checks.d.ts +40 -0
  499. package/src/lib/design/system/slow-checks.js +197 -0
  500. package/src/lib/design/system/slow-checks.js.map +1 -0
  501. package/src/lib/design/system/slow-run.d.ts +57 -0
  502. package/src/lib/design/system/slow-run.js +253 -0
  503. package/src/lib/design/system/slow-run.js.map +1 -0
  504. package/src/lib/design/system/stale-design-mocks.d.ts +20 -0
  505. package/src/lib/design/system/stale-design-mocks.js +59 -0
  506. package/src/lib/design/system/stale-design-mocks.js.map +1 -0
  507. package/src/lib/design/system/stale-dist.d.ts +25 -0
  508. package/src/lib/design/system/stale-dist.js +91 -0
  509. package/src/lib/design/system/stale-dist.js.map +1 -0
  510. package/src/lib/design/system/stale-parts.d.ts +30 -0
  511. package/src/lib/design/system/stale-parts.js +106 -0
  512. package/src/lib/design/system/stale-parts.js.map +1 -0
  513. package/src/lib/design/system/surface-nesting.d.ts +11 -0
  514. package/src/lib/design/system/surface-nesting.js +86 -0
  515. package/src/lib/design/system/surface-nesting.js.map +1 -0
  516. package/src/lib/design/system/system-command.js +8 -6
  517. package/src/lib/design/system/system-command.js.map +1 -1
  518. package/src/lib/design/system/system-modules.d.ts +16 -1
  519. package/src/lib/design/system/system-modules.js +18 -2
  520. package/src/lib/design/system/system-modules.js.map +1 -1
  521. package/src/lib/design/system/system-tsconfig.js +2 -2
  522. package/src/lib/design/system/system-tsconfig.js.map +1 -1
  523. package/src/lib/design/system/task-command.d.ts +51 -0
  524. package/src/lib/design/system/task-command.js +233 -0
  525. package/src/lib/design/system/task-command.js.map +1 -0
  526. package/src/lib/design/system/theming-text.d.ts +2 -0
  527. package/src/lib/design/system/theming-text.js +6 -0
  528. package/src/lib/design/system/theming-text.js.map +1 -0
  529. package/src/lib/design/system/tom-confirm.d.ts +40 -0
  530. package/src/lib/design/system/tom-confirm.js +55 -0
  531. package/src/lib/design/system/tom-confirm.js.map +1 -0
  532. package/src/lib/design/system/touched-parts.d.ts +16 -0
  533. package/src/lib/design/system/touched-parts.js +122 -0
  534. package/src/lib/design/system/touched-parts.js.map +1 -0
  535. package/src/lib/design/system/ts-source.d.ts +5 -0
  536. package/src/lib/design/system/ts-source.js +35 -4
  537. package/src/lib/design/system/ts-source.js.map +1 -1
  538. package/src/lib/design/system/unchanged-rows.d.ts +15 -0
  539. package/src/lib/design/system/unchanged-rows.js +134 -0
  540. package/src/lib/design/system/unchanged-rows.js.map +1 -0
  541. package/src/lib/design/system/uncommitted-decisions.d.ts +6 -0
  542. package/src/lib/design/system/uncommitted-decisions.js +38 -0
  543. package/src/lib/design/system/uncommitted-decisions.js.map +1 -0
  544. package/src/lib/design/system/uncovered-regions.d.ts +61 -0
  545. package/src/lib/design/system/uncovered-regions.js +171 -0
  546. package/src/lib/design/system/uncovered-regions.js.map +1 -0
  547. package/src/lib/design/system/unused-base-parts.d.ts +7 -0
  548. package/src/lib/design/system/unused-base-parts.js +76 -0
  549. package/src/lib/design/system/unused-base-parts.js.map +1 -0
  550. package/src/lib/design/system/visible-change-command.d.ts +48 -0
  551. package/src/lib/design/system/visible-change-command.js +308 -0
  552. package/src/lib/design/system/visible-change-command.js.map +1 -0
  553. package/src/lib/design/system/visible-change-parts.d.ts +28 -0
  554. package/src/lib/design/system/visible-change-parts.js +96 -0
  555. package/src/lib/design/system/visible-change-parts.js.map +1 -0
  556. package/src/lib/design/system/visible-change.d.ts +82 -0
  557. package/src/lib/design/system/visible-change.js +149 -0
  558. package/src/lib/design/system/visible-change.js.map +1 -0
  559. package/src/lib/design/thumb.d.ts +50 -6
  560. package/src/lib/design/thumb.js +154 -54
  561. package/src/lib/design/thumb.js.map +1 -1
  562. package/src/lib/design/typecheck.d.ts +1 -1
  563. package/src/lib/design/typecheck.js +3 -3
  564. package/src/lib/design/typecheck.js.map +1 -1
  565. package/src/lib/design/unstable-cells.d.ts +23 -0
  566. package/src/lib/design/unstable-cells.js +40 -0
  567. package/src/lib/design/unstable-cells.js.map +1 -0
  568. package/src/lib/design/variant-diff.js +1 -1
  569. package/src/lib/design/variant-diff.js.map +1 -1
  570. package/src/lib/design/wait.d.ts +15 -0
  571. package/src/lib/design/wait.js +30 -0
  572. package/src/lib/design/wait.js.map +1 -0
  573. package/src/lib/json-file.d.ts +11 -0
  574. package/src/lib/json-file.js +21 -0
  575. package/src/lib/json-file.js.map +1 -0
  576. package/src/lib/source-hash.d.ts +7 -0
  577. package/src/lib/source-hash.js +62 -0
  578. package/src/lib/source-hash.js.map +1 -0
  579. package/src/lib/update/agent-setup.js +2 -1
  580. package/src/lib/update/agent-setup.js.map +1 -1
  581. package/src/lib/update/migration-manifest.d.ts +12 -0
  582. package/src/lib/update/migration-manifest.js +13 -0
  583. package/src/lib/update/migration-manifest.js.map +1 -1
  584. package/src/lib/update/migration-record.js +2 -1
  585. package/src/lib/update/migration-record.js.map +1 -1
  586. package/src/lib/update/pending.js +2 -1
  587. package/src/lib/update/pending.js.map +1 -1
  588. package/src/lib/update/run-migrations.d.ts +3 -2
  589. package/src/lib/update/run-migrations.js +38 -5
  590. package/src/lib/update/run-migrations.js.map +1 -1
  591. package/src/lib/update/tasks.js +2 -1
  592. package/src/lib/update/tasks.js.map +1 -1
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.completenessOf = exports.inventoryIdsOf = exports.seePart = exports.completenessGapLineOf = exports.completenessGapsOf = exports.findingKeyOf = exports.isFindingOf = exports.declaredControlsOf = void 0;
12
+ exports.partsCompletenessOf = exports.completenessOf = exports.inventoryIdsOf = exports.seePart = exports.seeFrame = exports.PLAIN_CONTROL_SELECTOR = exports.SDK_CONTROLS = exports.isMissingStateGap = exports.completenessGapLineOf = exports.completenessGapsOf = exports.findingKeyOf = exports.isFindingOf = exports.smallChangeHintsOf = exports.introducedControlStateGapsOf = exports.controlStateGapsOf = exports.isControlPart = exports.isInteractionState = exports.declaredControlsOf = void 0;
13
13
  const fs_1 = require("fs");
14
14
  const path_1 = require("path");
15
15
  const browser_1 = require("../browser");
@@ -17,17 +17,21 @@ const force_interactions_1 = require("../force-interactions");
17
17
  const serve_1 = require("../serve");
18
18
  const shot_1 = require("../shot");
19
19
  const thumb_1 = require("../thumb");
20
+ const actions_1 = require("./actions");
20
21
  const resolve_product_1 = require("./resolve-product");
22
+ const contact_sheet_1 = require("../contact-sheet");
21
23
  const baseline_1 = require("./sketch/baseline");
22
24
  const merged_parts_1 = require("./sketch/merged-parts");
23
25
  const system_modules_1 = require("./system-modules");
24
26
  const exceptions_1 = require("./exceptions");
25
27
  const inventory_approval_1 = require("./inventory-approval");
28
+ const option_values_1 = require("./rules/option-values");
29
+ const demo_backdrop_1 = require("./demo-backdrop");
26
30
  const KINDS = {
27
31
  disclosure: { surface: 'body', closed: 'collapsed' },
28
32
  button: { adds: ['active'] },
29
- select: { surface: 'open', options: true },
30
- menu: { surface: 'open', options: true },
33
+ select: { surface: 'open', options: { interactions: ['hover', 'focus-visible'], selected: true } },
34
+ menu: { surface: 'open', options: { interactions: ['hover', 'focus-visible', 'active'], selected: false } },
31
35
  row: { selects: true, virtualFocus: true },
32
36
  field: { noActive: true },
33
37
  tooltip: { surface: 'tooltip' },
@@ -52,7 +56,7 @@ const requiredInteractionsOf = (control) => {
52
56
  ];
53
57
  };
54
58
  const gridGapOf = (options) => {
55
- const { grid, states, interactions } = options;
59
+ const { grid, states, interactions, disabledStates = new Set() } = options;
56
60
  const fix = `draw its states with interactionRows, which gives the grid a column per interaction (${interactions.join(', ')})`;
57
61
  if (!isRecord(grid) || !Array.isArray(grid['columns']) || !isRecord(grid['rows']))
58
62
  return `the part has no grid - ${fix}`;
@@ -60,12 +64,14 @@ const gridGapOf = (options) => {
60
64
  const missing = interactions.filter((interaction) => !columns.includes(interaction));
61
65
  if (missing.length > 0)
62
66
  return `its grid has no column ${missing.join(', ')} - ${fix}`;
63
- const holes = Object.entries(grid['rows']).flatMap(([row, cells]) => interactions
64
- .filter((interaction) => {
65
- const state = isRecord(cells) ? cells[interaction] : undefined;
66
- return typeof state !== 'string' || !states.includes(state);
67
- })
68
- .map((interaction) => `${row} ${interaction}`));
67
+ const holes = Object.entries(grid['rows']).flatMap(([row, cells]) => isRecord(cells) && typeof cells['rest'] === 'string' && disabledStates.has(cells['rest'])
68
+ ? []
69
+ : interactions
70
+ .filter((interaction) => {
71
+ const state = isRecord(cells) ? cells[interaction] : undefined;
72
+ return typeof state !== 'string' || !states.includes(state);
73
+ })
74
+ .map((interaction) => `${row} ${interaction}`));
69
75
  return holes.length > 0 ? `its grid draws no state in ${holes.join(', ')} - ${fix}` : null;
70
76
  };
71
77
  const declaredControlsOf = (value) => isRecord(value)
@@ -88,6 +94,86 @@ const declaredControlsOf = (value) => isRecord(value)
88
94
  }))
89
95
  : null;
90
96
  exports.declaredControlsOf = declaredControlsOf;
97
+ const INTERACTION_WORDS = new Set(['hover', 'hovered', 'focus', 'focused', 'pressed', 'active', 'selected']);
98
+ const NAME_WORDS = new Set([...INTERACTION_WORDS, 'visible', 'within', 'invalid', 'disabled', 'checked', 'open']);
99
+ const wordsOf = (state) => state
100
+ .replace(/([a-z0-9])([A-Z])/gu, '$1-$2')
101
+ .toLowerCase()
102
+ .split(/[^a-z0-9]+/u)
103
+ .filter((word) => word !== '');
104
+ /**
105
+ * Whether a state name shows an interaction: its last word, split at `-`, `_`, spaces and camelCase, or the whole name
106
+ * is hover, hovered, focus, focused, pressed, active or selected. `row-hover`, `collapseFocus` and `focus-visible`
107
+ * are; `active-only` and `inactive` are not.
108
+ */
109
+ const isInteractionState = (state) => {
110
+ var _a, _b;
111
+ const words = wordsOf(state);
112
+ while (words.length > 1 && ['visible', 'within'].includes((_a = words[words.length - 1]) !== null && _a !== void 0 ? _a : ''))
113
+ words.pop();
114
+ return INTERACTION_WORDS.has((_b = words[words.length - 1]) !== null && _b !== void 0 ? _b : '');
115
+ };
116
+ exports.isInteractionState = isInteractionState;
117
+ /** Whether a part may draw interaction states: it is no page, and its `controls` declare a control of a checked kind. */
118
+ const isControlPart = (options) => {
119
+ var _a;
120
+ return !options.part.startsWith('pages/') &&
121
+ Object.values((_a = (0, exports.declaredControlsOf)(options.controls)) !== null && _a !== void 0 ? _a : {}).some((control) => CHECKED_KINDS.includes(control.kind));
122
+ };
123
+ exports.isControlPart = isControlPart;
124
+ /**
125
+ * One `CONTROL-STATE` gap per element whose interaction states a part draws that is no control part. The element is
126
+ * the state name without its interaction words (`row-hover` names the row), or `control` when nothing is left.
127
+ */
128
+ const controlStateGapsOf = (options) => {
129
+ var _a, _b;
130
+ const { part, states } = options;
131
+ if ((0, exports.isControlPart)(options))
132
+ return [];
133
+ const elements = new Map();
134
+ for (const state of states.filter(exports.isInteractionState)) {
135
+ const element = wordsOf(state)
136
+ .filter((word) => !NAME_WORDS.has(word))
137
+ .join('-') || 'control';
138
+ elements.set(element, [...((_a = elements.get(element)) !== null && _a !== void 0 ? _a : []), state]);
139
+ }
140
+ const why = part.startsWith('pages/')
141
+ ? 'a page is no control part'
142
+ : `${part} declares no control of a kind ${CHECKED_KINDS.join(', ')}`;
143
+ const declaresNone = Object.keys((_b = (0, exports.declaredControlsOf)(options.controls)) !== null && _b !== void 0 ? _b : {}).length === 0;
144
+ const fixOf = (element) => part.startsWith('components/') && declaresNone
145
+ ? `declare its controls (Q164), or extract the ${element} as its own control part`
146
+ : `extract the ${element} as its own control part`;
147
+ return [...elements].map(([element, shown]) => ({
148
+ code: 'CONTROL-STATE',
149
+ target: part,
150
+ detail: `${shown.length === 1 ? 'state' : 'states'} ${statesShownOf(shown)} draw${shown.length === 1 ? 's' : ''} an interaction (hover, focus, pressed, active or selected), which only a control part draws, and ${why} - ${fixOf(element)} and draw ${shown.length === 1 ? 'this state' : 'these states'} there`,
151
+ }));
152
+ };
153
+ exports.controlStateGapsOf = controlStateGapsOf;
154
+ /**
155
+ * The `CONTROL-STATE` gaps render check fails a part on. Only a sketch variant fails, and only on interaction states
156
+ * its base part, `base`, does not already draw as a gap: product check leaves those gaps to `design complete`.
157
+ */
158
+ const introducedControlStateGapsOf = (options) => {
159
+ const { part, controls, states, sketch, base } = options;
160
+ if (!sketch)
161
+ return [];
162
+ const inherited = new Set(base && !(0, exports.isControlPart)({ part, controls: base.controls }) ? base.states.filter(exports.isInteractionState) : []);
163
+ return (0, exports.controlStateGapsOf)({ part, controls, states: states.filter((state) => !inherited.has(state)) });
164
+ };
165
+ exports.introducedControlStateGapsOf = introducedControlStateGapsOf;
166
+ const SMALL_CHANGE = 0.1;
167
+ /**
168
+ * One hint per state of an element or component that is no control part whose pixels differ from its first state in
169
+ * under a tenth of the frame. Pages compose parts, so they get none; interaction states are left to `CONTROL-STATE`.
170
+ */
171
+ const smallChangeHintsOf = (options) => options.part.startsWith('pages/') || (0, exports.isControlPart)(options)
172
+ ? []
173
+ : options.changes
174
+ .filter(({ state, share }) => share > 0 && share < SMALL_CHANGE && !(0, exports.isInteractionState)(state))
175
+ .map(({ state, base, share }) => `HINT ${options.part} ${state} - changes ${(share * 100).toFixed(1)} % of the frame against ${base} - extract the changed element as its own part`);
176
+ exports.smallChangeHintsOf = smallChangeHintsOf;
91
177
  /** Whether a discovered element is an undeclared or unclassified finding of the part, not owned or declared. */
92
178
  const isFindingOf = (declared) => (found) => {
93
179
  var _a;
@@ -96,8 +182,9 @@ const isFindingOf = (declared) => (found) => {
96
182
  !(found.kind === 'control' && found.marked !== null);
97
183
  };
98
184
  exports.isFindingOf = isFindingOf;
99
- const findingKeyOf = (found) => `${found.kind} ${found.what} ${found.path}`;
185
+ const findingKeyOf = (found) => { var _a; return `${found.kind} ${found.what} ${found.path} ${(_a = found.label) !== null && _a !== void 0 ? _a : ''}`; };
100
186
  exports.findingKeyOf = findingKeyOf;
187
+ const NATIVE_CONTROLS = ['button', 'a[href]', 'input:not([type="hidden"])', 'select', 'textarea', 'summary'];
101
188
  const discoveryGapsOf = (options) => {
102
189
  var _a, _b, _c, _d;
103
190
  const { part, declared, frames } = options;
@@ -125,7 +212,9 @@ const discoveryGapsOf = (options) => {
125
212
  ? {
126
213
  code: 'CONTROL-UNDECLARED',
127
214
  target: part,
128
- detail: `${where} - mark it with data-et-control and declare it in controls`,
215
+ detail: `${where} - ${NATIVE_CONTROLS.includes(found.what)
216
+ ? 'mark it with control(markup, name) from @ethlete/components/design/control and declare the name in controls'
217
+ : 'mark it with data-et-control and declare it in controls'}`,
129
218
  }
130
219
  : {
131
220
  code: 'CONTROL-UNCLASSIFIED',
@@ -134,6 +223,29 @@ const discoveryGapsOf = (options) => {
134
223
  };
135
224
  });
136
225
  };
226
+ const actionGapsOf = (options) => {
227
+ var _a, _b, _c;
228
+ const { part, declared, frames } = options;
229
+ const groups = new Map();
230
+ for (const frame of frames.filter((seen) => seen.interaction === null))
231
+ for (const found of (_a = frame.found) !== null && _a !== void 0 ? _a : []) {
232
+ if (found.action !== null ||
233
+ ((_b = found.owner) !== null && _b !== void 0 ? _b : null) !== null ||
234
+ found.within.some((id) => { var _a, _b; return ((_b = (_a = declared[id]) === null || _a === void 0 ? void 0 : _a.part) !== null && _b !== void 0 ? _b : null) !== null; }))
235
+ continue;
236
+ const key = (0, exports.findingKeyOf)(found);
237
+ const group = (_c = groups.get(key)) !== null && _c !== void 0 ? _c : { found, states: [] };
238
+ if (!group.states.includes(frame.state))
239
+ group.states.push(frame.state);
240
+ groups.set(key, group);
241
+ }
242
+ return [...groups.values()].map(({ found, states }) => ({
243
+ code: 'ACTION-UNDECLARED',
244
+ target: part,
245
+ detail: `${found.what}${found.label ? ` "${found.label}"` : ''} at ${found.path} in ${statesShownOf(states)} - declare what it does: data-et-action="<state>" or "emit:<output>"`,
246
+ }));
247
+ };
248
+ const isUndeclaredControlGap = (gap) => gap.code === 'CONTROL-UNDECLARED';
137
249
  const statesShownOf = (states) => states.length > 4 ? `${states.slice(0, 3).join(', ')} and ${states.length - 3} more` : states.join(', ');
138
250
  const overrideGapsOf = (options) => {
139
251
  var _a, _b;
@@ -190,17 +302,26 @@ const ownersOf = (frames) => [
190
302
  .flatMap((seen) => { var _a; return ((_a = seen.found) !== null && _a !== void 0 ? _a : []).map((found) => { var _a; return (_a = found.owner) !== null && _a !== void 0 ? _a : null; }); })
191
303
  .filter((owner) => owner !== null)),
192
304
  ];
193
- const interactionGapOf = (options) => {
305
+ const undefinedClassesGapOf = (options) => {
194
306
  var _a;
307
+ const { forced, what, interaction } = options;
308
+ const seen = forced.find((force) => { var _a; return (_a = force.undefinedClasses) === null || _a === void 0 ? void 0 : _a.length; });
309
+ if (!seen)
310
+ return null;
311
+ const classes = (_a = seen.undefinedClasses) !== null && _a !== void 0 ? _a : [];
312
+ return `state ${seen.state} forces ${interaction} on ${what}, but no stylesheet defines its ${classes.length === 1 ? 'class' : 'classes'} ${classes.join(', ')} - Tailwind generates no utility of that name; use a colour or value the product's theme defines`;
313
+ };
314
+ const interactionGapOf = (options) => {
315
+ var _a, _b;
195
316
  const { frames, id, interaction } = options;
196
317
  const forced = frames.flatMap((frame) => frame.controls
197
318
  .filter((control) => control.id === id)
198
319
  .flatMap((control) => control.forced.filter((force) => force.interaction === interaction))
199
- .map((force) => ({ state: frame.state, differs: force.differs })));
320
+ .map((force) => ({ state: frame.state, differs: force.differs, undefinedClasses: force.undefinedClasses })));
200
321
  if (forced.some((force) => force.differs))
201
322
  return null;
202
323
  if (forced.length > 0)
203
- return `state ${(_a = forced[0]) === null || _a === void 0 ? void 0 : _a.state} forces ${interaction} on it, but its box draws no different pixel than at rest - if a descendant draws ${interaction}, mark it with data-et-control-part`;
324
+ return ((_a = undefinedClassesGapOf({ forced, what: 'it', interaction })) !== null && _a !== void 0 ? _a : `state ${(_b = forced[0]) === null || _b === void 0 ? void 0 : _b.state} forces ${interaction} on it, but its box draws no different pixel than at rest - if a descendant draws ${interaction}, mark it with data-et-control-part`);
204
325
  return `no state draws it ${interaction} - draw a state that forces ${interaction} on the data-et-control element, e.g. with forceInteraction - a data-et-control-part in it takes the force too`;
205
326
  };
206
327
  const keyboardActiveRowGapOf = (options) => {
@@ -237,12 +358,12 @@ const lookGapOf = (options) => {
237
358
  return null;
238
359
  };
239
360
  const forcedGapOf = (options) => {
240
- var _a;
361
+ var _a, _b;
241
362
  const { forced, what, interaction } = options;
242
363
  if (forced.some((force) => force.differs))
243
364
  return null;
244
365
  if (forced.length > 0)
245
- return `state ${(_a = forced[0]) === null || _a === void 0 ? void 0 : _a.state} forces ${interaction} on ${what}, but its box draws no different pixel than at rest`;
366
+ return ((_a = undefinedClassesGapOf(options)) !== null && _a !== void 0 ? _a : `state ${(_b = forced[0]) === null || _b === void 0 ? void 0 : _b.state} forces ${interaction} on ${what}, but its box draws no different pixel than at rest`);
246
367
  return `no state draws ${what} ${interaction} - force ${interaction} on it, e.g. with forceInteraction`;
247
368
  };
248
369
  const surfaceGapsOf = (options) => {
@@ -285,19 +406,21 @@ const keyboardActiveGapOf = (options) => {
285
406
  return `state ${(_b = compared[0]) === null || _b === void 0 ? void 0 : _b.state} marks an option active by ${KEYBOARD_ACTIVE}, but it looks the same as a plain option - give the active option its own look`;
286
407
  };
287
408
  const optionGapsOf = (options) => {
288
- const { frames, surfaceId } = options;
409
+ const { frames, surfaceId, interactions } = options;
289
410
  const shownIn = (frame) => frame.surfaces.filter((seen) => seen.id === surfaceId && seen.shown).flatMap((seen) => { var _a; return (_a = seen.options) !== null && _a !== void 0 ? _a : []; });
290
411
  const what = `an option in ${surfaceId}`;
291
412
  const gaps = [];
292
- for (const interaction of ['hover', 'focus-visible']) {
413
+ for (const interaction of interactions) {
293
414
  const forced = frames.flatMap((frame) => shownIn(frame).flatMap((option) => option.forced
294
415
  .filter((force) => force.interaction === interaction)
295
- .map((force) => ({ state: frame.state, differs: force.differs }))));
416
+ .map((force) => ({ state: frame.state, differs: force.differs, undefinedClasses: force.undefinedClasses }))));
296
417
  const gap = forcedGapOf({ forced, what, interaction });
297
418
  const missing = gap && interaction === 'focus-visible' ? keyboardActiveGapOf({ frames, shownIn, forcedGap: gap }) : gap;
298
419
  if (missing)
299
420
  gaps.push([`option-${interaction}`, missing]);
300
421
  }
422
+ if (!options.selected)
423
+ return gaps;
301
424
  const seen = frames
302
425
  .filter((frame) => frame.interaction === null)
303
426
  .flatMap((frame) => shownIn(frame)
@@ -334,7 +457,7 @@ const requirementGapsOf = (options) => {
334
457
  const forced = frames.flatMap((frame) => frame.controls
335
458
  .filter((seen) => seen.id === id && seen.selected)
336
459
  .flatMap((seen) => seen.forced.filter((force) => force.interaction === 'hover'))
337
- .map((force) => ({ state: frame.state, differs: force.differs })));
460
+ .map((force) => ({ state: frame.state, differs: force.differs, undefinedClasses: force.undefinedClasses })));
338
461
  const hovered = forcedGapOf({ forced, what: 'it selected', interaction: 'hover' });
339
462
  if (selected)
340
463
  gaps.push(['selected', selected]);
@@ -354,7 +477,7 @@ const requirementGapsOf = (options) => {
354
477
  if (kind.surface)
355
478
  gaps.push(...surfaceGapsOf(Object.assign(Object.assign({}, options), { surface: kind.surface, closed: kind.closed })));
356
479
  if (own && kind.options && kind.surface)
357
- gaps.push(...optionGapsOf({ frames, surfaceId: `${id}.${kind.surface}` }));
480
+ gaps.push(...optionGapsOf(Object.assign({ frames, surfaceId: `${id}.${kind.surface}` }, kind.options)));
358
481
  return gaps;
359
482
  };
360
483
  /**
@@ -414,7 +537,10 @@ const completenessGapsOf = (options) => {
414
537
  detail: `${control.part} is not design complete: ${used.length} gap(s) - run design complete ${control.part}`,
415
538
  });
416
539
  const interactions = control.part === null && !part.startsWith('pages/') ? requiredInteractionsOf(control) : [];
417
- const gridGap = interactions.length > 0 ? gridGapOf({ grid, states, interactions }) : null;
540
+ const disabledStates = new Set(frames
541
+ .filter((frame) => frame.interaction === null && frame.controls.some((seen) => seen.id === id && seen.disabled))
542
+ .map((frame) => frame.state));
543
+ const gridGap = interactions.length > 0 ? gridGapOf({ grid, states, interactions, disabledStates }) : null;
418
544
  if (gridGap)
419
545
  gaps.push({ code: 'CONTROL-GRID-MISSING', target: `${part}.${id}`, detail: gridGap });
420
546
  if (!seenIds.has(id)) {
@@ -431,7 +557,8 @@ const completenessGapsOf = (options) => {
431
557
  }
432
558
  return [
433
559
  ...gaps,
434
- ...discoveryGapsOf({ part, declared, frames }),
560
+ ...discoveryGapsOf({ part, declared, frames }).filter((gap) => !isUndeclaredControlGap(gap)),
561
+ ...actionGapsOf({ part, declared, frames }),
435
562
  ...ownerGapsOf({ part, declared, frames, referenced }),
436
563
  ...overrideGapsOf({ part, frames }),
437
564
  ...inventoryGapsOf({ part, inventory }),
@@ -446,6 +573,10 @@ const inventoryGapsOf = ({ part, inventory }) => {
446
573
  };
447
574
  const completenessGapLineOf = (gap) => `${gap.code} ${gap.target} - ${gap.detail}`;
448
575
  exports.completenessGapLineOf = completenessGapLineOf;
576
+ const MISSING_STATE_CODES = ['CONTROL-UNDRAWN', 'CONTROL-GRID-MISSING', 'REQUIREMENT-MISSING'];
577
+ /** Whether a gap is a declared control that no state draws, or that lacks a drawn interaction, look or surface. */
578
+ const isMissingStateGap = (gap) => MISSING_STATE_CODES.includes(gap.code);
579
+ exports.isMissingStateGap = isMissingStateGap;
449
580
  const NO_MOTION = '*, *::before, *::after { transition: none !important; animation: none !important; }';
450
581
  const PAD = 8;
451
582
  const COLOUR_PROPERTIES = [
@@ -489,6 +620,28 @@ const coversOf = (property) => {
489
620
  return ['all', 'border', 'border-color', property.replace(/-color$/, ''), property];
490
621
  return ['all', property];
491
622
  };
623
+ const undefinedVariantClasses = (at) => `((at) => {
624
+ const control = document.querySelector('[data-et-complete="' + at + '"]');
625
+ const selectors = [];
626
+ const collect = (rules) => {
627
+ for (const rule of rules) {
628
+ if (rule.selectorText) selectors.push(rule.selectorText);
629
+ if (rule.cssRules) collect(rule.cssRules);
630
+ }
631
+ };
632
+ for (const sheet of document.styleSheets) {
633
+ try {
634
+ collect(sheet.cssRules);
635
+ } catch {}
636
+ }
637
+ const tokens = new Set([control, ...control.querySelectorAll('*')].flatMap((element) => [...element.classList]));
638
+ return [...tokens].filter((token) => token.includes(':') && !selectors.some((selector) => selector.includes('.' + CSS.escape(token))));
639
+ })(${JSON.stringify(at)})`;
640
+ const VARIANT_WORDS = { hover: 'hover', active: 'active', 'focus-visible': 'focus' };
641
+ const isVariantOf = (token, interaction) => token
642
+ .split(':')
643
+ .slice(0, -1)
644
+ .some((variant) => { var _a; return variant.includes((_a = VARIANT_WORDS[interaction]) !== null && _a !== void 0 ? _a : interaction); });
492
645
  const stillChangesOf = (rest, forced) => forced.names.flatMap((name, element) => {
493
646
  var _a;
494
647
  const { properties, durations } = (_a = forced.transitions[element]) !== null && _a !== void 0 ? _a : { properties: [], durations: [] };
@@ -526,7 +679,7 @@ const INTERACTIVE_ROLES = [
526
679
  'textbox',
527
680
  'treeitem',
528
681
  ];
529
- const SDK_CONTROLS = [
682
+ exports.SDK_CONTROLS = [
530
683
  '[et-button]',
531
684
  '[et-icon-button]',
532
685
  '[et-text-button]',
@@ -566,26 +719,26 @@ const SDK_CONTROLS = [
566
719
  'et-time-input',
567
720
  'et-toggletip',
568
721
  ];
569
- const LIKELY_CONTROLS = [
570
- ...SDK_CONTROLS,
571
- 'button',
572
- 'a[href]',
573
- 'input:not([type="hidden"])',
574
- 'select',
575
- 'textarea',
576
- 'summary',
577
- '[tabindex]',
578
- ...INTERACTIVE_ROLES.map((role) => `[role="${role}"]`),
579
- ];
722
+ const PLAIN_CONTROLS = [...NATIVE_CONTROLS, '[tabindex]', ...INTERACTIVE_ROLES.map((role) => `[role="${role}"]`)];
723
+ const LIKELY_CONTROLS = [...exports.SDK_CONTROLS, ...PLAIN_CONTROLS];
580
724
  const LOOK_PROPERTIES = [...COLOUR_PROPERTIES, 'opacity', 'box-shadow', 'font-weight', 'text-decoration-line'];
581
725
  const OPTION_SELECTOR = '[role="option"], [role^="menuitem"], [data-et-option]';
726
+ const COMPOSITE_ROLES = ['grid', 'listbox', 'menu', 'menubar', 'radiogroup', 'tablist', 'tree', 'treegrid'];
727
+ const DIALOG_ROLES = ['dialog', 'alertdialog'];
728
+ const FOCUS_CONTAINER = [
729
+ ...COMPOSITE_ROLES.flatMap((role) => [`[role="${role}"][tabindex="-1"]`, `[role="${role}"][aria-activedescendant]`]),
730
+ ...DIALOG_ROLES.map((role) => `[role="${role}"][tabindex="-1"]`),
731
+ ].join(', ');
732
+ exports.PLAIN_CONTROL_SELECTOR = `:is(${PLAIN_CONTROLS.join(', ')}):not(${FOCUS_CONTAINER})`;
582
733
  const discoverControls = `((root) => {
583
734
  const LIKELY = ${JSON.stringify(LIKELY_CONTROLS)};
584
735
  const likely = LIKELY.join(', ');
585
- const sdk = ${JSON.stringify(SDK_CONTROLS.join(', '))};
736
+ const container = ${JSON.stringify(FOCUS_CONTAINER)};
737
+ const isLikely = (element) => element.matches(likely) && !element.matches(container);
738
+ const sdk = ${JSON.stringify(exports.SDK_CONTROLS.join(', '))};
586
739
  const rendered = (element) => element.getClientRects().length > 0;
587
740
  const HOVER = /(?<!\\\\):hover(?![\\w-])/g;
588
- const FORCED_HOVER = /:is\\(:hover,\\s*\\[data-et-force~="?hover"?\\]\\)/g;
741
+ const FORCED_HOVER = /:is\\(:hover,\\s*\\[data-et-force~="?hover"?\\](?:,\\s*\\[data-et-force~="?active"?\\])?\\)/g;
589
742
  const hoveredOf = (written) => {
590
743
  const selector = written.replace(FORCED_HOVER, ':hover');
591
744
  const match = new RegExp(HOVER.source).exec(selector);
@@ -640,28 +793,32 @@ const discoverControls = `((root) => {
640
793
  const markedOf = (element) => {
641
794
  if (element.hasAttribute('data-et-control')) return element.getAttribute('data-et-control');
642
795
  for (let at = element.parentElement; at && at !== root; at = at.parentElement) {
643
- if (at.matches(likely)) return null;
796
+ if (isLikely(at)) return null;
644
797
  const id = markerOf(at, element);
645
798
  if (id !== null) return id;
646
799
  }
647
800
  return null;
648
801
  };
802
+ const labelOf = (element) =>
803
+ (element.getAttribute('aria-label') ?? element.innerText ?? element.textContent ?? '').replace(/\\s+/g, ' ').trim().slice(0, 60) || null;
649
804
  const found = [];
650
805
  for (const element of root.querySelectorAll('*')) {
651
806
  if (!rendered(element)) continue;
652
- const what = LIKELY.find((selector) => element.matches(selector));
807
+ const what = !element.matches(container) && LIKELY.find((selector) => element.matches(selector));
653
808
  if (what) {
654
809
  const inSdk = element.parentElement.closest(sdk);
655
810
  if (inSdk !== null && root.contains(inSdk)) continue;
656
- found.push({ kind: 'control', what: what.startsWith('[') ? element.tagName.toLowerCase() + what : what, path: pathOf(element), marked: markedOf(element), within: withinOf(element), owner: ownerOf(element)?.key ?? null, box: frameBoxOf(element) });
811
+ found.push({ kind: 'control', what: what.startsWith('[') ? element.tagName.toLowerCase() + what : what, path: pathOf(element), label: labelOf(element), marked: markedOf(element), within: withinOf(element), owner: ownerOf(element)?.key ?? null, box: frameBoxOf(element), covered: isCovered(element), ...(element.matches(${JSON.stringify(actions_1.INTERACTIVE_SELECTOR)}) ? { action: element.getAttribute('data-et-action') } : {}) });
657
812
  continue;
658
813
  }
659
814
  const cursor = getComputedStyle(element).cursor;
660
815
  const pointer = cursor === 'pointer' && getComputedStyle(element.parentElement).cursor !== 'pointer';
661
816
  if (!pointer && !hovered.has(element)) continue;
662
- if (element.closest('[data-et-control], ' + likely) !== null) continue;
817
+ let inControl = false;
818
+ for (let at = element; at && !inControl; at = at.parentElement) inControl = at.hasAttribute('data-et-control') || isLikely(at);
819
+ if (inControl) continue;
663
820
  const reason = [pointer ? 'cursor: pointer' : '', hovered.has(element) ? ':hover rule' : ''].filter(Boolean).join(' and ');
664
- found.push({ kind: 'unclassified', what: nameOf(element) + ' with ' + reason, path: pathOf(element), marked: null, within: [], owner: ownerOf(element)?.key ?? null, box: frameBoxOf(element) });
821
+ found.push({ kind: 'unclassified', what: nameOf(element) + ' with ' + reason, path: pathOf(element), label: labelOf(element), marked: null, within: [], owner: ownerOf(element)?.key ?? null, box: frameBoxOf(element), covered: isCovered(element) });
665
822
  }
666
823
  return found;
667
824
  })`;
@@ -745,7 +902,31 @@ const seeFrame = (options) => `(() => {
745
902
  ? { x: Math.round(box.left - ORIGIN.left), y: Math.round(box.top - ORIGIN.top), width: Math.round(box.width), height: Math.round(box.height) }
746
903
  : null;
747
904
  };
905
+ const isCovered = (element) => {
906
+ const box = element.getBoundingClientRect();
907
+ if (box.width <= 0 || box.height <= 0) return false;
908
+ const x = [box.left + 1, box.left + box.width / 2, box.right - 1];
909
+ const y = [box.top + 1, box.top + box.height / 2, box.bottom - 1];
910
+ const points = [[x[1], y[1]], [x[0], y[0]], [x[2], y[0]], [x[0], y[2]], [x[2], y[2]]];
911
+ let hit = false;
912
+ const inline = element.style.getPropertyValue('pointer-events');
913
+ const priority = element.style.getPropertyPriority('pointer-events');
914
+ element.style.setProperty('pointer-events', 'auto', 'important');
915
+ try {
916
+ for (const [px, py] of points) {
917
+ const top = document.elementFromPoint(px, py);
918
+ if (top === null) return false;
919
+ if (element.contains(top)) return false;
920
+ hit = true;
921
+ }
922
+ } finally {
923
+ if (inline) element.style.setProperty('pointer-events', inline, priority);
924
+ else element.style.removeProperty('pointer-events');
925
+ }
926
+ return hit;
927
+ };
748
928
  const OWN = ${JSON.stringify(options.part)};
929
+ const CONTROL_PARTS = ${JSON.stringify(options.controlParts)};
749
930
  const tokensOf = (element, name) => (element.getAttribute(name) ?? '').split(' ').filter(Boolean);
750
931
  const ownerOf = (element) => {
751
932
  const slotted = tokensOf(element, 'data-et-slot');
@@ -819,20 +1000,26 @@ const seeFrame = (options) => `(() => {
819
1000
  const isKeyboard = (element) => element.getAttribute('data-active-source') === 'keyboard';
820
1001
  let next = 0;
821
1002
  const tagged = (element) => {
822
- const at = next++;
1003
+ const at = element.hasAttribute('data-et-complete') ? Number(element.getAttribute('data-et-complete')) : next++;
823
1004
  element.setAttribute('data-et-complete', String(at));
824
1005
  const box = element.getBoundingClientRect();
825
1006
  const x = Math.max(0, box.x + scrollX - ${PAD});
826
1007
  const y = Math.max(0, box.y + scrollY - ${PAD});
1008
+ const width = Math.min(box.x + scrollX + box.width + ${PAD}, document.documentElement.scrollWidth) - x;
1009
+ const height = Math.min(box.y + scrollY + box.height + ${PAD}, document.documentElement.scrollHeight) - y;
827
1010
  return {
828
1011
  at,
829
1012
  forced: tokensOf(element, 'data-et-force'),
830
- box: box.width > 0 && box.height > 0 ? { x, y, width: box.width + ${PAD * 2}, height: box.height + ${PAD * 2} } : null,
1013
+ box: box.width > 0 && box.height > 0 && width > 0 && height > 0 ? { x, y, width, height } : null,
831
1014
  selected: isSelected(element),
832
1015
  look: lookOf(element),
833
1016
  };
834
1017
  };
835
- const controls = [...root.querySelectorAll('[data-et-control]')].filter((element) => ownerOf(element) === null).map((element) => {
1018
+ const isOwnControl = (element) => {
1019
+ const owner = ownerOf(element);
1020
+ return owner === null || CONTROL_PARTS[element.getAttribute('data-et-control')] === owner.key;
1021
+ };
1022
+ const controls = [...root.querySelectorAll('[data-et-control]')].filter(isOwnControl).map((element) => {
836
1023
  const parts = ${controlPartsOf}(element);
837
1024
  const forced = new Set(parts.flatMap((part) => tokensOf(part, 'data-et-force')));
838
1025
  for (const part of parts) if (forced.size > 0) part.setAttribute('data-et-force', [...forced].join(' '));
@@ -841,10 +1028,12 @@ const seeFrame = (options) => `(() => {
841
1028
  disabled: parts.some(isDisabled),
842
1029
  keyboard: parts.some(isKeyboard),
843
1030
  frameBox: frameBoxOf(element),
1031
+ covered: isCovered(element),
844
1032
  ...tagged(element),
845
1033
  };
846
1034
  });
847
- const surfaces = [...root.querySelectorAll('[data-et-surface]')].filter((element) => ownerOf(element) === null).map((element) => ({
1035
+ const partRoot = [root, ...root.querySelectorAll('[data-et-part]')].find((element) => (element.getAttribute('data-et-part') ?? '').split(' ').includes(${JSON.stringify(options.part)}));
1036
+ const surfaces = [...root.querySelectorAll('[data-et-surface]')].filter((element) => ownerOf(element) === null && !(element === partRoot && element.getAttribute('data-et-surface') === '')).map((element) => ({
848
1037
  id: element.getAttribute('data-et-surface'),
849
1038
  shown: shown(element),
850
1039
  options: [...element.querySelectorAll(${JSON.stringify(OPTION_SELECTOR)})].filter((option) => ownerOf(option) === null && shown(option)).map((option) => ({ ...tagged(option), named: option.id !== '' && named.has(option.id), keyboard: isKeyboard(option) })),
@@ -855,8 +1044,10 @@ const seeFrame = (options) => `(() => {
855
1044
  surfaces,
856
1045
  found: discover ? ${discoverControls}(root) : [],
857
1046
  overrides: discover ? ${findOverrides}(${JSON.stringify(options.ownCss)}) : [],
1047
+ backdrop: discover ? ${(0, demo_backdrop_1.findDemoBackdrop)(options.part)}(root) : null,
858
1048
  };
859
1049
  })()`;
1050
+ exports.seeFrame = seeFrame;
860
1051
  const forceOn = ({ at, interaction, on, }) => `((at, interaction, on) => {
861
1052
  const found = document.querySelector('[data-et-complete="' + at + '"]');
862
1053
  for (const element of found.hasAttribute('data-et-control') ? ${controlPartsOf}(found) : [found]) {
@@ -869,21 +1060,29 @@ const forceOn = ({ at, interaction, on, }) => `((at, interaction, on) => {
869
1060
  })(${JSON.stringify(at)}, ${JSON.stringify(interaction)}, ${JSON.stringify(on)})`;
870
1061
  const FORCEABLE = new Set(['hover', 'focus-visible', 'active']);
871
1062
  const seeFrames = (options) => __awaiter(void 0, void 0, void 0, function* () {
872
- const { browser, base, frames, part, ownCss } = options;
1063
+ const { browser, base, frames, part, ownCss, controlParts } = options;
873
1064
  const context = yield browser.newContext();
874
1065
  const seen = [];
875
1066
  const refused = [];
1067
+ const shots = [];
876
1068
  try {
877
1069
  const page = yield context.newPage();
878
- for (const frame of frames) {
1070
+ const seeOne = (frame) => __awaiter(void 0, void 0, void 0, function* () {
879
1071
  yield page.setViewportSize((0, shot_1.viewportOf)(frame.size));
880
1072
  yield (0, thumb_1.openFrame)(page, `${base}/frame.html?${frame.search}`);
881
1073
  yield page.addStyleTag({ content: NO_MOTION });
882
- yield page.evaluate(thumb_1.settled);
883
- const found = (yield page.evaluate(seeFrame({ discover: frame.interaction === null, part, ownCss, clip: frame.clip })));
1074
+ yield (0, thumb_1.awaitSettled)(page);
1075
+ const found = (yield page.evaluate((0, exports.seeFrame)({ discover: frame.interaction === null, part, ownCss, controlParts, clip: frame.clip })));
884
1076
  if ('refused' in found) {
885
1077
  refused.push(`${frame.state}: ${found.refused}`);
886
- continue;
1078
+ return;
1079
+ }
1080
+ if (frame.interaction === null) {
1081
+ const box = frame.clip ? yield page.locator('#root').boundingBox() : null;
1082
+ shots.push({
1083
+ state: frame.state,
1084
+ png: yield page.screenshot({ type: 'png', fullPage: true, animations: 'disabled', clip: box !== null && box !== void 0 ? box : undefined }),
1085
+ });
887
1086
  }
888
1087
  const forcedOf = (element) => __awaiter(void 0, void 0, void 0, function* () {
889
1088
  const forced = [];
@@ -896,22 +1095,23 @@ const seeFrames = (options) => __awaiter(void 0, void 0, void 0, function* () {
896
1095
  const drawn = yield shot();
897
1096
  const drawnColours = (yield page.evaluate(colourSnapshot(element.at)));
898
1097
  yield page.evaluate(forceOn({ at: element.at, interaction, on: false }));
899
- yield page.evaluate(thumb_1.settled);
1098
+ yield (0, thumb_1.awaitSettled)(page);
900
1099
  const rest = yield shot();
901
1100
  const restColours = (yield page.evaluate(colourSnapshot(element.at)));
902
1101
  yield page.evaluate(forceOn({ at: element.at, interaction, on: true }));
903
- forced.push({
904
- interaction,
905
- differs: !drawn.equals(rest),
906
- still: stillChangesOf(restColours, drawnColours),
907
- });
1102
+ const differs = !drawn.equals(rest);
1103
+ const undefinedClasses = differs
1104
+ ? []
1105
+ : (yield page.evaluate(undefinedVariantClasses(element.at))).filter((token) => isVariantOf(token, interaction));
1106
+ forced.push(Object.assign({ interaction,
1107
+ differs, still: stillChangesOf(restColours, drawnColours) }, (undefinedClasses.length > 0 ? { undefinedClasses } : {})));
908
1108
  }
909
1109
  return forced;
910
1110
  });
911
1111
  const controls = [];
912
1112
  const surfaces = [];
913
1113
  for (const control of found.controls)
914
- controls.push(Object.assign(Object.assign({ id: control.id, forced: yield forcedOf(control), selected: control.selected, disabled: control.disabled, look: control.look }, (control.keyboard ? { keyboard: true } : {})), { box: control.frameBox }));
1114
+ controls.push(Object.assign(Object.assign(Object.assign({ id: control.id, forced: yield forcedOf(control), selected: control.selected, disabled: control.disabled, look: control.look }, (control.keyboard ? { keyboard: true } : {})), { box: control.frameBox }), (control.covered ? { covered: true } : {})));
915
1115
  for (const surface of found.surfaces) {
916
1116
  const options = [];
917
1117
  for (const option of surface.options)
@@ -925,20 +1125,42 @@ const seeFrames = (options) => __awaiter(void 0, void 0, void 0, function* () {
925
1125
  surfaces,
926
1126
  found: found.found,
927
1127
  overrides: found.overrides,
1128
+ backdrop: found.backdrop,
928
1129
  });
1130
+ });
1131
+ for (const frame of frames) {
1132
+ try {
1133
+ yield seeOne(frame);
1134
+ }
1135
+ catch (error) {
1136
+ refused.push(`${frame.state}: design check could not draw this frame (${error instanceof Error ? error.message.split('\n')[0] : String(error)})`);
1137
+ }
929
1138
  }
930
1139
  }
931
1140
  finally {
932
1141
  yield context.close();
933
1142
  }
934
- return { seen, refused };
1143
+ const [first, ...others] = shots;
1144
+ const shares = first ? yield (0, contact_sheet_1.changedSharesOf)({ browser, base: first.png, others: others.map(({ png }) => png) }) : [];
1145
+ return {
1146
+ seen,
1147
+ refused,
1148
+ changes: others.map(({ state }, index) => {
1149
+ var _a, _b;
1150
+ return ({
1151
+ state,
1152
+ base: (_a = first === null || first === void 0 ? void 0 : first.state) !== null && _a !== void 0 ? _a : '',
1153
+ share: (_b = shares[index]) !== null && _b !== void 0 ? _b : 0,
1154
+ });
1155
+ }),
1156
+ };
935
1157
  });
936
1158
  /**
937
1159
  * Draws every state of one part of the product, at rest and, unless `restOnly`, in each interaction it declares,
938
1160
  * once at its first preset or width, and answers what each frame showed, or why its module did not load as a string.
939
1161
  */
940
1162
  const seePart = (options) => __awaiter(void 0, void 0, void 0, function* () {
941
- var _a, _b, _c, _d, _e;
1163
+ var _a, _b, _c, _d, _e, _f;
942
1164
  const { product, part, system, base, load, draw, restOnly = false, sketch = null } = options;
943
1165
  const key = (0, resolve_product_1.partKeyOf)(part);
944
1166
  const loaded = yield load((0, system_modules_1.productModuleIdOf)({ file: part.file, product: product.name, sketch }))
@@ -984,13 +1206,15 @@ const seePart = (options) => __awaiter(void 0, void 0, void 0, function* () {
984
1206
  .filter((file) => file.endsWith('.css'))
985
1207
  .sort()
986
1208
  .map((file) => (0, fs_1.readFileSync)((0, path_1.join)(dir, file), 'utf8'));
987
- const { seen, refused } = yield draw((browser) => seeFrames({ browser, base, frames, part: key, ownCss }));
1209
+ const controlParts = Object.fromEntries(Object.entries((_f = (0, exports.declaredControlsOf)(definition === null || definition === void 0 ? void 0 : definition.controls)) !== null && _f !== void 0 ? _f : {}).flatMap(([id, control]) => control.part === null ? [] : [[id, control.part]]));
1210
+ const { seen, refused, changes } = yield draw((browser) => seeFrames({ browser, base, frames, part: key, ownCss, controlParts }));
988
1211
  const owner = (0, inventory_approval_1.partOwnerOf)({ product, part });
989
1212
  return {
990
1213
  definition,
991
1214
  states,
992
1215
  seen,
993
1216
  refused,
1217
+ changes,
994
1218
  addresses: states.map((state) => ({ state, preset, width })),
995
1219
  owner,
996
1220
  hash: (0, baseline_1.partHashOf)({ product: owner, dir }),
@@ -1005,23 +1229,45 @@ exports.inventoryIdsOf = inventoryIdsOf;
1005
1229
  /**
1006
1230
  * Draws every state of one part, at rest and in each interaction it declares, once at its first preset or width,
1007
1231
  * and answers the gaps of its `controls` declaration, or why it could not draw. A part a control names in `part`,
1008
- * and an embedded part whose `data-et-part` root draws a control, is checked the same way, and its gaps fail it.
1232
+ * and an embedded part whose `data-et-part` root draws a control, is checked the same way, and its gaps fail it -
1233
+ * unless it is a part of the product's base, whose gaps stay its own.
1009
1234
  * A page fails until the user approves its control inventory in Studio. An exception the user approved in Studio
1010
1235
  * drops the gap it names until the part changes; a pending one still fails. With `sketch`, every part is drawn as
1011
1236
  * that variant draws it, and a part the variant changes is not merged yet, so it never fails as unreviewed.
1237
+ * A drawn control that no `controls` entry declares is a hint; the sketch check fails on one a sketch adds.
1012
1238
  */
1013
1239
  const completenessOf = (options) => __awaiter(void 0, void 0, void 0, function* () {
1014
1240
  var _a, _b, _c, _d;
1015
1241
  const { target, config, product, part, sketch = null } = options;
1016
- const resolveChromium = (_a = options.chromiumOf) !== null && _a !== void 0 ? _a : browser_1.chromiumOf;
1017
1242
  const system = (0, system_modules_1.createSystemModules)({ target, config });
1018
- const parts = (_c = (_b = (sketch ? system.drawnOf(product.name, sketch) : product)) === null || _b === void 0 ? void 0 : _b.parts) !== null && _c !== void 0 ? _c : [];
1243
+ const parts = (_b = (_a = (sketch ? system.drawnOf(product.name, sketch) : product)) === null || _a === void 0 ? void 0 : _a.parts) !== null && _b !== void 0 ? _b : [];
1019
1244
  if (!parts.some((candidate) => (0, resolve_product_1.partKeyOf)(candidate) === part))
1020
1245
  return {
1021
1246
  problem: sketch
1022
1247
  ? `variant "${sketch.variant}" of the sketch on ${sketch.target} in product "${product.name}" has no part "${part}"`
1023
1248
  : `product "${product.name}" has no part "${part}"`,
1024
1249
  };
1250
+ const checked = yield (0, exports.partsCompletenessOf)(Object.assign(Object.assign({}, options), { parts: [part] }));
1251
+ if ('unavailable' in checked)
1252
+ return checked;
1253
+ const gaps = (_c = checked.gaps.get(part)) !== null && _c !== void 0 ? _c : [];
1254
+ if (typeof gaps === 'string')
1255
+ return { problem: gaps };
1256
+ const hints = (_d = checked.hints.get(part)) !== null && _d !== void 0 ? _d : [];
1257
+ return Object.assign(Object.assign({ gaps }, (checked.exceptions.length > 0 ? { exceptions: checked.exceptions } : {})), (hints.length > 0 ? { hints } : {}));
1258
+ });
1259
+ exports.completenessOf = completenessOf;
1260
+ /**
1261
+ * Checks each named part as `completenessOf` does, sharing one server, browser and cache, and answers the gaps of
1262
+ * each part, or why it could not be checked as a string.
1263
+ */
1264
+ const partsCompletenessOf = (options) => __awaiter(void 0, void 0, void 0, function* () {
1265
+ var _a, _b, _c, _d;
1266
+ const { target, config, product, sketch = null } = options;
1267
+ const resolveChromium = (_a = options.chromiumOf) !== null && _a !== void 0 ? _a : browser_1.chromiumOf;
1268
+ const system = (0, system_modules_1.createSystemModules)({ target, config });
1269
+ const parts = (_c = (_b = (sketch ? system.drawnOf(product.name, sketch) : product)) === null || _b === void 0 ? void 0 : _b.parts) !== null && _c !== void 0 ? _c : [];
1270
+ const optionValuesOf = (0, option_values_1.optionValuesChecker)({ target, config, parts });
1025
1271
  if (!(yield resolveChromium(target)))
1026
1272
  return { unavailable: 'neither the checkout nor this package resolves playwright or playwright-core' };
1027
1273
  const queue = (0, thumb_1.createDrawQueue)({ target, chromiumOf: resolveChromium });
@@ -1031,6 +1277,7 @@ const completenessOf = (options) => __awaiter(void 0, void 0, void 0, function*
1031
1277
  const { port } = (_d = server.httpServer) === null || _d === void 0 ? void 0 : _d.address();
1032
1278
  const checked = new Map();
1033
1279
  const exceptions = [];
1280
+ const hints = new Map();
1034
1281
  const gapsOfPart = (key, chain) => __awaiter(void 0, void 0, void 0, function* () {
1035
1282
  const known = checked.get(key);
1036
1283
  if (known !== undefined && !chain.includes(key))
@@ -1040,7 +1287,7 @@ const completenessOf = (options) => __awaiter(void 0, void 0, void 0, function*
1040
1287
  return gaps;
1041
1288
  });
1042
1289
  const freshGapsOfPart = (key, chain) => __awaiter(void 0, void 0, void 0, function* () {
1043
- var _a, _b, _c;
1290
+ var _a, _b, _c, _d;
1044
1291
  const resolved = parts.find((candidate) => (0, resolve_product_1.partKeyOf)(candidate) === key);
1045
1292
  if (!resolved)
1046
1293
  return `product "${product.name}" has no part "${key}"`;
@@ -1057,41 +1304,64 @@ const completenessOf = (options) => __awaiter(void 0, void 0, void 0, function*
1057
1304
  });
1058
1305
  if (typeof sight === 'string')
1059
1306
  return [{ code: 'RENDER', target: key, detail: (_a = sight.split('\n')[0]) !== null && _a !== void 0 ? _a : '' }];
1060
- const { definition, states, seen, refused, owner, hash } = sight;
1061
- const sketched = ((_b = product.parts.find((candidate) => (0, resolve_product_1.partKeyOf)(candidate) === key)) === null || _b === void 0 ? void 0 : _b.file) !== resolved.file;
1307
+ const { definition, states, seen, refused, changes, owner, hash } = sight;
1308
+ const optionProblems = optionValuesOf(resolved, definition !== null && definition !== void 0 ? definition : {});
1309
+ hints.set(key, [
1310
+ ...(0, exports.smallChangeHintsOf)({ part: key, controls: definition === null || definition === void 0 ? void 0 : definition.controls, changes }),
1311
+ ...[
1312
+ ...(0, exports.controlStateGapsOf)({ part: key, controls: definition === null || definition === void 0 ? void 0 : definition.controls, states }),
1313
+ ...discoveryGapsOf({
1314
+ part: key,
1315
+ declared: (_b = (0, exports.declaredControlsOf)(definition === null || definition === void 0 ? void 0 : definition.controls)) !== null && _b !== void 0 ? _b : {},
1316
+ frames: seen,
1317
+ }).filter(isUndeclaredControlGap),
1318
+ ...optionProblems
1319
+ .filter((gap) => gap.code === 'OPTION-VALUE-MISSING')
1320
+ .map((gap) => (Object.assign(Object.assign({}, gap), { target: key }))),
1321
+ ].map((gap) => `HINT ${(0, exports.completenessGapLineOf)(gap)}`),
1322
+ ]);
1323
+ const sketched = ((_c = product.parts.find((candidate) => (0, resolve_product_1.partKeyOf)(candidate) === key)) === null || _c === void 0 ? void 0 : _c.file) !== resolved.file;
1062
1324
  const reviewed = sketched || (0, merged_parts_1.readMerged)(owner.dir)[key] === hash;
1063
1325
  const referenced = {};
1064
1326
  const used = [
1065
- ...Object.values((_c = (0, exports.declaredControlsOf)(definition === null || definition === void 0 ? void 0 : definition.controls)) !== null && _c !== void 0 ? _c : {}).map((control) => control.part),
1327
+ ...Object.values((_d = (0, exports.declaredControlsOf)(definition === null || definition === void 0 ? void 0 : definition.controls)) !== null && _d !== void 0 ? _d : {}).map((control) => control.part),
1066
1328
  ...ownersOf(seen),
1067
1329
  ];
1330
+ const isKitPart = (other) => { var _a; return resolved.origin !== 'base' && ((_a = parts.find((candidate) => (0, resolve_product_1.partKeyOf)(candidate) === other)) === null || _a === void 0 ? void 0 : _a.origin) === 'base'; };
1068
1331
  for (const other of used)
1069
1332
  if (other !== null && !(other in referenced))
1070
- referenced[other] = yield gapsOfPart(other, [...chain, key]);
1333
+ referenced[other] = isKitPart(other) ? [] : yield gapsOfPart(other, [...chain, key]);
1071
1334
  const excepted = (0, exceptions_1.withExceptions)({
1072
1335
  part: key,
1073
1336
  exceptions: (0, exceptions_1.readExceptions)(owner.dir),
1074
1337
  hash,
1075
- gaps: (0, exports.completenessGapsOf)({
1076
- part: key,
1077
- controls: definition === null || definition === void 0 ? void 0 : definition.controls,
1078
- states,
1079
- frames: seen,
1080
- reviewed,
1081
- grid: definition === null || definition === void 0 ? void 0 : definition.grid,
1082
- referenced,
1083
- inventory: resolved.layer === 'pages'
1084
- ? (0, inventory_approval_1.inventoryStateOf)({ approval: (0, inventory_approval_1.readInventory)(owner.dir)[key], ids: (0, exports.inventoryIdsOf)(seen), hash })
1085
- : undefined,
1086
- }),
1338
+ gaps: [
1339
+ ...(0, exports.completenessGapsOf)({
1340
+ part: key,
1341
+ controls: definition === null || definition === void 0 ? void 0 : definition.controls,
1342
+ states,
1343
+ frames: seen,
1344
+ reviewed,
1345
+ grid: definition === null || definition === void 0 ? void 0 : definition.grid,
1346
+ referenced,
1347
+ inventory: resolved.layer === 'pages'
1348
+ ? (0, inventory_approval_1.inventoryStateOf)({ approval: (0, inventory_approval_1.readInventory)(owner.dir)[key], ids: (0, exports.inventoryIdsOf)(seen), hash })
1349
+ : undefined,
1350
+ }),
1351
+ ...(resolved.layer === 'pages' ? [] : (0, demo_backdrop_1.demoBackdropGapsOf)({ part: key, frames: seen })),
1352
+ ],
1087
1353
  });
1088
1354
  exceptions.push(...excepted.listed);
1089
- return [...refused.map((detail) => ({ code: 'RENDER', target: key, detail })), ...excepted.gaps];
1355
+ return [
1356
+ ...refused.map((detail) => ({ code: 'RENDER', target: key, detail })),
1357
+ ...optionProblems.filter((gap) => gap.code !== 'OPTION-VALUE-MISSING').map((gap) => (Object.assign(Object.assign({}, gap), { target: key }))),
1358
+ ...excepted.gaps,
1359
+ ];
1090
1360
  });
1091
- const gaps = yield gapsOfPart(part, []);
1092
- if (typeof gaps === 'string')
1093
- return { problem: gaps };
1094
- return exceptions.length > 0 ? { gaps, exceptions } : { gaps };
1361
+ const gaps = new Map();
1362
+ for (const part of options.parts)
1363
+ gaps.set(part, yield gapsOfPart(part, []));
1364
+ return { gaps, exceptions, hints };
1095
1365
  }
1096
1366
  catch (error) {
1097
1367
  if (error instanceof thumb_1.ThumbUnavailableError)
@@ -1102,5 +1372,5 @@ const completenessOf = (options) => __awaiter(void 0, void 0, void 0, function*
1102
1372
  yield Promise.all([queue.close(), server.close()]);
1103
1373
  }
1104
1374
  });
1105
- exports.completenessOf = completenessOf;
1375
+ exports.partsCompletenessOf = partsCompletenessOf;
1106
1376
  //# sourceMappingURL=complete.js.map