@exponential_app/eui 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/catalog/a11y.json +10 -0
  2. package/catalog/core.catalog.json +284 -6
  3. package/catalog/core.schema.json +437 -4
  4. package/catalog/layout.json +3 -2
  5. package/catalog/limits.json +10 -1
  6. package/catalog/macros.json +1 -0
  7. package/catalog/recipes.json +3 -1
  8. package/catalog/strings.json +9 -2
  9. package/catalog/style.json +21 -0
  10. package/catalog/theme.schema.json +4435 -3676
  11. package/conformance/manifest.json +2 -2
  12. package/conformance/motion/build-corpus.ts +232 -0
  13. package/conformance/motion/corpus/SOURCES.md +117 -0
  14. package/conformance/motion/corpus/images/footage_0.json +1 -0
  15. package/conformance/motion/corpus/images/img_0.jpg +0 -0
  16. package/conformance/motion/corpus/images/img_1.jpg +0 -0
  17. package/conformance/motion/corpus/images/triangle.png +0 -0
  18. package/conformance/motion/corpus/skottie-3d-parenting-nocamera.json +367 -0
  19. package/conformance/motion/corpus/skottie-auto-orient-2.json +292 -0
  20. package/conformance/motion/corpus/skottie-auto-orient.json +717 -0
  21. package/conformance/motion/corpus/skottie-bezier-extranormal.json +199 -0
  22. package/conformance/motion/corpus/skottie-blendmode-hardmix.json +558 -0
  23. package/conformance/motion/corpus/skottie-chained-mattes.json +259 -0
  24. package/conformance/motion/corpus/skottie-dropshadow-ramp.json +852 -0
  25. package/conformance/motion/corpus/skottie-dropshadow-style.json +278 -0
  26. package/conformance/motion/corpus/skottie-effects-transform.json +385 -0
  27. package/conformance/motion/corpus/skottie-fill-effect.json +358 -0
  28. package/conformance/motion/corpus/skottie-fill-rule.json +457 -0
  29. package/conformance/motion/corpus/skottie-gaussian-blur.json +670 -0
  30. package/conformance/motion/corpus/skottie-gradient-opacity.json +451 -0
  31. package/conformance/motion/corpus/skottie-gradient-radial-highlight.json +581 -0
  32. package/conformance/motion/corpus/skottie-hidden-shapes-layers.json +381 -0
  33. package/conformance/motion/corpus/skottie-huesaturation-effect.json +1117 -0
  34. package/conformance/motion/corpus/skottie-invert-effect.json +665 -0
  35. package/conformance/motion/corpus/skottie-luma-matte.json +239 -0
  36. package/conformance/motion/corpus/skottie-mask-feather.json +892 -0
  37. package/conformance/motion/corpus/skottie-masking-opaque.json +2376 -0
  38. package/conformance/motion/corpus/skottie-masking-translucent.json +2376 -0
  39. package/conformance/motion/corpus/skottie-matte-blendmode.json +196 -0
  40. package/conformance/motion/corpus/skottie-matte-nonsequential.json +722 -0
  41. package/conformance/motion/corpus/skottie-matte-visible.json +666 -0
  42. package/conformance/motion/corpus/skottie-mergepaths-effect.json +722 -0
  43. package/conformance/motion/corpus/skottie-motion-blur-mask.json +120 -0
  44. package/conformance/motion/corpus/skottie-nested-animation.json +253 -0
  45. package/conformance/motion/corpus/skottie-offsetpaths-effect.json +525 -0
  46. package/conformance/motion/corpus/skottie-phonehub-connecting.json +947 -0
  47. package/conformance/motion/corpus/skottie-puckerbloat-effect.json +339 -0
  48. package/conformance/motion/corpus/skottie-repeater.json +234 -0
  49. package/conformance/motion/corpus/skottie-sample-1.json +168 -0
  50. package/conformance/motion/corpus/skottie-sample-search.json +329 -0
  51. package/conformance/motion/corpus/skottie-spatial-supernormal.json +898 -0
  52. package/conformance/motion/corpus/skottie-text-animator-1.json +1286 -0
  53. package/conformance/motion/corpus/skottie-text-fill-over-stroke.json +1014 -0
  54. package/conformance/motion/corpus/skottie-text-tracking.json +950 -0
  55. package/conformance/motion/corpus/skottie-text-valign.json +484 -0
  56. package/conformance/motion/corpus/skottie-time-reverse.json +297 -0
  57. package/conformance/motion/corpus/skottie-transform-skew.json +290 -0
  58. package/conformance/motion/corpus/skottie-trimpath-fill.json +933 -0
  59. package/conformance/motion/corpus/skottie-trimpath-modes.json +266 -0
  60. package/conformance/motion/corpus/skottie-tritone-effect.json +379 -0
  61. package/conformance/motion/corpus/spec-blend-mode.json +531 -0
  62. package/conformance/motion/corpus/spec-ellipse.json +142 -0
  63. package/conformance/motion/corpus/spec-fill.json +193 -0
  64. package/conformance/motion/corpus/spec-gradient-stroke.json +1263 -0
  65. package/conformance/motion/corpus/spec-gradient.json +1255 -0
  66. package/conformance/motion/corpus/spec-mask.json +773 -0
  67. package/conformance/motion/corpus/spec-masks.json +676 -0
  68. package/conformance/motion/corpus/spec-matte.json +390 -0
  69. package/conformance/motion/corpus/spec-metadata.json +1 -0
  70. package/conformance/motion/corpus/spec-path.json +177 -0
  71. package/conformance/motion/corpus/spec-pucker-bloat.json +179 -0
  72. package/conformance/motion/corpus/spec-rectangle.json +145 -0
  73. package/conformance/motion/corpus/spec-rounded-corners.json +187 -0
  74. package/conformance/motion/corpus/spec-slots.json +325 -0
  75. package/conformance/motion/corpus/spec-star.json +159 -0
  76. package/conformance/motion/corpus/spec-stroke.json +156 -0
  77. package/conformance/motion/corpus/spec-test-ellipse-xy-pos.json +141 -0
  78. package/conformance/motion/corpus/spec-test-gradient-fill.json +1 -0
  79. package/conformance/motion/corpus/spec-test-gradient-stroke.json +229 -0
  80. package/conformance/motion/corpus/spec-test-unknown-shape.json +63 -0
  81. package/conformance/motion/corpus/spec-time-remap.json +1090 -0
  82. package/conformance/motion/corpus/spec-time-stretch.json +594 -0
  83. package/conformance/motion/corpus/spec-transform.json +273 -0
  84. package/conformance/motion/corpus/spec-trim-path.json +209 -0
  85. package/conformance/motion/corpus/web-adrock.json +1 -0
  86. package/conformance/motion/corpus/web-bacon.json +1 -0
  87. package/conformance/motion/corpus/web-banner.json +1 -0
  88. package/conformance/motion/corpus/web-bodymovin.json +1 -0
  89. package/conformance/motion/corpus/web-dalek.json +1 -0
  90. package/conformance/motion/corpus/web-footage-data.json +1 -0
  91. package/conformance/motion/corpus/web-lights.json +1 -0
  92. package/conformance/motion/corpus/web-ripple.json +1 -0
  93. package/conformance/motion/corpus/web-starfish.json +1 -0
  94. package/conformance/motion/known-gaps.json +35 -0
  95. package/conformance/motion/parity/group-transforms-parenting@0.png +0 -0
  96. package/conformance/motion/parity/group-transforms-parenting@10.png +0 -0
  97. package/conformance/motion/parity/hidden-unknown-inactive@0.png +0 -0
  98. package/conformance/motion/parity/keyframes-transform@0.png +0 -0
  99. package/conformance/motion/parity/keyframes-transform@10.png +0 -0
  100. package/conformance/motion/parity/keyframes-transform@15.png +0 -0
  101. package/conformance/motion/parity/keyframes-transform@5.png +0 -0
  102. package/conformance/motion/parity/layer-opacity-blend@0.png +0 -0
  103. package/conformance/motion/parity/linear-gradient@0.png +0 -0
  104. package/conformance/motion/parity/masks-modes@0.png +0 -0
  105. package/conformance/motion/parity/matte-alpha@0.png +0 -0
  106. package/conformance/motion/parity/matte-luma@0.png +0 -0
  107. package/conformance/motion/parity/matte-parent-tp@0.png +0 -0
  108. package/conformance/motion/parity/path-evenodd@0.png +0 -0
  109. package/conformance/motion/parity/precomp-clip-offset@0.png +0 -0
  110. package/conformance/motion/parity/precomp-clip-offset@15.png +0 -0
  111. package/conformance/motion/parity/precomp-clip-offset@5.png +0 -0
  112. package/conformance/motion/parity/radial-gradient-highlight@0.png +0 -0
  113. package/conformance/motion/parity/rect-solid-fill@0.png +0 -0
  114. package/conformance/motion/parity/repeater@0.png +0 -0
  115. package/conformance/motion/parity/rounded-rect-ellipse@0.png +0 -0
  116. package/conformance/motion/parity/solid-and-image@0.png +0 -0
  117. package/conformance/motion/parity/split-position-skew@0.png +0 -0
  118. package/conformance/motion/parity/split-position-skew@10.png +0 -0
  119. package/conformance/motion/parity/star-polygon@0.png +0 -0
  120. package/conformance/motion/parity/stroke-caps-joins@0.png +0 -0
  121. package/conformance/motion/parity/stroke-dashes@0.png +0 -0
  122. package/conformance/motion/parity/stroke-dashes@10.png +0 -0
  123. package/conformance/motion/parity/time-remap@0.png +0 -0
  124. package/conformance/motion/parity/time-remap@10.png +0 -0
  125. package/conformance/motion/parity/time-remap@19.png +0 -0
  126. package/conformance/motion/parity/time-stretch@0.png +0 -0
  127. package/conformance/motion/parity/time-stretch@10.png +0 -0
  128. package/conformance/motion/parity/trim-individually@0.png +0 -0
  129. package/conformance/motion/parity/trim-path@0.png +0 -0
  130. package/conformance/motion/parity/trim-path@10.png +0 -0
  131. package/conformance/motion/refs/index.json +688 -0
  132. package/conformance/motion/refs/skottie-3d-parenting-nocamera@0.png +0 -0
  133. package/conformance/motion/refs/skottie-3d-parenting-nocamera@150.png +0 -0
  134. package/conformance/motion/refs/skottie-3d-parenting-nocamera@270.png +0 -0
  135. package/conformance/motion/refs/skottie-auto-orient-2@0.png +0 -0
  136. package/conformance/motion/refs/skottie-auto-orient-2@210.png +0 -0
  137. package/conformance/motion/refs/skottie-auto-orient-2@378.png +0 -0
  138. package/conformance/motion/refs/skottie-auto-orient@0.png +0 -0
  139. package/conformance/motion/refs/skottie-auto-orient@300.png +0 -0
  140. package/conformance/motion/refs/skottie-auto-orient@540.png +0 -0
  141. package/conformance/motion/refs/skottie-bezier-extranormal@0.png +0 -0
  142. package/conformance/motion/refs/skottie-bezier-extranormal@150.png +0 -0
  143. package/conformance/motion/refs/skottie-bezier-extranormal@270.png +0 -0
  144. package/conformance/motion/refs/skottie-blendmode-hardmix@0.png +0 -0
  145. package/conformance/motion/refs/skottie-blendmode-hardmix@150.png +0 -0
  146. package/conformance/motion/refs/skottie-blendmode-hardmix@270.png +0 -0
  147. package/conformance/motion/refs/skottie-chained-mattes@0.png +0 -0
  148. package/conformance/motion/refs/skottie-chained-mattes@300.png +0 -0
  149. package/conformance/motion/refs/skottie-chained-mattes@540.png +0 -0
  150. package/conformance/motion/refs/skottie-dropshadow-ramp@0.png +0 -0
  151. package/conformance/motion/refs/skottie-dropshadow-ramp@135.png +0 -0
  152. package/conformance/motion/refs/skottie-dropshadow-ramp@75.png +0 -0
  153. package/conformance/motion/refs/skottie-dropshadow-style@0.png +0 -0
  154. package/conformance/motion/refs/skottie-dropshadow-style@300.png +0 -0
  155. package/conformance/motion/refs/skottie-dropshadow-style@540.png +0 -0
  156. package/conformance/motion/refs/skottie-effects-transform@0.png +0 -0
  157. package/conformance/motion/refs/skottie-effects-transform@450.png +0 -0
  158. package/conformance/motion/refs/skottie-effects-transform@810.png +0 -0
  159. package/conformance/motion/refs/skottie-fill-effect@0.png +0 -0
  160. package/conformance/motion/refs/skottie-fill-effect@300.png +0 -0
  161. package/conformance/motion/refs/skottie-fill-effect@540.png +0 -0
  162. package/conformance/motion/refs/skottie-fill-rule@0.png +0 -0
  163. package/conformance/motion/refs/skottie-fill-rule@150.png +0 -0
  164. package/conformance/motion/refs/skottie-fill-rule@270.png +0 -0
  165. package/conformance/motion/refs/skottie-gaussian-blur@0.png +0 -0
  166. package/conformance/motion/refs/skottie-gaussian-blur@150.png +0 -0
  167. package/conformance/motion/refs/skottie-gaussian-blur@270.png +0 -0
  168. package/conformance/motion/refs/skottie-gradient-opacity@0.png +0 -0
  169. package/conformance/motion/refs/skottie-gradient-opacity@150.png +0 -0
  170. package/conformance/motion/refs/skottie-gradient-opacity@270.png +0 -0
  171. package/conformance/motion/refs/skottie-gradient-radial-highlight@0.png +0 -0
  172. package/conformance/motion/refs/skottie-gradient-radial-highlight@135.png +0 -0
  173. package/conformance/motion/refs/skottie-gradient-radial-highlight@75.png +0 -0
  174. package/conformance/motion/refs/skottie-hidden-shapes-layers@0.png +0 -0
  175. package/conformance/motion/refs/skottie-hidden-shapes-layers@150.png +0 -0
  176. package/conformance/motion/refs/skottie-hidden-shapes-layers@270.png +0 -0
  177. package/conformance/motion/refs/skottie-huesaturation-effect@0.png +0 -0
  178. package/conformance/motion/refs/skottie-huesaturation-effect@30.png +0 -0
  179. package/conformance/motion/refs/skottie-huesaturation-effect@54.png +0 -0
  180. package/conformance/motion/refs/skottie-invert-effect@0.png +0 -0
  181. package/conformance/motion/refs/skottie-invert-effect@300.png +0 -0
  182. package/conformance/motion/refs/skottie-invert-effect@540.png +0 -0
  183. package/conformance/motion/refs/skottie-luma-matte@0.png +0 -0
  184. package/conformance/motion/refs/skottie-luma-matte@150.png +0 -0
  185. package/conformance/motion/refs/skottie-luma-matte@270.png +0 -0
  186. package/conformance/motion/refs/skottie-mask-feather@0.png +0 -0
  187. package/conformance/motion/refs/skottie-mask-feather@150.png +0 -0
  188. package/conformance/motion/refs/skottie-mask-feather@270.png +0 -0
  189. package/conformance/motion/refs/skottie-masking-opaque@0.png +0 -0
  190. package/conformance/motion/refs/skottie-masking-opaque@135.png +0 -0
  191. package/conformance/motion/refs/skottie-masking-opaque@75.png +0 -0
  192. package/conformance/motion/refs/skottie-masking-translucent@0.png +0 -0
  193. package/conformance/motion/refs/skottie-masking-translucent@135.png +0 -0
  194. package/conformance/motion/refs/skottie-masking-translucent@75.png +0 -0
  195. package/conformance/motion/refs/skottie-matte-blendmode@0.png +0 -0
  196. package/conformance/motion/refs/skottie-matte-blendmode@150.png +0 -0
  197. package/conformance/motion/refs/skottie-matte-blendmode@270.png +0 -0
  198. package/conformance/motion/refs/skottie-matte-nonsequential@0.png +0 -0
  199. package/conformance/motion/refs/skottie-matte-nonsequential@150.png +0 -0
  200. package/conformance/motion/refs/skottie-matte-nonsequential@270.png +0 -0
  201. package/conformance/motion/refs/skottie-matte-visible@0.png +0 -0
  202. package/conformance/motion/refs/skottie-matte-visible@150.png +0 -0
  203. package/conformance/motion/refs/skottie-matte-visible@270.png +0 -0
  204. package/conformance/motion/refs/skottie-mergepaths-effect@0.png +0 -0
  205. package/conformance/motion/refs/skottie-mergepaths-effect@210.png +0 -0
  206. package/conformance/motion/refs/skottie-mergepaths-effect@378.png +0 -0
  207. package/conformance/motion/refs/skottie-motion-blur-mask@0.png +0 -0
  208. package/conformance/motion/refs/skottie-motion-blur-mask@150.png +0 -0
  209. package/conformance/motion/refs/skottie-motion-blur-mask@270.png +0 -0
  210. package/conformance/motion/refs/skottie-nested-animation@0.png +0 -0
  211. package/conformance/motion/refs/skottie-nested-animation@300.png +0 -0
  212. package/conformance/motion/refs/skottie-nested-animation@540.png +0 -0
  213. package/conformance/motion/refs/skottie-offsetpaths-effect@0.png +0 -0
  214. package/conformance/motion/refs/skottie-offsetpaths-effect@150.png +0 -0
  215. package/conformance/motion/refs/skottie-offsetpaths-effect@270.png +0 -0
  216. package/conformance/motion/refs/skottie-phonehub-connecting@0.png +0 -0
  217. package/conformance/motion/refs/skottie-puckerbloat-effect@0.png +0 -0
  218. package/conformance/motion/refs/skottie-puckerbloat-effect@210.png +0 -0
  219. package/conformance/motion/refs/skottie-puckerbloat-effect@378.png +0 -0
  220. package/conformance/motion/refs/skottie-repeater@0.png +0 -0
  221. package/conformance/motion/refs/skottie-repeater@300.png +0 -0
  222. package/conformance/motion/refs/skottie-repeater@540.png +0 -0
  223. package/conformance/motion/refs/skottie-sample-1@0.png +0 -0
  224. package/conformance/motion/refs/skottie-sample-1@100.png +0 -0
  225. package/conformance/motion/refs/skottie-sample-1@180.png +0 -0
  226. package/conformance/motion/refs/skottie-sample-search@0.png +0 -0
  227. package/conformance/motion/refs/skottie-sample-search@27.png +0 -0
  228. package/conformance/motion/refs/skottie-sample-search@48.png +0 -0
  229. package/conformance/motion/refs/skottie-spatial-supernormal@0.png +0 -0
  230. package/conformance/motion/refs/skottie-spatial-supernormal@200.png +0 -0
  231. package/conformance/motion/refs/skottie-spatial-supernormal@360.png +0 -0
  232. package/conformance/motion/refs/skottie-text-animator-1@0.png +0 -0
  233. package/conformance/motion/refs/skottie-text-animator-1@150.png +0 -0
  234. package/conformance/motion/refs/skottie-text-animator-1@270.png +0 -0
  235. package/conformance/motion/refs/skottie-text-fill-over-stroke@0.png +0 -0
  236. package/conformance/motion/refs/skottie-text-fill-over-stroke@210.png +0 -0
  237. package/conformance/motion/refs/skottie-text-fill-over-stroke@378.png +0 -0
  238. package/conformance/motion/refs/skottie-text-tracking@0.png +0 -0
  239. package/conformance/motion/refs/skottie-text-tracking@108.png +0 -0
  240. package/conformance/motion/refs/skottie-text-tracking@60.png +0 -0
  241. package/conformance/motion/refs/skottie-text-valign@0.png +0 -0
  242. package/conformance/motion/refs/skottie-text-valign@150.png +0 -0
  243. package/conformance/motion/refs/skottie-text-valign@270.png +0 -0
  244. package/conformance/motion/refs/skottie-time-reverse@0.png +0 -0
  245. package/conformance/motion/refs/skottie-time-reverse@300.png +0 -0
  246. package/conformance/motion/refs/skottie-time-reverse@540.png +0 -0
  247. package/conformance/motion/refs/skottie-transform-skew@0.png +0 -0
  248. package/conformance/motion/refs/skottie-transform-skew@300.png +0 -0
  249. package/conformance/motion/refs/skottie-transform-skew@540.png +0 -0
  250. package/conformance/motion/refs/skottie-trimpath-fill@0.png +0 -0
  251. package/conformance/motion/refs/skottie-trimpath-fill@300.png +0 -0
  252. package/conformance/motion/refs/skottie-trimpath-fill@540.png +0 -0
  253. package/conformance/motion/refs/skottie-trimpath-modes@0.png +0 -0
  254. package/conformance/motion/refs/skottie-trimpath-modes@300.png +0 -0
  255. package/conformance/motion/refs/skottie-trimpath-modes@540.png +0 -0
  256. package/conformance/motion/refs/skottie-tritone-effect@0.png +0 -0
  257. package/conformance/motion/refs/skottie-tritone-effect@300.png +0 -0
  258. package/conformance/motion/refs/skottie-tritone-effect@540.png +0 -0
  259. package/conformance/motion/refs/spec-blend-mode@0.png +0 -0
  260. package/conformance/motion/refs/spec-blend-mode@162.png +0 -0
  261. package/conformance/motion/refs/spec-blend-mode@90.png +0 -0
  262. package/conformance/motion/refs/spec-ellipse@0.png +0 -0
  263. package/conformance/motion/refs/spec-ellipse@162.png +0 -0
  264. package/conformance/motion/refs/spec-ellipse@90.png +0 -0
  265. package/conformance/motion/refs/spec-fill@0.png +0 -0
  266. package/conformance/motion/refs/spec-fill@162.png +0 -0
  267. package/conformance/motion/refs/spec-fill@90.png +0 -0
  268. package/conformance/motion/refs/spec-gradient-stroke@0.png +0 -0
  269. package/conformance/motion/refs/spec-gradient-stroke@162.png +0 -0
  270. package/conformance/motion/refs/spec-gradient-stroke@90.png +0 -0
  271. package/conformance/motion/refs/spec-gradient@0.png +0 -0
  272. package/conformance/motion/refs/spec-gradient@162.png +0 -0
  273. package/conformance/motion/refs/spec-gradient@90.png +0 -0
  274. package/conformance/motion/refs/spec-mask@0.png +0 -0
  275. package/conformance/motion/refs/spec-mask@300.png +0 -0
  276. package/conformance/motion/refs/spec-mask@540.png +0 -0
  277. package/conformance/motion/refs/spec-masks@0.png +0 -0
  278. package/conformance/motion/refs/spec-masks@135.png +0 -0
  279. package/conformance/motion/refs/spec-masks@75.png +0 -0
  280. package/conformance/motion/refs/spec-matte@0.png +0 -0
  281. package/conformance/motion/refs/spec-matte@162.png +0 -0
  282. package/conformance/motion/refs/spec-matte@90.png +0 -0
  283. package/conformance/motion/refs/spec-metadata@0.png +0 -0
  284. package/conformance/motion/refs/spec-metadata@162.png +0 -0
  285. package/conformance/motion/refs/spec-metadata@90.png +0 -0
  286. package/conformance/motion/refs/spec-path@0.png +0 -0
  287. package/conformance/motion/refs/spec-path@162.png +0 -0
  288. package/conformance/motion/refs/spec-path@90.png +0 -0
  289. package/conformance/motion/refs/spec-pucker-bloat@0.png +0 -0
  290. package/conformance/motion/refs/spec-pucker-bloat@162.png +0 -0
  291. package/conformance/motion/refs/spec-pucker-bloat@90.png +0 -0
  292. package/conformance/motion/refs/spec-rectangle@0.png +0 -0
  293. package/conformance/motion/refs/spec-rectangle@162.png +0 -0
  294. package/conformance/motion/refs/spec-rectangle@90.png +0 -0
  295. package/conformance/motion/refs/spec-rounded-corners@0.png +0 -0
  296. package/conformance/motion/refs/spec-rounded-corners@162.png +0 -0
  297. package/conformance/motion/refs/spec-rounded-corners@90.png +0 -0
  298. package/conformance/motion/refs/spec-slots@0.png +0 -0
  299. package/conformance/motion/refs/spec-slots@450.png +0 -0
  300. package/conformance/motion/refs/spec-slots@810.png +0 -0
  301. package/conformance/motion/refs/spec-star@0.png +0 -0
  302. package/conformance/motion/refs/spec-star@162.png +0 -0
  303. package/conformance/motion/refs/spec-star@90.png +0 -0
  304. package/conformance/motion/refs/spec-stroke@0.png +0 -0
  305. package/conformance/motion/refs/spec-stroke@162.png +0 -0
  306. package/conformance/motion/refs/spec-stroke@90.png +0 -0
  307. package/conformance/motion/refs/spec-test-ellipse-xy-pos@0.png +0 -0
  308. package/conformance/motion/refs/spec-test-ellipse-xy-pos@162.png +0 -0
  309. package/conformance/motion/refs/spec-test-ellipse-xy-pos@90.png +0 -0
  310. package/conformance/motion/refs/spec-test-gradient-fill@0.png +0 -0
  311. package/conformance/motion/refs/spec-test-gradient-fill@30.png +0 -0
  312. package/conformance/motion/refs/spec-test-gradient-fill@54.png +0 -0
  313. package/conformance/motion/refs/spec-test-gradient-stroke@0.png +0 -0
  314. package/conformance/motion/refs/spec-test-gradient-stroke@30.png +0 -0
  315. package/conformance/motion/refs/spec-test-gradient-stroke@54.png +0 -0
  316. package/conformance/motion/refs/spec-test-unknown-shape@0.png +0 -0
  317. package/conformance/motion/refs/spec-test-unknown-shape@162.png +0 -0
  318. package/conformance/motion/refs/spec-test-unknown-shape@90.png +0 -0
  319. package/conformance/motion/refs/spec-time-remap@0.png +0 -0
  320. package/conformance/motion/refs/spec-time-remap@300.png +0 -0
  321. package/conformance/motion/refs/spec-time-remap@540.png +0 -0
  322. package/conformance/motion/refs/spec-time-stretch@0.png +0 -0
  323. package/conformance/motion/refs/spec-time-stretch@300.png +0 -0
  324. package/conformance/motion/refs/spec-time-stretch@540.png +0 -0
  325. package/conformance/motion/refs/spec-transform@0.png +0 -0
  326. package/conformance/motion/refs/spec-transform@162.png +0 -0
  327. package/conformance/motion/refs/spec-transform@90.png +0 -0
  328. package/conformance/motion/refs/spec-trim-path@0.png +0 -0
  329. package/conformance/motion/refs/spec-trim-path@162.png +0 -0
  330. package/conformance/motion/refs/spec-trim-path@90.png +0 -0
  331. package/conformance/motion/refs/web-adrock@0.png +0 -0
  332. package/conformance/motion/refs/web-adrock@10.png +0 -0
  333. package/conformance/motion/refs/web-adrock@18.png +0 -0
  334. package/conformance/motion/refs/web-bacon@0.png +0 -0
  335. package/conformance/motion/refs/web-bacon@126.png +0 -0
  336. package/conformance/motion/refs/web-bacon@70.png +0 -0
  337. package/conformance/motion/refs/web-banner@0.png +0 -0
  338. package/conformance/motion/refs/web-banner@301.png +0 -0
  339. package/conformance/motion/refs/web-banner@542.png +0 -0
  340. package/conformance/motion/refs/web-bodymovin@0.png +0 -0
  341. package/conformance/motion/refs/web-bodymovin@51.png +0 -0
  342. package/conformance/motion/refs/web-bodymovin@92.png +0 -0
  343. package/conformance/motion/refs/web-dalek@0.png +0 -0
  344. package/conformance/motion/refs/web-dalek@145.png +0 -0
  345. package/conformance/motion/refs/web-dalek@261.png +0 -0
  346. package/conformance/motion/refs/web-footage-data@0.png +0 -0
  347. package/conformance/motion/refs/web-footage-data@180.png +0 -0
  348. package/conformance/motion/refs/web-footage-data@324.png +0 -0
  349. package/conformance/motion/refs/web-lights@0.png +0 -0
  350. package/conformance/motion/refs/web-lights@150.png +0 -0
  351. package/conformance/motion/refs/web-lights@270.png +0 -0
  352. package/conformance/motion/refs/web-ripple@0.png +0 -0
  353. package/conformance/motion/refs/web-ripple@180.png +0 -0
  354. package/conformance/motion/refs/web-ripple@324.png +0 -0
  355. package/conformance/motion/refs/web-starfish@0.png +0 -0
  356. package/conformance/motion/refs/web-starfish@150.png +0 -0
  357. package/conformance/motion/refs/web-starfish@270.png +0 -0
  358. package/conformance/motion/render-refs.ts +126 -0
  359. package/conformance/motion/report.json +1367 -0
  360. package/conformance/motion/web-parity-gaps.json +12 -0
  361. package/conformance/motion-parity-entry.ts +3 -0
  362. package/conformance/motion-parity.ts +101 -0
  363. package/dist/chunks/{index-4z7f2bp1.js → index-4xczxey5.js} +35 -15
  364. package/dist/chunks/{index-4z7f2bp1.js.map → index-4xczxey5.js.map} +4 -4
  365. package/dist/chunks/{index-dx45asrf.js → index-5sjj5p84.js} +174 -8
  366. package/dist/chunks/{index-dx45asrf.js.map → index-5sjj5p84.js.map} +2 -2
  367. package/dist/chunks/{index-fy7y2nz8.js → index-cvf7bbs5.js} +23 -2
  368. package/dist/chunks/{index-fy7y2nz8.js.map → index-cvf7bbs5.js.map} +1 -1
  369. package/dist/chunks/index-dgkf6yw5.js +48 -0
  370. package/dist/chunks/index-dgkf6yw5.js.map +10 -0
  371. package/dist/chunks/{index-abcjanhc.js → index-f9wkb6aq.js} +192 -3
  372. package/dist/chunks/{index-abcjanhc.js.map → index-f9wkb6aq.js.map} +2 -2
  373. package/dist/chunks/index-t2mwfbb6.js +1515 -0
  374. package/dist/chunks/index-t2mwfbb6.js.map +15 -0
  375. package/dist/chunks/{index-h3zgfghf.js → index-vkn82srs.js} +179 -8
  376. package/dist/chunks/{index-h3zgfghf.js.map → index-vkn82srs.js.map} +2 -2
  377. package/dist/chunks/wasm-ctcc3cma.js +424 -0
  378. package/dist/chunks/wasm-ctcc3cma.js.map +11 -0
  379. package/dist/conformance.js +3154 -63
  380. package/dist/conformance.js.map +2 -2
  381. package/dist/entries/prompt.js +2 -2
  382. package/dist/entries/schema.js +3 -3
  383. package/dist/host/index.js +3 -3
  384. package/dist/index.js +333 -98
  385. package/dist/index.js.map +4 -4
  386. package/dist/types/src/catalog.generated.d.ts +50 -4
  387. package/dist/types/src/index.d.ts +2 -0
  388. package/dist/types/src/layout.d.ts +2 -0
  389. package/dist/types/src/limits.d.ts +1 -0
  390. package/dist/types/src/motion/index.d.ts +1 -0
  391. package/dist/types/src/motion/server.d.ts +9 -0
  392. package/dist/types/src/motion/wasm.d.ts +11 -0
  393. package/dist/types/src/web/coerce.d.ts +3 -0
  394. package/dist/types/src/web/focus.d.ts +8 -0
  395. package/dist/types/src/web/index.d.ts +5 -2
  396. package/dist/types/src/web/primitives/carousel.d.ts +1 -1
  397. package/dist/types/src/web/primitives/dock.d.ts +5 -2
  398. package/dist/types/src/web/primitives/index.d.ts +2 -0
  399. package/dist/types/src/web/primitives/motion-paint.d.ts +36 -0
  400. package/dist/types/src/web/primitives/motion.d.ts +162 -0
  401. package/dist/types/src/web/primitives/zoomable-image.d.ts +158 -0
  402. package/dist/types/src/web/table.d.ts +8 -0
  403. package/dist/types/src/zoom.d.ts +128 -0
  404. package/dist/types/wasm/motion/bytes.d.ts +1 -0
  405. package/dist/web/index.js +165 -230
  406. package/dist/web/index.js.map +8 -9
  407. package/dist/web/primitives/index.js +584 -7
  408. package/dist/web/primitives/index.js.map +7 -6
  409. package/docs/components.generated.json +392 -4
  410. package/docs/round-6-contract.md +5 -3
  411. package/docs/themes.generated.json +27 -0
  412. package/fixtures/bind-time.json +4 -0
  413. package/fixtures/catalog-components.json +930 -16
  414. package/fixtures/catalog-macros.json +11 -0
  415. package/fixtures/conformance-baseline.json +33020 -32952
  416. package/fixtures/conformance-known.json +64 -70
  417. package/fixtures/kitchen-sink.expanded.json +72 -0
  418. package/fixtures/kitchen-sink.json +33 -0
  419. package/fixtures/layout-geometry-round1.json +42 -42
  420. package/fixtures/motion-frames.json +2618 -0
  421. package/fixtures/motion-playback.json +528 -0
  422. package/fixtures/motion-state.json +722 -0
  423. package/fixtures/motion-validate.json +138 -0
  424. package/fixtures/primitive-specimens.json +1 -0
  425. package/fixtures/prompt-budget.json +16 -16
  426. package/fixtures/specimens.json +717 -21
  427. package/fixtures/theme-recipes.json +1518 -32
  428. package/fixtures/theme-resolved.json +732 -56
  429. package/fixtures/zoom.json +1382 -0
  430. package/generated/ExponentialUICatalog.generated.kt +20 -20
  431. package/generated/ExponentialUICatalog.generated.swift +20 -20
  432. package/generated/ExponentialUIThemes.generated.kt +7 -7
  433. package/generated/ExponentialUIThemes.generated.swift +7 -7
  434. package/generated/catalog.descriptions.generated.rs +1 -1
  435. package/generated/catalog.generated.rs +29 -29
  436. package/generated/catalog.themes.generated.rs +8 -8
  437. package/generated/core.descriptions.json +171 -5
  438. package/generated/core.runtime.json +189 -1
  439. package/package.json +1 -1
  440. package/themes/neutral.theme.json +172 -3
  441. package/dist/chunks/index-t6qz1770.js +0 -95
  442. package/dist/chunks/index-t6qz1770.js.map +0 -11
