@ethlete/cli 3.0.0-next.26 → 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 (557) hide show
  1. package/CHANGELOG.md +328 -0
  2. package/build-info.json +1 -0
  3. package/design/define-call.ts +72 -30
  4. package/design/define-part.ts +37 -4
  5. package/design/icon-sheet.ts +1 -1
  6. package/design/interaction-rows.ts +13 -6
  7. package/design/mark-part.ts +51 -1
  8. package/design/token-sheet.ts +1 -1
  9. package/design/web/frame-fit.ts +7 -0
  10. package/design/web/frame-surfaces.ts +294 -0
  11. package/design/web/frame.ts +41 -15
  12. package/design/web/surface-interactive.css +42 -0
  13. package/design/with-action.ts +29 -0
  14. package/package.json +3 -1
  15. package/src/index.js +9 -1
  16. package/src/index.js.map +1 -1
  17. package/src/lib/design/asset-shot.js +2 -2
  18. package/src/lib/design/asset-shot.js.map +1 -1
  19. package/src/lib/design/build-watch.d.ts +26 -0
  20. package/src/lib/design/build-watch.js +138 -0
  21. package/src/lib/design/build-watch.js.map +1 -0
  22. package/src/lib/design/check.js +142 -16
  23. package/src/lib/design/check.js.map +1 -1
  24. package/src/lib/design/commit-hunks.d.ts +22 -0
  25. package/src/lib/design/commit-hunks.js +173 -0
  26. package/src/lib/design/commit-hunks.js.map +1 -0
  27. package/src/lib/design/design-command.d.ts +2 -0
  28. package/src/lib/design/design-command.js +160 -11
  29. package/src/lib/design/design-command.js.map +1 -1
  30. package/src/lib/design/force-interactions.d.ts +1 -1
  31. package/src/lib/design/force-interactions.js +4 -2
  32. package/src/lib/design/force-interactions.js.map +1 -1
  33. package/src/lib/design/inbox-command.js +9 -5
  34. package/src/lib/design/inbox-command.js.map +1 -1
  35. package/src/lib/design/mcp-command.d.ts +5 -1
  36. package/src/lib/design/mcp-command.js +29 -11
  37. package/src/lib/design/mcp-command.js.map +1 -1
  38. package/src/lib/design/merge-compare.d.ts +10 -2
  39. package/src/lib/design/merge-compare.js +63 -11
  40. package/src/lib/design/merge-compare.js.map +1 -1
  41. package/src/lib/design/motion-command.js +1 -1
  42. package/src/lib/design/motion-command.js.map +1 -1
  43. package/src/lib/design/motion-shot.js +3 -2
  44. package/src/lib/design/motion-shot.js.map +1 -1
  45. package/src/lib/design/new-call.js +19 -10
  46. package/src/lib/design/new-call.js.map +1 -1
  47. package/src/lib/design/part-marks.d.ts +3 -2
  48. package/src/lib/design/part-marks.js +13 -5
  49. package/src/lib/design/part-marks.js.map +1 -1
  50. package/src/lib/design/paths.d.ts +28 -0
  51. package/src/lib/design/paths.js.map +1 -1
  52. package/src/lib/design/product-command.d.ts +1 -1
  53. package/src/lib/design/product-command.js +12 -14
  54. package/src/lib/design/product-command.js.map +1 -1
  55. package/src/lib/design/ready-shots.d.ts +29 -3
  56. package/src/lib/design/ready-shots.js +105 -5
  57. package/src/lib/design/ready-shots.js.map +1 -1
  58. package/src/lib/design/render-packages.d.ts +4 -17
  59. package/src/lib/design/render-packages.js +20 -63
  60. package/src/lib/design/render-packages.js.map +1 -1
  61. package/src/lib/design/render-worker.js +1 -3
  62. package/src/lib/design/render-worker.js.map +1 -1
  63. package/src/lib/design/render.d.ts +2 -0
  64. package/src/lib/design/render.js +32 -7
  65. package/src/lib/design/render.js.map +1 -1
  66. package/src/lib/design/serve.d.ts +21 -1
  67. package/src/lib/design/serve.js +133 -19
  68. package/src/lib/design/serve.js.map +1 -1
  69. package/src/lib/design/server-identity.d.ts +36 -0
  70. package/src/lib/design/server-identity.js +68 -0
  71. package/src/lib/design/server-identity.js.map +1 -0
  72. package/src/lib/design/settle-frames.d.ts +4 -0
  73. package/src/lib/design/settle-frames.js +22 -0
  74. package/src/lib/design/settle-frames.js.map +1 -0
  75. package/src/lib/design/shot-command.d.ts +25 -4
  76. package/src/lib/design/shot-command.js +132 -46
  77. package/src/lib/design/shot-command.js.map +1 -1
  78. package/src/lib/design/shot.d.ts +50 -0
  79. package/src/lib/design/shot.js +143 -17
  80. package/src/lib/design/shot.js.map +1 -1
  81. package/src/lib/design/sketch-command.d.ts +6 -1
  82. package/src/lib/design/sketch-command.js +358 -126
  83. package/src/lib/design/sketch-command.js.map +1 -1
  84. package/src/lib/design/stale-cli-dist.d.ts +11 -0
  85. package/src/lib/design/stale-cli-dist.js +56 -0
  86. package/src/lib/design/stale-cli-dist.js.map +1 -0
  87. package/src/lib/design/stamp.d.ts +18 -1
  88. package/src/lib/design/stamp.js +53 -7
  89. package/src/lib/design/stamp.js.map +1 -1
  90. package/src/lib/design/started-by-studio.d.ts +1 -0
  91. package/src/lib/design/started-by-studio.js +6 -0
  92. package/src/lib/design/started-by-studio.js.map +1 -0
  93. package/src/lib/design/studio-api.d.ts +27 -8
  94. package/src/lib/design/studio-api.js +263 -58
  95. package/src/lib/design/studio-api.js.map +1 -1
  96. package/src/lib/design/system/accept-command.d.ts +39 -5
  97. package/src/lib/design/system/accept-command.js +109 -25
  98. package/src/lib/design/system/accept-command.js.map +1 -1
  99. package/src/lib/design/system/accepted-pictures.d.ts +83 -0
  100. package/src/lib/design/system/accepted-pictures.js +324 -0
  101. package/src/lib/design/system/accepted-pictures.js.map +1 -0
  102. package/src/lib/design/system/action-lost.d.ts +59 -0
  103. package/src/lib/design/system/action-lost.js +120 -0
  104. package/src/lib/design/system/action-lost.js.map +1 -0
  105. package/src/lib/design/system/action-press.d.ts +23 -0
  106. package/src/lib/design/system/action-press.js +76 -0
  107. package/src/lib/design/system/action-press.js.map +1 -0
  108. package/src/lib/design/system/action-undeclared.d.ts +34 -0
  109. package/src/lib/design/system/action-undeclared.js +81 -0
  110. package/src/lib/design/system/action-undeclared.js.map +1 -0
  111. package/src/lib/design/system/actions-command.d.ts +101 -0
  112. package/src/lib/design/system/actions-command.js +695 -0
  113. package/src/lib/design/system/actions-command.js.map +1 -0
  114. package/src/lib/design/system/actions.d.ts +158 -0
  115. package/src/lib/design/system/actions.js +295 -0
  116. package/src/lib/design/system/actions.js.map +1 -0
  117. package/src/lib/design/system/app-files.d.ts +10 -0
  118. package/src/lib/design/system/app-files.js +159 -0
  119. package/src/lib/design/system/app-files.js.map +1 -0
  120. package/src/lib/design/system/bespoke-controls.d.ts +30 -0
  121. package/src/lib/design/system/bespoke-controls.js +147 -0
  122. package/src/lib/design/system/bespoke-controls.js.map +1 -0
  123. package/src/lib/design/system/build-ready-contract.d.ts +27 -0
  124. package/src/lib/design/system/build-ready-contract.js +12 -0
  125. package/src/lib/design/system/build-ready-contract.js.map +1 -0
  126. package/src/lib/design/system/check-rules.d.ts +1 -0
  127. package/src/lib/design/system/check-rules.js +82 -0
  128. package/src/lib/design/system/check-rules.js.map +1 -0
  129. package/src/lib/design/system/check-system.d.ts +61 -6
  130. package/src/lib/design/system/check-system.js +479 -68
  131. package/src/lib/design/system/check-system.js.map +1 -1
  132. package/src/lib/design/system/comments/comment.d.ts +4 -1
  133. package/src/lib/design/system/comments/comment.js +13 -4
  134. package/src/lib/design/system/comments/comment.js.map +1 -1
  135. package/src/lib/design/system/comments/inbox.js +2 -2
  136. package/src/lib/design/system/comments/inbox.js.map +1 -1
  137. package/src/lib/design/system/compare-command.d.ts +119 -0
  138. package/src/lib/design/system/compare-command.js +558 -0
  139. package/src/lib/design/system/compare-command.js.map +1 -0
  140. package/src/lib/design/system/complete-command.js +1 -1
  141. package/src/lib/design/system/complete-command.js.map +1 -1
  142. package/src/lib/design/system/complete.d.ts +32 -1
  143. package/src/lib/design/system/complete.js +144 -48
  144. package/src/lib/design/system/complete.js.map +1 -1
  145. package/src/lib/design/system/component-outputs.d.ts +20 -0
  146. package/src/lib/design/system/component-outputs.js +86 -0
  147. package/src/lib/design/system/component-outputs.js.map +1 -0
  148. package/src/lib/design/system/contrast-check.d.ts +1 -1
  149. package/src/lib/design/system/contrast-check.js +14 -3
  150. package/src/lib/design/system/contrast-check.js.map +1 -1
  151. package/src/lib/design/system/demo-backdrop.d.ts +11 -0
  152. package/src/lib/design/system/demo-backdrop.js +41 -0
  153. package/src/lib/design/system/demo-backdrop.js.map +1 -0
  154. package/src/lib/design/system/design-hash.d.ts +31 -0
  155. package/src/lib/design/system/design-hash.js +73 -0
  156. package/src/lib/design/system/design-hash.js.map +1 -0
  157. package/src/lib/design/system/disabled-interaction.d.ts +8 -0
  158. package/src/lib/design/system/disabled-interaction.js +37 -0
  159. package/src/lib/design/system/disabled-interaction.js.map +1 -0
  160. package/src/lib/design/system/dom-command.d.ts +36 -0
  161. package/src/lib/design/system/dom-command.js +175 -0
  162. package/src/lib/design/system/dom-command.js.map +1 -0
  163. package/src/lib/design/system/drawn-open-points.d.ts +25 -3
  164. package/src/lib/design/system/drawn-open-points.js +65 -14
  165. package/src/lib/design/system/drawn-open-points.js.map +1 -1
  166. package/src/lib/design/system/dropped-props.d.ts +25 -0
  167. package/src/lib/design/system/dropped-props.js +159 -0
  168. package/src/lib/design/system/dropped-props.js.map +1 -0
  169. package/src/lib/design/system/embedded-actions.d.ts +21 -0
  170. package/src/lib/design/system/embedded-actions.js +37 -0
  171. package/src/lib/design/system/embedded-actions.js.map +1 -0
  172. package/src/lib/design/system/exceptions.js +2 -1
  173. package/src/lib/design/system/exceptions.js.map +1 -1
  174. package/src/lib/design/system/flows/flow.js +2 -1
  175. package/src/lib/design/system/flows/flow.js.map +1 -1
  176. package/src/lib/design/system/frozen-animations.d.ts +13 -0
  177. package/src/lib/design/system/frozen-animations.js +51 -0
  178. package/src/lib/design/system/frozen-animations.js.map +1 -0
  179. package/src/lib/design/system/go-batch.d.ts +24 -0
  180. package/src/lib/design/system/go-batch.js +110 -0
  181. package/src/lib/design/system/go-batch.js.map +1 -0
  182. package/src/lib/design/system/go-command.d.ts +4 -0
  183. package/src/lib/design/system/go-command.js +64 -0
  184. package/src/lib/design/system/go-command.js.map +1 -0
  185. package/src/lib/design/system/go-guard.d.ts +26 -0
  186. package/src/lib/design/system/go-guard.js +70 -0
  187. package/src/lib/design/system/go-guard.js.map +1 -0
  188. package/src/lib/design/system/go-step.d.ts +13 -0
  189. package/src/lib/design/system/go-step.js +84 -0
  190. package/src/lib/design/system/go-step.js.map +1 -0
  191. package/src/lib/design/system/handoff.js +2 -1
  192. package/src/lib/design/system/handoff.js.map +1 -1
  193. package/src/lib/design/system/harness-build-cache.d.ts +35 -0
  194. package/src/lib/design/system/harness-build-cache.js +175 -0
  195. package/src/lib/design/system/harness-build-cache.js.map +1 -0
  196. package/src/lib/design/system/harness-command.d.ts +7 -0
  197. package/src/lib/design/system/harness-command.js +51 -0
  198. package/src/lib/design/system/harness-command.js.map +1 -0
  199. package/src/lib/design/system/harness-config.d.ts +9 -0
  200. package/src/lib/design/system/harness-config.js +65 -0
  201. package/src/lib/design/system/harness-config.js.map +1 -0
  202. package/src/lib/design/system/harness-map.d.ts +44 -0
  203. package/src/lib/design/system/harness-map.js +126 -0
  204. package/src/lib/design/system/harness-map.js.map +1 -0
  205. package/src/lib/design/system/harness-samples.d.ts +20 -0
  206. package/src/lib/design/system/harness-samples.js +92 -0
  207. package/src/lib/design/system/harness-samples.js.map +1 -0
  208. package/src/lib/design/system/harness-server.d.ts +40 -0
  209. package/src/lib/design/system/harness-server.js +296 -0
  210. package/src/lib/design/system/harness-server.js.map +1 -0
  211. package/src/lib/design/system/imports.js +14 -1
  212. package/src/lib/design/system/imports.js.map +1 -1
  213. package/src/lib/design/system/in-order-at-once.d.ts +6 -0
  214. package/src/lib/design/system/in-order-at-once.js +28 -0
  215. package/src/lib/design/system/in-order-at-once.js.map +1 -0
  216. package/src/lib/design/system/inventory-approval.js +2 -1
  217. package/src/lib/design/system/inventory-approval.js.map +1 -1
  218. package/src/lib/design/system/inventory.d.ts +13 -4
  219. package/src/lib/design/system/inventory.js +36 -7
  220. package/src/lib/design/system/inventory.js.map +1 -1
  221. package/src/lib/design/system/list-system.d.ts +4 -0
  222. package/src/lib/design/system/list-system.js +12 -3
  223. package/src/lib/design/system/list-system.js.map +1 -1
  224. package/src/lib/design/system/live-actions.d.ts +121 -0
  225. package/src/lib/design/system/live-actions.js +665 -0
  226. package/src/lib/design/system/live-actions.js.map +1 -0
  227. package/src/lib/design/system/live-compare.d.ts +136 -0
  228. package/src/lib/design/system/live-compare.js +441 -0
  229. package/src/lib/design/system/live-compare.js.map +1 -0
  230. package/src/lib/design/system/live-uncovered.d.ts +40 -0
  231. package/src/lib/design/system/live-uncovered.js +123 -0
  232. package/src/lib/design/system/live-uncovered.js.map +1 -0
  233. package/src/lib/design/system/nested-scroll.d.ts +7 -0
  234. package/src/lib/design/system/nested-scroll.js +25 -0
  235. package/src/lib/design/system/nested-scroll.js.map +1 -0
  236. package/src/lib/design/system/notes/note.js +2 -1
  237. package/src/lib/design/system/notes/note.js.map +1 -1
  238. package/src/lib/design/system/occluded.d.ts +13 -0
  239. package/src/lib/design/system/occluded.js +111 -0
  240. package/src/lib/design/system/occluded.js.map +1 -0
  241. package/src/lib/design/system/open-points.d.ts +24 -6
  242. package/src/lib/design/system/open-points.js +59 -30
  243. package/src/lib/design/system/open-points.js.map +1 -1
  244. package/src/lib/design/system/part-build-ready.d.ts +39 -0
  245. package/src/lib/design/system/part-build-ready.js +107 -0
  246. package/src/lib/design/system/part-build-ready.js.map +1 -0
  247. package/src/lib/design/system/part-command.js +2 -9
  248. package/src/lib/design/system/part-command.js.map +1 -1
  249. package/src/lib/design/system/part-compare.d.ts +123 -0
  250. package/src/lib/design/system/part-compare.js +396 -0
  251. package/src/lib/design/system/part-compare.js.map +1 -0
  252. package/src/lib/design/system/part-go.d.ts +70 -0
  253. package/src/lib/design/system/part-go.js +94 -0
  254. package/src/lib/design/system/part-go.js.map +1 -0
  255. package/src/lib/design/system/part-ready.d.ts +44 -6
  256. package/src/lib/design/system/part-ready.js +88 -17
  257. package/src/lib/design/system/part-ready.js.map +1 -1
  258. package/src/lib/design/system/part-task.d.ts +147 -0
  259. package/src/lib/design/system/part-task.js +285 -0
  260. package/src/lib/design/system/part-task.js.map +1 -0
  261. package/src/lib/design/system/pointer-focus.d.ts +81 -0
  262. package/src/lib/design/system/pointer-focus.js +152 -0
  263. package/src/lib/design/system/pointer-focus.js.map +1 -0
  264. package/src/lib/design/system/prettier.d.ts +10 -0
  265. package/src/lib/design/system/prettier.js +36 -0
  266. package/src/lib/design/system/prettier.js.map +1 -0
  267. package/src/lib/design/system/reach.d.ts +12 -0
  268. package/src/lib/design/system/reach.js +186 -0
  269. package/src/lib/design/system/reach.js.map +1 -0
  270. package/src/lib/design/system/reachable-controls.d.ts +6 -0
  271. package/src/lib/design/system/reachable-controls.js +19 -0
  272. package/src/lib/design/system/reachable-controls.js.map +1 -0
  273. package/src/lib/design/system/reachable-files.d.ts +14 -0
  274. package/src/lib/design/system/reachable-files.js +101 -0
  275. package/src/lib/design/system/reachable-files.js.map +1 -0
  276. package/src/lib/design/system/reached-state.d.ts +23 -0
  277. package/src/lib/design/system/reached-state.js +53 -0
  278. package/src/lib/design/system/reached-state.js.map +1 -0
  279. package/src/lib/design/system/read-open-points.d.ts +9 -3
  280. package/src/lib/design/system/read-open-points.js +38 -9
  281. package/src/lib/design/system/read-open-points.js.map +1 -1
  282. package/src/lib/design/system/ready-command.d.ts +6 -2
  283. package/src/lib/design/system/ready-command.js +32 -15
  284. package/src/lib/design/system/ready-command.js.map +1 -1
  285. package/src/lib/design/system/render-check.d.ts +50 -0
  286. package/src/lib/design/system/render-check.js +341 -88
  287. package/src/lib/design/system/render-check.js.map +1 -1
  288. package/src/lib/design/system/resolve-product.js +5 -0
  289. package/src/lib/design/system/resolve-product.js.map +1 -1
  290. package/src/lib/design/system/rules/app-spec.d.ts +30 -0
  291. package/src/lib/design/system/rules/app-spec.js +87 -0
  292. package/src/lib/design/system/rules/app-spec.js.map +1 -0
  293. package/src/lib/design/system/rules/canonical-class.d.ts +2 -0
  294. package/src/lib/design/system/rules/canonical-class.js +36 -110
  295. package/src/lib/design/system/rules/canonical-class.js.map +1 -1
  296. package/src/lib/design/system/rules/capability-place.d.ts +44 -0
  297. package/src/lib/design/system/rules/capability-place.js +116 -0
  298. package/src/lib/design/system/rules/capability-place.js.map +1 -0
  299. package/src/lib/design/system/rules/denied-class.d.ts +9 -0
  300. package/src/lib/design/system/rules/denied-class.js +121 -0
  301. package/src/lib/design/system/rules/denied-class.js.map +1 -0
  302. package/src/lib/design/system/rules/exemptions.d.ts +18 -0
  303. package/src/lib/design/system/rules/exemptions.js +18 -0
  304. package/src/lib/design/system/rules/exemptions.js.map +1 -0
  305. package/src/lib/design/system/rules/flow.js +1 -1
  306. package/src/lib/design/system/rules/flow.js.map +1 -1
  307. package/src/lib/design/system/rules/glued-interpolation.d.ts +8 -0
  308. package/src/lib/design/system/rules/glued-interpolation.js +61 -0
  309. package/src/lib/design/system/rules/glued-interpolation.js.map +1 -0
  310. package/src/lib/design/system/rules/hard-coded-colour.js +2 -1
  311. package/src/lib/design/system/rules/hard-coded-colour.js.map +1 -1
  312. package/src/lib/design/system/rules/implemented-components.d.ts +22 -0
  313. package/src/lib/design/system/rules/implemented-components.js +45 -0
  314. package/src/lib/design/system/rules/implemented-components.js.map +1 -0
  315. package/src/lib/design/system/rules/implements.d.ts +2 -1
  316. package/src/lib/design/system/rules/implements.js +26 -21
  317. package/src/lib/design/system/rules/implements.js.map +1 -1
  318. package/src/lib/design/system/rules/inline-svg.js +4 -1
  319. package/src/lib/design/system/rules/inline-svg.js.map +1 -1
  320. package/src/lib/design/system/rules/inline-ui-in-page-open.d.ts +13 -0
  321. package/src/lib/design/system/rules/inline-ui-in-page-open.js +5 -0
  322. package/src/lib/design/system/rules/inline-ui-in-page-open.js.map +1 -0
  323. package/src/lib/design/system/rules/inline-ui-in-page.d.ts +18 -0
  324. package/src/lib/design/system/rules/inline-ui-in-page.js +123 -0
  325. package/src/lib/design/system/rules/inline-ui-in-page.js.map +1 -0
  326. package/src/lib/design/system/rules/inline-ui.d.ts +16 -0
  327. package/src/lib/design/system/rules/inline-ui.js +100 -0
  328. package/src/lib/design/system/rules/inline-ui.js.map +1 -0
  329. package/src/lib/design/system/rules/motion.d.ts +1 -1
  330. package/src/lib/design/system/rules/motion.js +25 -17
  331. package/src/lib/design/system/rules/motion.js.map +1 -1
  332. package/src/lib/design/system/rules/native-title.d.ts +7 -0
  333. package/src/lib/design/system/rules/native-title.js +64 -0
  334. package/src/lib/design/system/rules/native-title.js.map +1 -0
  335. package/src/lib/design/system/rules/orphan-endpoint-known.d.ts +12 -0
  336. package/src/lib/design/system/rules/orphan-endpoint-known.js +20 -0
  337. package/src/lib/design/system/rules/orphan-endpoint-known.js.map +1 -0
  338. package/src/lib/design/system/rules/orphan-endpoint.d.ts +23 -0
  339. package/src/lib/design/system/rules/orphan-endpoint.js +166 -0
  340. package/src/lib/design/system/rules/orphan-endpoint.js.map +1 -0
  341. package/src/lib/design/system/rules/part-rewrite.d.ts +13 -0
  342. package/src/lib/design/system/rules/part-rewrite.js +125 -0
  343. package/src/lib/design/system/rules/part-rewrite.js.map +1 -0
  344. package/src/lib/design/system/rules/sample-default-known.d.ts +5 -0
  345. package/src/lib/design/system/rules/sample-default-known.js +17 -0
  346. package/src/lib/design/system/rules/sample-default-known.js.map +1 -0
  347. package/src/lib/design/system/rules/sample-default.d.ts +22 -0
  348. package/src/lib/design/system/rules/sample-default.js +92 -0
  349. package/src/lib/design/system/rules/sample-default.js.map +1 -0
  350. package/src/lib/design/system/rules/stale-replace.js +4 -0
  351. package/src/lib/design/system/rules/stale-replace.js.map +1 -1
  352. package/src/lib/design/system/rules/state-in-component.d.ts +16 -0
  353. package/src/lib/design/system/rules/state-in-component.js +101 -0
  354. package/src/lib/design/system/rules/state-in-component.js.map +1 -0
  355. package/src/lib/design/system/rules/tailwind-classes.d.ts +51 -0
  356. package/src/lib/design/system/rules/tailwind-classes.js +232 -0
  357. package/src/lib/design/system/rules/tailwind-classes.js.map +1 -0
  358. package/src/lib/design/system/rules/top-level-await.d.ts +9 -0
  359. package/src/lib/design/system/rules/top-level-await.js +62 -0
  360. package/src/lib/design/system/rules/top-level-await.js.map +1 -0
  361. package/src/lib/design/system/rules/unbound-input-known.d.ts +5 -0
  362. package/src/lib/design/system/rules/unbound-input-known.js +47 -0
  363. package/src/lib/design/system/rules/unbound-input-known.js.map +1 -0
  364. package/src/lib/design/system/rules/unbound-input.d.ts +22 -0
  365. package/src/lib/design/system/rules/unbound-input.js +61 -0
  366. package/src/lib/design/system/rules/unbound-input.js.map +1 -0
  367. package/src/lib/design/system/rules/uncovered-region.d.ts +13 -0
  368. package/src/lib/design/system/rules/uncovered-region.js +36 -0
  369. package/src/lib/design/system/rules/uncovered-region.js.map +1 -0
  370. package/src/lib/design/system/rules/undefined-class.d.ts +9 -0
  371. package/src/lib/design/system/rules/undefined-class.js +32 -0
  372. package/src/lib/design/system/rules/undefined-class.js.map +1 -0
  373. package/src/lib/design/system/rules/undefined-token.d.ts +1 -1
  374. package/src/lib/design/system/rules/undefined-token.js +7 -61
  375. package/src/lib/design/system/rules/undefined-token.js.map +1 -1
  376. package/src/lib/design/system/rules/utility-css.d.ts +2 -1
  377. package/src/lib/design/system/rules/utility-css.js +29 -14
  378. package/src/lib/design/system/rules/utility-css.js.map +1 -1
  379. package/src/lib/design/system/rules/view-coverage.d.ts +8 -0
  380. package/src/lib/design/system/rules/view-coverage.js +51 -0
  381. package/src/lib/design/system/rules/view-coverage.js.map +1 -0
  382. package/src/lib/design/system/rules/visible-change.d.ts +20 -0
  383. package/src/lib/design/system/rules/visible-change.js +48 -0
  384. package/src/lib/design/system/rules/visible-change.js.map +1 -0
  385. package/src/lib/design/system/sdk-errors.d.ts +14 -0
  386. package/src/lib/design/system/sdk-errors.js +38 -0
  387. package/src/lib/design/system/sdk-errors.js.map +1 -0
  388. package/src/lib/design/system/see-through.d.ts +12 -0
  389. package/src/lib/design/system/see-through.js +112 -0
  390. package/src/lib/design/system/see-through.js.map +1 -0
  391. package/src/lib/design/system/settled-panes.d.ts +18 -0
  392. package/src/lib/design/system/settled-panes.js +70 -0
  393. package/src/lib/design/system/settled-panes.js.map +1 -0
  394. package/src/lib/design/system/sketch/after-merge.d.ts +11 -0
  395. package/src/lib/design/system/sketch/after-merge.js +51 -0
  396. package/src/lib/design/system/sketch/after-merge.js.map +1 -0
  397. package/src/lib/design/system/sketch/aktuell-placeholders.d.ts +30 -0
  398. package/src/lib/design/system/sketch/aktuell-placeholders.js +87 -0
  399. package/src/lib/design/system/sketch/aktuell-placeholders.js.map +1 -0
  400. package/src/lib/design/system/sketch/baseline.d.ts +19 -1
  401. package/src/lib/design/system/sketch/baseline.js +29 -7
  402. package/src/lib/design/system/sketch/baseline.js.map +1 -1
  403. package/src/lib/design/system/sketch/check-sketches.d.ts +10 -0
  404. package/src/lib/design/system/sketch/check-sketches.js +50 -4
  405. package/src/lib/design/system/sketch/check-sketches.js.map +1 -1
  406. package/src/lib/design/system/sketch/cli-args.d.ts +12 -2
  407. package/src/lib/design/system/sketch/cli-args.js +18 -3
  408. package/src/lib/design/system/sketch/cli-args.js.map +1 -1
  409. package/src/lib/design/system/sketch/edit-sketch.d.ts +21 -0
  410. package/src/lib/design/system/sketch/edit-sketch.js +117 -0
  411. package/src/lib/design/system/sketch/edit-sketch.js.map +1 -0
  412. package/src/lib/design/system/sketch/frame-budget.d.ts +24 -0
  413. package/src/lib/design/system/sketch/frame-budget.js +23 -0
  414. package/src/lib/design/system/sketch/frame-budget.js.map +1 -0
  415. package/src/lib/design/system/sketch/identical-renders.d.ts +31 -0
  416. package/src/lib/design/system/sketch/identical-renders.js +137 -0
  417. package/src/lib/design/system/sketch/identical-renders.js.map +1 -0
  418. package/src/lib/design/system/sketch/merge-shared.d.ts +2 -0
  419. package/src/lib/design/system/sketch/merge-shared.js +7 -10
  420. package/src/lib/design/system/sketch/merge-shared.js.map +1 -1
  421. package/src/lib/design/system/sketch/merge-step.d.ts +35 -0
  422. package/src/lib/design/system/sketch/merge-step.js +98 -0
  423. package/src/lib/design/system/sketch/merge-step.js.map +1 -0
  424. package/src/lib/design/system/sketch/merge.d.ts +10 -3
  425. package/src/lib/design/system/sketch/merge.js +103 -30
  426. package/src/lib/design/system/sketch/merge.js.map +1 -1
  427. package/src/lib/design/system/sketch/merged-layout.d.ts +17 -0
  428. package/src/lib/design/system/sketch/merged-layout.js +57 -0
  429. package/src/lib/design/system/sketch/merged-layout.js.map +1 -0
  430. package/src/lib/design/system/sketch/merged-parts.d.ts +40 -10
  431. package/src/lib/design/system/sketch/merged-parts.js +112 -49
  432. package/src/lib/design/system/sketch/merged-parts.js.map +1 -1
  433. package/src/lib/design/system/sketch/no-visible-change.d.ts +10 -0
  434. package/src/lib/design/system/sketch/no-visible-change.js +16 -6
  435. package/src/lib/design/system/sketch/no-visible-change.js.map +1 -1
  436. package/src/lib/design/system/sketch/part-definition.d.ts +21 -1
  437. package/src/lib/design/system/sketch/part-definition.js +79 -17
  438. package/src/lib/design/system/sketch/part-definition.js.map +1 -1
  439. package/src/lib/design/system/sketch/rebase-port.d.ts +24 -0
  440. package/src/lib/design/system/sketch/rebase-port.js +170 -0
  441. package/src/lib/design/system/sketch/rebase-port.js.map +1 -0
  442. package/src/lib/design/system/sketch/sample-mark-drift.d.ts +33 -0
  443. package/src/lib/design/system/sketch/sample-mark-drift.js +88 -0
  444. package/src/lib/design/system/sketch/sample-mark-drift.js.map +1 -0
  445. package/src/lib/design/system/sketch/sketch-check-worker.d.ts +1 -0
  446. package/src/lib/design/system/sketch/sketch-check-worker.js +27 -0
  447. package/src/lib/design/system/sketch/sketch-check-worker.js.map +1 -0
  448. package/src/lib/design/system/sketch/sketch-checker.d.ts +27 -0
  449. package/src/lib/design/system/sketch/sketch-checker.js +99 -0
  450. package/src/lib/design/system/sketch/sketch-checker.js.map +1 -0
  451. package/src/lib/design/system/sketch/sketch.d.ts +63 -2
  452. package/src/lib/design/system/sketch/sketch.js +185 -30
  453. package/src/lib/design/system/sketch/sketch.js.map +1 -1
  454. package/src/lib/design/system/sketch/stale-base.d.ts +22 -0
  455. package/src/lib/design/system/sketch/stale-base.js +56 -0
  456. package/src/lib/design/system/sketch/stale-base.js.map +1 -0
  457. package/src/lib/design/system/sketch/unchanged-states.d.ts +32 -0
  458. package/src/lib/design/system/sketch/unchanged-states.js +52 -13
  459. package/src/lib/design/system/sketch/unchanged-states.js.map +1 -1
  460. package/src/lib/design/system/sketch/unused-closure.js +16 -4
  461. package/src/lib/design/system/sketch/unused-closure.js.map +1 -1
  462. package/src/lib/design/system/sketch/viewed-shots.d.ts +24 -0
  463. package/src/lib/design/system/sketch/viewed-shots.js +61 -0
  464. package/src/lib/design/system/sketch/viewed-shots.js.map +1 -0
  465. package/src/lib/design/system/slow-checks.d.ts +40 -0
  466. package/src/lib/design/system/slow-checks.js +197 -0
  467. package/src/lib/design/system/slow-checks.js.map +1 -0
  468. package/src/lib/design/system/slow-run.d.ts +57 -0
  469. package/src/lib/design/system/slow-run.js +253 -0
  470. package/src/lib/design/system/slow-run.js.map +1 -0
  471. package/src/lib/design/system/stale-design-mocks.d.ts +20 -0
  472. package/src/lib/design/system/stale-design-mocks.js +59 -0
  473. package/src/lib/design/system/stale-design-mocks.js.map +1 -0
  474. package/src/lib/design/system/stale-dist.d.ts +25 -0
  475. package/src/lib/design/system/stale-dist.js +91 -0
  476. package/src/lib/design/system/stale-dist.js.map +1 -0
  477. package/src/lib/design/system/stale-parts.d.ts +30 -0
  478. package/src/lib/design/system/stale-parts.js +106 -0
  479. package/src/lib/design/system/stale-parts.js.map +1 -0
  480. package/src/lib/design/system/surface-nesting.d.ts +11 -0
  481. package/src/lib/design/system/surface-nesting.js +86 -0
  482. package/src/lib/design/system/surface-nesting.js.map +1 -0
  483. package/src/lib/design/system/system-command.js +8 -6
  484. package/src/lib/design/system/system-command.js.map +1 -1
  485. package/src/lib/design/system/system-modules.d.ts +16 -1
  486. package/src/lib/design/system/system-modules.js +18 -2
  487. package/src/lib/design/system/system-modules.js.map +1 -1
  488. package/src/lib/design/system/task-command.d.ts +51 -0
  489. package/src/lib/design/system/task-command.js +233 -0
  490. package/src/lib/design/system/task-command.js.map +1 -0
  491. package/src/lib/design/system/theming-text.d.ts +2 -0
  492. package/src/lib/design/system/theming-text.js +6 -0
  493. package/src/lib/design/system/theming-text.js.map +1 -0
  494. package/src/lib/design/system/tom-confirm.d.ts +40 -0
  495. package/src/lib/design/system/tom-confirm.js +55 -0
  496. package/src/lib/design/system/tom-confirm.js.map +1 -0
  497. package/src/lib/design/system/touched-parts.d.ts +16 -0
  498. package/src/lib/design/system/touched-parts.js +122 -0
  499. package/src/lib/design/system/touched-parts.js.map +1 -0
  500. package/src/lib/design/system/ts-source.d.ts +2 -0
  501. package/src/lib/design/system/ts-source.js +15 -1
  502. package/src/lib/design/system/ts-source.js.map +1 -1
  503. package/src/lib/design/system/unchanged-rows.d.ts +15 -0
  504. package/src/lib/design/system/unchanged-rows.js +134 -0
  505. package/src/lib/design/system/unchanged-rows.js.map +1 -0
  506. package/src/lib/design/system/uncommitted-decisions.d.ts +6 -0
  507. package/src/lib/design/system/uncommitted-decisions.js +38 -0
  508. package/src/lib/design/system/uncommitted-decisions.js.map +1 -0
  509. package/src/lib/design/system/uncovered-regions.d.ts +61 -0
  510. package/src/lib/design/system/uncovered-regions.js +171 -0
  511. package/src/lib/design/system/uncovered-regions.js.map +1 -0
  512. package/src/lib/design/system/unused-base-parts.d.ts +7 -0
  513. package/src/lib/design/system/unused-base-parts.js +76 -0
  514. package/src/lib/design/system/unused-base-parts.js.map +1 -0
  515. package/src/lib/design/system/visible-change-command.d.ts +48 -0
  516. package/src/lib/design/system/visible-change-command.js +308 -0
  517. package/src/lib/design/system/visible-change-command.js.map +1 -0
  518. package/src/lib/design/system/visible-change-parts.d.ts +28 -0
  519. package/src/lib/design/system/visible-change-parts.js +96 -0
  520. package/src/lib/design/system/visible-change-parts.js.map +1 -0
  521. package/src/lib/design/system/visible-change.d.ts +82 -0
  522. package/src/lib/design/system/visible-change.js +149 -0
  523. package/src/lib/design/system/visible-change.js.map +1 -0
  524. package/src/lib/design/thumb.d.ts +19 -2
  525. package/src/lib/design/thumb.js +50 -15
  526. package/src/lib/design/thumb.js.map +1 -1
  527. package/src/lib/design/typecheck.d.ts +1 -1
  528. package/src/lib/design/typecheck.js +3 -3
  529. package/src/lib/design/typecheck.js.map +1 -1
  530. package/src/lib/design/unstable-cells.d.ts +23 -0
  531. package/src/lib/design/unstable-cells.js +40 -0
  532. package/src/lib/design/unstable-cells.js.map +1 -0
  533. package/src/lib/design/variant-diff.js +1 -1
  534. package/src/lib/design/variant-diff.js.map +1 -1
  535. package/src/lib/design/wait.d.ts +15 -0
  536. package/src/lib/design/wait.js +30 -0
  537. package/src/lib/design/wait.js.map +1 -0
  538. package/src/lib/json-file.d.ts +11 -0
  539. package/src/lib/json-file.js +21 -0
  540. package/src/lib/json-file.js.map +1 -0
  541. package/src/lib/source-hash.d.ts +7 -0
  542. package/src/lib/source-hash.js +62 -0
  543. package/src/lib/source-hash.js.map +1 -0
  544. package/src/lib/update/agent-setup.js +2 -1
  545. package/src/lib/update/agent-setup.js.map +1 -1
  546. package/src/lib/update/migration-manifest.d.ts +12 -0
  547. package/src/lib/update/migration-manifest.js +13 -0
  548. package/src/lib/update/migration-manifest.js.map +1 -1
  549. package/src/lib/update/migration-record.js +2 -1
  550. package/src/lib/update/migration-record.js.map +1 -1
  551. package/src/lib/update/pending.js +2 -1
  552. package/src/lib/update/pending.js.map +1 -1
  553. package/src/lib/update/run-migrations.d.ts +3 -2
  554. package/src/lib/update/run-migrations.js +38 -5
  555. package/src/lib/update/run-migrations.js.map +1 -1
  556. package/src/lib/update/tasks.js +2 -1
  557. package/src/lib/update/tasks.js.map +1 -1
