@prestack/thread-ui 0.0.1

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 (408) hide show
  1. package/CHANGELOG.md +348 -0
  2. package/dist/attach.d.ts +1 -0
  3. package/dist/attach.js +1 -0
  4. package/dist/ui/animations/anm_appear.d.ts +16 -0
  5. package/dist/ui/animations/anm_appear.js +10 -0
  6. package/dist/ui/animations/anm_blur_in.d.ts +22 -0
  7. package/dist/ui/animations/anm_blur_in.js +16 -0
  8. package/dist/ui/animations/anm_blur_out.d.ts +22 -0
  9. package/dist/ui/animations/anm_blur_out.js +16 -0
  10. package/dist/ui/animations/anm_dismiss.d.ts +22 -0
  11. package/dist/ui/animations/anm_dismiss.js +16 -0
  12. package/dist/ui/animations/anm_drop.d.ts +22 -0
  13. package/dist/ui/animations/anm_drop.js +16 -0
  14. package/dist/ui/animations/anm_fall.d.ts +22 -0
  15. package/dist/ui/animations/anm_fall.js +16 -0
  16. package/dist/ui/animations/anm_flash.d.ts +19 -0
  17. package/dist/ui/animations/anm_flash.js +16 -0
  18. package/dist/ui/animations/anm_glow.d.ts +16 -0
  19. package/dist/ui/animations/anm_glow.js +14 -0
  20. package/dist/ui/animations/anm_lift.d.ts +16 -0
  21. package/dist/ui/animations/anm_lift.js +14 -0
  22. package/dist/ui/animations/anm_nudge.d.ts +16 -0
  23. package/dist/ui/animations/anm_nudge.js +14 -0
  24. package/dist/ui/animations/anm_pop_in.d.ts +29 -0
  25. package/dist/ui/animations/anm_pop_in.js +20 -0
  26. package/dist/ui/animations/anm_pop_out.d.ts +29 -0
  27. package/dist/ui/animations/anm_pop_out.js +20 -0
  28. package/dist/ui/animations/anm_press.d.ts +19 -0
  29. package/dist/ui/animations/anm_press.js +10 -0
  30. package/dist/ui/animations/anm_pulse.d.ts +20 -0
  31. package/dist/ui/animations/anm_pulse.js +11 -0
  32. package/dist/ui/animations/anm_rise.d.ts +22 -0
  33. package/dist/ui/animations/anm_rise.js +16 -0
  34. package/dist/ui/animations/anm_shake.d.ts +23 -0
  35. package/dist/ui/animations/anm_shake.js +11 -0
  36. package/dist/ui/animations/anm_slide_in_left.d.ts +22 -0
  37. package/dist/ui/animations/anm_slide_in_left.js +16 -0
  38. package/dist/ui/animations/anm_slide_in_right.d.ts +22 -0
  39. package/dist/ui/animations/anm_slide_in_right.js +16 -0
  40. package/dist/ui/animations/anm_slide_out_left.d.ts +22 -0
  41. package/dist/ui/animations/anm_slide_out_left.js +16 -0
  42. package/dist/ui/animations/anm_slide_out_right.d.ts +22 -0
  43. package/dist/ui/animations/anm_slide_out_right.js +16 -0
  44. package/dist/ui/animations/anm_spin.d.ts +16 -0
  45. package/dist/ui/animations/anm_spin.js +10 -0
  46. package/dist/ui/animations/anm_swell.d.ts +16 -0
  47. package/dist/ui/animations/anm_swell.js +14 -0
  48. package/dist/ui/animations/anm_wobble.d.ts +27 -0
  49. package/dist/ui/animations/anm_wobble.js +22 -0
  50. package/dist/ui/animations/anm_zoom_in.d.ts +22 -0
  51. package/dist/ui/animations/anm_zoom_in.js +16 -0
  52. package/dist/ui/animations/anm_zoom_out.d.ts +22 -0
  53. package/dist/ui/animations/anm_zoom_out.js +16 -0
  54. package/dist/ui/animations.d.ts +59 -0
  55. package/dist/ui/animations.js +227 -0
  56. package/dist/ui/attach.d.ts +3 -0
  57. package/dist/ui/attach.js +497 -0
  58. package/dist/ui/charts.d.ts +32 -0
  59. package/dist/ui/charts.js +35 -0
  60. package/dist/ui/checked.d.ts +19 -0
  61. package/dist/ui/checked.js +3 -0
  62. package/dist/ui/collector.d.ts +32 -0
  63. package/dist/ui/collector.js +75 -0
  64. package/dist/ui/compositions.d.ts +21 -0
  65. package/dist/ui/compositions.js +305 -0
  66. package/dist/ui/consent.d.ts +22 -0
  67. package/dist/ui/consent.js +44 -0
  68. package/dist/ui/content.d.ts +9 -0
  69. package/dist/ui/content.js +11 -0
  70. package/dist/ui/contrast.d.ts +3 -0
  71. package/dist/ui/contrast.js +23 -0
  72. package/dist/ui/controls.d.ts +14 -0
  73. package/dist/ui/controls.js +2 -0
  74. package/dist/ui/disclosure.d.ts +14 -0
  75. package/dist/ui/disclosure.js +2 -0
  76. package/dist/ui/dismiss-layer.d.ts +14 -0
  77. package/dist/ui/dismiss-layer.js +66 -0
  78. package/dist/ui/door.d.ts +40 -0
  79. package/dist/ui/door.js +100 -0
  80. package/dist/ui/drag.d.ts +82 -0
  81. package/dist/ui/drag.js +212 -0
  82. package/dist/ui/elements/accordion.d.ts +12 -0
  83. package/dist/ui/elements/accordion.js +16 -0
  84. package/dist/ui/elements/accordion.works.d.ts +22 -0
  85. package/dist/ui/elements/accordion.works.js +44 -0
  86. package/dist/ui/elements/aspect-ratio.d.ts +10 -0
  87. package/dist/ui/elements/aspect-ratio.js +9 -0
  88. package/dist/ui/elements/aspect-ratio.works.d.ts +2 -0
  89. package/dist/ui/elements/aspect-ratio.works.js +3 -0
  90. package/dist/ui/elements/avatar.d.ts +11 -0
  91. package/dist/ui/elements/avatar.js +10 -0
  92. package/dist/ui/elements/avatar.works.d.ts +4 -0
  93. package/dist/ui/elements/avatar.works.js +16 -0
  94. package/dist/ui/elements/badge.d.ts +11 -0
  95. package/dist/ui/elements/badge.js +10 -0
  96. package/dist/ui/elements/badge.works.d.ts +5 -0
  97. package/dist/ui/elements/badge.works.js +6 -0
  98. package/dist/ui/elements/bars.d.ts +14 -0
  99. package/dist/ui/elements/bars.js +17 -0
  100. package/dist/ui/elements/bars.works.d.ts +12 -0
  101. package/dist/ui/elements/bars.works.js +20 -0
  102. package/dist/ui/elements/box.d.ts +12 -0
  103. package/dist/ui/elements/box.js +11 -0
  104. package/dist/ui/elements/breadcrumb.d.ts +10 -0
  105. package/dist/ui/elements/breadcrumb.js +12 -0
  106. package/dist/ui/elements/breadcrumb.works.d.ts +7 -0
  107. package/dist/ui/elements/breadcrumb.works.js +21 -0
  108. package/dist/ui/elements/button.d.ts +17 -0
  109. package/dist/ui/elements/button.js +16 -0
  110. package/dist/ui/elements/button.works.d.ts +17 -0
  111. package/dist/ui/elements/button.works.js +34 -0
  112. package/dist/ui/elements/column.d.ts +9 -0
  113. package/dist/ui/elements/column.js +8 -0
  114. package/dist/ui/elements/consent.d.ts +13 -0
  115. package/dist/ui/elements/consent.js +21 -0
  116. package/dist/ui/elements/consent.works.d.ts +41 -0
  117. package/dist/ui/elements/consent.works.js +79 -0
  118. package/dist/ui/elements/donut.d.ts +13 -0
  119. package/dist/ui/elements/donut.js +16 -0
  120. package/dist/ui/elements/donut.works.d.ts +11 -0
  121. package/dist/ui/elements/donut.works.js +28 -0
  122. package/dist/ui/elements/each.d.ts +14 -0
  123. package/dist/ui/elements/each.js +9 -0
  124. package/dist/ui/elements/each.works.d.ts +3 -0
  125. package/dist/ui/elements/each.works.js +68 -0
  126. package/dist/ui/elements/empty.d.ts +9 -0
  127. package/dist/ui/elements/empty.js +12 -0
  128. package/dist/ui/elements/field.d.ts +16 -0
  129. package/dist/ui/elements/field.js +15 -0
  130. package/dist/ui/elements/field.works.d.ts +17 -0
  131. package/dist/ui/elements/field.works.js +45 -0
  132. package/dist/ui/elements/funnel.d.ts +14 -0
  133. package/dist/ui/elements/funnel.js +17 -0
  134. package/dist/ui/elements/funnel.works.d.ts +12 -0
  135. package/dist/ui/elements/funnel.works.js +23 -0
  136. package/dist/ui/elements/gauge.d.ts +12 -0
  137. package/dist/ui/elements/gauge.js +15 -0
  138. package/dist/ui/elements/gauge.works.d.ts +11 -0
  139. package/dist/ui/elements/gauge.works.js +31 -0
  140. package/dist/ui/elements/glyph.d.ts +10 -0
  141. package/dist/ui/elements/glyph.js +9 -0
  142. package/dist/ui/elements/glyph.works.d.ts +5 -0
  143. package/dist/ui/elements/glyph.works.js +16 -0
  144. package/dist/ui/elements/grid.d.ts +9 -0
  145. package/dist/ui/elements/grid.js +8 -0
  146. package/dist/ui/elements/heatmap.d.ts +15 -0
  147. package/dist/ui/elements/heatmap.js +17 -0
  148. package/dist/ui/elements/heatmap.works.d.ts +11 -0
  149. package/dist/ui/elements/heatmap.works.js +11 -0
  150. package/dist/ui/elements/hit-box.d.ts +19 -0
  151. package/dist/ui/elements/hit-box.js +15 -0
  152. package/dist/ui/elements/hit-box.works.d.ts +87 -0
  153. package/dist/ui/elements/hit-box.works.js +451 -0
  154. package/dist/ui/elements/image.d.ts +10 -0
  155. package/dist/ui/elements/image.js +9 -0
  156. package/dist/ui/elements/line-chart.d.ts +13 -0
  157. package/dist/ui/elements/line-chart.js +16 -0
  158. package/dist/ui/elements/line-chart.works.d.ts +12 -0
  159. package/dist/ui/elements/line-chart.works.js +27 -0
  160. package/dist/ui/elements/link.d.ts +12 -0
  161. package/dist/ui/elements/link.js +15 -0
  162. package/dist/ui/elements/link.works.d.ts +10 -0
  163. package/dist/ui/elements/link.works.js +15 -0
  164. package/dist/ui/elements/media.d.ts +11 -0
  165. package/dist/ui/elements/media.js +22 -0
  166. package/dist/ui/elements/menu.d.ts +12 -0
  167. package/dist/ui/elements/menu.js +18 -0
  168. package/dist/ui/elements/menu.works.d.ts +50 -0
  169. package/dist/ui/elements/menu.works.js +100 -0
  170. package/dist/ui/elements/money.d.ts +10 -0
  171. package/dist/ui/elements/money.js +9 -0
  172. package/dist/ui/elements/money.works.d.ts +4 -0
  173. package/dist/ui/elements/money.works.js +4 -0
  174. package/dist/ui/elements/pagination.d.ts +11 -0
  175. package/dist/ui/elements/pagination.js +12 -0
  176. package/dist/ui/elements/pagination.works.d.ts +5 -0
  177. package/dist/ui/elements/pagination.works.js +15 -0
  178. package/dist/ui/elements/progress.d.ts +11 -0
  179. package/dist/ui/elements/progress.js +11 -0
  180. package/dist/ui/elements/progress.works.d.ts +2 -0
  181. package/dist/ui/elements/progress.works.js +6 -0
  182. package/dist/ui/elements/radio-group.d.ts +15 -0
  183. package/dist/ui/elements/radio-group.js +16 -0
  184. package/dist/ui/elements/radio-group.works.d.ts +10 -0
  185. package/dist/ui/elements/radio-group.works.js +22 -0
  186. package/dist/ui/elements/row.d.ts +9 -0
  187. package/dist/ui/elements/row.js +8 -0
  188. package/dist/ui/elements/scatter.d.ts +13 -0
  189. package/dist/ui/elements/scatter.js +15 -0
  190. package/dist/ui/elements/scatter.works.d.ts +11 -0
  191. package/dist/ui/elements/scatter.works.js +24 -0
  192. package/dist/ui/elements/select.d.ts +13 -0
  193. package/dist/ui/elements/select.js +11 -0
  194. package/dist/ui/elements/select.works.d.ts +4 -0
  195. package/dist/ui/elements/select.works.js +3 -0
  196. package/dist/ui/elements/separator.d.ts +10 -0
  197. package/dist/ui/elements/separator.js +9 -0
  198. package/dist/ui/elements/skeleton.d.ts +8 -0
  199. package/dist/ui/elements/skeleton.js +9 -0
  200. package/dist/ui/elements/slider.d.ts +14 -0
  201. package/dist/ui/elements/slider.js +10 -0
  202. package/dist/ui/elements/slider.works.d.ts +4 -0
  203. package/dist/ui/elements/slider.works.js +3 -0
  204. package/dist/ui/elements/sparkline.d.ts +10 -0
  205. package/dist/ui/elements/sparkline.js +15 -0
  206. package/dist/ui/elements/sparkline.works.d.ts +10 -0
  207. package/dist/ui/elements/sparkline.works.js +19 -0
  208. package/dist/ui/elements/spinner.d.ts +9 -0
  209. package/dist/ui/elements/spinner.js +12 -0
  210. package/dist/ui/elements/stack.d.ts +9 -0
  211. package/dist/ui/elements/stack.js +8 -0
  212. package/dist/ui/elements/stat.d.ts +12 -0
  213. package/dist/ui/elements/stat.js +10 -0
  214. package/dist/ui/elements/stat.works.d.ts +3 -0
  215. package/dist/ui/elements/stat.works.js +10 -0
  216. package/dist/ui/elements/surface.d.ts +9 -0
  217. package/dist/ui/elements/surface.js +15 -0
  218. package/dist/ui/elements/surface.works.d.ts +7 -0
  219. package/dist/ui/elements/surface.works.js +4 -0
  220. package/dist/ui/elements/table.d.ts +13 -0
  221. package/dist/ui/elements/table.js +16 -0
  222. package/dist/ui/elements/table.works.d.ts +11 -0
  223. package/dist/ui/elements/table.works.js +15 -0
  224. package/dist/ui/elements/tabs.d.ts +12 -0
  225. package/dist/ui/elements/tabs.js +16 -0
  226. package/dist/ui/elements/tabs.works.d.ts +25 -0
  227. package/dist/ui/elements/tabs.works.js +53 -0
  228. package/dist/ui/elements/text.d.ts +13 -0
  229. package/dist/ui/elements/text.js +9 -0
  230. package/dist/ui/elements/textarea.d.ts +14 -0
  231. package/dist/ui/elements/textarea.js +11 -0
  232. package/dist/ui/elements/textarea.works.d.ts +4 -0
  233. package/dist/ui/elements/textarea.works.js +3 -0
  234. package/dist/ui/elements/time.d.ts +11 -0
  235. package/dist/ui/elements/time.js +14 -0
  236. package/dist/ui/elements/time.works.d.ts +11 -0
  237. package/dist/ui/elements/time.works.js +16 -0
  238. package/dist/ui/elements/toggle.d.ts +11 -0
  239. package/dist/ui/elements/toggle.js +10 -0
  240. package/dist/ui/elements/toggle.works.d.ts +4 -0
  241. package/dist/ui/elements/toggle.works.js +3 -0
  242. package/dist/ui/elements/tooltip.d.ts +12 -0
  243. package/dist/ui/elements/tooltip.js +15 -0
  244. package/dist/ui/elements/tooltip.works.d.ts +28 -0
  245. package/dist/ui/elements/tooltip.works.js +54 -0
  246. package/dist/ui/elements/value.d.ts +12 -0
  247. package/dist/ui/elements/value.js +9 -0
  248. package/dist/ui/elements/value.works.d.ts +4 -0
  249. package/dist/ui/elements/value.works.js +4 -0
  250. package/dist/ui/elements.d.ts +1143 -0
  251. package/dist/ui/elements.js +68 -0
  252. package/dist/ui/focus-scope.d.ts +7 -0
  253. package/dist/ui/focus-scope.js +109 -0
  254. package/dist/ui/fonts.d.ts +103 -0
  255. package/dist/ui/fonts.js +243 -0
  256. package/dist/ui/generators/dev.d.ts +2 -0
  257. package/dist/ui/generators/dev.js +61 -0
  258. package/dist/ui/generators/elements.d.ts +31 -0
  259. package/dist/ui/generators/elements.js +520 -0
  260. package/dist/ui/generators/i18n.d.ts +5 -0
  261. package/dist/ui/generators/i18n.js +264 -0
  262. package/dist/ui/generators/icons.d.ts +1 -0
  263. package/dist/ui/generators/icons.js +187 -0
  264. package/dist/ui/generators/react.d.ts +26 -0
  265. package/dist/ui/generators/react.js +218 -0
  266. package/dist/ui/generators/routes.d.ts +11 -0
  267. package/dist/ui/generators/routes.js +597 -0
  268. package/dist/ui/generators/show.d.ts +1 -0
  269. package/dist/ui/generators/show.js +231 -0
  270. package/dist/ui/generators/styles.d.ts +1 -0
  271. package/dist/ui/generators/styles.js +502 -0
  272. package/dist/ui/generators/variants.d.ts +12 -0
  273. package/dist/ui/generators/variants.js +162 -0
  274. package/dist/ui/i18n/catalogs/en.d.ts +172 -0
  275. package/dist/ui/i18n/catalogs/en.js +148 -0
  276. package/dist/ui/i18n/format.d.ts +13 -0
  277. package/dist/ui/i18n/format.js +161 -0
  278. package/dist/ui/i18n/locales.d.ts +9 -0
  279. package/dist/ui/i18n/locales.js +20 -0
  280. package/dist/ui/i18n/parse.d.ts +45 -0
  281. package/dist/ui/i18n/parse.js +249 -0
  282. package/dist/ui/i18n/translator.d.ts +10 -0
  283. package/dist/ui/i18n/translator.js +22 -0
  284. package/dist/ui/i18n/types.d.ts +33 -0
  285. package/dist/ui/i18n/types.js +9 -0
  286. package/dist/ui/icons.d.ts +67 -0
  287. package/dist/ui/icons.js +249 -0
  288. package/dist/ui/islands/map.d.ts +33 -0
  289. package/dist/ui/islands/map.js +44 -0
  290. package/dist/ui/localizations.d.ts +33 -0
  291. package/dist/ui/localizations.js +51 -0
  292. package/dist/ui/makers/message.d.ts +1 -0
  293. package/dist/ui/makers/message.js +230 -0
  294. package/dist/ui/material.d.ts +83 -0
  295. package/dist/ui/material.js +95 -0
  296. package/dist/ui/materials/mat_bordered.d.ts +22 -0
  297. package/dist/ui/materials/mat_bordered.js +12 -0
  298. package/dist/ui/materials/mat_ceramic.d.ts +22 -0
  299. package/dist/ui/materials/mat_ceramic.js +12 -0
  300. package/dist/ui/materials/mat_clay.d.ts +22 -0
  301. package/dist/ui/materials/mat_clay.js +12 -0
  302. package/dist/ui/materials/mat_elevated.d.ts +32 -0
  303. package/dist/ui/materials/mat_elevated.js +23 -0
  304. package/dist/ui/materials/mat_flat.d.ts +50 -0
  305. package/dist/ui/materials/mat_flat.js +33 -0
  306. package/dist/ui/materials/mat_glass.d.ts +32 -0
  307. package/dist/ui/materials/mat_glass.js +19 -0
  308. package/dist/ui/materials/mat_lit.d.ts +22 -0
  309. package/dist/ui/materials/mat_lit.js +12 -0
  310. package/dist/ui/materials/mat_moulded.d.ts +16 -0
  311. package/dist/ui/materials/mat_moulded.js +10 -0
  312. package/dist/ui/materials.d.ts +56 -0
  313. package/dist/ui/materials.js +175 -0
  314. package/dist/ui/modes.d.ts +25 -0
  315. package/dist/ui/modes.js +25 -0
  316. package/dist/ui/navigation.d.ts +3 -0
  317. package/dist/ui/navigation.js +24 -0
  318. package/dist/ui/positioning.d.ts +24 -0
  319. package/dist/ui/positioning.js +48 -0
  320. package/dist/ui/presented.d.ts +10 -0
  321. package/dist/ui/presented.js +81 -0
  322. package/dist/ui/provider.d.ts +31 -0
  323. package/dist/ui/provider.js +104 -0
  324. package/dist/ui/render-loop.d.ts +12 -0
  325. package/dist/ui/render-loop.js +94 -0
  326. package/dist/ui/roving-focus.d.ts +15 -0
  327. package/dist/ui/roving-focus.js +143 -0
  328. package/dist/ui/screens.d.ts +17 -0
  329. package/dist/ui/screens.js +112 -0
  330. package/dist/ui/scroll-lock.d.ts +2 -0
  331. package/dist/ui/scroll-lock.js +24 -0
  332. package/dist/ui/series.d.ts +9 -0
  333. package/dist/ui/series.js +67 -0
  334. package/dist/ui/signals.d.ts +120 -0
  335. package/dist/ui/signals.js +286 -0
  336. package/dist/ui/styleguide.d.ts +27 -0
  337. package/dist/ui/styleguide.js +138 -0
  338. package/dist/ui/styleguides.d.ts +11 -0
  339. package/dist/ui/styleguides.js +299 -0
  340. package/dist/ui/themes.d.ts +5 -0
  341. package/dist/ui/themes.js +16 -0
  342. package/dist/ui/token.d.ts +16 -0
  343. package/dist/ui/token.js +37 -0
  344. package/dist/ui/tokens/shadow.d.ts +6 -0
  345. package/dist/ui/tokens/shadow.js +17 -0
  346. package/dist/ui/tokens.d.ts +180 -0
  347. package/dist/ui/tokens.js +200 -0
  348. package/dist/ui/validators.d.ts +37 -0
  349. package/dist/ui/validators.js +184 -0
  350. package/dist/ui/variant.d.ts +122 -0
  351. package/dist/ui/variant.js +201 -0
  352. package/dist/ui/variants/var_avatar-round.d.ts +23 -0
  353. package/dist/ui/variants/var_avatar-round.js +13 -0
  354. package/dist/ui/variants/var_bubble-me.d.ts +21 -0
  355. package/dist/ui/variants/var_bubble-me.js +13 -0
  356. package/dist/ui/variants/var_bubble-them.d.ts +18 -0
  357. package/dist/ui/variants/var_bubble-them.js +12 -0
  358. package/dist/ui/variants/var_button-border.d.ts +116 -0
  359. package/dist/ui/variants/var_button-border.js +75 -0
  360. package/dist/ui/variants/var_button-cta.d.ts +116 -0
  361. package/dist/ui/variants/var_button-cta.js +75 -0
  362. package/dist/ui/variants/var_button-destructive-ghost.d.ts +113 -0
  363. package/dist/ui/variants/var_button-destructive-ghost.js +71 -0
  364. package/dist/ui/variants/var_button-destructive.d.ts +116 -0
  365. package/dist/ui/variants/var_button-destructive.js +75 -0
  366. package/dist/ui/variants/var_button-fill.d.ts +116 -0
  367. package/dist/ui/variants/var_button-fill.js +75 -0
  368. package/dist/ui/variants/var_button-ghost.d.ts +113 -0
  369. package/dist/ui/variants/var_button-ghost.js +71 -0
  370. package/dist/ui/variants/var_button-glass.d.ts +84 -0
  371. package/dist/ui/variants/var_button-glass.js +54 -0
  372. package/dist/ui/variants/var_button-normal.d.ts +116 -0
  373. package/dist/ui/variants/var_button-normal.js +75 -0
  374. package/dist/ui/variants/var_button-quiet.d.ts +119 -0
  375. package/dist/ui/variants/var_button-quiet.js +73 -0
  376. package/dist/ui/variants/var_card.d.ts +30 -0
  377. package/dist/ui/variants/var_card.js +16 -0
  378. package/dist/ui/variants/var_chip.d.ts +18 -0
  379. package/dist/ui/variants/var_chip.js +12 -0
  380. package/dist/ui/variants/var_choice.d.ts +26 -0
  381. package/dist/ui/variants/var_choice.js +14 -0
  382. package/dist/ui/variants/var_framed.d.ts +11 -0
  383. package/dist/ui/variants/var_framed.js +9 -0
  384. package/dist/ui/variants/var_glyph-plain.d.ts +14 -0
  385. package/dist/ui/variants/var_glyph-plain.js +10 -0
  386. package/dist/ui/variants/var_input.d.ts +61 -0
  387. package/dist/ui/variants/var_input.js +42 -0
  388. package/dist/ui/variants/var_link-inline.d.ts +39 -0
  389. package/dist/ui/variants/var_link-inline.js +28 -0
  390. package/dist/ui/variants/var_list-row.d.ts +47 -0
  391. package/dist/ui/variants/var_list-row.js +33 -0
  392. package/dist/ui/variants/var_rule.d.ts +11 -0
  393. package/dist/ui/variants/var_rule.js +9 -0
  394. package/dist/ui/variants/var_skeleton-block.d.ts +17 -0
  395. package/dist/ui/variants/var_skeleton-block.js +11 -0
  396. package/dist/ui/variants/var_spinner-turning.d.ts +17 -0
  397. package/dist/ui/variants/var_spinner-turning.js +11 -0
  398. package/dist/ui/variants/var_stat-tile.d.ts +18 -0
  399. package/dist/ui/variants/var_stat-tile.js +12 -0
  400. package/dist/ui/variants/var_tab-bar.d.ts +24 -0
  401. package/dist/ui/variants/var_tab-bar.js +14 -0
  402. package/dist/ui/variants/var_tap-target.d.ts +33 -0
  403. package/dist/ui/variants/var_tap-target.js +24 -0
  404. package/dist/ui/variants.d.ts +174 -0
  405. package/dist/ui/variants.js +50 -0
  406. package/dist/ui/wrappers.d.ts +128 -0
  407. package/dist/ui/wrappers.js +220 -0
  408. package/package.json +16 -0