@@ -1,5 +1,5 @@
1
1
  {
2
- "$comment": "Round 2 (docs/round-2-contract.md §7): the layout NUMBERS every painter shares where no theme token decides (px unless noted). `windowThreshold` = items past which List and Table window; `windowOverscan` = items rendered beyond each viewport edge; `resizeStep` = percentage points per arrow key on a Resizable handle; `panelMin` = a panel's min (percent) when unset; `resizeHandleHit` = a handle's hit area across its hairline; `fieldIntrinsicWidth` = the max-content width of a text field (Input, Textarea, NumberField, ChipInput: never the browser's `size` default) — picker triggers (Select, DatePicker, DateRangePicker, TimePicker) size to their content; `mediaIntrinsicWidth` = the max-content width of an Image/Video without a width (its min-content is 0); `mediaAspectRatio` = width/height of an Image without `aspectRatio` or a height (Video: its `aspectRatio` default); `treeGuideColumn` = one TreeGuides gutter column (the recipe's `line` width is the STROKE; round 3: 14, the ×4 app indent, the elbow lands on the parent's lead glyph); `treeGuideRadius` = the elbow's corner radius; `treeGuideBridge` = how far the guide verticals overshoot the row's TOP edge (paint only) so a Section's hairline divider never breaks the line. EXP-1259 (packages/domain-contract/fixtures/feedback-states.json + search-list.json): `pendingDelayMs` = how long a `loading` Button waits before it shows the spinner and its `pendingLabel` (a fast action never flashes; presses are refused at once); `skeletonPulseMs` / `skeletonOpacityLow` / `skeletonOpacityHigh` = the placeholder's ONE opacity pulse (low → high → low, ease-in-out), `skeletonReducedOpacity` = its static opacity under reduce motion; `searchListFade` = the bottom fade over a SearchList (or a searchable submenu) while more rows sit below. Generated into every target; src/layout.ts reads it.",
2
+ "$comment": "Round 2 (docs/round-2-contract.md §7): the layout NUMBERS every painter shares where no theme token decides (px unless noted). `windowThreshold` = items past which List and Table window; `windowOverscan` = items rendered beyond each viewport edge; `resizeStep` = percentage points per arrow key on a Resizable handle; `panelMin` = a panel's min (percent) when unset; `resizeHandleHit` = a handle's hit area across its hairline; `fieldIntrinsicWidth` = the max-content width of a text field (Input, Textarea, NumberField, ChipInput: never the browser's `size` default) — picker triggers (Select, DatePicker, DateRangePicker, TimePicker) size to their content; `mediaIntrinsicWidth` = the max-content width of an Image/Video without a width (its min-content is 0); `mediaAspectRatio` = width/height of an Image without `aspectRatio` or a height (Video: its `aspectRatio` default); `treeGuideColumn` = one TreeGuides gutter column (the recipe's `line` width is the STROKE; round 3: 14, the ×4 app indent, the elbow lands on the parent's lead glyph); `treeGuideRadius` = the elbow's corner radius; `treeGuideBridge` = how far the guide verticals overshoot the row's TOP edge (paint only) so a Section's hairline divider never breaks the line. EXP-1259 (packages/domain-contract/fixtures/feedback-states.json + search-list.json): `pendingDelayMs` = how long a `loading` Button waits before it shows the spinner and its `pendingLabel` (a fast action never flashes; presses are refused at once); `skeletonPulseMs` / `skeletonOpacityLow` / `skeletonOpacityHigh` = the placeholder's ONE opacity pulse (low → high → low, ease-in-out), `skeletonReducedOpacity` = its static opacity under reduce motion; `searchListFade` = the bottom fade over a SearchList (or a searchable submenu) while more rows sit below. EXP-1548: `tableColumnMin` = the narrowest a Table column without a `width` gets; a table whose columns need more than its box scrolls horizontally. Generated into every target; src/layout.ts reads it.",
3
3
  "windowThreshold": 50,
4
4
  "windowOverscan": 5,
5
5
  "resizeStep": 10,
@@ -16,5 +16,6 @@
16
16
  "skeletonOpacityLow": 0.45,
17
17
  "skeletonOpacityHigh": 0.9,
18
18
  "skeletonReducedOpacity": 0.6,
19
- "searchListFade": 24
19
+ "searchListFade": 24,
20
+ "tableColumnMin": 120
20
21
  }