@@ -1,4 +1,4 @@
1
- import { Drawing } from './define-call';
1
+ import { Drawing, withNgStyles } from './define-call';
2
2
  import { forceBody } from './mark-part';
3
3
 
4
4
  export { contrastRatioOf } from './contrast';
@@ -18,6 +18,8 @@ export { svgAsset } from './svg-asset';
18
18
  export type { SvgAssetOptions } from './svg-asset';
19
19
  export { tokenSheet } from './token-sheet';
20
20
  export type { TokenSheetOptions } from './token-sheet';
21
+ export { withAction } from './with-action';
22
+ export type { ActionTarget } from './with-action';
21
23
 
22
24
  /** An interaction Studio can force on a part's root element. Rest is always drawn and never listed. */
23
25
  export type Interaction = 'hover' | 'focus-visible' | 'active' | 'disabled';
@@ -26,6 +28,8 @@ export type Interaction = 'hover' | 'focus-visible' | 'active' | 'disabled';
26
28
  * One part of a product's design system. `note` records why the part has its current shape, and
27
29
  * `madeBy` the model ids that drew it, written by a sketch merge.
28
30
  * `states` names each state it is drawn in with the props for that state, and `render` draws it.
31
+ * `frame` wraps the body of each of the part's own states in a demo frame (padding, a page background); a part that
32
+ * calls `render` of this one gets the part without it.
29
33
  * `styles` is the part's stylesheet: every drawing of the part gets it before the styles `render` returns, and a