@@ -0,0 +1,502 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
10
+ import { dirname, join, resolve } from 'node:path';
11
+ import { argv, stderr, stdout } from 'node:process';
12
+ import { fileURLToPath, pathToFileURL } from 'node:url';
13
+ import { exit } from "@prestack/thread/core/invoked";
14
+ import { named as packageOf } from "@prestack/thread/core/scope";
15
+ import { findTree, inTree } from "@prestack/thread/core/tree";
16
+ import { keyframeName, shorthandOf, stopsOf } from "../animations.js";
17
+ import { classOfRole, familyFor, fontStack, fontVariable, setNamed, settingsOf } from "../fonts.js";
18
+ import { sizeNamed, sizeRows, SIZE_PREFIX } from "../icons.js";
19
+ import { compose, keyframesOf } from "../material.js";
20
+ import { checkInteractions, knowSignals } from "../signals.js";
21
+ import { chosen, shifted, themedBy } from "../styleguide.js";
22
+ import { naming, nameOf, sheeted } from "../token.js";
23
+ import { classOf, classOfComposition, classOfElement, classOfScreen, complete, statesOf, structural, under, undeclaredStates, unreacted, boundHeld } from "../variant.js";
24
+ function inside(node) {
25
+ return [...(node.holds ?? []), ...(node.declares ?? [])];
26
+ }
27
+ const LAYERS = ['token', 'font', 'animation', 'material', 'element', 'variant', 'composition', 'screen'];
28
+ const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
29
+ const exported = (id) => id.replace(/-/g, '_').toUpperCase();
30
+ function dashed(property) {
31
+ return property.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
32
+ }
33
+ function block(selector, made, indent) {
34
+ const properties = Object.keys(made).sort(compare);
35
+ if (properties.length === 0)
36
+ return [];
37
+ const lines = [`${indent}${selector} {`];
38
+ for (const property of properties)
39
+ lines.push(`${indent} ${dashed(property)}: ${made[property] ?? ''};`);
40
+ lines.push(`${indent}}`, '');
41
+ return lines;
42
+ }
43
+ function sheet(tokens, guide, materials, variants, modes, themes, screens, compositions, elements, fonts, icons, animations) {
44
+ const wrong = checkInteractions()[0];
45
+ if (wrong !== undefined)
46
+ throw new Error(`${wrong.path}: ${wrong.message}`);
47
+ const sizes = sizeRows(inside(icons));
48
+ if (sizes.length === 0) {
49
+ throw new Error('The icons sheet declares no size row, so nothing says how large a symbol is drawn. The style ' +
50
+ 'guide holds no icon size — one row per size in `icons.ts`, holding a length.');
51
+ }
52
+ const values = { ...chosen(guide, tokens), ...Object.fromEntries(sizes.map((one) => [one.id, sheeted(one.id, one.is)])) };
53
+ const named = new Set(Object.keys(values));
54
+ const themeIds = new Set(themes.map((theme) => theme.id));
55
+ const kinds = {};
56
+ for (const pick of guide.picks)
57
+ kinds[pick.id] = pick.token;
58
+ for (const size of sizes)
59
+ kinds[size.id] = 'icon';
60
+ const played = (made) => {
61
+ const out = {};
62
+ for (const [id, value] of Object.entries(made)) {
63
+ if (kinds[id] !== 'animation') {
64
+ out[id] = value;
65
+ continue;
66
+ }
67
+ const animation = animations[value];
68
+ if (animation === undefined) {
69
+ const has = Object.keys(animations).sort().map((one) => `\`${one}\``);
70
+ throw new Error(`\`${id}\` names the animation \`${value}\`, and no row declares one by that name. ` +
71
+ (has.length === 0
72
+ ? 'The app declares no animations.'
73
+ : `The declared animations are ${has.join(', ')}.`));
74
+ }
75
+ out[id] = sheeted(value, shorthandOf(animation, named));
76
+ }
77
+ return out;
78
+ };
79
+ const variables = (made, selector, indent) => {
80
+ const names = Object.keys(made).sort(compare);
81
+ if (names.length === 0)
82
+ return [];
83
+ const held = [`${indent}${selector} {`];
84
+ for (const id of names)
85
+ held.push(`${indent} ${nameOf(id)}: ${made[id] ?? ''};`);
86
+ held.push(`${indent}}`, '');
87
+ return held;
88
+ };
89
+ const lines = [
90
+ '/* GENERATED by thread — do not edit. Change the declarations and regenerate. */',
91
+ '',
92
+ `@layer ${LAYERS.join(', ')};`,
93
+ '',
94
+ '@layer token {',
95
+ ...variables(played(values), ':root', ' '),
96
+ ];
97
+ for (const mode of modes) {
98
+ const held = variables(played(shifted(guide, tokens, mode.id, undefined, themeIds)), ':root', ' ');
99
+ if (held.length === 0)
100
+ continue;
101
+ lines.push(` @media ${mode.is} {`, ...held, ' }', '');
102
+ }
103
+ for (const theme of themes) {
104
+ lines.push(...variables(played(shifted(guide, tokens, undefined, theme.id, themeIds)), themedBy(theme.id), ' '));
105
+ for (const mode of modes) {
106
+ const held = variables(played(shifted(guide, tokens, mode.id, theme.id, themeIds)), themedBy(theme.id), ' ');
107
+ if (held.length === 0)
108
+ continue;
109
+ lines.push(` @media ${mode.is} {`, ...held, ' }', '');
110
+ }
111
+ }
112
+ const asked = modes.map((mode) => mode.id).join(' ');
113
+ lines.push(...(asked === '' ? [] : [' :root {', ` color-scheme: ${asked};`, ' }', '']), ' body {', ' background: var(--colour-page);', ' color: var(--colour-ink);', ' }', '');
114
+ lines.push('}', '');
115
+ const type = typography(fonts);
116
+ lines.push('@layer font {', ...type.lines, '}', '');
117
+ lines.push('@layer animation {');
118
+ for (const id of Object.keys(animations).sort(compare)) {
119
+ const animation = animations[id];
120
+ if (animation === undefined)
121
+ continue;
122
+ lines.push(` @keyframes ${keyframeName(id)} {`);
123
+ for (const stop of stopsOf(animation, named, tokens, kinds))
124
+ lines.push(...block(stop.stop, stop.made, ' '));
125
+ lines.push(' }', '');
126
+ }
127
+ lines.push('}', '');
128
+ const moving = new Map();
129
+ for (const id of Object.keys(materials).sort(compare)) {
130
+ const material = materials[id];
131
+ if (material === undefined)
132
+ continue;
133
+ for (const one of keyframesOf(material, named, tokens, kinds)) {
134
+ const already = moving.get(one.id);
135
+ if (already !== undefined) {
136
+ throw new Error(`\`${id}\` and \`${already.by}\` both declare keyframes called \`${one.id}\`, and a ` +
137
+ 'stylesheet holds one rule per name, so whichever came last would silently win.');
138
+ }
139
+ moving.set(one.id, { by: id, stops: one.stops });
140
+ }
141
+ }
142
+ lines.push('@layer material {');
143
+ for (const name of [...moving.keys()].sort(compare)) {
144
+ lines.push(` @keyframes ${name} {`);
145
+ for (const stop of moving.get(name)?.stops ?? [])
146
+ lines.push(...block(stop.stop, stop.made, ' '));
147
+ lines.push(' }', '');
148
+ }
149
+ for (const id of Object.keys(materials).sort(compare)) {
150
+ const material = materials[id];
151
+ if (material === undefined)
152
+ continue;
153
+ const gap = undeclaredStates(material)[0];
154
+ if (gap !== undefined)
155
+ throw new Error(`\`${id}\`: ${gap}`);
156
+ compose(material, named, tokens, kinds);
157
+ under(material, named, tokens, kinds);
158
+ }
159
+ lines.push('}', '');
160
+ lines.push('@layer variant {');
161
+ for (const id of Object.keys(variants).sort(compare)) {
162
+ const variant = variants[id];
163
+ if (variant === undefined)
164
+ continue;
165
+ const whole = statesOf(variant, materials);
166
+ const first = undeclaredStates(whole)[0];
167
+ if (first !== undefined)
168
+ throw new Error(`\`${id}\`: ${first}`);
169
+ const unclaimed = unreacted(variant, materials)[0];
170
+ if (unclaimed !== undefined)
171
+ throw new Error(unclaimed);
172
+ let typed = {};
173
+ if (variant.type !== undefined) {
174
+ const role = type.roles.get(variant.type);
175
+ if (role === undefined) {
176
+ const has = [...type.roles.keys()].sort(compare).map((one) => `\`${one}\``);
177
+ throw new Error(`\`${id}\` sets its wording in the \`${variant.type}\` role, and the fonts sheet declares ` +
178
+ `no role by that name. The declared roles are ${has.join(', ')}.`);
179
+ }
180
+ typed = role;
181
+ }
182
+ const made = { ...typed, ...complete(variant, materials, named, tokens, kinds) };
183
+ lines.push(...block(`.${classOf(id)}`, made, ' '));
184
+ lines.push(...playing(`.${classOf(id)}`, variant.plays, named, id));
185
+ lines.push(...symbols(id, variant.icon, named, made['display'] !== undefined));
186
+ for (const state of under(whole, named, tokens, kinds)) {
187
+ lines.push(...block(`.${classOf(id)}${state.marks}`, state.made, ' '));
188
+ }
189
+ }
190
+ lines.push('}', '');
191
+ for (const held of [
192
+ { layer: 'element', named: classOfElement, rows: elements },
193
+ { layer: 'composition', named: classOfComposition, rows: compositions },
194
+ { layer: 'screen', named: classOfScreen, rows: screens },
195
+ ]) {
196
+ lines.push(`@layer ${held.layer} {`);
197
+ for (const row of [...held.rows].sort((one, two) => compare(one.id, two.id))) {
198
+ const selector = `.${held.named(row.id)}`;
199
+ lines.push(...block(selector, resolved(row.sets ?? {}, guide, row.id, row.measures), ' '));
200
+ lines.push(...playing(selector, row.plays, named, row.id));
201
+ for (const [id, made] of Object.entries(row.places ?? {})) {
202
+ if (!PLACE.test(id)) {
203
+ throw new Error(`\`${row.id}\` gives a place the name "${id}", and a place is named in the markup as \`at="${id}"\` ` +
204
+ 'and becomes part of a class, so it has to be lowercase words joined by dashes. Anything else ' +
205
+ 'produces a class the child can never match, and nothing would look wrong until you saw the screen.');
206
+ }
207
+ const looks = Object.fromEntries(Object.entries(made).filter(([key]) => !SAID.has(key)));
208
+ lines.push(...block(`${selector}-${id}`, resolved(looks, guide, `${row.id} place \`${id}\``, row.measures), ' '));
209
+ }
210
+ for (const [id, made] of Object.entries(row.modes ?? {})) {
211
+ if (typeof made === 'string')
212
+ continue;
213
+ const query = modes.find((one) => one.id === id)?.is;
214
+ if (query === undefined) {
215
+ throw new Error(`\`${row.id}\` arranges itself under "${id}", and no mode by that name is declared, so nothing ` +
216
+ 'can tell when it applies. A breakpoint is a mode — declare it beside dark and light, with the ' +
217
+ 'width as its query.');
218
+ }
219
+ lines.push(` @media ${query} {`, ...block(selector, resolved(made, guide, row.id), ' '), ' }', '');
220
+ }
221
+ }
222
+ lines.push('}', '');
223
+ }
224
+ return lines.join('\n');
225
+ }
226
+ const LAID = 'layout-flex';
227
+ const CENTRED = 'align-centre';
228
+ function symbols(id, size, named, laid) {
229
+ if (size === undefined)
230
+ return [];
231
+ const row = sizeNamed(size);
232
+ if (!named.has(row)) {
233
+ const has = [...named].filter((one) => one.startsWith(SIZE_PREFIX)).sort(compare).map((one) => `\`${one}\``);
234
+ throw new Error(`\`${id}\` draws the symbol inside it at \`${row}\`, and the icons sheet declares no size by ` +
235
+ `that name. The declared sizes are ${has.join(', ')}.`);
236
+ }
237
+ const drawn = naming(named, row, id, 'the size its symbol is drawn at');
238
+ const centred = laid || !named.has(LAID) || !named.has(CENTRED)
239
+ ? []
240
+ : block(`.${classOf(id)}`, {
241
+ display: naming(named, LAID, id, 'how what it holds is laid out'),
242
+ alignItems: naming(named, CENTRED, id, 'where its symbol sits across that'),
243
+ }, ' ');
244
+ return [
245
+ ...centred,
246
+ ...block(`.${classOf(id)} > svg`, { width: drawn, height: drawn, minWidth: drawn, minHeight: drawn }, ' '),
247
+ ];
248
+ }
249
+ function typography(node) {
250
+ const rows = inside(node);
251
+ const roles = new Map();
252
+ const picked = rows.find((row) => row.id === 'family-set');
253
+ if (picked?.is === undefined) {
254
+ throw new Error('The fonts sheet declares no `family-set` row, so nothing says which set of families the app ' +
255
+ 'draws from. One row, naming a registered set — every face is drawn from it.');
256
+ }
257
+ const set = setNamed(picked.is);
258
+ const faces = {};
259
+ const classes = [];
260
+ for (const row of rows) {
261
+ if (row.id === 'family-set')
262
+ continue;
263
+ if (row.sets === undefined) {
264
+ throw new Error(`\`${row.id}\` is declared a font role and states nothing about how it is set. A role names a ` +
265
+ 'face and states its size, weight, leading and tracking.');
266
+ }
267
+ const role = row.sets;
268
+ const family = familyFor(set, role.face, row.id);
269
+ faces[role.face] = fontStack(family);
270
+ const made = settingsOf(row.id, role);
271
+ roles.set(row.id, made);
272
+ classes.push(...block(`.${classOfRole(row.id)}`, made, ' '));
273
+ }
274
+ const held = [' :root {'];
275
+ for (const face of Object.keys(faces).sort(compare))
276
+ held.push(` ${fontVariable(face)}: ${faces[face] ?? ''};`);
277
+ held.push(' }', '');
278
+ return { lines: [...held, ...classes], roles };
279
+ }
280
+ function playing(selector, plays, named, by) {
281
+ const held = [];
282
+ for (const [moment, row, on] of [
283
+ ['in', plays?.in, `${selector}[data-arriving]`],
284
+ ['out', plays?.out, `${selector}[data-leaving]`],
285
+ ]) {
286
+ if (row === undefined)
287
+ continue;
288
+ if (!named.has(row)) {
289
+ throw new Error(`\`${by}\` plays \`${row}\` on the way ${moment}, and the style guide holds no row by that name. ` +
290
+ 'What a thing plays is a style guide value like any other — name a row, and the row names the animation.');
291
+ }
292
+ held.push(...block(on, { animation: naming(named, row, by, `what it plays on the way ${moment}`) }, ' '));
293
+ }
294
+ return held;
295
+ }
296
+ const PLACE = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
297
+ const SAID = structural;
298
+ const RAW = /\d\s*(px|rem|em|ch|vh|vw)\b|\d%|#[0-9a-fA-F]{3,8}\b|\brgba?\(|\bhsla?\(/;
299
+ function resolved(sets, guide, by, measures = []) {
300
+ const made = {};
301
+ const bound = boundHeld();
302
+ for (const [property, whole] of Object.entries(sets)) {
303
+ const words = whole.trim().split(/\s+/);
304
+ const held = [];
305
+ for (const value of words) {
306
+ if (measures.includes(value)) {
307
+ held.push(`var(--${value})`);
308
+ continue;
309
+ }
310
+ if (RAW.test(value)) {
311
+ throw new Error(`\`${by}\` sets ${property} to "${value}", and that is a value written where a name belongs. ` +
312
+ 'An arrangement names a style guide row and the row holds the value — so the whole app moves ' +
313
+ 'when the row moves. Add a row for it, or name one that exists.');
314
+ }
315
+ const row = guide.picks.find((one) => one.id === value);
316
+ if (row === undefined) {
317
+ throw new Error(`\`${by}\` sets ${property} to "${value}", and that names neither a style guide row nor one ` +
318
+ "of this element's measures. A name that is neither is written into the stylesheet as-is " +
319
+ 'and thrown away by the browser. Declare it in `measures`, or name a row.');
320
+ }
321
+ const kinds = bound[property];
322
+ if (kinds !== undefined && !kinds.includes(String(row.token))) {
323
+ throw new Error(`\`${by}\` sets ${property} to \`${value}\`, which is a \`${String(row.token)}\` row. ` +
324
+ `${property} takes ${kinds.map((one) => `\`${one}\``).join(' or ')}. A row of the wrong kind ` +
325
+ 'is written into the stylesheet and dropped by the browser without a word.');
326
+ }
327
+ held.push(`var(--${value})`);
328
+ }
329
+ made[property] = sheeted(whole, held.join(' '));
330
+ }
331
+ return made;
332
+ }
333
+ async function fileFor(root, at, id, what) {
334
+ const module = (await import(__rewriteRelativeImportExtension(pathToFileURL(resolve(root, at)).href)));
335
+ const one = module[exported(id)];
336
+ if (one === undefined) {
337
+ throw new Error(`${what} \`${id}\` is declared at ${at}, and that file exports no \`${exported(id)}\`. ` +
338
+ 'A row names a file, and the file is the thing.');
339
+ }
340
+ return one;
341
+ }
342
+ async function loaded(root, node, what) {
343
+ const found = {};
344
+ for (const row of inside(node)) {
345
+ if (row.at === undefined) {
346
+ throw new Error(`${what} \`${row.id}\` names no file, so there is nothing to read it from.`);
347
+ }
348
+ found[row.id] = await fileFor(root, row.at, row.id, what);
349
+ }
350
+ return found;
351
+ }
352
+ async function tokensIn(root, node) {
353
+ const found = {};
354
+ for (const row of inside(node)) {
355
+ found[row.id] =
356
+ row.at === undefined || row.at === node.at
357
+ ? { id: row.id }
358
+ : await fileFor(root, row.at, row.id, 'token');
359
+ }
360
+ return found;
361
+ }
362
+ function guideIn(node) {
363
+ return {
364
+ id: node.id ?? 'styleguide',
365
+ picks: inside(node).map((row) => {
366
+ if (row.token === undefined) {
367
+ throw new Error(`\`${row.id}\` names no token. A style guide row is one value OF a token, so it has to ` +
368
+ 'say which token it is one of.');
369
+ }
370
+ return {
371
+ id: row.id,
372
+ token: row.token,
373
+ ...(row.is === undefined ? {} : { is: row.is }),
374
+ ...(row.asks === undefined ? {} : { asks: row.asks }),
375
+ ...(row.modes === undefined
376
+ ? {}
377
+ : {
378
+ modes: Object.fromEntries(Object.entries(row.modes).filter((one) => typeof one[1] === 'string')),
379
+ }),
380
+ ...(row.themes === undefined ? {} : { themes: row.themes }),
381
+ };
382
+ }),
383
+ };
384
+ }
385
+ function pascal(id) {
386
+ return id
387
+ .split('-')
388
+ .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
389
+ .join('');
390
+ }
391
+ function unwearable(variants, elements) {
392
+ const declared = new Set((elements.declares ?? []).map((row) => pascal(row.id)));
393
+ const missing = [];
394
+ for (const row of variants.declares ?? []) {
395
+ for (const element of row.wears ?? []) {
396
+ if (declared.has(element))
397
+ continue;
398
+ missing.push(`\`${row.id}\` says \`${element}\` accepts it, and no element by that name is declared, ` +
399
+ 'so nothing would ever wear it.');
400
+ }
401
+ }
402
+ return missing;
403
+ }
404
+ function modesIn(node) {
405
+ return inside(node).map((row) => {
406
+ if (row.is === undefined) {
407
+ throw new Error(`\`${row.id}\` is declared a mode and states no query, so nothing could tell when it applies. ` +
408
+ 'A mode is the question a device asks — give it the media query that answers it.');
409
+ }
410
+ return { id: row.id, is: row.is };
411
+ });
412
+ }
413
+ const OWN_AT = '../..';
414
+ async function node(root, file, name) {
415
+ const own = argv.includes('--own');
416
+ const at = own ? resolve(fileURLToPath(import.meta.url), OWN_AT, file) : inTree(findTree(), file);
417
+ if (!own && !existsSync(at)) {
418
+ stdout.write(`styles: this tree has no ${findTree().name}/${file}, so it declares nothing to style and there is no stylesheet to write or check.\n`);
419
+ exit(0);
420
+ }
421
+ const module = (await import(__rewriteRelativeImportExtension(pathToFileURL(at).href)));
422
+ const one = module[own ? `${name}S` : name];
423
+ if (one === undefined) {
424
+ throw new Error(own ? `this package's own ${file} exports no \`${name}S\`.` : `_threads/${file} exports no \`${name}\`.`);
425
+ }
426
+ return one;
427
+ }
428
+ async function run() {
429
+ const own = argv.includes('--own');
430
+ const root = own ? resolve(fileURLToPath(import.meta.url), '../../../../..') : findTree().at;
431
+ knowSignals(inside(await node(root, 'signals.ts', 'SIGNAL')).map((one) => one.id));
432
+ const tokens = await tokensIn(root, await node(root, 'tokens.ts', 'TOKEN'));
433
+ const guide = guideIn(await node(root, 'styleguides.ts', 'STYLEGUIDE'));
434
+ const materials = await loaded(root, await node(root, 'materials.ts', 'MATERIAL'), 'material');
435
+ const declaring = await node(root, 'variants.ts', 'VARIANT');
436
+ const variants = await loaded(root, declaring, 'variant');
437
+ const unworn = unwearable(declaring, await node(root, 'elements.ts', 'ELEMENT'))[0];
438
+ if (unworn !== undefined)
439
+ throw new Error(unworn);
440
+ const fonts = await node(root, 'fonts.ts', 'FONT');
441
+ const icons = await node(root, `icons.${'ts'}`, 'ICON');
442
+ const animations = await loaded(root, await node(root, 'animations.ts', 'ANIMATION'), 'animation');
443
+ const modes = modesIn(await node(root, 'modes.ts', 'MODE'));
444
+ const themes = inside(await node(root, 'themes.ts', 'THEME'));
445
+ const screens = (await node(root, 'screens.ts', 'SCREEN')).declares ?? [];
446
+ const compositions = (await node(root, 'compositions.ts', 'COMPOSITION')).declares ?? [];
447
+ const elements = ((await node(root, 'elements.ts', 'ELEMENT')).declares ?? []).filter((one) => one.sets !== undefined || one.places !== undefined);
448
+ const camelOf = (id) => id.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
449
+ const worn = (declaring.declares ?? [])
450
+ .filter((one) => typeof one.id === 'string' && (one.wears ?? []).length > 0)
451
+ .map((one) => ` readonly ${camelOf(String(one.id))}: ${(one.wears ?? []).map((e) => `'${e}'`).join(' | ')}`);
452
+ const asking = ((await node(root, 'signals.ts', 'SIGNAL')).holds ?? []).filter((one) => typeof one.id === 'string');
453
+ const wearingSource = [
454
+ '/* GENERATED by thread — do not edit. It is derived from what this app declares. */',
455
+ '',
456
+ `declare module '${packageOf('ui')}/checked' {`,
457
+ ...(worn.length === 0 ? [' interface Wearing {}'] : [' interface Wearing {', ...worn, ' }']),
458
+ '}',
459
+ '',
460
+ 'export const ASKING = [',
461
+ ...asking.map((one) => ` { id: '${String(one.id)}', selector: '${one.selector ?? `[data-${String(one.id)}]`}' },`),
462
+ '] as const',
463
+ '',
464
+ ].join('\n');
465
+ const at = join(root, 'app/_generated/tokens.css');
466
+ const made = sheet(tokens, guide, materials, variants, modes, themes, screens, compositions, elements, fonts, icons, animations);
467
+ if (own) {
468
+ stdout.write(`styles: this framework's own declarations build a stylesheet — ${String(guide.picks.length)} values, ` +
469
+ `${String(Object.keys(materials).length)} materials, ${String(Object.keys(variants).length)} variants, ` +
470
+ `${String(Object.keys(animations).length)} animations, every one naming rows that exist. ` +
471
+ 'Nothing is written: a stylesheet belongs to an app, and building it is the check.\n');
472
+ return 0;
473
+ }
474
+ if (argv.includes('--check')) {
475
+ let current = '';
476
+ try {
477
+ current = readFileSync(at, 'utf8');
478
+ }
479
+ catch {
480
+ current = '';
481
+ }
482
+ if (current === made) {
483
+ stdout.write('styles: app/_generated/tokens.css is the bytes the declarations produce\n');
484
+ return 0;
485
+ }
486
+ stderr.write('styles: app/_generated/tokens.css is not what the declarations produce. A derived file that ' +
487
+ 'differs from its generator is a hand edit wearing a generated name, and every reader downstream ' +
488
+ 'believes the wrong one. Run `thread styles` and commit what it writes.\n');
489
+ return 1;
490
+ }
491
+ mkdirSync(dirname(at), { recursive: true });
492
+ writeFileSync(at, made, 'utf8');
493
+ writeFileSync(join(root, 'app/_generated/declared.ts'), wearingSource, 'utf8');
494
+ stdout.write(`thread: wrote app/_generated/tokens.css — ${String(Object.keys(tokens).length)} tokens, ` +
495
+ `${String(guide.picks.length)} values, ${String(Object.keys(materials).length)} materials, ` +
496
+ `${String(Object.keys(variants).length)} variants, ${String(inside(fonts).length - 1)} font roles, ` +
497
+ `${String(Object.keys(animations).length)} animations, ${String(modes.length)} modes, ` +
498
+ `${String(themes.length)} themes, ${String(compositions.length)} compositions, ${String(screens.length)} screens\n`);
499
+ return 0;
500
+ }
501
+ if (argv[1] !== undefined)
502
+ exit(await run());
@@ -0,0 +1,12 @@
1
+ import type { Threaded } from '@prestack/thread/core/thread';
2
+ export declare function nameOf(id: string): string;
3
+ export declare function seeds(rows: readonly Threaded[], has: (at: string) => boolean): readonly {
4
+ readonly path: string;
5
+ readonly content: string;
6
+ }[];
7
+ export declare function mismatched(rows: readonly Threaded[], loader: (row: Threaded) => Promise<{
8
+ readonly id?: string;
9
+ } | undefined>): Promise<readonly string[]>;
10
+ export declare function orphaned(rows: readonly Threaded[], strays: readonly string[]): readonly string[];
11
+ export declare function unguarded(rows: readonly Threaded[], read: (at: string) => string): readonly string[];
12
+ export declare function guarding(source: string): string | undefined;
@@ -0,0 +1,162 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
10
+ import { basename, dirname, join, resolve } from 'node:path';
11
+ import { argv, stdout } from 'node:process';
12
+ import { fileURLToPath, pathToFileURL } from 'node:url';
13
+ import { exit, invoked } from "@prestack/thread/core/invoked";
14
+ import { findTree, inTree, strayFiles } from "@prestack/thread/core/tree";
15
+ export function nameOf(id) {
16
+ return id.replace(/-/g, '_').toUpperCase();
17
+ }
18
+ function starter(row) {
19
+ return `import { variant } from '../variant.ts'
20
+
21
+ export const ${nameOf(row.id)} = variant({
22
+ id: '${row.id}',
23
+ sets: [],
24
+ reacts: [],
25
+ } as const)
26
+ `;
27
+ }
28
+ export function seeds(rows, has) {
29
+ return rows.filter((row) => !has(row.at)).map((row) => ({ path: row.at, content: starter(row) }));
30
+ }
31
+ export async function mismatched(rows, loader) {
32
+ const found = [];
33
+ for (const row of rows) {
34
+ const variant = await loader(row);
35
+ if (variant === undefined) {
36
+ found.push(`\`${row.id}\` is declared at \`${row.at}\`, and that file exports no \`${nameOf(row.id)}\`. ` +
37
+ 'A row names a file, and the file is the thing.');
38
+ continue;
39
+ }
40
+ if (variant.id !== row.id) {
41
+ found.push(`\`${row.at}\` declares itself \`${String(variant.id)}\`, and the row that names it calls it \`${row.id}\`. ` +
42
+ "A variant file and the row that names it have to be the same variant — make the file's `id` match the row, or fix the row.");
43
+ }
44
+ }
45
+ return found;
46
+ }
47
+ function extensionOf(path) {
48
+ const name = basename(path);
49
+ const at = name.lastIndexOf('.');
50
+ return at === -1 ? '' : name.slice(at);
51
+ }
52
+ const VAR_PREFIX = /^var_/;
53
+ export function orphaned(rows, strays) {
54
+ const named = new Set(rows.map((row) => row.at));
55
+ return strays
56
+ .filter((one) => !named.has(one))
57
+ .map((one) => `\`${one}\` is under variants and no row names it — not a variant, a file somebody wrote. ` +
58
+ 'Add a row for it, or delete the file.');
59
+ }
60
+ const GUARDED = /=\s*variant\s*\(/;
61
+ const TYPED = /import type \{ Variant \} from '([^']*)'/;
62
+ const OPENS = /export const ([A-Z0-9_]+) = \{/;
63
+ const CLOSES = /\} as const satisfies Variant/;
64
+ export function unguarded(rows, read) {
65
+ return rows
66
+ .filter((row) => !GUARDED.test(read(row.at)))
67
+ .map((row) => `\`${row.at}\` declares \`${row.id}\` with \`satisfies Variant\`, which accepts a value no ` +
68
+ 'row holds — `satisfies` checks against `string`, so `8px` and `var(--x)` compile. Run ' +
69
+ '`thread variants` and it rewrites the two lines that wrap the declaration, leaving what is ' +
70
+ 'between them alone.');
71
+ }
72
+ export function guarding(source) {
73
+ if (GUARDED.test(source))
74
+ return undefined;
75
+ const typed = TYPED.exec(source);
76
+ const opens = OPENS.exec(source);
77
+ if (typed === null || opens === null || !CLOSES.test(source))
78
+ return undefined;
79
+ return source
80
+ .replace(typed[0], `import { variant } from '${typed[1] ?? ''}'`)
81
+ .replace(opens[0], `export const ${opens[1] ?? ''} = variant({`)
82
+ .replace(CLOSES, '} as const)');
83
+ }
84
+ const SHEET = `variants.${'ts'}`;
85
+ const MINE = `variants.${'ts'}`;
86
+ async function run() {
87
+ const own = argv.includes('--own');
88
+ const held = own
89
+ ? (await import(__rewriteRelativeImportExtension(pathToFileURL(resolve(fileURLToPath(import.meta.url), '../..', MINE)).href)))
90
+ : undefined;
91
+ const tree = own ? undefined : findTree();
92
+ const root = tree === undefined ? resolve(fileURLToPath(import.meta.url), '../../../../..') : tree.at;
93
+ if (tree !== undefined && !existsSync(inTree(tree, SHEET))) {
94
+ stdout.write(`thread: this tree has no ${tree.name}/${SHEET}, so it declares no variant and there is nothing to seed or check.\n`);
95
+ return 0;
96
+ }
97
+ const sheet = tree === undefined
98
+ ? { VARIANT: held?.VARIANTS }
99
+ : (await import(__rewriteRelativeImportExtension(pathToFileURL(inTree(tree, SHEET)).href)));
100
+ if (sheet.VARIANT === undefined) {
101
+ stdout.write(own
102
+ ? `variants: this package's own ${MINE} exports no \`VARIANTS\`.\n`
103
+ : `thread: ${String(tree?.name)}/${SHEET} exports no \`VARIANT\`, so nothing declares a variant here.\n`);
104
+ return 1;
105
+ }
106
+ const rows = sheet.VARIANT.declares ?? [];
107
+ const checking = argv.includes('--check');
108
+ const exists = (where) => existsSync(join(root, where));
109
+ const made = seeds(rows, exists);
110
+ if (checking) {
111
+ const unseeded = rows.find((row) => !exists(row.at));
112
+ if (unseeded !== undefined) {
113
+ stdout.write(`thread: \`${unseeded.id}\` is declared at \`${unseeded.at}\`, and the file is not there yet. ` +
114
+ 'A row names a file, and `--check` never writes one — run `thread variants` and commit what it seeds.\n');
115
+ return 1;
116
+ }
117
+ }
118
+ else {
119
+ for (const seed of made) {
120
+ mkdirSync(dirname(join(root, seed.path)), { recursive: true });
121
+ writeFileSync(join(root, seed.path), seed.content, 'utf8');
122
+ stdout.write(`thread: seeded ${seed.path}\n`);
123
+ }
124
+ }
125
+ const wrong = (await mismatched(rows, async (row) => {
126
+ const module = (await import(__rewriteRelativeImportExtension(pathToFileURL(join(root, row.at)).href)));
127
+ return module[nameOf(row.id)];
128
+ }))[0];
129
+ if (wrong !== undefined) {
130
+ stdout.write(`thread: ${wrong}\n`);
131
+ return 1;
132
+ }
133
+ const read = (at) => readFileSync(join(root, at), 'utf8');
134
+ if (checking) {
135
+ const loose = unguarded(rows, read)[0];
136
+ if (loose !== undefined) {
137
+ stdout.write(`thread: ${loose}\n`);
138
+ return 1;
139
+ }
140
+ }
141
+ else {
142
+ for (const row of rows) {
143
+ const written = guarding(read(row.at));
144
+ if (written === undefined)
145
+ continue;
146
+ writeFileSync(join(root, row.at), written, 'utf8');
147
+ stdout.write(`thread: ${row.at} now declares through \`variant(...)\`\n`);
148
+ }
149
+ }
150
+ const stray = orphaned(rows, strayFiles(root, 'var_', '.' + 'ts'))[0];
151
+ if (stray !== undefined) {
152
+ stdout.write(`thread: ${stray}\n`);
153
+ return 1;
154
+ }
155
+ stdout.write(checking
156
+ ? `thread: ${String(rows.length)} variant(s) declared, all seeded\n`
157
+ : `thread: ${String(rows.length)} variant(s) declared, ${String(made.length)} seeded, ` +
158
+ `${String(rows.length - made.length)} already written\n`);
159
+ return 0;
160
+ }
161
+ if (invoked(import.meta.url))
162
+ exit(await run());