@@ -5,5 +5,14 @@
5
5
  "maxMessageBytes": 4194304,
6
6
  "maxTemplateItems": 10000,
7
7
  "maxPointerBytes": 1024,
8
- "maxPointerSegments": 64
8
+ "maxPointerSegments": 64,
9
+ "motion": {
10
+ "$comment": "EXP-1584/1602: the eUI Motion (Lottie) limits, enforced by the one engine (apps/desktop/crates/eui-motion, src/validate.rs Limits) on every renderer through its WASM and uniffi builds. A source past maxBytes (UTF-8 JSON), maxShapes (shape items: objects with a string `ty` inside a layer's `shapes` or a group's `it`) or maxSeconds ((op − ip) / fr) is refused with an issue (`limit-bytes`, `limit-shapes`, `limit-duration`; expressions are refused too: `expression`); maxVertices = path vertices in one sampled frame (checked per frame by the player, not by the validator); maxFps = the highest frame rate a player samples at; maxPlayingPerSurface = Motion components one surface animates at once. Cases: fixtures/motion-validate.json.",
11
+ "maxBytes": 2097152,
12
+ "maxShapes": 5000,
13
+ "maxVertices": 100000,
14
+ "maxSeconds": 120,
15
+ "maxFps": 60,
16
+ "maxPlayingPerSurface": 8
17
+ }
9
18
  }