30
34
  * host that embeds a piece of the part's markup takes it from the default export.
31
35
  * A part that responds to its width lists the container `widths` it is drawn at; without them a
@@ -36,18 +40,21 @@ export type Interaction = 'hover' | 'focus-visible' | 'active' | 'disabled';
36
40
  * complete` requires the states and surfaces its `kind` and `input` need, see `Control`.
37
41
  * `motions` names each motion between two of its states, see `Motion`; a rule in `rules` can name one.
38
42
  * `unreachable` lists the state pairs no user can move between, each with its `reason`; they need no motion.
43
+ * `instant` is the reason every switch between two states happens at once; no pair then needs a motion.
39
44
  * `omits` records mock option values deliberately left off the grid, each with a reason.
40
45
  * `checks.skip` names the render checks of `design check` the part breaks on purpose, such as
41
46
  * `CLIPPED` for a part that cuts its content. To skip a check for one element only, put
42
47
  * `data-et-skip="CLIPPED"` on it; the check then ignores that element and everything inside it.
43
48
  * `contrast` feeds the contrast check of `design check`, see `PartContrast`.
44
49
  * `implements` links the part to the code that builds it, see `PartLink`.
50
+ * `sample` makes an embedded instance of the part comparable across the states of its host, see `PartSample`.
45
51
  */
46
52
  export type Part<TProps, TState extends string = string> = {
47
53
  note: string;
48
54
  madeBy?: string[];
49
55
  states: Record<TState, TProps>;
50
56
  styles?: string;
57
+ frame?: (body: string, props: TProps) => string;
51
58
  widths?: number[];
52
59
  interactions?: Interaction[];
53
60
  grid?: StateGrid<TState>;
@@ -56,17 +63,28 @@ export type Part<TProps, TState extends string = string> = {
56
63
  contrast?: PartContrast;
57
64
  motions?: Record<string, Motion<TState>>;
58
65
  unreachable?: { from: TState; to: TState; reason: string }[];
66
+ instant?: string;
59
67
  omits?: { option: keyof TProps & string; value: string; reason: string }[];
60
68
  rules?: PartRule<TState>[];
61
69
  implements?: PartLink;
70
+ sample?: PartSample<TProps>;
62
71
  render: (props: TProps, options?: RenderOptions) => DrawnPart | Promise<DrawnPart>;
63
72
  };
64
73
 
65
74
  /**
66
75
  * The code a part is built in: a component or element names the repo-relative path of its `.component.ts`, a page
67
- * names its route. `design check` fails on a path that does not exist, and lists a part without a link as open.
76
+ * names its route and, for `design compare`, the presentational `component` it renders. `design check` fails on a
77
+ * path that does not exist, and lists a part without a link as open.
68
78
  */
69
- export type PartLink = `${string}.component.ts` | { route: `/${string}` };
79
+ /**
80
+ * The prop `id` a host passes to name an embedded instance, and the props `marks` that carry its sample marks. Every
81
+ * state of one host that draws the same `id` must pass the same `marks`: `design sketch check` warns and
82
+ * `design sketch ready` refuses with `SAMPLE-MARK-DRIFT` otherwise. A host state that shows another sample passes
83
+ * another `id`.
84
+ */
85
+ export type PartSample<TProps> = { id: keyof TProps & string; marks: readonly (keyof TProps & string)[] };
86
+
87
+ export type PartLink = `${string}.component.ts` | { route: `/${string}`; component?: `${string}.component.ts` };
70
88
 
71
89
  /** What `play` of a motion may use, so Studio controls time: `at` schedules `fn` at `ms` into the motion on the tool's clock, `random` is seeded, `rect` measures a selector in the `from` state. */
72
90
  export type MotionContext = {
@@ -152,8 +170,10 @@ export type RenderOptions = { interaction?: Interaction };
152
170
 
153
171
  type PartSource<TProps, TState extends string, TColumn extends string> = Omit<
154
172
  Part<TProps, TState>,
155
- 'states' | 'grid' | 'controls' | 'motions' | 'rules' | 'render'
173
+ 'states' | 'grid' | 'controls' | 'motions' | 'rules' | 'render' | 'frame' | 'sample'
156
174
  > & {
175
+ sample?: PartSample<NoInfer<TProps>>;
176
+ frame?: (body: string, props: NoInfer<TProps>) => string;
157
177
  motions?: Record<string, Motion<NoInfer<TState>>>;
158
178
  rules?: PartRule<NoInfer<TState>>[];
159
179
  states: Record<TState, NoInfer<TProps>>;
@@ -168,6 +188,13 @@ type PartSource<TProps, TState extends string, TColumn extends string> = Omit<
168
188
  */
169
189
  export const forceInteraction = (markup: string, interaction: Interaction) => forceBody(markup, interaction);
170
190
 
191
+ /**
192
+ * The attribute that marks an element as the region `name` whose content the implementing component projects with
193
+ * `<ng-content>`, e.g. `<main ${slot('canvas')}>`. `design compare` empties it in the design picture, as the harness
194
+ * projects nothing.
195
+ */
196
+ export const slot = (name: string) => `data-et-projected="${name}"`;
197
+
171
198
  const finished = (
172
199
  drawn: Drawing,
173
200
  { styles, interaction }: { styles?: string; interaction?: Interaction },
@@ -177,6 +204,12 @@ const finished = (
177
204
  styles: [styles, drawn.styles].filter(Boolean).join('\n'),
178
205
  });
179
206
 
207
+ /** Draws `props` as one of the part's own states: the drawing of `render` inside the part's `frame`. */
208
+ export const drawState = <TProps>(part: Part<TProps>, props: TProps): Promise<DrawnPart> =>
209
+ Promise.resolve(part.render(props)).then((drawn) =>
210
+ withNgStyles(part.frame ? { ...drawn, body: part.frame(drawn.body, props) } : drawn),
211
+ );
212
+
180
213
  /**
181
214
  * Types a part where it is written. A part file default-exports the result, and may export named
182
215
  * helpers next to it that other parts import from `@system/<layer>/<name>`. Without type
@@ -31,7 +31,7 @@ const SHEET_STYLES = `
31
31
  .ics-cell { display: flex; }
