@prestack/thread-ui 0.1.1 → 0.1.2

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 (343) hide show
  1. package/CHANGELOG.md +174 -0
  2. package/dist/ui/animations/anm_appear.d.ts +8 -8
  3. package/dist/ui/animations/anm_blur_in.d.ts +12 -12
  4. package/dist/ui/animations/anm_blur_out.d.ts +12 -12
  5. package/dist/ui/animations/anm_dismiss.d.ts +12 -12
  6. package/dist/ui/animations/anm_drop.d.ts +12 -12
  7. package/dist/ui/animations/anm_fall.d.ts +12 -12
  8. package/dist/ui/animations/anm_flash.d.ts +9 -9
  9. package/dist/ui/animations/anm_glow.d.ts +8 -8
  10. package/dist/ui/animations/anm_lift.d.ts +8 -8
  11. package/dist/ui/animations/anm_nudge.d.ts +8 -8
  12. package/dist/ui/animations/anm_pop_in.d.ts +16 -16
  13. package/dist/ui/animations/anm_pop_out.d.ts +16 -16
  14. package/dist/ui/animations/anm_press.d.ts +9 -9
  15. package/dist/ui/animations/anm_pulse.d.ts +10 -10
  16. package/dist/ui/animations/anm_rise.d.ts +12 -12
  17. package/dist/ui/animations/anm_shake.d.ts +11 -11
  18. package/dist/ui/animations/anm_slide_in_left.d.ts +12 -12
  19. package/dist/ui/animations/anm_slide_in_right.d.ts +12 -12
  20. package/dist/ui/animations/anm_slide_out_left.d.ts +12 -12
  21. package/dist/ui/animations/anm_slide_out_right.d.ts +12 -12
  22. package/dist/ui/animations/anm_spin.d.ts +8 -8
  23. package/dist/ui/animations/anm_swell.d.ts +8 -8
  24. package/dist/ui/animations/anm_wobble.d.ts +13 -13
  25. package/dist/ui/animations/anm_zoom_in.d.ts +12 -12
  26. package/dist/ui/animations/anm_zoom_out.d.ts +12 -12
  27. package/dist/ui/animations.d.ts +8 -8
  28. package/dist/ui/animations.js +4 -4
  29. package/dist/ui/animations.ts +1 -1
  30. package/dist/ui/attach.js +22 -78
  31. package/dist/ui/attach.ts +8 -66
  32. package/dist/ui/charts.d.ts +0 -3
  33. package/dist/ui/charts.js +3 -7
  34. package/dist/ui/charts.tsx +0 -4
  35. package/dist/ui/checked.d.ts +1 -1
  36. package/dist/ui/checked.ts +1 -1
  37. package/dist/ui/collector.js +1 -1
  38. package/dist/ui/collector.ts +1 -1
  39. package/dist/ui/compositions.d.ts +9 -3
  40. package/dist/ui/compositions.js +9 -158
  41. package/dist/ui/compositions.ts +6 -170
  42. package/dist/ui/content.js +4 -7
  43. package/dist/ui/content.tsx +4 -15
  44. package/dist/ui/controls.js +1 -1
  45. package/dist/ui/door.d.ts +1 -1
  46. package/dist/ui/elements/accordion.d.ts +2 -1
  47. package/dist/ui/elements/accordion.js +4 -4
  48. package/dist/ui/elements/accordion.tsx +2 -1
  49. package/dist/ui/elements/aspect-ratio.d.ts +2 -1
  50. package/dist/ui/elements/aspect-ratio.js +1 -1
  51. package/dist/ui/elements/aspect-ratio.tsx +2 -1
  52. package/dist/ui/elements/avatar.d.ts +2 -1
  53. package/dist/ui/elements/avatar.js +3 -3
  54. package/dist/ui/elements/avatar.tsx +2 -1
  55. package/dist/ui/elements/badge.d.ts +2 -1
  56. package/dist/ui/elements/badge.js +3 -3
  57. package/dist/ui/elements/badge.tsx +2 -1
  58. package/dist/ui/elements/bars.d.ts +2 -1
  59. package/dist/ui/elements/bars.js +5 -5
  60. package/dist/ui/elements/bars.tsx +2 -1
  61. package/dist/ui/elements/bars.works.js +3 -3
  62. package/dist/ui/elements/box.d.ts +2 -1
  63. package/dist/ui/elements/box.js +1 -1
  64. package/dist/ui/elements/box.tsx +2 -1
  65. package/dist/ui/elements/breadcrumb.d.ts +2 -1
  66. package/dist/ui/elements/breadcrumb.js +5 -5
  67. package/dist/ui/elements/breadcrumb.tsx +2 -1
  68. package/dist/ui/elements/breadcrumb.works.js +1 -1
  69. package/dist/ui/elements/button.d.ts +2 -1
  70. package/dist/ui/elements/button.js +3 -3
  71. package/dist/ui/elements/button.tsx +2 -1
  72. package/dist/ui/elements/button.works.js +2 -2
  73. package/dist/ui/elements/column.d.ts +2 -1
  74. package/dist/ui/elements/column.js +1 -1
  75. package/dist/ui/elements/column.tsx +2 -1
  76. package/dist/ui/elements/consent.d.ts +2 -1
  77. package/dist/ui/elements/consent.js +10 -10
  78. package/dist/ui/elements/consent.tsx +2 -1
  79. package/dist/ui/elements/consent.works.js +1 -1
  80. package/dist/ui/elements/donut.d.ts +2 -1
  81. package/dist/ui/elements/donut.js +4 -4
  82. package/dist/ui/elements/donut.tsx +2 -1
  83. package/dist/ui/elements/donut.works.js +2 -2
  84. package/dist/ui/elements/each.d.ts +2 -1
  85. package/dist/ui/elements/each.js +3 -3
  86. package/dist/ui/elements/each.tsx +2 -1
  87. package/dist/ui/elements/each.works.js +2 -2
  88. package/dist/ui/elements/empty.d.ts +2 -1
  89. package/dist/ui/elements/empty.js +2 -2
  90. package/dist/ui/elements/empty.tsx +2 -1
  91. package/dist/ui/elements/field.d.ts +2 -1
  92. package/dist/ui/elements/field.js +3 -3
  93. package/dist/ui/elements/field.tsx +2 -1
  94. package/dist/ui/elements/field.works.js +1 -1
  95. package/dist/ui/elements/funnel.d.ts +2 -1
  96. package/dist/ui/elements/funnel.js +5 -5
  97. package/dist/ui/elements/funnel.tsx +2 -1
  98. package/dist/ui/elements/funnel.works.js +3 -3
  99. package/dist/ui/elements/gauge.d.ts +2 -1
  100. package/dist/ui/elements/gauge.js +3 -3
  101. package/dist/ui/elements/gauge.tsx +2 -1
  102. package/dist/ui/elements/gauge.works.js +1 -1
  103. package/dist/ui/elements/glyph.d.ts +2 -1
  104. package/dist/ui/elements/glyph.js +3 -3
  105. package/dist/ui/elements/glyph.tsx +2 -1
  106. package/dist/ui/elements/glyph.works.js +1 -1
  107. package/dist/ui/elements/grid.d.ts +2 -1
  108. package/dist/ui/elements/grid.js +1 -1
  109. package/dist/ui/elements/grid.tsx +2 -1
  110. package/dist/ui/elements/heatmap.d.ts +2 -1
  111. package/dist/ui/elements/heatmap.js +5 -5
  112. package/dist/ui/elements/heatmap.tsx +2 -1
  113. package/dist/ui/elements/heatmap.works.js +1 -1
  114. package/dist/ui/elements/hit-box.d.ts +2 -1
  115. package/dist/ui/elements/hit-box.js +2 -2
  116. package/dist/ui/elements/hit-box.tsx +2 -1
  117. package/dist/ui/elements/hit-box.works.d.ts +2 -2
  118. package/dist/ui/elements/hit-box.works.js +5 -5
  119. package/dist/ui/elements/hit-box.works.tsx +2 -1
  120. package/dist/ui/elements/image.d.ts +2 -1
  121. package/dist/ui/elements/image.js +2 -2
  122. package/dist/ui/elements/image.tsx +2 -1
  123. package/dist/ui/elements/line-chart.d.ts +2 -1
  124. package/dist/ui/elements/line-chart.js +4 -4
  125. package/dist/ui/elements/line-chart.tsx +2 -1
  126. package/dist/ui/elements/line-chart.works.js +2 -2
  127. package/dist/ui/elements/link.d.ts +2 -1
  128. package/dist/ui/elements/link.js +3 -3
  129. package/dist/ui/elements/link.tsx +2 -1
  130. package/dist/ui/elements/link.works.js +1 -1
  131. package/dist/ui/elements/media.d.ts +2 -1
  132. package/dist/ui/elements/media.js +2 -2
  133. package/dist/ui/elements/media.tsx +2 -1
  134. package/dist/ui/elements/menu.d.ts +2 -1
  135. package/dist/ui/elements/menu.js +5 -5
  136. package/dist/ui/elements/menu.tsx +2 -1
  137. package/dist/ui/elements/menu.works.d.ts +2 -1
  138. package/dist/ui/elements/menu.works.js +5 -5
  139. package/dist/ui/elements/menu.works.tsx +2 -1
  140. package/dist/ui/elements/money.d.ts +3 -1
  141. package/dist/ui/elements/money.js +10 -5
  142. package/dist/ui/elements/money.tsx +12 -3
  143. package/dist/ui/elements/money.works.js +1 -1
  144. package/dist/ui/elements/pagination.d.ts +2 -1
  145. package/dist/ui/elements/pagination.js +5 -5
  146. package/dist/ui/elements/pagination.tsx +2 -1
  147. package/dist/ui/elements/progress.d.ts +2 -1
  148. package/dist/ui/elements/progress.js +3 -3
  149. package/dist/ui/elements/progress.tsx +2 -1
  150. package/dist/ui/elements/radio-group.d.ts +2 -1
  151. package/dist/ui/elements/radio-group.js +4 -4
  152. package/dist/ui/elements/radio-group.tsx +2 -1
  153. package/dist/ui/elements/radio-group.works.js +1 -1
  154. package/dist/ui/elements/row.d.ts +2 -1
  155. package/dist/ui/elements/row.js +1 -1
  156. package/dist/ui/elements/row.tsx +2 -1
  157. package/dist/ui/elements/scatter.d.ts +2 -1
  158. package/dist/ui/elements/scatter.js +3 -3
  159. package/dist/ui/elements/scatter.tsx +2 -1
  160. package/dist/ui/elements/scatter.works.js +1 -1
  161. package/dist/ui/elements/select.d.ts +2 -1
  162. package/dist/ui/elements/select.js +4 -4
  163. package/dist/ui/elements/select.tsx +2 -1
  164. package/dist/ui/elements/separator.d.ts +2 -1
  165. package/dist/ui/elements/separator.js +2 -2
  166. package/dist/ui/elements/separator.tsx +2 -1
  167. package/dist/ui/elements/skeleton.d.ts +2 -1
  168. package/dist/ui/elements/skeleton.js +2 -2
  169. package/dist/ui/elements/skeleton.tsx +2 -1
  170. package/dist/ui/elements/slider.d.ts +2 -1
  171. package/dist/ui/elements/slider.js +3 -3
  172. package/dist/ui/elements/slider.tsx +2 -1
  173. package/dist/ui/elements/sparkline.d.ts +2 -1
  174. package/dist/ui/elements/sparkline.js +3 -3
  175. package/dist/ui/elements/sparkline.tsx +2 -1
  176. package/dist/ui/elements/sparkline.works.js +1 -1
  177. package/dist/ui/elements/spinner.d.ts +2 -1
  178. package/dist/ui/elements/spinner.js +2 -2
  179. package/dist/ui/elements/spinner.tsx +2 -1
  180. package/dist/ui/elements/stack.d.ts +2 -1
  181. package/dist/ui/elements/stack.js +1 -1
  182. package/dist/ui/elements/stack.tsx +2 -1
  183. package/dist/ui/elements/stat.d.ts +2 -1
  184. package/dist/ui/elements/stat.js +3 -3
  185. package/dist/ui/elements/stat.tsx +2 -1
  186. package/dist/ui/elements/stat.works.js +1 -1
  187. package/dist/ui/elements/surface.d.ts +2 -1
  188. package/dist/ui/elements/surface.js +2 -2
  189. package/dist/ui/elements/surface.tsx +2 -1
  190. package/dist/ui/elements/surface.works.js +1 -1
  191. package/dist/ui/elements/table.d.ts +2 -1
  192. package/dist/ui/elements/table.js +4 -4
  193. package/dist/ui/elements/table.tsx +2 -1
  194. package/dist/ui/elements/table.works.js +1 -1
  195. package/dist/ui/elements/tabs.d.ts +2 -1
  196. package/dist/ui/elements/tabs.js +4 -4
  197. package/dist/ui/elements/tabs.tsx +2 -1
  198. package/dist/ui/elements/tabs.works.js +1 -1
  199. package/dist/ui/elements/text.d.ts +2 -1
  200. package/dist/ui/elements/text.js +2 -2
  201. package/dist/ui/elements/text.tsx +2 -1
  202. package/dist/ui/elements/textarea.d.ts +2 -1
  203. package/dist/ui/elements/textarea.js +4 -4
  204. package/dist/ui/elements/textarea.tsx +2 -1
  205. package/dist/ui/elements/time.d.ts +3 -1
  206. package/dist/ui/elements/time.js +7 -4
  207. package/dist/ui/elements/time.tsx +9 -2
  208. package/dist/ui/elements/time.works.d.ts +1 -0
  209. package/dist/ui/elements/time.works.js +7 -3
  210. package/dist/ui/elements/time.works.ts +6 -2
  211. package/dist/ui/elements/toggle.d.ts +2 -1
  212. package/dist/ui/elements/toggle.js +3 -3
  213. package/dist/ui/elements/toggle.tsx +2 -1
  214. package/dist/ui/elements/tooltip.d.ts +2 -1
  215. package/dist/ui/elements/tooltip.js +2 -2
  216. package/dist/ui/elements/tooltip.tsx +2 -1
  217. package/dist/ui/elements/tooltip.works.js +2 -2
  218. package/dist/ui/elements/value.d.ts +3 -1
  219. package/dist/ui/elements/value.js +10 -5
  220. package/dist/ui/elements/value.tsx +12 -3
  221. package/dist/ui/elements/value.works.js +1 -1
  222. package/dist/ui/elements.d.ts +15 -11
  223. package/dist/ui/elements.js +6 -6
  224. package/dist/ui/elements.ts +7 -7
  225. package/dist/ui/fonts.d.ts +1 -1
  226. package/dist/ui/fonts.js +1 -1
  227. package/dist/ui/generators/dev.d.ts +1 -2
  228. package/dist/ui/generators/dev.js +33 -37
  229. package/dist/ui/generators/dev.ts +30 -37
  230. package/dist/ui/generators/elements.d.ts +1 -0
  231. package/dist/ui/generators/elements.js +11 -9
  232. package/dist/ui/generators/elements.ts +12 -9
  233. package/dist/ui/generators/i18n.js +6 -23
  234. package/dist/ui/generators/i18n.ts +1 -18
  235. package/dist/ui/generators/icons.js +5 -14
  236. package/dist/ui/generators/icons.ts +1 -10
  237. package/dist/ui/generators/react.js +4 -5
  238. package/dist/ui/generators/react.ts +2 -3
  239. package/dist/ui/generators/routes.js +66 -51
  240. package/dist/ui/generators/routes.ts +67 -46
  241. package/dist/ui/generators/show.js +9 -6
  242. package/dist/ui/generators/show.ts +4 -2
  243. package/dist/ui/generators/styles.js +12 -16
  244. package/dist/ui/generators/styles.ts +1 -5
  245. package/dist/ui/generators/variants.js +3 -3
  246. package/dist/ui/generators/variants.ts +1 -1
  247. package/dist/ui/i18n/catalogs/en.js +1 -1
  248. package/dist/ui/i18n/format.js +1 -1
  249. package/dist/ui/i18n/translator.js +2 -2
  250. package/dist/ui/material.d.ts +11 -11
  251. package/dist/ui/material.js +1 -1
  252. package/dist/ui/materials/mat_bordered.d.ts +13 -13
  253. package/dist/ui/materials/mat_bordered.js +1 -1
  254. package/dist/ui/materials/mat_ceramic.d.ts +13 -13
  255. package/dist/ui/materials/mat_ceramic.js +1 -1
  256. package/dist/ui/materials/mat_clay.d.ts +13 -13
  257. package/dist/ui/materials/mat_clay.js +1 -1
  258. package/dist/ui/materials/mat_elevated.d.ts +13 -13
  259. package/dist/ui/materials/mat_elevated.js +1 -1
  260. package/dist/ui/materials/mat_flat.d.ts +25 -25
  261. package/dist/ui/materials/mat_flat.js +1 -1
  262. package/dist/ui/materials/mat_glass.d.ts +17 -17
  263. package/dist/ui/materials/mat_glass.js +1 -1
  264. package/dist/ui/materials/mat_lit.d.ts +13 -13
  265. package/dist/ui/materials/mat_lit.js +1 -1
  266. package/dist/ui/materials/mat_moulded.d.ts +9 -9
  267. package/dist/ui/materials/mat_moulded.js +1 -1
  268. package/dist/ui/materials.d.ts +30 -30
  269. package/dist/ui/materials.js +3 -3
  270. package/dist/ui/materials.ts +1 -1
  271. package/dist/ui/modes.d.ts +2 -2
  272. package/dist/ui/presented.js +5 -5
  273. package/dist/ui/provider.d.ts +3 -0
  274. package/dist/ui/provider.js +9 -10
  275. package/dist/ui/provider.tsx +7 -5
  276. package/dist/ui/screens.js +6 -6
  277. package/dist/ui/screens.ts +1 -1
  278. package/dist/ui/scroll-lock.js +1 -1
  279. package/dist/ui/series.js +1 -1
  280. package/dist/ui/styleguide.js +1 -1
  281. package/dist/ui/tokens.d.ts +2 -2
  282. package/dist/ui/tokens.js +3 -3
  283. package/dist/ui/tokens.ts +1 -1
  284. package/dist/ui/validators.js +1 -1
  285. package/dist/ui/variant.d.ts +37 -37
  286. package/dist/ui/variant.js +2 -2
  287. package/dist/ui/variants/var_avatar-round.d.ts +13 -13
  288. package/dist/ui/variants/var_avatar-round.js +1 -1
  289. package/dist/ui/variants/var_bubble-me.d.ts +12 -12
  290. package/dist/ui/variants/var_bubble-me.js +1 -1
  291. package/dist/ui/variants/var_bubble-them.d.ts +10 -10
  292. package/dist/ui/variants/var_bubble-them.js +1 -1
  293. package/dist/ui/variants/var_button-border.d.ts +61 -61
  294. package/dist/ui/variants/var_button-border.js +1 -1
  295. package/dist/ui/variants/var_button-cta.d.ts +61 -61
  296. package/dist/ui/variants/var_button-cta.js +1 -1
  297. package/dist/ui/variants/var_button-destructive-ghost.d.ts +59 -59
  298. package/dist/ui/variants/var_button-destructive-ghost.js +1 -1
  299. package/dist/ui/variants/var_button-destructive.d.ts +61 -61
  300. package/dist/ui/variants/var_button-destructive.js +1 -1
  301. package/dist/ui/variants/var_button-fill.d.ts +61 -61
  302. package/dist/ui/variants/var_button-fill.js +1 -1
  303. package/dist/ui/variants/var_button-ghost.d.ts +59 -59
  304. package/dist/ui/variants/var_button-ghost.js +1 -1
  305. package/dist/ui/variants/var_button-glass.d.ts +40 -40
  306. package/dist/ui/variants/var_button-glass.js +1 -1
  307. package/dist/ui/variants/var_button-normal.d.ts +61 -61
  308. package/dist/ui/variants/var_button-normal.js +1 -1
  309. package/dist/ui/variants/var_button-quiet.d.ts +63 -63
  310. package/dist/ui/variants/var_button-quiet.js +1 -1
  311. package/dist/ui/variants/var_card.d.ts +17 -17
  312. package/dist/ui/variants/var_card.js +1 -1
  313. package/dist/ui/variants/var_chip.d.ts +10 -10
  314. package/dist/ui/variants/var_chip.js +1 -1
  315. package/dist/ui/variants/var_choice.d.ts +15 -15
  316. package/dist/ui/variants/var_choice.js +1 -1
  317. package/dist/ui/variants/var_framed.d.ts +5 -5
  318. package/dist/ui/variants/var_framed.js +1 -1
  319. package/dist/ui/variants/var_glyph-plain.d.ts +7 -7
  320. package/dist/ui/variants/var_glyph-plain.js +1 -1
  321. package/dist/ui/variants/var_input.d.ts +30 -30
  322. package/dist/ui/variants/var_input.js +1 -1
  323. package/dist/ui/variants/var_link-inline.d.ts +17 -17
  324. package/dist/ui/variants/var_link-inline.js +1 -1
  325. package/dist/ui/variants/var_list-row.d.ts +22 -22
  326. package/dist/ui/variants/var_list-row.js +1 -1
  327. package/dist/ui/variants/var_rule.d.ts +5 -5
  328. package/dist/ui/variants/var_rule.js +1 -1
  329. package/dist/ui/variants/var_skeleton-block.d.ts +9 -9
  330. package/dist/ui/variants/var_skeleton-block.js +1 -1
  331. package/dist/ui/variants/var_spinner-turning.d.ts +9 -9
  332. package/dist/ui/variants/var_spinner-turning.js +1 -1
  333. package/dist/ui/variants/var_stat-tile.d.ts +10 -10
  334. package/dist/ui/variants/var_stat-tile.js +1 -1
  335. package/dist/ui/variants/var_tab-bar.d.ts +14 -14
  336. package/dist/ui/variants/var_tab-bar.js +1 -1
  337. package/dist/ui/variants/var_tap-target.d.ts +11 -11
  338. package/dist/ui/variants/var_tap-target.js +1 -1
  339. package/dist/ui/variants.d.ts +88 -88
  340. package/dist/ui/wrappers.d.ts +7 -6
  341. package/dist/ui/wrappers.js +16 -14
  342. package/dist/ui/wrappers.tsx +21 -18
  343. package/package.json +2 -2