@@ -2025,6 +2025,7 @@
2025
2025
  }
2026
2026
  },
2027
2027
  "alignItems": "stretch",
2028
+ "gap": "$spacing.lg",
2028
2029
  "width": "100%",
2029
2030
  "minHeight": 0
2030
2031
  },
@@ -1,5 +1,5 @@
1
1
  {
2
- "$comment": "VAPP-92: the RECIPE contract. A theme styles a component PART under a `when` selector (the node's recipe props + the interaction `state`); this file fixes what a theme may name. `states` = the interaction states a painter reports (`default` is the absence of all; round 1 adds `invalid` = a field whose checks failed, `dragover` = a drop zone a drag hovers); `keys` = the whitelist a recipe style may set: a SUBSET of style.json's visual keys plus the padding/gap/size keys a part's box needs and `native` (true = the painter may use the platform's own control for this part, geometry still from the tokens); round 1 lets a recipe set `transition`/`transitionEasing` (so a theme's motion tokens finally animate hover/press/open), `transform` (a chevron that rotates when `open`), `borderStyle`, the four per-side border widths (an app bar's bottom rule, a tab bar's top rule), `textDecoration`, `letterSpacing`, `fontStyle`, `textTransform`. A part-level discriminator the painter supplies per drawn piece: CodeBlock/token `kind` (the codeToken enum), Table/headerCell+cell `align` and Table/row `striped` (true on ODD rows of a striped table), Stepper's step `status` (a macro `$recipe`). `native` lists every native component's PARTS (the painter paints each part with its resolved recipe) and the PROPS a `when` may key on (the component's enum/boolean props; the catalog default fills an unset one, so a theme always sees a concrete value; a part-level discriminator the PAINTER supplies is listed too, see below). Macro parts come from macros.json (every template `part`) and their `when` props from the macro's `recipeProps` (+ a part's `$recipe` keys); src/recipes.ts derives them. Both lists are append-only. Round 2 (docs/round-2-contract.md §6): `parts` lists EVERY part a painter lays out (the conformance dump names each `<node id>.<part>[.<index or row key>]`), so the layout-only parts are here too (Switch/body, Radio/items, Slider/header, Table/body, CodeBlock/body+code, FileUpload/title+browse+fileIcon, the fields' `input`, Tooltip/anchor, Accordion/count, List/section, Carousel/controls+previous+next); keys add `backdropBlur` (`$blur.*`) and `animation`; Resizable is new. EXP-1259: SearchList is new (its parts are also a searchable Menu submenu's: head, search, count, list, empty, fade), Tabs gain `close` + `new` (props `closable`, `addable`), Skeleton gains its rows (`row`, `dot`, `bar`). EXP-1324: CodeBlock gains the `variant` (default|destructive) and `size` (default|sm) props, shadcn's code-block. VAPP-162 (docs/round-5-contract.md): Segmented gains `orientation` + the `badge` part (an option `count`), VoiceWave the `variant` prop + the `bar` part (the `bars` meter), QrCode and QrScanner are new. EXP-1495 (docs/round-6-contract.md): Carousel gains `counter` (prop + part) and the `thumbnails` strip (parts `thumbnails`, `thumbnail`, state `selected` = the current page).",
2
+ "$comment": "VAPP-92: the RECIPE contract. A theme styles a component PART under a `when` selector (the node's recipe props + the interaction `state`); this file fixes what a theme may name. `states` = the interaction states a painter reports (`default` is the absence of all; round 1 adds `invalid` = a field whose checks failed, `dragover` = a drop zone a drag hovers); `keys` = the whitelist a recipe style may set: a SUBSET of style.json's visual keys plus the padding/gap/size keys a part's box needs and `native` (true = the painter may use the platform's own control for this part, geometry still from the tokens); round 1 lets a recipe set `transition`/`transitionEasing` (so a theme's motion tokens finally animate hover/press/open), `transform` (a chevron that rotates when `open`), `borderStyle`, the four per-side border widths (an app bar's bottom rule, a tab bar's top rule), `textDecoration`, `letterSpacing`, `fontStyle`, `textTransform`. A part-level discriminator the painter supplies per drawn piece: CodeBlock/token `kind` (the codeToken enum), Table/headerCell+cell `align` and Table/row `striped` (true on ODD rows of a striped table), Stepper's step `status` (a macro `$recipe`). `native` lists every native component's PARTS (the painter paints each part with its resolved recipe) and the PROPS a `when` may key on (the component's enum/boolean props; the catalog default fills an unset one, so a theme always sees a concrete value; a part-level discriminator the PAINTER supplies is listed too, see below). Macro parts come from macros.json (every template `part`) and their `when` props from the macro's `recipeProps` (+ a part's `$recipe` keys); src/recipes.ts derives them. Both lists are append-only. Round 2 (docs/round-2-contract.md §6): `parts` lists EVERY part a painter lays out (the conformance dump names each `<node id>.<part>[.<index or row key>]`), so the layout-only parts are here too (Switch/body, Radio/items, Slider/header, Table/body, CodeBlock/body+code, FileUpload/title+browse+fileIcon, the fields' `input`, Tooltip/anchor, Accordion/count, List/section, Carousel/controls+previous+next); keys add `backdropBlur` (`$blur.*`) and `animation`; Resizable is new. EXP-1259: SearchList is new (its parts are also a searchable Menu submenu's: head, search, count, list, empty, fade), Tabs gain `close` + `new` (props `closable`, `addable`), Skeleton gains its rows (`row`, `dot`, `bar`). EXP-1324: CodeBlock gains the `variant` (default|destructive) and `size` (default|sm) props, shadcn's code-block. VAPP-162 (docs/round-5-contract.md): Segmented gains `orientation` + the `badge` part (an option `count`), VoiceWave the `variant` prop + the `bar` part (the `bars` meter), QrCode and QrScanner are new. EXP-1495 (docs/round-6-contract.md): Carousel gains `counter` (prop + part) and the `thumbnails` strip (parts `thumbnails`, `thumbnail`, state `selected` = the current page). EXP-1586: ZoomableImage is new (the picture `image` + THE zoom pill: `pill`, `zoomOut`, `percent`, `zoomIn`, `divider`, `fit`; `fit` reports `selected` while the view is at rest).",
3
3
  "states": ["hover", "pressed", "focus", "disabled", "checked", "open", "selected", "invalid", "dragover"],
4
4
  "keys": [
5
5
  "backgroundColor", "color", "borderColor", "borderWidth", "borderTopWidth", "borderRightWidth", "borderBottomWidth", "borderLeftWidth", "borderRadius", "borderStyle",
@@ -15,11 +15,13 @@
15
15
  "Text": { "parts": ["root"], "props": ["variant", "tone"] },
16
16
  "Markdown": { "parts": ["root", "paragraph", "heading", "link", "code", "codeBlock", "quote", "table", "listItem"], "props": [] },
17
17
  "Image": { "parts": ["root", "fallback"], "props": ["fit"] },
18
+ "Motion": { "parts": ["root"], "props": ["fit"] },
18
19
  "Icon": { "parts": ["root"], "props": ["size", "tone"] },
19
20
  "Video": { "parts": ["root", "controls", "poster"], "props": ["autoplay"] },
20
21
  "AudioPlayer": { "parts": ["root", "controls", "track"], "props": [] },
21
22
  "Avatar": { "parts": ["root", "image", "fallback"], "props": ["size"] },
22
23
  "QrCode": { "parts": ["root", "plate", "module", "label"], "props": ["level"] },
24
+ "ZoomableImage": { "parts": ["root", "image", "pill", "zoomOut", "percent", "zoomIn", "divider", "fit"], "props": ["controls"] },
23
25
  "Carousel": { "parts": ["root", "page", "indicator", "controls", "previous", "next", "counter", "thumbnails", "thumbnail"], "props": ["loop", "indicators", "counter"] },
24
26
  "Tabs": { "parts": ["root", "list", "tab", "indicator", "content", "close", "new"], "props": ["fill", "closable", "addable"] },
25
27
  "Segmented": { "parts": ["root", "item", "icon", "label", "badge"], "props": ["type", "variant", "size", "fill", "orientation"] },
@@ -1,5 +1,5 @@
1
1
  {
2
- "$comment": "Round 1 (docs/round-1-contract.md §4): the built-in UI STRINGS every renderer shows — the copy no author writes (a Select's search placeholder, the calendar's month buttons, the copy button, the Pagination arrows' labels). Keys are the ids, values the English defaults. A renderer ships this table (generated into TS/Swift/Kotlin/Rust as STRING_IDS + STRING_DEFAULTS) and lets the HOST override any id per surface (`strings: {search: \"Suchen…\"}`); the catalog refers to an entry as `$string.<id>` in a prop default or a macro template (`$string.previous`), which the renderer resolves at bind time like a token. `{name}` placeholders are filled by the renderer (src/strings.ts formatString; a macro template uses `$fill` → the core `fill` function): a sentence is ONE id with placeholders, never concatenated fragments. Round 2 adds the names the renderers still hard-coded (`invalidValue` = a failed check without a message, `message` = the Composer field, `codeBlock` = an untitled CodeBlock, `dialog` = an untitled Dialog/Drawer, `table` = an uncaptioned Table, `carousel`/`slide` = the carousel's role descriptions, `resize` = a Resizable handle). EXP-1259 adds `closeTab` and `newTab` (the Tabs close glyph and + button). Append-only (round 1 dropped the unused fragment `of`). VAPP-162 adds the call buttons (`mute`, `unmute`, `speaker`, `speakerOff`, `endCall`), the Plan answers (`yes`, `no`), the MessageBubble delivery labels (`sending`, `sent`, `read`) and the QrScanner's `scanQrCode` + `cameraUnavailable`.",
2
+ "$comment": "Round 1 (docs/round-1-contract.md §4): the built-in UI STRINGS every renderer shows — the copy no author writes (a Select's search placeholder, the calendar's month buttons, the copy button, the Pagination arrows' labels). Keys are the ids, values the English defaults. A renderer ships this table (generated into TS/Swift/Kotlin/Rust as STRING_IDS + STRING_DEFAULTS) and lets the HOST override any id per surface (`strings: {search: \"Suchen…\"}`); the catalog refers to an entry as `$string.<id>` in a prop default or a macro template (`$string.previous`), which the renderer resolves at bind time like a token. `{name}` placeholders are filled by the renderer (src/strings.ts formatString; a macro template uses `$fill` → the core `fill` function): a sentence is ONE id with placeholders, never concatenated fragments. Round 2 adds the names the renderers still hard-coded (`invalidValue` = a failed check without a message, `message` = the Composer field, `codeBlock` = an untitled CodeBlock, `dialog` = an untitled Dialog/Drawer, `table` = an uncaptioned Table, `carousel`/`slide` = the carousel's role descriptions, `resize` = a Resizable handle). EXP-1259 adds `closeTab` and `newTab` (the Tabs close glyph and + button). Append-only (round 1 dropped the unused fragment `of`). VAPP-162 adds the call buttons (`mute`, `unmute`, `speaker`, `speakerOff`, `endCall`), the Plan answers (`yes`, `no`), the MessageBubble delivery labels (`sending`, `sent`, `read`) and the QrScanner's `scanQrCode` + `cameraUnavailable`. EXP-1586 adds the ZoomableImage pill (`zoomIn`, `zoomOut`, `zoomToFit`, `zoomLevel` = the percent button's label, `zoomFit` = its Menu's Fit row).",
3
3
  "strings": {
4
4
  "back": "Back",
5
5
  "breadcrumb": "Breadcrumb",
@@ -46,6 +46,8 @@
46
46
  "pageCounter": "{page} / {total}",
47
47
  "pageOf": "Page {page} of {total}",
48
48
  "pagination": "Pagination",
49
+ "pause": "Pause",
50
+ "play": "Play",
49
51
  "previous": "Previous",
50
52
  "previousMonth": "Previous month",
51
53
  "ratingStar": "{value} of {max}",
@@ -84,6 +86,11 @@
84
86
  "unmute": "Unmute",
85
87
  "unsupportedFile": "Unsupported file",
86
88
  "unsupportedFileNamed": "{name}: Unsupported file",
87
- "yes": "Yes"
89
+ "yes": "Yes",
90
+ "zoomFit": "Fit",
91
+ "zoomIn": "Zoom in",
92
+ "zoomLevel": "Zoom level",
93
+ "zoomOut": "Zoom out",
94
+ "zoomToFit": "Zoom to fit"
88
95
  }
89
96
  }
@@ -176,5 +176,26 @@
176
176
  "hintGap": 12,
177
177
  "placeholderIcon": "ui-scan",
178
178
  "placeholderIconSize": 32
179
+ },
180
+ "zoomableImage": {
181
+ "$comment": "EXP-1586: the ZoomableImage native. THE MATHS COMES FROM THE CORE: src/zoom.ts (the Rust core's `zoom` ports it; fixtures/zoom.json locks it). THE BOX: as wide as its parent; its height = the style height, else width \u00d7 naturalHeight / naturalWidth (capped at the width for a TALL picture, so a full-page capture opens as a landscape window onto its top), else 16:9; the picture clips to it. A view = {scale, x, y}: scale = displayed px per image px (1 = 100%: one image pixel per point), x/y = the picture's top-left in the viewport. FIT = min(1, vw/iw, vh/ih) (never upscales) = the minimum scale; the maximum = max(fit, maxScale). REST = the scale it opens at: `fit`, `fitWidth` = min(1, vw/iw), `actual` = 1, `auto` = fitWidth when the picture is TALL (w/h < tallAspect) else fit. An axis where the scaled picture is no larger than the viewport is CENTRED; otherwise x is clamped to [vw \u2212 sw, 0] (no letterbox shows); rest views of a tall picture start at the top. Zoom keeps the anchor point fixed (the cursor, the fingers' midpoint, the double-tap point, the viewport centre for keys and the pill). Wheel with \u2318/ctrl (or a trackpad pinch) = factor exp(\u2212deltaY \u00d7 wheelRate) (lines \u00d7 wheelLinePx first); a plain wheel PANS. Steps (+ / \u2212 / the pill) = the next `presets` entry strictly above / below the current scale (fit joins the ladder), clamped. Double tap / click: at rest \u2192 max(1, 2 \u00d7 rest) capped at the max, about the point; otherwise \u2192 the rest view. Keys: + = step up, \u2212 = step down, 0 = the rest view, 1 = 100% about the centre. Drag past an edge = the overshoot through rubberBand(o, d) = (1 \u2212 1 / (o \u00d7 rubber / d + 1)) \u00d7 d (d = the viewport's extent on that axis), released = the clamped view (sprung with motion.standard; reduced motion snaps). A pinch past the min/max rubber-bands the scale the same way (d = the limit). Mouse-drag momentum: v(t) = v0 \u00d7 e^(\u2212t/momentumTauMs), travel = v0 \u00d7 \u03c4 \u00d7 (1 \u2212 e^(\u2212t/\u03c4)), stopping at the edges; touch and trackpads use the platform's own inertia. Pan ROOM = an axis whose scaled picture is larger than the viewport: a horizontal swipe with no x room belongs to the host (paging); with room the picture pans. A new src = the rest view; a resize at rest = the new rest view, zoomed = the same scale about the viewport centre, clamped. THE PILL (controls auto/always): one glass capsule bottom-centre `pill.inset` above the picture's bottom edge: Button ghost icon-sm `ui-minus`, the percent (round(scale \u00d7 100) + '%', tabular, a ghost button opening THE Menu of `menuPresets` (0 = Fit, the rest view; outside [min, max] dropped)), Button ghost icon-sm `ui-add`, a hairline divider, Button ghost icon-sm `ui-fullscreen` (pressed = the rest view; drawn ACTIVE while at rest). \u2212 is disabled at the min, + at the max. `auto` shows it on appear and hides it autoHideMs after the last pointer move / zoom / focus inside (kept while hovered or focused; a touch tap on the picture toggles it); `none` never draws it.",
182
+ "tallAspect": 0.3333333333333333,
183
+ "maxScale": 8,
184
+ "presets": [0.25, 0.33, 0.5, 0.67, 1, 1.5, 2, 3, 4, 6, 8],
185
+ "menuPresets": [0, 0.5, 1, 2, 4],
186
+ "doubleTapFactor": 2,
187
+ "wheelRate": 0.002,
188
+ "wheelLinePx": 16,
189
+ "rubber": 0.55,
190
+ "momentumTauMs": 325,
191
+ "autoHideMs": 2000,
192
+ "pill": {
193
+ "height": 36,
194
+ "inset": 16,
195
+ "padding": 4,
196
+ "gap": 2,
197
+ "percentMinWidth": 56,
198
+ "dividerHeight": 16
199
+ }
179
200
  }
180
201
  }