32
32
  .ics-construction { display: grid; gap: var(--space-5, 2rem); }
33
33
  .ics-item { display: flex; flex-direction: column; align-items: center; gap: var(--space-2, 0.8rem); }
34
- .ics-frame { position: relative; display: flex; border: 1px solid var(--surface-border, oklch(0.34 0 0)); background: var(--surface, oklch(0.17 0 0)); }
34
+ .ics-frame { position: relative; display: flex; border: 1px solid var(--surface-border, oklch(0.34 0 0)); }
35
35
  .ics-icon { position: relative; }
36
36
  .ics-guides { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--accent, oklch(0.7 0.15 250)); pointer-events: none; }
37
37
  .ics-guides path, .ics-guides rect { vector-effect: non-scaling-stroke; stroke-width: 1px; }
@@ -5,28 +5,35 @@ export type InteractionRowsOptions<TProps, TInteraction extends string> = {
5
5
 
6
6
  type RowState<TRow extends string, TInteraction extends string> = TRow | `${TRow}-${TInteraction}`;
7
7
 
8
+ const isDisabledRow = (props: unknown) =>
9
+ typeof props === 'object' && props !== null && (props as { disabled?: unknown }).disabled === true;
10
+
8
11
  /**
9
12
  * Builds the `states` and `grid` of a part from one props object per row: each row is drawn at rest as `<row>` and
10
- * in each of `interactions` as `<row>-<interaction>`, with the props `force` returns. Spread the result into
11
- * `definePart`; the built state names stay in its type.
13
+ * in each of `interactions` as `<row>-<interaction>`, with the props `force` returns. A row whose props carry
14
+ * `disabled: true` is drawn only at rest. Spread the result into `definePart`; the built state names stay in its type.
12
15
  */
13
16
  export const interactionRows = <TProps, const TRow extends string, const TInteraction extends string>(
14
17
  rows: Record<TRow, TProps>,
15
18
  { interactions, force }: InteractionRowsOptions<TProps, TInteraction>,
16
19
  ) => {
17
20
  const entries = Object.entries(rows) as [TRow, TProps][];
21
+ const interactionsOf = (props: TProps) => (isDisabledRow(props) ? [] : interactions);
18
22
  const states = Object.fromEntries(
19
23
  entries.flatMap(([row, props]) => [
20
24
  [row, props],
21
- ...interactions.map((interaction) => [`${row}-${interaction}`, force(props, interaction)]),
25
+ ...interactionsOf(props).map((interaction) => [`${row}-${interaction}`, force(props, interaction)]),
22
26
  ]),
23
27
  ) as Record<RowState<TRow, TInteraction>, TProps>;
24
28
  const gridRows = Object.fromEntries(
25
- entries.map(([row]) => [
29
+ entries.map(([row, props]) => [
26
30
  row,
27
- Object.fromEntries([['rest', row], ...interactions.map((interaction) => [interaction, `${row}-${interaction}`])]),
31
+ Object.fromEntries([
32
+ ['rest', row],
33
+ ...interactionsOf(props).map((interaction) => [interaction, `${row}-${interaction}`]),
34
+ ]),
28
35
  ]),
29
- ) as Record<TRow, Record<'rest' | TInteraction, RowState<TRow, TInteraction>>>;
36
+ ) as Record<TRow, { rest: TRow } & Partial<Record<TInteraction, RowState<TRow, TInteraction>>>>;
30
37
 
31
38
  return { states, grid: { columns: ['rest', ...interactions] as const, rows: gridRows } };
32
39
  };
@@ -37,11 +37,19 @@ export const markBody = (body: string, key: string) => {
37
37
  return `${body.slice(0, valueEnd)} ${key}${body.slice(valueEnd)}`;
38
38
  };
39
39
 
40
- /** Forces `interaction` on the first element of `body` the way a frame forces it on the root of a part. */
40
+ const DISABLED_ATTRIBUTE = /\s(?:disabled(?=[\s=/>]|$)|aria-disabled\s*=\s*["']?true\b)/i;
41
+
42
+ const isDisabledMarkup = (attributes: string) => DISABLED_ATTRIBUTE.test(attributes);
43
+
44
+ /**
45
+ * Forces `interaction` on the first element of `body` the way a frame forces it on the root of a part. A disabled
46
+ * element stays at rest: it gets no forced hover, active or focus-visible.
47
+ */
41
48
  export const forceBody = (body: string, interaction: Interaction) => {
42
49
  const attributesAt = attributesAtOf(body);
43
50
 
44
51
  if (attributesAt === null) return body;
52
+ if (interaction !== 'disabled' && isDisabledMarkup(ATTRIBUTES.exec(body.slice(attributesAt))?.[0] ?? '')) return body;
45
53
 
46
54
  const forced = interaction === 'disabled' ? ' disabled aria-disabled="true"' : ` data-et-force="${interaction}"`;
47
55
 
@@ -117,6 +125,23 @@ const slotProps = (value: unknown, { key, depth = 0 }: { key: string; depth?: nu
117
125
  return value;
118
126
  };
119
127
 
128
+ const SAMPLES = Symbol.for('@ethlete/cli/design/samples');
129
+
130
+ /** Reports `props` to the sample recorder a check installs, when the part declares a `sample` and the props carry its `id`. */
131
+ const recordSample = ({ key, part }: { key: string; part: unknown }, props: unknown) => {
132
+ const record = (globalThis as Record<symbol, unknown>)[SAMPLES];
133
+ const sample = isPlainObject(part) ? part['sample'] : undefined;
134
+
135
+ if (typeof record !== 'function' || !isPlainObject(sample) || !isPlainObject(props)) return;
136
+
137
+ const id = props[String(sample['id'])];
138
+ const marks = Array.isArray(sample['marks']) ? (sample['marks'] as unknown[]).map(String) : [];
139
+
140
+ if (typeof id !== 'string' || id === '') return;
141
+
142
+ record({ part: key, id, marks: Object.fromEntries(marks.map((mark) => [mark, props[mark] ?? null])) });
143
+ };
144
+
120
145
  const markDrawing = <TDrawing extends Drawing>(drawn: TDrawing, key: string): TDrawing =>
121
146
  typeof drawn?.body === 'string' ? { ...drawn, body: markBody(drawn.body, key) } : drawn;
122
147
 
@@ -135,9 +160,34 @@ export const markPart = <TProps, TState extends string>(
135
160
  return {
136
161
  ...part,
137
162
  render: (props: TProps, options?: RenderOptions) => {
163
+ recordSample({ key, part }, props);
164
+
138
165
  const drawn = render.call(part, slotProps(props, { key }) as TProps, options);
139
166
 
140
167
  return drawn instanceof Promise ? drawn.then((done) => markDrawing(done, key)) : markDrawing(drawn, key);
141
168
  },
142
169
  };
143
170
  };
171
+
172
+ const markOutput = (output: unknown, key: string) =>
173
+ typeof output === 'string' ? markBody(output, key) : markDrawing(output as Drawing, key);
174
+
175
+ /**
176
+ * `value` as a named export of the part `key`: a function whose markup, or drawing body, comes back with its first
177
+ * element marked as the root of `key`, and the markup of its arguments as slotted into `key`. Any other value, a
178
+ * class included, stays as it is. A call whose first argument carries the `sample` id of `part` is reported as a sample.
179
+ */
180
+ export const markNamed = <T>(value: T, { key, part }: { key: string; part?: unknown }): T => {
181
+ if (typeof value !== 'function' || /^class\b/u.test(Function.prototype.toString.call(value))) return value;
182
+
183
+ return function (this: unknown, ...args: unknown[]) {
184
+ recordSample({ key, part }, args[0]);
185
+
186
+ const output = value.apply(
187
+ this,
188
+ args.map((arg) => slotProps(arg, { key })),
189
+ );
190
+
191
+ return output instanceof Promise ? output.then((done) => markOutput(done, key)) : markOutput(output, key);
192
+ } as T;
193
+ };
@@ -18,7 +18,7 @@ const SHEET_STYLES = `
18
18
  .ts-root { position: relative; display: flex; flex-direction: column; gap: var(--space-4, 1.6rem); width: 960px; padding: var(--space-6, 2.4rem); box-sizing: border-box; background: var(--surface, oklch(0.17 0 0)); color: var(--text, oklch(0.94 0 0)); font-family: var(--font-ui, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif); font-size: var(--text-md, 1.3rem); line-height: var(--text-md-line, 1.8rem); }
19
19
  .ts-title { margin: 0; font-size: var(--text-xl, 1.7rem); line-height: var(--text-xl-line, 2.2rem); font-weight: var(--weight-strong, 600); }
20
20
  .ts-note { margin: 0; max-width: 64rem; color: var(--text-muted, oklch(0.72 0 0)); }
21
- .ts-panel { margin: 0; padding: var(--space-4, 1.6rem); background: var(--surface, oklch(0.17 0 0)); border: 1px solid var(--surface-border, oklch(0.34 0 0)); border-radius: var(--radius-control-lg, 1rem); }
21
+ .ts-panel { margin: 0; padding: var(--space-4, 1.6rem); border: 1px solid var(--surface-border, oklch(0.34 0 0)); border-radius: var(--radius-control-lg, 1rem); }
22
22
  .ts-list { list-style: none; display: flex; flex-direction: column; gap: var(--space-1, 0.4rem); }
23
23
  .ts-row { display: grid; grid-template-columns: 200px 240px 1fr; align-items: center; gap: var(--space-3, 1.2rem); min-height: var(--row, 2.4rem); }
24
24
  .ts-name { font-family: var(--font-code, ui-monospace, "SF Mono", Menlo, Consolas, monospace); font-size: var(--text-sm, 1.15rem); line-height: var(--text-sm-line, 1.6rem); color: var(--text-muted, oklch(0.72 0 0)); }
@@ -0,0 +1,7 @@
1
+ /** Sizes the frame root to its content; `padded` keeps a 16 px margin around it, which a bare compare shot leaves out. */
2
+ export const fitRoot = (root: HTMLElement, options: { padded: boolean }) => {
3
+ root.ownerDocument.documentElement.style.overflow = 'hidden';
4
+ root.style.width = 'max-content';
5
+
6
+ if (options.padded) root.style.padding = '16px';
7
+ };
@@ -0,0 +1,294 @@
1
+ export type FrameSurfaceTheme = {
2
+ name: string;
3
+ type: string;
4
+ elevation: number;
5
+ isDefault: boolean;
6
+ colorThemeVariants: Partial<Record<string, string>>;
7
+ };
8
+ export type FrameColorTheme = { name: string; type: string | null; isDefault: boolean };
9
+ export type FrameThemes = { surfaces: FrameSurfaceTheme[]; colors: FrameColorTheme[] };
10
+
11
+ export const AUTO_SURFACE_ATTRIBUTE = 'data-et-auto-surface';
12
+ export const SURFACE_INTERACTIVE_ATTRIBUTE = 'data-et-surface-interactive';
13
+ export const SEMANTIC_COLOR_ATTRIBUTE = 'data-et-semantic-color';
14
+
15
+ const SURFACE_CLASS_PREFIX = 'et-surface--';
16
+ const COLOR_CLASS_PREFIX = 'et-color--';
17
+ const SURFACE_INTERACTIVE_CLASS = 'et-surface-interactive';
18
+ const SURFACE_CLASS_SELECTOR = /^\.et-surface--([\w-]+)$/u;
19
+ const COLOR_CLASS_SELECTOR = /^\.et-color--([\w-]+)$/u;
20
+ const RESERVED_COLORS = new Set(['default', 'surface']);
21
+
22
+ const surfaceVarsOf = (style: CSSStyleDeclaration) => {
23
+ const type = style.getPropertyValue('--et-surface-type').trim();
24
+ const elevation = Number.parseInt(style.getPropertyValue('--et-surface-elevation'), 10);
25
+
26
+ return type && Number.isFinite(elevation) ? { type, elevation } : null;
27
+ };
28
+
29
+ const colorThemeVariantsOf = (style: CSSStyleDeclaration) =>
30
+ Object.fromEntries(
31
+ style
32
+ .getPropertyValue('--et-surface-color-theme-variants')
33
+ .split(',')
34
+ .map((entry) => entry.trim().split(/\s+/u))
35
+ .filter((pair): pair is [string, string] => pair.length === 2),
36
+ );
37
+
38
+ const scopeNamesOf = (rule: CSSStyleRule, selector: RegExp) =>
39
+ rule.selectorText
40
+ .split(',')
41
+ .map((part) => selector.exec(part.trim())?.[1])
42
+ .filter((name): name is string => name !== undefined);
43
+
44
+ const themesOfRules = (rules: CSSRuleList, themes: FrameThemes) => {
45
+ for (const rule of Array.from(rules)) {
46
+ if (rule instanceof CSSStyleRule) {
47
+ const surface = surfaceVarsOf(rule.style);
48
+
49
+ if (surface) {
50
+ const names = scopeNamesOf(rule, SURFACE_CLASS_SELECTOR);
51
+ const isDefault = names.includes(`default-${surface.type}`);
52
+ const registered = names.length > 1 ? names.filter((name) => name !== `default-${surface.type}`) : names;
53
+ const colorThemeVariants = colorThemeVariantsOf(rule.style);
54
+
55
+ registered.forEach((name) => themes.surfaces.push({ name, ...surface, isDefault, colorThemeVariants }));
56
+ }
57
+
58
+ if (rule.style.getPropertyValue('--et-color-primary')) {
59
+ const names = scopeNamesOf(rule, COLOR_CLASS_SELECTOR);
60
+ const type = rule.style.getPropertyValue('--et-color-theme-type').trim() || null;
61
+ const isDefault = names.includes('default');
62
+
63
+ names
64
+ .filter((name) => !RESERVED_COLORS.has(name))
65
+ .forEach((name) => themes.colors.push({ name, type, isDefault }));
66
+ }
67
+ }
68
+
69
+ if ('cssRules' in rule) themesOfRules((rule as CSSGroupingRule).cssRules, themes);
70
+ }
71
+
72
+ return themes;
73
+ };
74
+
75
+ const sheetThemes = new WeakMap<CSSStyleSheet, FrameThemes>();
76
+
77
+ /**
78
+ * The surface and colour themes the frame's stylesheets register, as the SDK's generated theme CSS writes them: every
79
+ * `.et-surface--<name>` rule that sets `--et-surface-type` and `--et-surface-elevation` (with its
80
+ * `--et-surface-color-theme-variants`), and every `.et-color--<name>` rule that sets `--et-color-primary` (with its
81
+ * `--et-color-theme-type`).
82
+ */
83
+ export const registeredThemesOf = (document: Document): FrameThemes => {
84
+ const all: FrameThemes = { surfaces: [], colors: [] };
85
+
86
+ for (const sheet of Array.from(document.styleSheets)) {
87
+ let themes = sheetThemes.get(sheet);
88
+
89
+ if (!themes) {
90
+ try {
91
+ themes = themesOfRules(sheet.cssRules, { surfaces: [], colors: [] });
92
+ } catch {
93
+ // A cross-origin sheet hides its rules.
94
+ continue;
95
+ }
96
+
97
+ sheetThemes.set(sheet, themes);
98
+ }
99
+
100
+ all.surfaces.push(...themes.surfaces);
101
+ all.colors.push(...themes.colors);
102
+ }
103
+
104
+ return all;
105
+ };
106
+
107
+ const surfaceThemeOf = (element: Element, themes: FrameSurfaceTheme[]): FrameSurfaceTheme | null => {
108
+ for (let current: Element | null = element; current; current = current.parentElement) {
109
+ for (const className of Array.from(current.classList)) {
110
+ if (!className.startsWith(SURFACE_CLASS_PREFIX)) continue;
111
+
112
+ const name = className.slice(SURFACE_CLASS_PREFIX.length);
113
+ const theme = themes.find((candidate) =>
114
+ name.startsWith('default-')
115
+ ? candidate.isDefault && `default-${candidate.type}` === name
116
+ : candidate.name === name,
117
+ );
118
+
119
+ if (theme) return theme;
120
+ }
121
+ }
122
+
123
+ const vars = surfaceVarsOf(getComputedStyle(element));
124
+ const matches = vars ? themes.filter((theme) => theme.type === vars.type && theme.elevation === vars.elevation) : [];
125
+
126
+ return matches.find((theme) => theme.isDefault) ?? matches[0] ?? null;
127
+ };
128
+
129
+ const colorVariantOf = (
130
+ surface: FrameSurfaceTheme | null,
131
+ { chosen, colors }: { chosen: string; colors: FrameColorTheme[] },
132
+ ) => {
133
+ const variant = surface?.colorThemeVariants[chosen];
134
+
135
+ return variant && colors.some((theme) => theme.name === variant) ? variant : chosen;
136
+ };
137
+
138
+ const appliedSurface = new WeakMap<Element, string>();
139
+ const appliedColor = new WeakMap<Element, { chosen: string; variant: string }>();
140
+
141
+ const defaultColorOf = (colors: FrameColorTheme[]) => colors.find((theme) => theme.isDefault)?.name ?? null;
142
+
143
+ const chosenColorOf = (element: Element | null, colors: FrameColorTheme[]) => {
144
+ for (let current = element; current; current = current.parentElement) {
145
+ const applied = appliedColor.get(current);
146
+
147
+ if (applied) return applied.chosen;
148
+
149
+ for (const className of Array.from(current.classList)) {
150
+ if (!className.startsWith(COLOR_CLASS_PREFIX)) continue;
151
+
152
+ const name = className.slice(COLOR_CLASS_PREFIX.length);
153
+
154
+ if (name === 'default') return defaultColorOf(colors);
155
+ if (colors.some((theme) => theme.name === name)) return name;
156
+ }
157
+ }
158
+
159
+ return defaultColorOf(colors);
160
+ };
161
+
162
+ const applyColor = (element: Element, color: { chosen: string; variant: string } | null) => {
163
+ const previous = appliedColor.get(element);
164
+
165
+ if (previous && previous.variant !== color?.variant)
166
+ element.classList.remove(`${COLOR_CLASS_PREFIX}${previous.variant}`);
167
+
168
+ if (!color) {
169
+ appliedColor.delete(element);
170
+
171
+ return;
172
+ }
173
+
174
+ appliedColor.set(element, color);
175
+ if (!element.classList.contains(`${COLOR_CLASS_PREFIX}${color.variant}`))
176
+ element.classList.add(`${COLOR_CLASS_PREFIX}${color.variant}`);
177
+ };
178
+
179
+ const resolveAutoSurface = (element: Element, themes: FrameSurfaceTheme[]) => {
180
+ const parent = element.parentElement ? surfaceVarsOf(getComputedStyle(element.parentElement)) : null;
181
+ const name = parent
182
+ ? (themes.find((theme) => theme.type === parent.type && theme.elevation === parent.elevation + 1)?.name ?? null)
183
+ : null;
184
+ const previous = appliedSurface.get(element);
185
+
186
+ if (previous !== undefined && previous !== name) element.classList.remove(`${SURFACE_CLASS_PREFIX}${previous}`);
187
+
188
+ if (name === null) {
189
+ appliedSurface.delete(element);
190
+
191
+ return;
192
+ }
193
+
194
+ appliedSurface.set(element, name);
195
+ if (!element.classList.contains(`${SURFACE_CLASS_PREFIX}${name}`))
196
+ element.classList.add(`${SURFACE_CLASS_PREFIX}${name}`);
197
+ };
198
+
199
+ const resolveColor = (element: Element, themes: FrameThemes) => {
200
+ const type = element.getAttribute(SEMANTIC_COLOR_ATTRIBUTE);
201
+
202
+ if (type) {
203
+ const chosen = themes.colors.find((theme) => theme.type === type)?.name;
204
+
205
+ applyColor(
206
+ element,
207
+ chosen
208
+ ? {
209
+ chosen,
210
+ variant: colorVariantOf(surfaceThemeOf(element, themes.surfaces), { chosen, colors: themes.colors }),
211
+ }
212
+ : null,
213
+ );
214
+
215
+ return;
216
+ }
217
+
218
+ const chosen = element.hasAttribute(AUTO_SURFACE_ATTRIBUTE)
219
+ ? chosenColorOf(element.parentElement, themes.colors)
220
+ : null;
221
+
222
+ if (!chosen || !element.parentElement) {
223
+ applyColor(element, null);
224
+
225
+ return;
226
+ }
227
+
228
+ const variant = colorVariantOf(surfaceThemeOf(element, themes.surfaces), { chosen, colors: themes.colors });
229
+ const inherited = colorVariantOf(surfaceThemeOf(element.parentElement, themes.surfaces), {
230
+ chosen,
231
+ colors: themes.colors,
232
+ });
233
+
234
+ applyColor(element, variant === inherited ? null : { chosen, variant });
235
+ };
236
+
237
+ /**
238
+ * Resolves the theming attributes under `root` in document order, outer first: `[data-et-auto-surface]` gets the
239
+ * `et-surface--<name>` class of the theme one elevation above the surface it sits on, with the same type, like
240
+ * `etAutoSurface` (without such a theme it keeps the parent surface), plus the class of that surface's
241
+ * `colorThemeVariants` swap of the inherited accent, like `etProvideSurface`. `[data-et-semantic-color="<type>"]`
242
+ * gets the `et-color--<name>` class of the first colour theme of that type, swapped for its surface, like
243
+ * `injectSemanticColorTheme`; without a theme of that type it gets none.
244
+ */
245
+ export const resolveTheming = (root: ParentNode, themes: FrameThemes) => {
246
+ for (const element of Array.from(
247
+ root.querySelectorAll(`[${AUTO_SURFACE_ATTRIBUTE}], [${SEMANTIC_COLOR_ATTRIBUTE}]`),
248
+ )) {
249
+ if (element.hasAttribute(AUTO_SURFACE_ATTRIBUTE)) resolveAutoSurface(element, themes.surfaces);
250
+
251
+ resolveColor(element, themes);
252
+ }
253
+ };
254
+
255
+ /**
256
+ * Resolves the theming attributes under `root` now and again after every change of its markup or of the page's
257
+ * stylesheets: auto surfaces and semantic colours as `resolveTheming`, and `[data-et-surface-interactive]` as `etSurfaceInteractive`, whose CSS
258
+ * (`interactiveCss`) goes into the page once. Returns the resolve function.
259
+ */
260
+ export const watchSurfaces = (root: HTMLElement, interactiveCss: string) => {
261
+ const document = root.ownerDocument;
262
+ let styled = false;
263
+
264
+ const resolve = () => {
265
+ const interactive = Array.from(root.querySelectorAll(`[${SURFACE_INTERACTIVE_ATTRIBUTE}]`));
266
+
267
+ interactive.forEach((element) => {
268
+ if (!element.classList.contains(SURFACE_INTERACTIVE_CLASS)) element.classList.add(SURFACE_INTERACTIVE_CLASS);
269
+ });
270
+
271
+ if (interactive.length > 0 && !styled) {
272
+ const style = document.createElement('style');
273
+
274
+ styled = true;
275
+ style.textContent = interactiveCss;
276
+ document.head.append(style);
277
+ }
278
+
279
+ if (root.querySelector(`[${AUTO_SURFACE_ATTRIBUTE}], [${SEMANTIC_COLOR_ATTRIBUTE}]`))
280
+ resolveTheming(root, registeredThemesOf(document));
281
+ };
282
+
283
+ resolve();
284
+
285
+ new MutationObserver(resolve).observe(root, {
286
+ childList: true,
287
+ subtree: true,
288
+ attributes: true,
289
+ attributeFilter: ['class', AUTO_SURFACE_ATTRIBUTE, SURFACE_INTERACTIVE_ATTRIBUTE, SEMANTIC_COLOR_ATTRIBUTE],
290
+ });
291
+ new MutationObserver(resolve).observe(document.head, { childList: true, subtree: true, characterData: true });
292
+
293
+ return resolve;
294
+ };