package/dist/ui/attach.js CHANGED
@@ -1,18 +1,18 @@
1
- import { named } from "@prestack/thread/core/scope";
2
- import { ANIMATIONS } from "./animations.js";
3
- import { COMPOSITIONS } from "./compositions.js";
4
- import { FONTS } from "./fonts.js";
5
- import { ICONS } from "./icons.js";
6
- import { LOCALIZATIONS } from "./localizations.js";
7
- import { ELEMENTS } from "./elements.js";
8
- import { MATERIALS } from "./materials.js";
9
- import { MODES } from "./modes.js";
10
- import { SCREENS } from "./screens.js";
11
- import { STYLEGUIDES } from "./styleguides.js";
12
- import { SIGNALS } from "./signals.js";
13
- import { THEMES } from "./themes.js";
14
- import { TOKENS } from "./tokens.js";
15
- import { VARIANTS } from "./variants.js";
1
+ import { named } from '@prestack/thread/core/scope';
2
+ import { ANIMATIONS } from './animations.js';
3
+ import { COMPOSITIONS } from './compositions.js';
4
+ import { FONTS } from './fonts.js';
5
+ import { ICONS } from './icons.js';
6
+ import { LOCALIZATIONS } from './localizations.js';
7
+ import { ELEMENTS } from './elements.js';
8
+ import { MATERIALS } from './materials.js';
9
+ import { MODES } from './modes.js';
10
+ import { SCREENS } from './screens.js';
11
+ import { STYLEGUIDES } from './styleguides.js';
12
+ import { SIGNALS } from './signals.js';
13
+ import { THEMES } from './themes.js';
14
+ import { TOKENS } from './tokens.js';
15
+ import { VARIANTS } from './variants.js';
16
16
  const SEEDED = {
17
17
  attaches: ['@prestack/thread'],
18
18
  id: 'ui',
@@ -48,19 +48,19 @@ const SHIPPED = [
48
48
  into: 'ui.ts',
49
49
  list: 'GENERATORS',
50
50
  id: 'i18n-generator',
51
- source: " {\n id: 'i18n-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/i18n.js',\n describes: 'The generator of an app\\'s wording — it reads the languages the app declares and every message key its interface names, and writes one file per language holding a line for each. It cannot invent a sentence, so a key it has just found arrives holding nothing; run with `--check`, the mode the gate runs it in, it writes nothing and refuses a language file that is not what the declarations produce, and refuses any key left unanswered. It also writes the module the app imports, which states the keys the interface uses as a type, so a language missing one is a compiler error before it is a gate error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n derives: [\n {\n id: 'wording',\n at: 'app/_generated/wording.ts',\n describes: 'Every language this app is in, as one module the layout hands to the provider, with the keys the interface names stated as a type so a language missing one is a compiler error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n },\n ],\n },",
51
+ source: " {\n id: 'i18n-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/i18n.js',\n describes: 'The generator of an app\\'s wording — it reads the languages the app declares and every message key its interface names, and writes one file per language holding a line for each. It cannot invent a sentence, so a key it has just found arrives holding nothing; run with `--check`, the mode the gate runs it in, it writes nothing and refuses a language file that is not what the declarations produce, and refuses any key left unanswered. It also writes the module the app imports, which states the keys the interface uses as a type, so a language missing one is a compiler error before it is a gate error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n derives: [\n {\n id: 'wording',\n at: 'app/_generated/wording.ts',\n describes: 'Every language this app is in, as one module the layout hands to the provider, with the keys the interface names stated as a type so a language missing one is a compiler error. That type is written as an assignment rather than a satisfies clause, because satisfies would also refuse the extra keys a filled wording always carries.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n },\n ],\n },",
52
52
  },
53
53
  {
54
54
  into: 'ui.ts',
55
55
  list: 'GENERATORS',
56
56
  id: 'routes-generator',
57
- source: " {\n id: 'routes-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/routes.js',\n describes: 'The generator of the routes, the map, the pages a browser reaches, and the root layout. Nobody types a route. The first page an app declares answers `/`, every other page answers its own name, and a sheet, popover, overlay or toast has no route, so the page under each route follows from the screens sheet. It reads every `navigateTo` the screens and their compositions hold and writes the map: from which screen, through which button, to which screen. A button is the only thing that makes a link. A press that names a sheet, popover, overlay or toast is a link like any other, and the client half opens that screen where somebody already is. A name no screen has, a destination not written out as a name, and a route typed into a screen are each refused by name. The layout imports what the other generators produce. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a hand edit to any of these files, exactly as the stylesheet is refused.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n derives: [\n {\n id: 'layout',\n at: 'app/layout.tsx',\n describes: 'The root layout — it imports what the other generators produce and hands the wording to the provider, so the one file every page passes through is a consequence of the declarations rather than something somebody keeps in step with them.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'door',\n at: 'app/_generated/door.tsx',\n describes: 'This app\\'s own client half. It is written when the app has operations a page can reach, or screens a press can move between. The provider takes something to run an operation with and something to move between screens with, and the layout cannot hand either over: the layout is a server component and the provider is a client one, and a function does not cross that line — \"Functions cannot be passed directly to Client Components\", measured 2026-09-01 as a page that returned 500 on every request while the gate was green. So both are made on the side that uses them. This file imports what the operations half derived and the map, and hands them over itself. The layout renders this and passes only the actor, which is data and crosses the way data does.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'bundler',\n at: 'next.config.js',\n describes: 'Where the bundler resolves from, derived from where the packages actually are. Only written when they live outside this app, which is when a bundler cannot see them and every import fails at run time while the compiler is content.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'map',\n at: 'app/_generated/map.ts',\n describes: 'Every screen this app has, where each one lives, and every way from one to another: from which screen, through which button, to which screen. It is read off every `navigateTo` the screens and their compositions hold, so a button is the only thing that makes a link. The client half moves through it: a press that names a page goes to the address held here, and a press that names a sheet, popover, overlay or toast opens it where somebody already is. A screen no button reaches is printed by `thread routes` rather than found by somebody looking for it.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n ],\n },",
57
+ source: " {\n id: 'routes-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/routes.js',\n describes: 'The generator of the routes, the map, the pages a browser reaches, and the root layout. Nobody types a route. The first page an app declares answers `/`, every other page answers its own name, and a sheet, popover, overlay or toast has no route, so the page under each route follows from the screens sheet. It reads every `navigateTo` the screens and their compositions hold and writes the map: from which screen, through which button, to which screen. A button is the only thing that makes a link. A press that names a sheet, popover, overlay or toast is a link like any other, and the client half opens that screen where somebody already is. A name no screen has, a destination not written out as a name, and a route typed into a screen are each refused by name. The layout imports what the other generators produce. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a hand edit to any of these files, exactly as the stylesheet is refused.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n derives: [\n {\n id: 'layout',\n at: 'app/layout.tsx',\n describes: 'The root layout — it imports what the other generators produce and hands the wording to the provider, so the one file every page passes through is a consequence of the declarations rather than something somebody keeps in step with them.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'door',\n at: 'app/_generated/door.tsx',\n describes: 'This app\\'s own client half. It is written when the app has operations a page can reach, or screens a press can move between. The provider takes something to run an operation with and something to move between screens with, and the layout cannot hand either over: the layout is a server component and the provider is a client one, and a function does not cross that line — \"Functions cannot be passed directly to Client Components\", measured 2026-09-01 as a page that returned 500 on every request while the gate was green. So both are made on the side that uses them. This file imports what the operations half derived and the map, and hands them over itself. The layout renders this and passes only the actor, which is data and crosses the way data does.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'bundler',\n at: 'next.config.js',\n describes: 'What Next reads to serve this app. It is written whenever the manifest runs Next, whether or not this app declares a screen, because it states three things a served app needs and one of them is that Next may not write files of its own into a tree where every file is declared. It also refuses to compile anything until the gate has passed, and names where the bundler resolves from when the packages live outside this app — which is when a bundler cannot see them and every import fails at run time while the compiler is content. It opens the disk itself rather than through the disk this framework declares, because Next reads this file before any TypeScript in this tree has been loaded — a file that gates the build cannot import the thing it is gating.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'map',\n at: 'app/_generated/map.ts',\n describes: 'Every screen this app has, where each one lives, and every way from one to another: from which screen, through which button, to which screen. It is read off every `navigateTo` the screens and their compositions hold, so a button is the only thing that makes a link. The client half moves through it: a press that names a page goes to the address held here, and a press that names a sheet, popover, overlay or toast opens it where somebody already is. A screen no button reaches is printed by `thread routes` rather than found by somebody looking for it.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n ],\n },",
58
58
  },
59
59
  {
60
60
  into: 'ui.ts',
61
61
  list: 'GENERATORS',
62
62
  id: 'dev-generator',
63
- source: " {\n id: 'dev-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/dev.js',\n describes: 'The command that runs the app, and the only one here that puts a pixel on a screen — until it existed the framework could build an interface nothing in it could start, because a gate answers whether declarations agree with files and cannot answer whether a button is where somebody says it is not. It is two halves in one word. First it settles this tree: every generator the declarations name is run until the checks stop complaining, which is what `thread create` and `thread run trial` already did and what starting the app was alone in not doing — an app had `thread gate` in front of `next dev`, and a gate refuses a stale file rather than writing it. Then it runs the entry the manifest declares, which is where the gate hook fires and Next is reached. Neither half is written down here: the generators are read off the rows, and `next dev` appears nowhere, so a package attached tomorrow is run by this without this changing and an app served by something else needs no edit. `--ship` swaps the entry for the build. Alone among the generators it carries no `runs:`, because a server stays up until it is stopped and a gate step that never returns is a gate that hangs.',\n version: 1,\n by: 'thread dev',\n },",
63
+ source: " {\n id: 'dev-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/dev.js',\n describes: 'The command that runs the app, and the only one here that puts a pixel on a screen — until it existed the framework could build an interface nothing in it could start, because a gate answers whether declarations agree with files and cannot answer whether a button is where somebody says it is not. It is two halves in one word. First it settles this tree: every generator the declarations name is run until the checks stop complaining, which is what `thread create` and `thread run trial` already did and what starting the app was alone in not doing — an app had `thread gate` in front of `next dev`, and a gate refuses a stale file rather than writing it. Then it runs the gate, and then starts Next itself, because Next is what this package installs to serve an app and the manifest carries no script for it. The generators are read off the rows, and `next dev` is the one thing written down here: this package serves an app with Next and nothing else. `--ship` swaps the entry for the build. Alone among the generators it carries no `runs:`, because a server stays up until it is stopped and a gate step that never returns is a gate that hangs.',\n version: 1,\n by: 'thread dev',\n },",
64
64
  },
65
65
  {
66
66
  into: 'ui.ts',
@@ -84,7 +84,7 @@ const SHIPPED = [
84
84
  into: 'ui.ts',
85
85
  list: 'GENERATORS',
86
86
  id: 'icons-generator',
87
- source: " {\n id: 'icons-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/icons.js',\n describes: 'The generator of the icon module — it reads which library the icon rows name and which meanings they declare, and writes the one module that imports exactly those symbols and installs them. A meaning is what an element asks for, so changing the library row redraws every icon in the app and rewrites nothing else. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a generated file that does not match the rows.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n derives: [\n {\n id: 'symbols',\n at: 'app/_generated/icons.ts',\n describes: 'The one module importing exactly the symbols the icon rows name, from the one library they name.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n },\n ],\n },",
87
+ source: " {\n id: 'icons-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/icons.js',\n describes: 'The generator of the icon module — it reads which library the icon rows name and which meanings they declare, and writes the one module that imports exactly those symbols and installs them. A meaning is what an element asks for, so changing the library row redraws every icon in the app and rewrites nothing else. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a generated file that does not match the rows.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n derives: [\n {\n id: 'symbols',\n at: 'app/_generated/icons.ts',\n describes: 'The one module importing exactly the symbols the icon rows name, from the one library they name. The layout renders it rather than merely importing it, because a bare import of a client module from a server layout is a reference that never runs — the install never happens and every icon on the page refuses.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n },\n ],\n },",
88
88
  },
89
89
  {
90
90
  into: 'ui.ts',
@@ -210,7 +210,7 @@ function stated(rows, always = []) {
210
210
  return Object.keys(SHAPES).filter((key) => held.has(key));
211
211
  }
212
212
  function inside(node) {
213
- return [...(node.holds ?? []), ...(node.declares ?? [])];
213
+ return [...(node.holds ?? []), ...(node.declares ?? []), ...(node.derives ?? [])];
214
214
  }
215
215
  function quoted(value) {
216
216
  return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
@@ -315,14 +315,9 @@ const ARRANGES = {
315
315
  styleguide: ['themes'],
316
316
  element: ['tag', 'raises', 'carries', 'always', 'places', 'works', 'measures', 'reads', 'gives', 'keeps', 'animates', 'shows', 'called', 'wires', 'dresses'],
317
317
  };
318
- const TEACHING = {
319
- composition: `export { TEACHES, catalogue } from '${named('ui')}/compositions'`,
320
- screen: `export { TEACHES, screening as catalogue } from '${named('ui')}/compositions'`,
321
- };
322
318
  function source(node, file, rows) {
323
319
  const extra = stated(rows, ARRANGES[node.id] ?? []).map((key) => SHAPES[key] ?? '');
324
- const taught = TEACHING[node.id];
325
- const authors = node.declares !== undefined || rows.some((one) => one.at !== undefined && one.at !== node.at);
320
+ const authors = node.declares !== undefined || node.derives !== undefined || rows.some((one) => one.at !== undefined && one.at !== node.at);
326
321
  const values = node.holds !== undefined || rows.some((one) => one.at === undefined || one.at === node.at);
327
322
  const own = node.id
328
323
  .split('-')
@@ -356,7 +351,7 @@ export const ${node.id.toUpperCase()}: ${bespoke ? own : 'Threaded'} = {
356
351
  version: 1,
357
352
  ${held.join('\n')}
358
353
  }
359
- ${taught === undefined ? '' : `\n${taught}\n`}`;
354
+ `;
360
355
  }
361
356
  const LISTS = [
362
357
  { node: TOKENS, file: 'tokens.ts' },
@@ -409,56 +404,6 @@ ${SEEDED.declares.split('\n').slice(1, -1).map((line) => line.slice(4)).join('\n
409
404
 
410
405
  export const GENERATORS: readonly Threaded[] = []
411
406
  `;
412
- const RETIRED = [
413
- {
414
- into: 'tokens.ts',
415
- list: 'holds',
416
- id: 'font',
417
- why: 'a font is not a token — the fonts sheet holds faces, sizes and appearance directly, so there is no variable of this kind for a style guide to give a value to',
418
- },
419
- ...['sm', 'md', 'lg'].map((one) => ({
420
- into: 'styleguides.ts',
421
- list: 'holds',
422
- id: `icon-${one}`,
423
- why: 'the style guide holds no icon size — `icons.ts` does, and it is the one place a symbol is measured. These rows and a constant inside the package were both claiming to decide it, and the constant was what anything actually drew at, so changing the row moved the CSS variable and left every icon the size it already was',
424
- })),
425
- ...['link', 'glyph', 'avatar', 'skeleton', 'spinner'].map((one) => ({
426
- into: 'variants.ts',
427
- list: 'declares',
428
- id: one,
429
- why: `a variant sharing a word with the element that wears it — \`${one}\` was coined twice, once as the element and once as the look, with two different meanings. The framework's own rule refuses that, and an app made entirely by these commands failed its own descent on five words this package had shipped. Renamed to \`${one}-\` plus what distinguishes it`,
430
- })),
431
- ...['icon', 'icon-ghost', 'icon-border', 'label-icon', 'elevated'].map((one) => ({
432
- into: 'variants.ts',
433
- list: 'declares',
434
- id: `button-${one}`,
435
- why: 'a variant may not decide what a button CONTAINS — a symbol, a word or both is the composition\'s to arrange, and four variants existed only to answer it. `button-ghost`, `button-fill` and the rest each serve every shape of content. `button-elevated` is withdrawn as simply poor',
436
- })),
437
- ...['filled', 'outlined', 'plain'].map((one) => ({
438
- into: 'materials.ts',
439
- list: 'declares',
440
- id: one,
441
- why: 'not a material — a background, an ink and a border width are three style guide rows, and wrapping them in a material only added a second place to look. A material is for what composes into one appearance worth naming: glass, a real relief, a glaze. The variants that wore these now name the rows directly',
442
- })),
443
- ...['primary', 'secondary'].map((one) => ({
444
- into: 'variants.ts',
445
- list: 'declares',
446
- id: `button-${one}`,
447
- why: 'a second name for something the button family already carries — `button-primary` is `button-fill` and `button-secondary` is `button-border`. Two names for one look is the defect this framework refuses everywhere else, and it was shipping it in the one place an app looks first',
448
- })),
449
- ...['sans', 'serif', 'mono', 'display'].map((one) => ({
450
- into: 'styleguides.ts',
451
- list: 'holds',
452
- id: `font-${one}`,
453
- why: 'the style guide holds no font — a font is not a token value, and the fonts sheet is the source for faces',
454
- })),
455
- ...['display', 'heading', 'body', 'label'].map((one) => ({
456
- into: 'variants.ts',
457
- list: 'declares',
458
- id: one,
459
- why: 'a type role, not a variant — it set a face, a size and a weight, all of which the fonts sheet now decides',
460
- })),
461
- ];
462
407
  export const ATTACH = {
463
408
  attaches: SEEDED.attaches,
464
409
  id: SEEDED.id,
@@ -488,7 +433,6 @@ export const ATTACH = {
488
433
  ...LISTS.flatMap((one) => sectioned(one)),
489
434
  ...SHIPPED,
490
435
  ],
491
- retires: RETIRED,
492
436
  declares: SEEDED.declares,
493
437
  writes: [
494
438
  { file: 'ui.ts', source: UI_SOURCE },
package/dist/ui/attach.ts CHANGED
@@ -53,19 +53,19 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
53
53
  into: 'ui.ts',
54
54
  list: 'GENERATORS',
55
55
  id: 'i18n-generator',
56
- source: " {\n id: 'i18n-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/i18n.js',\n describes: 'The generator of an app\\'s wording — it reads the languages the app declares and every message key its interface names, and writes one file per language holding a line for each. It cannot invent a sentence, so a key it has just found arrives holding nothing; run with `--check`, the mode the gate runs it in, it writes nothing and refuses a language file that is not what the declarations produce, and refuses any key left unanswered. It also writes the module the app imports, which states the keys the interface uses as a type, so a language missing one is a compiler error before it is a gate error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n derives: [\n {\n id: 'wording',\n at: 'app/_generated/wording.ts',\n describes: 'Every language this app is in, as one module the layout hands to the provider, with the keys the interface names stated as a type so a language missing one is a compiler error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n },\n ],\n },",
56
+ source: " {\n id: 'i18n-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/i18n.js',\n describes: 'The generator of an app\\'s wording — it reads the languages the app declares and every message key its interface names, and writes one file per language holding a line for each. It cannot invent a sentence, so a key it has just found arrives holding nothing; run with `--check`, the mode the gate runs it in, it writes nothing and refuses a language file that is not what the declarations produce, and refuses any key left unanswered. It also writes the module the app imports, which states the keys the interface uses as a type, so a language missing one is a compiler error before it is a gate error.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n derives: [\n {\n id: 'wording',\n at: 'app/_generated/wording.ts',\n describes: 'Every language this app is in, as one module the layout hands to the provider, with the keys the interface names stated as a type so a language missing one is a compiler error. That type is written as an assignment rather than a satisfies clause, because satisfies would also refuse the extra keys a filled wording always carries.',\n version: 1,\n by: 'thread i18n',\n runs: 'thread i18n --check',\n },\n ],\n },",
57
57
  },
58
58
  {
59
59
  into: 'ui.ts',
60
60
  list: 'GENERATORS',
61
61
  id: 'routes-generator',
62
- source: " {\n id: 'routes-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/routes.js',\n describes: 'The generator of the routes, the map, the pages a browser reaches, and the root layout. Nobody types a route. The first page an app declares answers `/`, every other page answers its own name, and a sheet, popover, overlay or toast has no route, so the page under each route follows from the screens sheet. It reads every `navigateTo` the screens and their compositions hold and writes the map: from which screen, through which button, to which screen. A button is the only thing that makes a link. A press that names a sheet, popover, overlay or toast is a link like any other, and the client half opens that screen where somebody already is. A name no screen has, a destination not written out as a name, and a route typed into a screen are each refused by name. The layout imports what the other generators produce. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a hand edit to any of these files, exactly as the stylesheet is refused.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n derives: [\n {\n id: 'layout',\n at: 'app/layout.tsx',\n describes: 'The root layout — it imports what the other generators produce and hands the wording to the provider, so the one file every page passes through is a consequence of the declarations rather than something somebody keeps in step with them.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'door',\n at: 'app/_generated/door.tsx',\n describes: 'This app\\'s own client half. It is written when the app has operations a page can reach, or screens a press can move between. The provider takes something to run an operation with and something to move between screens with, and the layout cannot hand either over: the layout is a server component and the provider is a client one, and a function does not cross that line — \"Functions cannot be passed directly to Client Components\", measured 2026-09-01 as a page that returned 500 on every request while the gate was green. So both are made on the side that uses them. This file imports what the operations half derived and the map, and hands them over itself. The layout renders this and passes only the actor, which is data and crosses the way data does.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'bundler',\n at: 'next.config.js',\n describes: 'Where the bundler resolves from, derived from where the packages actually are. Only written when they live outside this app, which is when a bundler cannot see them and every import fails at run time while the compiler is content.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'map',\n at: 'app/_generated/map.ts',\n describes: 'Every screen this app has, where each one lives, and every way from one to another: from which screen, through which button, to which screen. It is read off every `navigateTo` the screens and their compositions hold, so a button is the only thing that makes a link. The client half moves through it: a press that names a page goes to the address held here, and a press that names a sheet, popover, overlay or toast opens it where somebody already is. A screen no button reaches is printed by `thread routes` rather than found by somebody looking for it.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n ],\n },",
62
+ source: " {\n id: 'routes-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/routes.js',\n describes: 'The generator of the routes, the map, the pages a browser reaches, and the root layout. Nobody types a route. The first page an app declares answers `/`, every other page answers its own name, and a sheet, popover, overlay or toast has no route, so the page under each route follows from the screens sheet. It reads every `navigateTo` the screens and their compositions hold and writes the map: from which screen, through which button, to which screen. A button is the only thing that makes a link. A press that names a sheet, popover, overlay or toast is a link like any other, and the client half opens that screen where somebody already is. A name no screen has, a destination not written out as a name, and a route typed into a screen are each refused by name. The layout imports what the other generators produce. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a hand edit to any of these files, exactly as the stylesheet is refused.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n derives: [\n {\n id: 'layout',\n at: 'app/layout.tsx',\n describes: 'The root layout — it imports what the other generators produce and hands the wording to the provider, so the one file every page passes through is a consequence of the declarations rather than something somebody keeps in step with them.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'door',\n at: 'app/_generated/door.tsx',\n describes: 'This app\\'s own client half. It is written when the app has operations a page can reach, or screens a press can move between. The provider takes something to run an operation with and something to move between screens with, and the layout cannot hand either over: the layout is a server component and the provider is a client one, and a function does not cross that line — \"Functions cannot be passed directly to Client Components\", measured 2026-09-01 as a page that returned 500 on every request while the gate was green. So both are made on the side that uses them. This file imports what the operations half derived and the map, and hands them over itself. The layout renders this and passes only the actor, which is data and crosses the way data does.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'bundler',\n at: 'next.config.js',\n describes: 'What Next reads to serve this app. It is written whenever the manifest runs Next, whether or not this app declares a screen, because it states three things a served app needs and one of them is that Next may not write files of its own into a tree where every file is declared. It also refuses to compile anything until the gate has passed, and names where the bundler resolves from when the packages live outside this app — which is when a bundler cannot see them and every import fails at run time while the compiler is content. It opens the disk itself rather than through the disk this framework declares, because Next reads this file before any TypeScript in this tree has been loaded — a file that gates the build cannot import the thing it is gating.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n {\n id: 'map',\n at: 'app/_generated/map.ts',\n describes: 'Every screen this app has, where each one lives, and every way from one to another: from which screen, through which button, to which screen. It is read off every `navigateTo` the screens and their compositions hold, so a button is the only thing that makes a link. The client half moves through it: a press that names a page goes to the address held here, and a press that names a sheet, popover, overlay or toast opens it where somebody already is. A screen no button reaches is printed by `thread routes` rather than found by somebody looking for it.',\n version: 1,\n by: 'thread routes',\n runs: 'thread routes --check',\n },\n ],\n },",
63
63
  },
64
64
  {
65
65
  into: 'ui.ts',
66
66
  list: 'GENERATORS',
67
67
  id: 'dev-generator',
68
- source: " {\n id: 'dev-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/dev.js',\n describes: 'The command that runs the app, and the only one here that puts a pixel on a screen — until it existed the framework could build an interface nothing in it could start, because a gate answers whether declarations agree with files and cannot answer whether a button is where somebody says it is not. It is two halves in one word. First it settles this tree: every generator the declarations name is run until the checks stop complaining, which is what `thread create` and `thread run trial` already did and what starting the app was alone in not doing — an app had `thread gate` in front of `next dev`, and a gate refuses a stale file rather than writing it. Then it runs the entry the manifest declares, which is where the gate hook fires and Next is reached. Neither half is written down here: the generators are read off the rows, and `next dev` appears nowhere, so a package attached tomorrow is run by this without this changing and an app served by something else needs no edit. `--ship` swaps the entry for the build. Alone among the generators it carries no `runs:`, because a server stays up until it is stopped and a gate step that never returns is a gate that hangs.',\n version: 1,\n by: 'thread dev',\n },",
68
+ source: " {\n id: 'dev-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/dev.js',\n describes: 'The command that runs the app, and the only one here that puts a pixel on a screen — until it existed the framework could build an interface nothing in it could start, because a gate answers whether declarations agree with files and cannot answer whether a button is where somebody says it is not. It is two halves in one word. First it settles this tree: every generator the declarations name is run until the checks stop complaining, which is what `thread create` and `thread run trial` already did and what starting the app was alone in not doing — an app had `thread gate` in front of `next dev`, and a gate refuses a stale file rather than writing it. Then it runs the gate, and then starts Next itself, because Next is what this package installs to serve an app and the manifest carries no script for it. The generators are read off the rows, and `next dev` is the one thing written down here: this package serves an app with Next and nothing else. `--ship` swaps the entry for the build. Alone among the generators it carries no `runs:`, because a server stays up until it is stopped and a gate step that never returns is a gate that hangs.',\n version: 1,\n by: 'thread dev',\n },",
69
69
  },
70
70
  {
71
71
  into: 'ui.ts',
@@ -89,7 +89,7 @@ const SHIPPED: readonly { readonly into: string; readonly list: string; readonly
89
89
  into: 'ui.ts',
90
90
  list: 'GENERATORS',
91
91
  id: 'icons-generator',
92
- source: " {\n id: 'icons-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/icons.js',\n describes: 'The generator of the icon module — it reads which library the icon rows name and which meanings they declare, and writes the one module that imports exactly those symbols and installs them. A meaning is what an element asks for, so changing the library row redraws every icon in the app and rewrites nothing else. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a generated file that does not match the rows.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n derives: [\n {\n id: 'symbols',\n at: 'app/_generated/icons.ts',\n describes: 'The one module importing exactly the symbols the icon rows name, from the one library they name.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n },\n ],\n },",
92
+ source: " {\n id: 'icons-generator',\n at: 'node_modules/@prestack/thread-ui/dist/ui/generators/icons.js',\n describes: 'The generator of the icon module — it reads which library the icon rows name and which meanings they declare, and writes the one module that imports exactly those symbols and installs them. A meaning is what an element asks for, so changing the library row redraws every icon in the app and rewrites nothing else. Run with `--check`, the mode the gate runs it in, it writes nothing and refuses a generated file that does not match the rows.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n derives: [\n {\n id: 'symbols',\n at: 'app/_generated/icons.ts',\n describes: 'The one module importing exactly the symbols the icon rows name, from the one library they name. The layout renders it rather than merely importing it, because a bare import of a client module from a server layout is a reference that never runs — the install never happens and every icon on the page refuses.',\n version: 1,\n by: 'thread icons',\n runs: 'thread icons --check',\n },\n ],\n },",
93
93
  },
94
94
  {
95
95
  into: 'ui.ts',
@@ -272,11 +272,12 @@ interface Node {
272
272
  readonly describes: string
273
273
  readonly files?: string
274
274
  readonly declares?: readonly Row[]
275
+ readonly derives?: readonly Row[]
275
276
  readonly holds?: readonly Row[]
276
277
  }
277
278
 
278
279
  function inside(node: Node): readonly Row[] {
279
- return [...(node.holds ?? []), ...(node.declares ?? [])]
280
+ return [...(node.holds ?? []), ...(node.declares ?? []), ...(node.derives ?? [])]
280
281
  }
281
282
 
282
283
  function quoted(value: string): string {
@@ -397,16 +398,10 @@ const ARRANGES: Readonly<Record<string, readonly string[]>> = {
397
398
  element: ['tag', 'raises', 'carries', 'always', 'places', 'works', 'measures', 'reads', 'gives', 'keeps', 'animates', 'shows', 'called', 'wires', 'dresses'],
398
399
  }
399
400
 
400
- const TEACHING: Readonly<Record<string, string>> = {
401
- composition: `export { TEACHES, catalogue } from '${named('ui')}/compositions'`,
402
- screen: `export { TEACHES, screening as catalogue } from '${named('ui')}/compositions'`,
403
- }
404
-
405
401
  function source(node: Node, file: string, rows: readonly Row[]): string {
406
402
  const extra = stated(rows, ARRANGES[node.id] ?? []).map((key) => SHAPES[key] ?? '')
407
- const taught = TEACHING[node.id]
408
403
 
409
- const authors = node.declares !== undefined || rows.some((one) => one.at !== undefined && one.at !== node.at)
404
+ const authors = node.declares !== undefined || node.derives !== undefined || rows.some((one) => one.at !== undefined && one.at !== node.at)
410
405
  const values = node.holds !== undefined || rows.some((one) => one.at === undefined || one.at === node.at)
411
406
 
412
407
  const own = node.id
@@ -449,7 +444,7 @@ export const ${node.id.toUpperCase()}: ${bespoke ? own : 'Threaded'} = {
449
444
  version: 1,
450
445
  ${held.join('\n')}
451
446
  }
452
- ${taught === undefined ? '' : `\n${taught}\n`}`
447
+ `
453
448
  }
454
449
 
455
450
  const LISTS: readonly { readonly node: Node; readonly file: string; readonly rows?: readonly Row[] }[] = [
@@ -513,58 +508,6 @@ ${SEEDED.declares.split('\n').slice(1, -1).map((line) => line.slice(4)).join('\n
513
508
  export const GENERATORS: readonly Threaded[] = []
514
509
  `
515
510
 
516
- const RETIRED = [
517
- {
518
- into: 'tokens.ts',
519
- list: 'holds',
520
- id: 'font',
521
- why: 'a font is not a token — the fonts sheet holds faces, sizes and appearance directly, so there is no variable of this kind for a style guide to give a value to',
522
- },
523
- ...(['sm', 'md', 'lg'] as const).map((one) => ({
524
- into: 'styleguides.ts',
525
- list: 'holds',
526
- id: `icon-${one}`,
527
- why: 'the style guide holds no icon size — `icons.ts` does, and it is the one place a symbol is measured. These rows and a constant inside the package were both claiming to decide it, and the constant was what anything actually drew at, so changing the row moved the CSS variable and left every icon the size it already was',
528
- })),
529
- ...(['link', 'glyph', 'avatar', 'skeleton', 'spinner'] as const).map((one) => ({
530
- into: 'variants.ts',
531
- list: 'declares',
532
- id: one,
533
- why: `a variant sharing a word with the element that wears it — \`${one}\` was coined twice, once as the element and once as the look, with two different meanings. The framework's own rule refuses that, and an app made entirely by these commands failed its own descent on five words this package had shipped. Renamed to \`${one}-\` plus what distinguishes it`,
534
- })),
535
-
536
- ...(['icon', 'icon-ghost', 'icon-border', 'label-icon', 'elevated'] as const).map((one) => ({
537
- into: 'variants.ts',
538
- list: 'declares',
539
- id: `button-${one}`,
540
- why: 'a variant may not decide what a button CONTAINS — a symbol, a word or both is the composition\'s to arrange, and four variants existed only to answer it. `button-ghost`, `button-fill` and the rest each serve every shape of content. `button-elevated` is withdrawn as simply poor',
541
- })),
542
- ...(['filled', 'outlined', 'plain'] as const).map((one) => ({
543
- into: 'materials.ts',
544
- list: 'declares',
545
- id: one,
546
- why: 'not a material — a background, an ink and a border width are three style guide rows, and wrapping them in a material only added a second place to look. A material is for what composes into one appearance worth naming: glass, a real relief, a glaze. The variants that wore these now name the rows directly',
547
- })),
548
- ...(['primary', 'secondary'] as const).map((one) => ({
549
- into: 'variants.ts',
550
- list: 'declares',
551
- id: `button-${one}`,
552
- why: 'a second name for something the button family already carries — `button-primary` is `button-fill` and `button-secondary` is `button-border`. Two names for one look is the defect this framework refuses everywhere else, and it was shipping it in the one place an app looks first',
553
- })),
554
- ...(['sans', 'serif', 'mono', 'display'] as const).map((one) => ({
555
- into: 'styleguides.ts',
556
- list: 'holds',
557
- id: `font-${one}`,
558
- why: 'the style guide holds no font — a font is not a token value, and the fonts sheet is the source for faces',
559
- })),
560
- ...(['display', 'heading', 'body', 'label'] as const).map((one) => ({
561
- into: 'variants.ts',
562
- list: 'declares',
563
- id: one,
564
- why: 'a type role, not a variant — it set a face, a size and a weight, all of which the fonts sheet now decides',
565
- })),
566
- ]
567
-
568
511
  export const ATTACH: Attaching = {
569
512
  attaches: SEEDED.attaches,
570
513
  id: SEEDED.id,
@@ -595,7 +538,6 @@ export const ATTACH: Attaching = {
595
538
  ...LISTS.flatMap((one) => sectioned(one)),
596
539
  ...SHIPPED,
597
540
  ],
598
- retires: RETIRED,
599
541
  declares: SEEDED.declares,
600
542
  writes: [
601
543
  { file: 'ui.ts', source: UI_SOURCE },
@@ -12,9 +12,6 @@ export declare const str: (row: Row, key: string) => string;
12
12
  export declare function useRamp(count: number): readonly string[];
13
13
  export declare function placed(element: string, place: string): string;
14
14
  export declare function measured(held: Readonly<Record<string, string | number>>): Record<string, string | number>;
15
- export declare function EmptyFrame({ className }: {
16
- className?: string;
17
- }): React.ReactElement;
18
15
  export interface SeriesProps extends ChartBase {
19
16
  readonly value: string;
20
17
  readonly at: string;
package/dist/ui/charts.js CHANGED
@@ -1,8 +1,7 @@
1
1
  'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { seriesRamp } from "./series.js";
4
- import { classOfElement } from "./variant.js";
5
- import { useUi } from "./wrappers.js";
2
+ import { seriesRamp } from './series.js';
3
+ import { classOfElement } from './variant.js';
4
+ import { useUi } from './wrappers.js';
6
5
  export const num = (row, key) => {
7
6
  const v = row[key];
8
7
  return typeof v === 'number' ? v : Number(v ?? 0);
@@ -21,9 +20,6 @@ export function measured(held) {
21
20
  out[`--${name}`] = value;
22
21
  return out;
23
22
  }
24
- export function EmptyFrame({ className }) {
25
- return _jsx("div", { className: className, "data-empty": "true" });
26
- }
27
23
  export function polyline(values, width, height) {
28
24
  if (values.length === 0)
29
25
  return '';
@@ -41,10 +41,6 @@ export function measured(held: Readonly<Record<string, string | number>>): Recor
41
41
  return out
42
42
  }
43
43
 
44
- export function EmptyFrame({ className }: { className?: string }): React.ReactElement {
45
- return <div className={className} data-empty="true" />
46
- }
47
-
48
44
  export interface SeriesProps extends ChartBase {
49
45
  readonly value: string
50
46
  readonly at: string
@@ -11,7 +11,7 @@ export type VariantsFor<E extends string> = Shipped extends infer One ? One exte
11
11
  } ? E extends One['wears'][number] ? Camel<One['id']> : never : never : never;
12
12
  type Pascal<S extends string> = S extends `${infer Head}-${infer Rest}` ? `${Capitalize<Head>}${Pascal<Rest>}` : Capitalize<S>;
13
13
  type Camel<S extends string> = S extends `${infer Head}-${infer Rest}` ? `${Head}${Pascal<Rest>}` : S;
14
- export type ArrangementElement = (typeof ELEMENTS)['declares'][number] extends infer One ? One extends {
14
+ export type ArrangementElement = (typeof ELEMENTS)['derives'][number] extends infer One ? One extends {
15
15
  readonly arranges: true;
16
16
  readonly id: infer Id extends string;
17
17
  } ? Pascal<Id> : never : never;
@@ -21,7 +21,7 @@ type Pascal<S extends string> = S extends `${infer Head}-${infer Rest}`
21
21
 
22
22
  type Camel<S extends string> = S extends `${infer Head}-${infer Rest}` ? `${Head}${Pascal<Rest>}` : S
23
23
 
24
- export type ArrangementElement = (typeof ELEMENTS)['declares'][number] extends infer One
24
+ export type ArrangementElement = (typeof ELEMENTS)['derives'][number] extends infer One
25
25
  ? One extends { readonly arranges: true; readonly id: infer Id extends string }
26
26
  ? Pascal<Id>
27
27
  : never
@@ -23,7 +23,7 @@ export function createCollector(options) {
23
23
  const body = JSON.stringify({ events: batch });
24
24
  if (options.beacon !== undefined && options.beacon(options.endpoint, body))
25
25
  return;
26
- const doFetch = options.fetch ?? globalThis.fetch;
26
+ const doFetch = options.fetch;
27
27
  if (doFetch === undefined) {
28
28
  dropped += batch.length;
29
29
  return;
@@ -82,7 +82,7 @@ export function createCollector(options: CollectorOptions): Collector {
82
82
 
83
83
  if (options.beacon !== undefined && options.beacon(options.endpoint, body)) return
84
84
 
85
- const doFetch = options.fetch ?? globalThis.fetch
85
+ const doFetch = options.fetch
86
86
  if (doFetch === undefined) {
87
87
  dropped += batch.length
88
88
  return
@@ -1,14 +1,20 @@
1
1
  import type { Threaded } from '@prestack/thread/core/thread';
2
2
  import type { Tree } from '@prestack/thread/core/tree';
3
- export declare const TEACHES: readonly string[];
4
3
  export declare const REACHES: RegExp;
5
4
  export declare const declares: readonly Threaded[];
6
5
  export declare const COMPOSITIONS: Threaded & {
7
6
  readonly files: string;
8
7
  };
8
+ export declare const PASCAL: (id: string) => string;
9
9
  export declare function nameOf(at: string): string;
10
- export declare const catalogue: () => Promise<readonly string[]>;
11
- export declare const screening: () => Promise<readonly string[]>;
10
+ export type Listed = {
11
+ readonly id: string;
12
+ readonly at?: string;
13
+ readonly describes?: string;
14
+ readonly wears?: readonly string[];
15
+ readonly arranges?: boolean;
16
+ };
17
+ export declare function sheetOf(tree: Tree, file: string, ...named: readonly string[]): readonly Listed[];
12
18
  export declare function composed(body: string, rows: readonly {
13
19
  readonly id: string;
14
20
  readonly at?: string;