@scaffold-ui-kit/preview 0.0.0-stage → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1868 -2
  3. package/application/host/bootstrap.ts +43 -0
  4. package/application/host/main.ts +31 -0
  5. package/application/host/shell-host.ts +47 -0
  6. package/application/index.html +12 -0
  7. package/application/lib/base-url.ts +15 -0
  8. package/application/lib/no-code-block.ts +7 -0
  9. package/application/lib/no-setup.ts +3 -0
  10. package/application/lib/no-views.ts +6 -0
  11. package/application/preview/code/code.html +12 -0
  12. package/application/preview/code/main.ts +89 -0
  13. package/application/preview/globals.ts +254 -0
  14. package/application/preview/html/main.ts +93 -0
  15. package/application/preview/html/preview.html +12 -0
  16. package/application/preview/react/main.tsx +146 -0
  17. package/application/preview/react/preview.html +12 -0
  18. package/application/preview/svelte/Preview.svelte +104 -0
  19. package/application/preview/svelte/main.ts +13 -0
  20. package/application/preview/svelte/preview.html +12 -0
  21. package/application/preview/svelte/story-props.ts +172 -0
  22. package/application/preview/view/main.ts +124 -0
  23. package/application/preview/view/view.html +12 -0
  24. package/application/preview/vue/main.ts +145 -0
  25. package/application/preview/vue/preview.html +12 -0
  26. package/application/shells/charcell/components/Application/index.css +37 -0
  27. package/application/shells/charcell/components/Application/index.tsx +65 -0
  28. package/application/shells/charcell/components/Bar/index.css +68 -0
  29. package/application/shells/charcell/components/Bar/index.tsx +60 -0
  30. package/application/shells/charcell/components/CodePane/index.css +60 -0
  31. package/application/shells/charcell/components/CodePane/index.tsx +113 -0
  32. package/application/shells/charcell/components/ComponentStage/index.css +26 -0
  33. package/application/shells/charcell/components/ComponentStage/index.tsx +110 -0
  34. package/application/shells/charcell/components/Control/index.css +20 -0
  35. package/application/shells/charcell/components/Control/index.tsx +118 -0
  36. package/application/shells/charcell/components/CopyLink/index.tsx +35 -0
  37. package/application/shells/charcell/components/Description/index.css +6 -0
  38. package/application/shells/charcell/components/Description/index.tsx +24 -0
  39. package/application/shells/charcell/components/EditorAddDialog/index.css +9 -0
  40. package/application/shells/charcell/components/EditorAddDialog/index.tsx +158 -0
  41. package/application/shells/charcell/components/EditorPanel/index.css +48 -0
  42. package/application/shells/charcell/components/EditorPanel/index.tsx +496 -0
  43. package/application/shells/charcell/components/EventsRow/index.css +42 -0
  44. package/application/shells/charcell/components/EventsRow/index.tsx +68 -0
  45. package/application/shells/charcell/components/HeadingRow/index.css +11 -0
  46. package/application/shells/charcell/components/HeadingRow/index.tsx +16 -0
  47. package/application/shells/charcell/components/Hint/index.css +16 -0
  48. package/application/shells/charcell/components/Hint/index.tsx +81 -0
  49. package/application/shells/charcell/components/HtmlWarnings/index.tsx +45 -0
  50. package/application/shells/charcell/components/KeyHints/index.css +27 -0
  51. package/application/shells/charcell/components/KeyHints/index.tsx +106 -0
  52. package/application/shells/charcell/components/KitCodeBlock/index.css +55 -0
  53. package/application/shells/charcell/components/KitCodeBlock/index.tsx +18 -0
  54. package/application/shells/charcell/components/Markdown/index.tsx +16 -0
  55. package/application/shells/charcell/components/Navigation/index.css +13 -0
  56. package/application/shells/charcell/components/Navigation/index.tsx +98 -0
  57. package/application/shells/charcell/components/NavigationSplit/index.css +16 -0
  58. package/application/shells/charcell/components/NavigationSplit/index.tsx +82 -0
  59. package/application/shells/charcell/components/OptionControls/index.tsx +93 -0
  60. package/application/shells/charcell/components/PaneStatus/index.css +7 -0
  61. package/application/shells/charcell/components/PaneStatus/index.tsx +47 -0
  62. package/application/shells/charcell/components/PaneWidth/index.tsx +45 -0
  63. package/application/shells/charcell/components/PreviewGrid/index.css +39 -0
  64. package/application/shells/charcell/components/PreviewGrid/index.tsx +344 -0
  65. package/application/shells/charcell/components/PreviewPane/index.css +127 -0
  66. package/application/shells/charcell/components/PreviewPane/index.tsx +182 -0
  67. package/application/shells/charcell/components/PromptBar/index.tsx +133 -0
  68. package/application/shells/charcell/components/ScenarioRow/index.css +36 -0
  69. package/application/shells/charcell/components/ScenarioRow/index.tsx +71 -0
  70. package/application/shells/charcell/components/Select/index.tsx +48 -0
  71. package/application/shells/charcell/components/SlotOutlet/index.css +7 -0
  72. package/application/shells/charcell/components/SlotOutlet/index.tsx +25 -0
  73. package/application/shells/charcell/components/StageBar/index.css +7 -0
  74. package/application/shells/charcell/components/StageBar/index.tsx +109 -0
  75. package/application/shells/charcell/components/StageSplit/index.css +11 -0
  76. package/application/shells/charcell/components/StageSplit/index.tsx +99 -0
  77. package/application/shells/charcell/components/StatusBar/index.tsx +30 -0
  78. package/application/shells/charcell/components/ViewControls/index.css +15 -0
  79. package/application/shells/charcell/components/ViewControls/index.tsx +58 -0
  80. package/application/shells/charcell/components/ViewHeading/index.css +13 -0
  81. package/application/shells/charcell/components/ViewHeading/index.tsx +8 -0
  82. package/application/shells/charcell/components/ViewStage/index.css +9 -0
  83. package/application/shells/charcell/components/ViewStage/index.tsx +25 -0
  84. package/application/shells/charcell/components/WrapToggle/index.tsx +27 -0
  85. package/application/shells/charcell/configuration.ts +45 -0
  86. package/application/shells/charcell/controller-context.ts +27 -0
  87. package/application/shells/charcell/fit-labels.ts +42 -0
  88. package/application/shells/charcell/html-warnings.ts +18 -0
  89. package/application/shells/charcell/index.tsx +82 -0
  90. package/application/shells/charcell/page-loading.html +57 -0
  91. package/application/shells/charcell/placement.ts +24 -0
  92. package/application/shells/charcell/shell-options.ts +23 -0
  93. package/application/shells/charcell/shell.css +37 -0
  94. package/application/shells/charcell/shell.tsx +25 -0
  95. package/application/shells/charcell/split-reset.ts +47 -0
  96. package/application/shells/charcell/stacked-rows.ts +117 -0
  97. package/application/shells/charcell/stage-toggles.ts +93 -0
  98. package/application/types/manifest.d.ts +6 -0
  99. package/application/types/preview-configuration.d.ts +10 -0
  100. package/application/types/preview-shell.d.ts +7 -0
  101. package/application/types/react-registry.d.ts +15 -0
  102. package/application/types/vue-registry.d.ts +6 -0
  103. package/dist/build.d.ts +24 -0
  104. package/dist/build.js +34 -0
  105. package/dist/check.d.ts +48 -0
  106. package/dist/check.js +781 -0
  107. package/dist/cli.d.ts +2 -0
  108. package/dist/cli.js +88 -0
  109. package/dist/context.d.ts +179 -0
  110. package/dist/context.js +783 -0
  111. package/dist/controller/catalog.d.ts +339 -0
  112. package/dist/controller/catalog.js +367 -0
  113. package/dist/controller/create-preview-controller.d.ts +532 -0
  114. package/dist/controller/create-preview-controller.js +1707 -0
  115. package/dist/controller/editor-tree.d.ts +161 -0
  116. package/dist/controller/editor-tree.js +373 -0
  117. package/dist/controller/html-source.d.ts +62 -0
  118. package/dist/controller/html-source.js +61 -0
  119. package/dist/controller/index.d.ts +9 -0
  120. package/dist/controller/index.js +12 -0
  121. package/dist/controller/persistence.d.ts +191 -0
  122. package/dist/controller/persistence.js +315 -0
  123. package/dist/controller/regeneration.d.ts +30 -0
  124. package/dist/controller/regeneration.js +27 -0
  125. package/dist/controller/source.d.ts +80 -0
  126. package/dist/controller/source.js +236 -0
  127. package/dist/controller/store.d.ts +27 -0
  128. package/dist/controller/store.js +40 -0
  129. package/dist/declarations/application/shells/charcell/components/Application/index.d.ts +2 -0
  130. package/dist/declarations/application/shells/charcell/components/Bar/index.d.ts +11 -0
  131. package/dist/declarations/application/shells/charcell/components/CodePane/index.d.ts +5 -0
  132. package/dist/declarations/application/shells/charcell/components/ComponentStage/index.d.ts +2 -0
  133. package/dist/declarations/application/shells/charcell/components/Control/index.d.ts +9 -0
  134. package/dist/declarations/application/shells/charcell/components/CopyLink/index.d.ts +1 -0
  135. package/dist/declarations/application/shells/charcell/components/Description/index.d.ts +5 -0
  136. package/dist/declarations/application/shells/charcell/components/EditorAddDialog/index.d.ts +6 -0
  137. package/dist/declarations/application/shells/charcell/components/EditorPanel/index.d.ts +2 -0
  138. package/dist/declarations/application/shells/charcell/components/EventsRow/index.d.ts +4 -0
  139. package/dist/declarations/application/shells/charcell/components/HeadingRow/index.d.ts +6 -0
  140. package/dist/declarations/application/shells/charcell/components/Hint/index.d.ts +11 -0
  141. package/dist/declarations/application/shells/charcell/components/HtmlWarnings/index.d.ts +5 -0
  142. package/dist/declarations/application/shells/charcell/components/KeyHints/index.d.ts +2 -0
  143. package/dist/declarations/application/shells/charcell/components/KitCodeBlock/index.d.ts +5 -0
  144. package/dist/declarations/application/shells/charcell/components/Markdown/index.d.ts +3 -0
  145. package/dist/declarations/application/shells/charcell/components/Navigation/index.d.ts +8 -0
  146. package/dist/declarations/application/shells/charcell/components/NavigationSplit/index.d.ts +7 -0
  147. package/dist/declarations/application/shells/charcell/components/OptionControls/index.d.ts +7 -0
  148. package/dist/declarations/application/shells/charcell/components/PaneStatus/index.d.ts +2 -0
  149. package/dist/declarations/application/shells/charcell/components/PaneWidth/index.d.ts +4 -0
  150. package/dist/declarations/application/shells/charcell/components/PreviewGrid/index.d.ts +7 -0
  151. package/dist/declarations/application/shells/charcell/components/PreviewPane/index.d.ts +9 -0
  152. package/dist/declarations/application/shells/charcell/components/PromptBar/index.d.ts +1 -0
  153. package/dist/declarations/application/shells/charcell/components/ScenarioRow/index.d.ts +2 -0
  154. package/dist/declarations/application/shells/charcell/components/Select/index.d.ts +16 -0
  155. package/dist/declarations/application/shells/charcell/components/SlotOutlet/index.d.ts +5 -0
  156. package/dist/declarations/application/shells/charcell/components/StageBar/index.d.ts +2 -0
  157. package/dist/declarations/application/shells/charcell/components/StageSplit/index.d.ts +17 -0
  158. package/dist/declarations/application/shells/charcell/components/StatusBar/index.d.ts +1 -0
  159. package/dist/declarations/application/shells/charcell/components/ViewControls/index.d.ts +9 -0
  160. package/dist/declarations/application/shells/charcell/components/ViewHeading/index.d.ts +4 -0
  161. package/dist/declarations/application/shells/charcell/components/ViewStage/index.d.ts +4 -0
  162. package/dist/declarations/application/shells/charcell/components/WrapToggle/index.d.ts +1 -0
  163. package/dist/declarations/application/shells/charcell/configuration.d.ts +31 -0
  164. package/dist/declarations/application/shells/charcell/controller-context.d.ts +9 -0
  165. package/dist/declarations/application/shells/charcell/fit-labels.d.ts +18 -0
  166. package/dist/declarations/application/shells/charcell/html-warnings.d.ts +5 -0
  167. package/dist/declarations/application/shells/charcell/index.d.ts +39 -0
  168. package/dist/declarations/application/shells/charcell/placement.d.ts +7 -0
  169. package/dist/declarations/application/shells/charcell/shell-options.d.ts +15 -0
  170. package/dist/declarations/application/shells/charcell/shell.d.ts +9 -0
  171. package/dist/declarations/application/shells/charcell/split-reset.d.ts +30 -0
  172. package/dist/declarations/application/shells/charcell/stacked-rows.d.ts +58 -0
  173. package/dist/declarations/application/shells/charcell/stage-toggles.d.ts +28 -0
  174. package/dist/declarations/src/controller/catalog.d.ts +339 -0
  175. package/dist/declarations/src/controller/create-preview-controller.d.ts +532 -0
  176. package/dist/declarations/src/controller/editor-tree.d.ts +161 -0
  177. package/dist/declarations/src/controller/html-source.d.ts +62 -0
  178. package/dist/declarations/src/controller/index.d.ts +9 -0
  179. package/dist/declarations/src/controller/persistence.d.ts +191 -0
  180. package/dist/declarations/src/controller/regeneration.d.ts +30 -0
  181. package/dist/declarations/src/controller/source.d.ts +80 -0
  182. package/dist/declarations/src/controller/store.d.ts +27 -0
  183. package/dist/declarations/src/emit/common.d.ts +103 -0
  184. package/dist/declarations/src/emit/manifest.d.ts +138 -0
  185. package/dist/declarations/src/emit/source.d.ts +87 -0
  186. package/dist/declarations/src/lib/jsx-roots.d.ts +22 -0
  187. package/dist/declarations/src/lib/module-of-source.d.ts +18 -0
  188. package/dist/declarations/src/lib/naming.d.ts +29 -0
  189. package/dist/declarations/src/lib/react-spelling.d.ts +68 -0
  190. package/dist/declarations/src/lib/scenario-story.d.ts +41 -0
  191. package/dist/declarations/src/lib/slot-fill.d.ts +15 -0
  192. package/dist/declarations/src/lib/types.d.ts +741 -0
  193. package/dist/declarations/src/options.d.ts +224 -0
  194. package/dist/declarations/src/protocol.d.ts +541 -0
  195. package/dist/declarations/src/react-view.d.ts +22 -0
  196. package/dist/declarations/src/react.d.ts +17 -0
  197. package/dist/declarations/src/shell.d.ts +99 -0
  198. package/dist/declarations/src/views.d.ts +152 -0
  199. package/dist/development-server.d.ts +121 -0
  200. package/dist/development-server.js +331 -0
  201. package/dist/emit/common.d.ts +103 -0
  202. package/dist/emit/common.js +170 -0
  203. package/dist/emit/html-source.d.ts +46 -0
  204. package/dist/emit/html-source.js +322 -0
  205. package/dist/emit/manifest.d.ts +138 -0
  206. package/dist/emit/manifest.js +74 -0
  207. package/dist/emit/react.d.ts +16 -0
  208. package/dist/emit/react.js +210 -0
  209. package/dist/emit/scratch.d.ts +40 -0
  210. package/dist/emit/scratch.js +116 -0
  211. package/dist/emit/source.d.ts +87 -0
  212. package/dist/emit/source.js +789 -0
  213. package/dist/emit/svelte.d.ts +9 -0
  214. package/dist/emit/svelte.js +177 -0
  215. package/dist/emit/vue.d.ts +2 -0
  216. package/dist/emit/vue.js +152 -0
  217. package/dist/enumerate.d.ts +2 -0
  218. package/dist/enumerate.js +162 -0
  219. package/dist/generate.d.ts +43 -0
  220. package/dist/generate.js +302 -0
  221. package/dist/html-stylesheet.d.ts +43 -0
  222. package/dist/html-stylesheet.js +145 -0
  223. package/dist/index.d.ts +18 -0
  224. package/dist/index.js +21 -0
  225. package/dist/landing.d.ts +16 -0
  226. package/dist/landing.js +45 -0
  227. package/dist/lib/exported-types.d.ts +42 -0
  228. package/dist/lib/exported-types.js +86 -0
  229. package/dist/lib/html-attributes.d.ts +2 -0
  230. package/dist/lib/html-attributes.js +111 -0
  231. package/dist/lib/html-warnings.d.ts +19 -0
  232. package/dist/lib/html-warnings.js +79 -0
  233. package/dist/lib/jsx-roots.d.ts +22 -0
  234. package/dist/lib/jsx-roots.js +243 -0
  235. package/dist/lib/module-of-source.d.ts +18 -0
  236. package/dist/lib/module-of-source.js +24 -0
  237. package/dist/lib/naming.d.ts +29 -0
  238. package/dist/lib/naming.js +56 -0
  239. package/dist/lib/parse-type.d.ts +32 -0
  240. package/dist/lib/parse-type.js +103 -0
  241. package/dist/lib/react-spelling.d.ts +68 -0
  242. package/dist/lib/react-spelling.js +197 -0
  243. package/dist/lib/scenario-story.d.ts +41 -0
  244. package/dist/lib/scenario-story.js +84 -0
  245. package/dist/lib/slot-fill.d.ts +15 -0
  246. package/dist/lib/slot-fill.js +92 -0
  247. package/dist/lib/template-files.d.ts +14 -0
  248. package/dist/lib/template-files.js +25 -0
  249. package/dist/lib/types.d.ts +741 -0
  250. package/dist/lib/types.js +13 -0
  251. package/dist/lib/void-elements.d.ts +7 -0
  252. package/dist/lib/void-elements.js +13 -0
  253. package/dist/load.d.ts +37 -0
  254. package/dist/load.js +82 -0
  255. package/dist/model.d.ts +44 -0
  256. package/dist/model.js +464 -0
  257. package/dist/options.d.ts +224 -0
  258. package/dist/options.js +223 -0
  259. package/dist/prop-types.d.ts +26 -0
  260. package/dist/prop-types.js +102 -0
  261. package/dist/props-from.d.ts +84 -0
  262. package/dist/props-from.js +510 -0
  263. package/dist/protocol.d.ts +541 -0
  264. package/dist/protocol.js +819 -0
  265. package/dist/react-view.d.ts +22 -0
  266. package/dist/react-view.js +36 -0
  267. package/dist/react.d.ts +17 -0
  268. package/dist/react.js +23 -0
  269. package/dist/sass-importers.d.ts +26 -0
  270. package/dist/sass-importers.js +32 -0
  271. package/dist/shell-acceptance.d.ts +21 -0
  272. package/dist/shell-acceptance.js +37 -0
  273. package/dist/shell-page.d.ts +36 -0
  274. package/dist/shell-page.js +90 -0
  275. package/dist/shell-peers.d.ts +38 -0
  276. package/dist/shell-peers.js +61 -0
  277. package/dist/shell.d.ts +99 -0
  278. package/dist/shell.js +52 -0
  279. package/dist/shells/charcell/page.d.ts +8 -0
  280. package/dist/shells/charcell/page.js +69 -0
  281. package/dist/story-source.d.ts +113 -0
  282. package/dist/story-source.js +271 -0
  283. package/dist/story.d.ts +5 -0
  284. package/dist/story.js +28 -0
  285. package/dist/testing.d.ts +218 -0
  286. package/dist/testing.js +284 -0
  287. package/dist/views.d.ts +152 -0
  288. package/dist/views.js +7 -0
  289. package/dist/vite-configuration.d.ts +114 -0
  290. package/dist/vite-configuration.js +578 -0
  291. package/package.json +123 -3
  292. package/src/build.ts +51 -0
  293. package/src/check.ts +1062 -0
  294. package/src/cli.ts +123 -0
  295. package/src/context.ts +1168 -0
  296. package/src/controller/catalog.ts +719 -0
  297. package/src/controller/create-preview-controller.ts +2683 -0
  298. package/src/controller/editor-tree.ts +530 -0
  299. package/src/controller/html-source.ts +114 -0
  300. package/src/controller/index.ts +105 -0
  301. package/src/controller/persistence.ts +403 -0
  302. package/src/controller/regeneration.ts +55 -0
  303. package/src/controller/source.ts +333 -0
  304. package/src/controller/store.ts +55 -0
  305. package/src/development-server.ts +442 -0
  306. package/src/emit/common.ts +201 -0
  307. package/src/emit/html-source.ts +402 -0
  308. package/src/emit/manifest.ts +241 -0
  309. package/src/emit/react.ts +263 -0
  310. package/src/emit/scratch.ts +175 -0
  311. package/src/emit/source.ts +1094 -0
  312. package/src/emit/svelte.ts +230 -0
  313. package/src/emit/vue.ts +194 -0
  314. package/src/enumerate.ts +220 -0
  315. package/src/generate.ts +443 -0
  316. package/src/html-stylesheet.ts +173 -0
  317. package/src/index.ts +60 -0
  318. package/src/landing.ts +58 -0
  319. package/src/lib/exported-types.ts +114 -0
  320. package/src/lib/html-attributes.ts +113 -0
  321. package/src/lib/html-warnings.ts +81 -0
  322. package/src/lib/jsx-roots.ts +238 -0
  323. package/src/lib/module-of-source.ts +26 -0
  324. package/src/lib/naming.ts +65 -0
  325. package/src/lib/parse-type.ts +143 -0
  326. package/src/lib/react-spelling.ts +235 -0
  327. package/src/lib/scenario-story.ts +97 -0
  328. package/src/lib/slot-fill.ts +102 -0
  329. package/src/lib/template-files.ts +31 -0
  330. package/src/lib/types.ts +778 -0
  331. package/src/lib/void-elements.ts +15 -0
  332. package/src/load.ts +144 -0
  333. package/src/model.ts +568 -0
  334. package/src/options.ts +435 -0
  335. package/src/prop-types.ts +133 -0
  336. package/src/props-from.ts +678 -0
  337. package/src/protocol.ts +1135 -0
  338. package/src/react-view.ts +45 -0
  339. package/src/react.ts +34 -0
  340. package/src/sass-importers.ts +45 -0
  341. package/src/shell-acceptance.ts +45 -0
  342. package/src/shell-page.ts +133 -0
  343. package/src/shell-peers.ts +70 -0
  344. package/src/shell.ts +194 -0
  345. package/src/shells/charcell/page.ts +82 -0
  346. package/src/story-source.ts +391 -0
  347. package/src/story.ts +42 -0
  348. package/src/testing.ts +497 -0
  349. package/src/views.ts +183 -0
  350. package/src/vite-configuration.ts +675 -0
@@ -0,0 +1,69 @@
1
+ // The charcell shell's page: what the host page shows before the shell's
2
+ // script has loaded. charcell's dark ground paints from the first frame, the
3
+ // upright face is declared and its font preloaded, and the root holds the
4
+ // loading note the shell mounts over.
5
+ import { readFileSync } from 'node:fs';
6
+ import { createRequire } from 'node:module';
7
+ import { dirname, resolve } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+ import { defineShellPage } from '../../shell.js';
10
+ const here = dirname(fileURLToPath(import.meta.url));
11
+ /** The loading note and its styles, kept beside the shell. */
12
+ const loadingNote = resolve(here, '../../../application/shells/charcell/page-loading.html');
13
+ /**
14
+ * charcell's upright face, as its base stylesheet declares it.
15
+ *
16
+ * @returns The `@font-face` rule, the address it gives the font file, and
17
+ * the file's absolute path; or nothing when charcell or the rule cannot be
18
+ * found.
19
+ */
20
+ function uprightFace() {
21
+ let stylesheet;
22
+ let source;
23
+ try {
24
+ stylesheet = createRequire(import.meta.url).resolve('charcell/css/base');
25
+ source = readFileSync(stylesheet, 'utf8');
26
+ }
27
+ catch {
28
+ return undefined;
29
+ }
30
+ const rule = (source.match(/@font-face\s*\{[^}]*\}/g) ?? []).find((face) => /font-style:\s*normal/.test(face));
31
+ const address = rule?.match(/url\((["']?)([^"')]+)\1\)/)?.[2];
32
+ // Only a font file beside the stylesheet: an address of another kind, a
33
+ // data address or one with a query, names no file to preload.
34
+ if (rule === undefined ||
35
+ address === undefined ||
36
+ !/^\.{0,2}\/?[\w./-]+\.woff2$/.test(address)) {
37
+ return undefined;
38
+ }
39
+ return { rule, address, file: resolve(dirname(stylesheet), address) };
40
+ }
41
+ /**
42
+ * The charcell shell's page: charcell's dark ground and its face in the
43
+ * head, the font preloaded, and the loading note in the root. A kit that
44
+ * names the charcell shell as it is gets it without naming it; a module of
45
+ * the kit's that configures the shell names it as `preview.shell.page`.
46
+ */
47
+ export default defineShellPage({
48
+ head({ asset }) {
49
+ // The ground sits in the first, lowest cascade layer, so charcell's own
50
+ // page rule and a kit's overrides win once they load.
51
+ const ground = '<style>@layer { html { color-scheme: dark; background: #000000; } }</style>';
52
+ const face = uprightFace();
53
+ if (face === undefined)
54
+ return ground;
55
+ const font = asset(face.file);
56
+ // The face as charcell declares it, except that text waits for the font
57
+ // rather than showing in another face first: the loading note appears in
58
+ // the face the shell's text has, on the same cells.
59
+ const rule = face.rule
60
+ .replace(face.address, () => font)
61
+ .replace(/font-display:\s*[a-z]+/, 'font-display:block');
62
+ return [
63
+ ground,
64
+ `<link rel="preload" as="font" type="font/woff2" crossorigin href="${font}" />`,
65
+ `<style>${rule}</style>`,
66
+ ].join('\n');
67
+ },
68
+ root: () => readFileSync(loadingNote, 'utf8'),
69
+ });
@@ -0,0 +1,113 @@
1
+ import type { ConfigurationLookupOptions } from 'scaffold-ui-kit';
2
+ import { type PreviewContext } from './context.js';
3
+ import { type HtmlSourceResult } from './emit/html-source.js';
4
+ import type { EnumeratedComponent, JsonValue, Story, SlotFill, StoryAround, ResolvedStory, Target } from './lib/types.js';
5
+ /** What `storySource` prints: a framework's source, or the rendered markup. */
6
+ export type SourceTarget = Target | 'html';
7
+ /**
8
+ * What `storySource` returns: the source per target, and, when the `html`
9
+ * leaves something out, the warnings naming it.
10
+ */
11
+ export type StorySource = Partial<Record<SourceTarget, string>> & {
12
+ /** What the `html` could not work out at rest and left out, such as an
13
+ * expression reading the component's script state; the markup shows that
14
+ * part at a default. Absent when there is nothing to name. */
15
+ htmlWarnings?: string[];
16
+ };
17
+ export interface StorySourceOptions extends ConfigurationLookupOptions {
18
+ /** A scenario id (curated or generated); its props apply over the story's. */
19
+ scenario?: string;
20
+ /** The targets to print. Defaults to every target the component renders
21
+ * into, and `html`. */
22
+ targets?: SourceTarget[];
23
+ }
24
+ /**
25
+ * Prints a component's story as the source a consumer would write per target:
26
+ * a React component, a Vue single-file component, a Svelte component. Imports
27
+ * name the kit's package entry for each target (`<package>/react`); props are
28
+ * those the story file sets (`defaultProps`, `fixed`) and the scenario's, leaving
29
+ * out values equal to the template's declared default. A default slot the
30
+ * story leaves unfilled prints no content. A two-way prop the story gives
31
+ * is bound to state of the source's own, as a consumer controls
32
+ * it: React's `useState` with the value and the change prop, Vue's `v-model`
33
+ * or `v-model:<prop>`, Svelte's `bind:<prop>` on `$state` in runes mode or a
34
+ * plain `let` in legacy mode, as the kit builds Svelte, its state typed by
35
+ * the prop's declared type where that names types the kit's package entry
36
+ * exports, imported from it. The prop its value starts from otherwise (its
37
+ * default prop) is left out, as is a prop the scenario gives `null`, unless
38
+ * it is a two-way prop the source binds. The `html` is the markup at the
39
+ * given value.
40
+ *
41
+ * `html` is the markup the story renders to, at rest: the template rendered
42
+ * once for those props and slot content, components it references rendered
43
+ * inline, and assumes the kit's stylesheet. A component written by hand
44
+ * renders as `handWrittenComponents` maps it - its content, or the template
45
+ * it renders - inside one comment saying its behavior is not included, and
46
+ * slot content written per framework renders its `html`. A story with any
47
+ * other part that has no markup gets no `html`, with a warning naming it.
48
+ * What the markup cannot work out at rest, such as an expression reading the
49
+ * component's script state, is left out, shows at a default, and is named
50
+ * once in `htmlWarnings` and a printed warning.
51
+ *
52
+ * @param kitRoot - The kit root (where its package.json lives)
53
+ * @param componentName - The component, by name
54
+ * @param options - The scenario and the targets to print, and the kit
55
+ * configuration file when it is not the one the kit root gives
56
+ * @returns The source per target, and the html's warnings
57
+ * @example
58
+ * ```ts
59
+ * const { react } = await storySource(kitRoot, 'Button', { scenario: 'variant-dense' });
60
+ * ```
61
+ */
62
+ export declare function storySource(kitRoot: string, componentName: string, options?: StorySourceOptions): Promise<StorySource>;
63
+ /** A story as its source prints it: the props a consumer writes and its slot content. */
64
+ export interface SourceStoryContent {
65
+ props: Record<string, JsonValue>;
66
+ children?: SlotFill;
67
+ named: Record<string, SlotFill>;
68
+ /** The content beside the component, as its siblings. */
69
+ around?: StoryAround;
70
+ }
71
+ /**
72
+ * What a story's source prints for a scenario's props: the props the story file
73
+ * sets (`defaultProps`, `fixed`) and the scenario's, less those equal to the
74
+ * component's declared default, and the story file's slot content, or its
75
+ * `children` text where it curates none. A default slot the story leaves
76
+ * unfilled prints no content: the component's name the preview shows there
77
+ * is the preview's own, which a consumer never writes, unless `placeholder`
78
+ * asks for it, as the html the panes render does.
79
+ *
80
+ * @param component - The component.
81
+ * @param story - Its story file, when it has one.
82
+ * @param model - Its resolved story.
83
+ * @param scenarioProps - The scenario's props.
84
+ * @param options - `placeholder` keeps the preview's text in an unfilled default slot.
85
+ * @returns The props and slot content to print.
86
+ */
87
+ export declare function sourceStoryOf(component: EnumeratedComponent, story: Story | undefined, model: ResolvedStory, scenarioProps: Record<string, JsonValue>, options?: {
88
+ placeholder?: boolean;
89
+ }): SourceStoryContent;
90
+ /**
91
+ * The lines that report what a story's html leaves out, once per story: a
92
+ * heading, then each evaluation warning indented on a line of its own, a
93
+ * warning about the story's own component without its name, and the
94
+ * warnings one component gives for one reason as a single line counting
95
+ * them (see `summarizeHtmlWarnings`).
96
+ *
97
+ * @param componentName - The story's component.
98
+ * @param warnings - The expressions the html could not evaluate at rest.
99
+ * @returns The lines, joined, without a prefix.
100
+ */
101
+ export declare function htmlWarningLine(componentName: string, warnings: readonly string[]): string;
102
+ /**
103
+ * Renders a story to the markup it shows at rest, with the kit's shared
104
+ * modules in scope and its styling, as `storySource`'s `html` does.
105
+ *
106
+ * @param context - The kit's preview context.
107
+ * @param components - Every component of the kit.
108
+ * @param story - The component, its props and its slot content.
109
+ * @returns The markup, or what the story holds that has none.
110
+ */
111
+ export declare function printHtmlSource(context: PreviewContext, components: readonly EnumeratedComponent[], story: SourceStoryContent & {
112
+ component: EnumeratedComponent;
113
+ }): Promise<HtmlSourceResult>;
@@ -0,0 +1,271 @@
1
+ // A story as consumer source per target, for a kit's docs: the component,
2
+ // the props its story file curates (and a scenario's), and its slot content,
3
+ // importing from the kit's package entry for each target - and the markup the
4
+ // story renders to, as html. Read from the same story files the preview renders,
5
+ // so the snippets follow them.
6
+ import { REACT_ATTRIBUTE_NAMES } from '@js-template-engine/extension-react';
7
+ import { loadPreviewContext } from './context.js';
8
+ import { loadKit } from './load.js';
9
+ import { storyOnScenario } from './lib/scenario-story.js';
10
+ import { resolveStory } from './model.js';
11
+ import { declaredAttributes } from './lib/react-spelling.js';
12
+ import { moduleOfSource } from './lib/module-of-source.js';
13
+ import { htmlSource } from './emit/html-source.js';
14
+ import { inDeclarationOrder, SOURCE_PRINTERS, } from './emit/source.js';
15
+ import { exportedTypesOf } from './lib/exported-types.js';
16
+ import { summarizeHtmlWarnings } from './lib/html-warnings.js';
17
+ /**
18
+ * Prints a component's story as the source a consumer would write per target:
19
+ * a React component, a Vue single-file component, a Svelte component. Imports
20
+ * name the kit's package entry for each target (`<package>/react`); props are
21
+ * those the story file sets (`defaultProps`, `fixed`) and the scenario's, leaving
22
+ * out values equal to the template's declared default. A default slot the
23
+ * story leaves unfilled prints no content. A two-way prop the story gives
24
+ * is bound to state of the source's own, as a consumer controls
25
+ * it: React's `useState` with the value and the change prop, Vue's `v-model`
26
+ * or `v-model:<prop>`, Svelte's `bind:<prop>` on `$state` in runes mode or a
27
+ * plain `let` in legacy mode, as the kit builds Svelte, its state typed by
28
+ * the prop's declared type where that names types the kit's package entry
29
+ * exports, imported from it. The prop its value starts from otherwise (its
30
+ * default prop) is left out, as is a prop the scenario gives `null`, unless
31
+ * it is a two-way prop the source binds. The `html` is the markup at the
32
+ * given value.
33
+ *
34
+ * `html` is the markup the story renders to, at rest: the template rendered
35
+ * once for those props and slot content, components it references rendered
36
+ * inline, and assumes the kit's stylesheet. A component written by hand
37
+ * renders as `handWrittenComponents` maps it - its content, or the template
38
+ * it renders - inside one comment saying its behavior is not included, and
39
+ * slot content written per framework renders its `html`. A story with any
40
+ * other part that has no markup gets no `html`, with a warning naming it.
41
+ * What the markup cannot work out at rest, such as an expression reading the
42
+ * component's script state, is left out, shows at a default, and is named
43
+ * once in `htmlWarnings` and a printed warning.
44
+ *
45
+ * @param kitRoot - The kit root (where its package.json lives)
46
+ * @param componentName - The component, by name
47
+ * @param options - The scenario and the targets to print, and the kit
48
+ * configuration file when it is not the one the kit root gives
49
+ * @returns The source per target, and the html's warnings
50
+ * @example
51
+ * ```ts
52
+ * const { react } = await storySource(kitRoot, 'Button', { scenario: 'variant-dense' });
53
+ * ```
54
+ */
55
+ export async function storySource(kitRoot, componentName, options = {}) {
56
+ const context = loadPreviewContext(kitRoot, {
57
+ configuration: options.configuration,
58
+ workingDirectory: options.workingDirectory,
59
+ });
60
+ const { components } = await loadKit(context);
61
+ const loaded = components.find((entry) => entry.component.name === componentName);
62
+ if (!loaded) {
63
+ throw new Error(`[preview] no component named ${componentName} in ${kitRoot}`);
64
+ }
65
+ const { component, story } = loaded;
66
+ const model = resolveStory(component, story, context.configuration.controlHints ?? {}, context.configuration.labels, context.omitPattern, context.targets);
67
+ let scenarioProps = {};
68
+ let scenario;
69
+ if (options.scenario !== undefined) {
70
+ scenario = model.scenarios.find((entry) => entry.id === options.scenario);
71
+ if (!scenario) {
72
+ throw new Error(`[preview] ${componentName} has no scenario '${options.scenario}'; it has ${model.scenarios.map((entry) => `'${entry.id}'`).join(', ') || 'none'}`);
73
+ }
74
+ scenarioProps = scenario.props ?? {};
75
+ }
76
+ // A scenario with slot content of its own prints that over the story's.
77
+ const { props, children, named, around } = sourceStoryOf(component, story, storyOnScenario(model, scenario), scenarioProps);
78
+ // Each component imports from its source's package entry, as generation does.
79
+ const loadedByName = new Map(components.map((entry) => [entry.component.name, entry]));
80
+ const defaultModule = context.sources[0].moduleBase;
81
+ const importsFor = (target) => {
82
+ const imports = new Map();
83
+ for (const name of [model.name, ...model.slotComponents]) {
84
+ const entry = loadedByName.get(name);
85
+ imports.set(name, {
86
+ module: entry?.component.importModule?.[target] ??
87
+ moduleOfSource(entry?.source.moduleBase ?? defaultModule, target),
88
+ exported: entry?.component.exportName ?? name,
89
+ ...(entry
90
+ ? {
91
+ declaredAttributes: declaredAttributes(Object.keys(entry.component.props), REACT_ATTRIBUTE_NAMES),
92
+ }
93
+ : {}),
94
+ });
95
+ }
96
+ return imports;
97
+ };
98
+ // The types each component's module exports, which a bound prop's state
99
+ // is typed by where its declared type names them.
100
+ const exportedTypesFor = (target) => {
101
+ const types = new Map();
102
+ // A component's own name, or the name it is exported under, is a value.
103
+ const values = new Set(components.flatMap((entry) => [
104
+ entry.component.name,
105
+ entry.component.exportName ?? entry.component.name,
106
+ ]));
107
+ // The story's own component first, so its type wins a name another
108
+ // component's module exports too.
109
+ const ordered = [
110
+ ...components.filter((entry) => entry.component.name === componentName),
111
+ ...components.filter((entry) => entry.component.name !== componentName),
112
+ ];
113
+ for (const entry of ordered)
114
+ for (const type of exportedTypesOf(entry.component, [target])?.[target] ??
115
+ [])
116
+ if (!types.has(type) && !values.has(type))
117
+ types.set(type, entry.component.importModule?.[target] ??
118
+ moduleOfSource(entry.source.moduleBase ?? defaultModule, target));
119
+ return types;
120
+ };
121
+ // A two-way prop the story gives is controlled: its source binds it.
122
+ const declaredTypes = new Map(model.propTypes.map((propType) => [propType.name, propType.declaredType]));
123
+ const bindings = (model.bindings ?? [])
124
+ .filter((binding) => binding.prop in props)
125
+ .map((binding) => {
126
+ const declaredType = declaredTypes.get(binding.prop);
127
+ return { ...binding, ...(declaredType ? { declaredType } : {}) };
128
+ });
129
+ const requested = options.targets ?? [...model.targets, 'html'];
130
+ const sources = {};
131
+ for (const target of requested) {
132
+ if (target === 'html') {
133
+ const result = await printHtmlSource(context, components.map((entry) => entry.component), { component, props, children, named, around });
134
+ if (result.markup !== undefined) {
135
+ sources.html = result.markup;
136
+ if (result.warnings.length > 0) {
137
+ sources.htmlWarnings = result.warnings;
138
+ console.warn(`[preview] ${htmlWarningLine(componentName, result.warnings)}`);
139
+ }
140
+ }
141
+ else {
142
+ console.warn(`[preview] ${componentName} has no html source: it holds ${result.missing.join('; ')}`);
143
+ }
144
+ continue;
145
+ }
146
+ if (!model.targets.includes(target))
147
+ continue;
148
+ sources[target] = SOURCE_PRINTERS[target]({
149
+ component: model.name,
150
+ props,
151
+ children,
152
+ named,
153
+ ...(around ? { around } : {}),
154
+ imports: importsFor(target),
155
+ ...(bindings.length > 0 ? { bindings } : {}),
156
+ svelteMode: context.svelteMode,
157
+ reactAttributeNames: REACT_ATTRIBUTE_NAMES,
158
+ exportedTypes: exportedTypesFor(target),
159
+ });
160
+ }
161
+ return sources;
162
+ }
163
+ /**
164
+ * What a story's source prints for a scenario's props: the props the story file
165
+ * sets (`defaultProps`, `fixed`) and the scenario's, less those equal to the
166
+ * component's declared default, and the story file's slot content, or its
167
+ * `children` text where it curates none. A default slot the story leaves
168
+ * unfilled prints no content: the component's name the preview shows there
169
+ * is the preview's own, which a consumer never writes, unless `placeholder`
170
+ * asks for it, as the html the panes render does.
171
+ *
172
+ * @param component - The component.
173
+ * @param story - Its story file, when it has one.
174
+ * @param model - Its resolved story.
175
+ * @param scenarioProps - The scenario's props.
176
+ * @param options - `placeholder` keeps the preview's text in an unfilled default slot.
177
+ * @returns The props and slot content to print.
178
+ */
179
+ export function sourceStoryOf(component, story, model, scenarioProps, options = {}) {
180
+ // What the story file and scenario set, not the preview's own control defaults.
181
+ const props = {
182
+ ...(story?.defaultProps ?? {}),
183
+ ...(story?.fixed ?? {}),
184
+ ...scenarioProps,
185
+ };
186
+ let children = model.slots?.default;
187
+ const childrenText = 'children' in props
188
+ ? props.children
189
+ : options.placeholder
190
+ ? model.defaultProps.children
191
+ : undefined;
192
+ delete props.children;
193
+ if (!children && typeof childrenText === 'string')
194
+ children = { kind: 'text', value: childrenText };
195
+ for (const [name, value] of Object.entries(props)) {
196
+ const declared = component.props[name]?.default;
197
+ if (value === undefined ||
198
+ (declared !== undefined &&
199
+ JSON.stringify(declared) === JSON.stringify(value))) {
200
+ delete props[name];
201
+ }
202
+ }
203
+ return {
204
+ props: inDeclarationOrder(props, Object.keys(component.props)),
205
+ children,
206
+ named: model.slots?.named ?? {},
207
+ ...(model.around ? { around: model.around } : {}),
208
+ };
209
+ }
210
+ /**
211
+ * The lines that report what a story's html leaves out, once per story: a
212
+ * heading, then each evaluation warning indented on a line of its own, a
213
+ * warning about the story's own component without its name, and the
214
+ * warnings one component gives for one reason as a single line counting
215
+ * them (see `summarizeHtmlWarnings`).
216
+ *
217
+ * @param componentName - The story's component.
218
+ * @param warnings - The expressions the html could not evaluate at rest.
219
+ * @returns The lines, joined, without a prefix.
220
+ */
221
+ export function htmlWarningLine(componentName, warnings) {
222
+ const own = `${componentName}: `;
223
+ return [
224
+ `${componentName}'s html leaves out what it cannot evaluate at rest:`,
225
+ ...summarizeHtmlWarnings(warnings).map((warning) => ` ${warning.startsWith(own) ? warning.slice(own.length) : warning}`),
226
+ ].join('\n');
227
+ }
228
+ /**
229
+ * Renders a story to the markup it shows at rest, with the kit's shared
230
+ * modules in scope and its styling, as `storySource`'s `html` does.
231
+ *
232
+ * @param context - The kit's preview context.
233
+ * @param components - Every component of the kit.
234
+ * @param story - The component, its props and its slot content.
235
+ * @returns The markup, or what the story holds that has none.
236
+ */
237
+ export async function printHtmlSource(context, components, story) {
238
+ return htmlSource({
239
+ scope: await sharedScope(context),
240
+ component: story.component,
241
+ props: story.props,
242
+ children: story.children,
243
+ named: story.named,
244
+ ...(story.around ? { around: story.around } : {}),
245
+ components,
246
+ styling: context.styling,
247
+ handWrittenComponents: context.configuration.handWrittenComponents ?? {},
248
+ });
249
+ }
250
+ /**
251
+ * The exports of `@scaffold-ui-kit/helpers`' framework-free entries and of
252
+ * the kit's shared modules - the helpers its templates import by specifier -
253
+ * under their names, later modules winning a clash, so a kit's own module
254
+ * wins over the package. A module that fails to load contributes nothing; an
255
+ * expression naming one of its exports is then a comment in the markup.
256
+ */
257
+ async function sharedScope(context) {
258
+ const scope = {};
259
+ for (const modulePath of [
260
+ ...context.helperModulesAbsolute,
261
+ ...context.sharedModulesAbsolute,
262
+ ]) {
263
+ try {
264
+ Object.assign(scope, (await context.importModule(modulePath)));
265
+ }
266
+ catch {
267
+ // Left out: the markup marks what depends on it.
268
+ }
269
+ }
270
+ return scope;
271
+ }
@@ -0,0 +1,5 @@
1
+ import type { Story } from './lib/types.js';
2
+ import type { ModuleImporter } from './lib/types.js';
3
+ /** Whether the kit's `omitPattern` leaves this component out by its name. */
4
+ export declare function isStructurallyOmitted(name: string, omitPattern?: RegExp): boolean;
5
+ export declare function loadStory(name: string, storiesDirectory: string | undefined, importModule: ModuleImporter): Promise<Story | undefined>;
package/dist/story.js ADDED
@@ -0,0 +1,28 @@
1
+ // Load a component's story file (stories/<Name>.story.ts, default export) if
2
+ // present. Also decides the omit by name: a kit whose naming marks a compound's
3
+ // parts declares the pattern (`preview.omitPattern`), and a matching
4
+ // component gets no story of its own.
5
+ import { existsSync } from 'node:fs';
6
+ import { resolve } from 'node:path';
7
+ /** Whether the kit's `omitPattern` leaves this component out by its name. */
8
+ export function isStructurallyOmitted(name, omitPattern) {
9
+ return omitPattern?.test(name) ?? false;
10
+ }
11
+ export async function loadStory(name, storiesDirectory, importModule) {
12
+ if (!storiesDirectory)
13
+ return undefined;
14
+ const file = resolve(storiesDirectory, `${name}.story.ts`);
15
+ if (!existsSync(file))
16
+ return undefined;
17
+ const mod = (await importModule(file));
18
+ // A story file that exports nothing would silently drop the component's
19
+ // curation (its defaults, slots and scenarios), so it is an error. The module
20
+ // importer's interop answers `default` even when none is exported, so the
21
+ // export is looked for among the module's own keys.
22
+ if (!Object.keys(mod).includes('default') ||
23
+ !mod.default ||
24
+ typeof mod.default !== 'object') {
25
+ throw new Error(`[preview] ${file} must default-export the ${name} story object`);
26
+ }
27
+ return mod.default;
28
+ }