@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,302 @@
1
+ // The preview generator: enumerate every source's component templates → build
2
+ // one target-agnostic model per component → emit a per-target
3
+ // render-registry + the host manifest into `<kitRoot>/.preview-generated/`. Pure
4
+ // function of the preview context - no kit names or paths are baked in; the
5
+ // kit supplies everything through its `preview` block (see context.ts).
6
+ //
7
+ // Every output is rendered before anything is written, so a kit module that
8
+ // fails to load leaves the previous output in place. A file is written only
9
+ // when its content differs from what is on disk, so a development server
10
+ // serving the tree reloads only for what changed.
11
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from 'node:fs';
12
+ import { basename, dirname, join, relative, resolve } from 'node:path';
13
+ import { kitPaneWidths, loadKit } from './load.js';
14
+ import { landingProblems } from './landing.js';
15
+ import { scenarioStories, storyOnScenario } from './lib/scenario-story.js';
16
+ import { resolveStory } from './model.js';
17
+ import { REACT_ATTRIBUTE_NAMES } from '@js-template-engine/extension-react';
18
+ import { declaredAttributes } from './lib/react-spelling.js';
19
+ import { emitReactRegistry } from './emit/react.js';
20
+ import { emitVueRegistry } from './emit/vue.js';
21
+ import { emitSvelteRegistry, emitSvelteWrapper } from './emit/svelte.js';
22
+ import { buildManifest } from './emit/manifest.js';
23
+ import { writeScratchStubs } from './emit/scratch.js';
24
+ import { optionProblems } from './options.js';
25
+ import { htmlWarningLine, printHtmlSource, sourceStoryOf, } from './story-source.js';
26
+ import { htmlSourceResponse } from './html-stylesheet.js';
27
+ import { HTML_SOURCE_DIRECTORY, } from './controller/html-source.js';
28
+ import { exportedTypesOf } from './lib/exported-types.js';
29
+ import { sanitize } from './lib/naming.js';
30
+ import { moduleOfSource } from './lib/module-of-source.js';
31
+ const targets = ['react', 'vue', 'svelte'];
32
+ /** Every file under `directory`, as absolute paths. */
33
+ function filesUnder(directory) {
34
+ return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
35
+ const path = join(directory, entry.name);
36
+ return entry.isDirectory() ? filesUnder(path) : [path];
37
+ });
38
+ }
39
+ /** Writes `content` to `path` unless the file already holds exactly that. */
40
+ function writeIfChanged(path, content) {
41
+ const bytes = typeof content === 'string' ? Buffer.from(content) : content;
42
+ if (existsSync(path) && readFileSync(path).equals(bytes))
43
+ return false;
44
+ mkdirSync(dirname(path), { recursive: true });
45
+ writeFileSync(path, bytes);
46
+ return true;
47
+ }
48
+ /**
49
+ * Generates the preview into `<kitRoot>/.preview-generated/`: a render
50
+ * registry per target, the Svelte wrappers, the module-resolution data the
51
+ * scenario editor reads, the host manifest, and the themes' stylesheets.
52
+ *
53
+ * @param context - The kit's preview context.
54
+ * @param options - Whether the generated tree is emptied first.
55
+ * @returns The files written and removed.
56
+ * @example
57
+ * ```ts
58
+ * await generatePreview(loadPreviewContext(kitRoot));
59
+ * ```
60
+ */
61
+ export async function generatePreview(context, options = {}) {
62
+ const { clean = true, htmlSources = false } = options;
63
+ const { generatedRoot, sources } = context;
64
+ const directory = {};
65
+ for (const target of targets) {
66
+ directory[target] = resolve(generatedRoot, target);
67
+ }
68
+ const { components } = await loadKit(context);
69
+ const hints = context.configuration.controlHints ?? {};
70
+ const problems = optionProblems(context.configuration.options);
71
+ if (problems.length > 0) {
72
+ throw new Error(`[preview] ${context.configurationPath} gives unsound preview.options:\n ${problems.join('\n ')}`);
73
+ }
74
+ const paneWidths = kitPaneWidths(context);
75
+ if (paneWidths.errors.length > 0)
76
+ throw new Error(`[preview] ${paneWidths.errors.join('\n[preview] ')}`);
77
+ // Each output, in the order it is written: a registry after the wrappers it
78
+ // imports, and the manifest, which names every story, last.
79
+ const outputs = [];
80
+ const themeSources = [];
81
+ // `moduleByName` remembers which module each component imports from, so the
82
+ // emitters group imports per source.
83
+ const moduleByName = new Map();
84
+ const importOverrideByName = new Map();
85
+ const exportByName = new Map();
86
+ for (const { component, source } of components) {
87
+ moduleByName.set(component.name, source.moduleBase);
88
+ if (component.importModule)
89
+ importOverrideByName.set(component.name, component.importModule);
90
+ if (component.exportName && component.exportName !== component.name) {
91
+ exportByName.set(component.name, component.exportName);
92
+ }
93
+ }
94
+ const built = components.map(({ component, story, source }) => ({
95
+ ...resolveStory(component, story, hints, context.configuration.labels, context.omitPattern, context.targets),
96
+ source: source.id,
97
+ }));
98
+ // A component's per-target import module: a per-component override (a
99
+ // playground fixture outside its source's published barrel) wins; otherwise
100
+ // the source's module for the target (`moduleOfSource`), defaulting slot children that belong to
101
+ // no registered source to the kit's own (first) source.
102
+ const defaultModule = sources[0].moduleBase;
103
+ const moduleFor = (name, target) => importOverrideByName.get(name)?.[target] ??
104
+ moduleOfSource(moduleByName.get(name) ?? defaultModule, target);
105
+ const exportFor = (name) => exportByName.get(name) ?? name;
106
+ // The names each component declares that React would otherwise respell
107
+ // (`class`, `style`, an attribute React renames): it takes them as they
108
+ // are, and every other attribute a story gives it as React spells it.
109
+ const declaredAttributesByName = new Map(components.map(({ component }) => [
110
+ component.name,
111
+ declaredAttributes(Object.keys(component.props), REACT_ATTRIBUTE_NAMES),
112
+ ]));
113
+ const declaredAttributesOf = (name) => declaredAttributesByName.get(name) ?? [];
114
+ const declaredAttributesRecord = Object.fromEntries([...declaredAttributesByName].filter(([, names]) => names.length > 0));
115
+ // Browseable stories get registries + a nav entry; components that are not
116
+ // standalone (compound parts, shared blocks) are editor-only; omitted parts
117
+ // drop out entirely.
118
+ const stories = [];
119
+ const editorOnly = [];
120
+ const omitted = [];
121
+ for (const model of built) {
122
+ if (model.omit) {
123
+ omitted.push(model.name);
124
+ continue;
125
+ }
126
+ (model.standalone ? stories : editorOnly).push(model);
127
+ }
128
+ const landing = landingProblems(context.configuration.landing, stories);
129
+ if (landing.length > 0)
130
+ throw new Error(`[preview] ${landing.join('\n[preview] ')}`);
131
+ // Per-target registries (id → render unit) across ALL sources. A component
132
+ // renders only into the targets it declares within the kit's, so each
133
+ // target's registry sees only its own stories; a target the kit does not
134
+ // build gets an empty registry, so its iframe entry still builds.
135
+ // A scenario with slot content of its own is a story beside its
136
+ // component's, so its content renders as the component's does.
137
+ const forTarget = (target) => stories
138
+ .filter((model) => model.targets.includes(target))
139
+ .flatMap((model) => [model, ...scenarioStories(model)]);
140
+ for (const model of forTarget('svelte')) {
141
+ const wrapper = emitSvelteWrapper(model, moduleFor, exportFor);
142
+ outputs.push([resolve(directory.svelte, wrapper.fileName), wrapper.source]);
143
+ }
144
+ outputs.push([
145
+ resolve(directory.react, 'registry.tsx'),
146
+ emitReactRegistry(forTarget('react'), moduleFor, exportFor, declaredAttributesOf),
147
+ ], [
148
+ resolve(directory.vue, 'registry.ts'),
149
+ emitVueRegistry(forTarget('vue'), moduleFor, exportFor),
150
+ ], [
151
+ resolve(directory.svelte, 'registry.ts'),
152
+ emitSvelteRegistry(forTarget('svelte')),
153
+ ]);
154
+ // The module-resolution data the scratch regeneration endpoint reads (it runs in the
155
+ // Vite dev middleware with no kit imports of its own).
156
+ const scratchModules = {
157
+ defaultModule,
158
+ moduleByName: Object.fromEntries(moduleByName),
159
+ importOverrideByName: Object.fromEntries(importOverrideByName),
160
+ exportByName: Object.fromEntries(exportByName),
161
+ targets: context.targets,
162
+ ...(Object.keys(declaredAttributesRecord).length > 0
163
+ ? { declaredAttributes: declaredAttributesRecord }
164
+ : {}),
165
+ };
166
+ outputs.push([
167
+ resolve(generatedRoot, 'modules.json'),
168
+ JSON.stringify(scratchModules, null, 2) + '\n',
169
+ ]);
170
+ // Framework-neutral host manifest (nav, controls, color tokens) - stories
171
+ // plus the editor-only components (the editor reads both; the nav leaves
172
+ // those out).
173
+ const sourceMeta = sources.map((source) => ({
174
+ id: source.id,
175
+ label: source.label,
176
+ order: source.order,
177
+ moduleBase: source.moduleBase,
178
+ }));
179
+ // How a consumer imports each component, omitted ones included: a story's
180
+ // source in the browser names what its slot content holds.
181
+ const imports = {};
182
+ for (const { component } of components) {
183
+ const types = exportedTypesOf(component, context.targets);
184
+ imports[component.name] = {
185
+ exportName: exportFor(component.name),
186
+ ...(declaredAttributesOf(component.name).length > 0
187
+ ? { declaredAttributes: declaredAttributesOf(component.name) }
188
+ : {}),
189
+ modules: Object.fromEntries(context.targets.map((target) => [
190
+ target,
191
+ moduleFor(component.name, target),
192
+ ])),
193
+ ...(types ? { types } : {}),
194
+ };
195
+ }
196
+ const manifest = [
197
+ resolve(generatedRoot, 'manifest.json'),
198
+ JSON.stringify(buildManifest([...stories, ...editorOnly], sourceMeta, hints.colorTokens ?? [], context.kitName, context.configuration.labels, context.kitVersion, context.configuration.persistence, context.buildsHtml ? [...context.targets, 'html'] : context.targets, imports, context.configuration.codeBlock
199
+ ? { framework: context.configuration.codeBlock.framework ?? 'dom' }
200
+ : undefined, paneWidths.paneWidths, context.targets.includes('svelte') ? context.svelteMode : undefined, context.targets.includes('react') ? REACT_ATTRIBUTE_NAMES : undefined, context.configuration.landing), null, 2) + '\n',
201
+ ];
202
+ // Themes: copy each theme's compiled stylesheet (+ optional asset dir) into
203
+ // the served tree - `<generatedRoot>/public` is the Vite publicDir, so the iframes
204
+ // link `themes/<id>/theme.css` (under the URL the preview is served from) by convention in dev and static build alike.
205
+ for (const theme of context.configuration.themes) {
206
+ const themeDirectory = resolve(generatedRoot, 'public/themes', theme.id);
207
+ const cssSource = resolve(context.kitRoot, theme.css);
208
+ if (!existsSync(cssSource)) {
209
+ throw new Error(`[preview] theme '${theme.id}' stylesheet not found: ${cssSource}`);
210
+ }
211
+ themeSources.push(cssSource);
212
+ outputs.push([
213
+ resolve(themeDirectory, 'theme.css'),
214
+ readFileSync(cssSource),
215
+ ]);
216
+ if (theme.assets) {
217
+ const assetsSource = resolve(context.kitRoot, theme.assets);
218
+ themeSources.push(assetsSource);
219
+ if (existsSync(assetsSource)) {
220
+ const assetsDestination = resolve(themeDirectory, basename(assetsSource));
221
+ const files = statSync(assetsSource).isDirectory()
222
+ ? filesUnder(assetsSource)
223
+ : [assetsSource];
224
+ for (const file of files) {
225
+ outputs.push([
226
+ resolve(assetsDestination, relative(assetsSource, file)),
227
+ readFileSync(file),
228
+ ]);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ // The html of each story's scenarios, which the static build cannot print
234
+ // on request: one file per component, by scenario id, the anonymous
235
+ // default under ''.
236
+ if (htmlSources) {
237
+ const enumerated = components.map((entry) => entry.component);
238
+ for (const [index, model] of built.entries()) {
239
+ if (model.omit || !model.standalone)
240
+ continue;
241
+ const { component, story } = components[index];
242
+ const byScenario = {};
243
+ // What the html leaves out, once per story however many of its
244
+ // scenarios do.
245
+ const warnings = new Set();
246
+ const anonymous = { id: '', props: {} };
247
+ for (const scenario of [anonymous, ...model.scenarios]) {
248
+ const result = await printHtmlSource(context, enumerated, {
249
+ component,
250
+ // The html the panes render, the unfilled default slot's
251
+ // placeholder included, as the scripted panes show it, and the
252
+ // scenario's own slot content where it has any.
253
+ ...sourceStoryOf(component, story, storyOnScenario(model, scenario), scenario.props ?? {}, { placeholder: true }),
254
+ });
255
+ if (result.markup !== undefined)
256
+ for (const warning of result.warnings)
257
+ warnings.add(warning);
258
+ byScenario[scenario.id] = htmlSourceResponse(context, enumerated, result);
259
+ }
260
+ if (warnings.size > 0)
261
+ console.warn(`[preview:generate] ${htmlWarningLine(model.name, [...warnings])}`);
262
+ outputs.push([
263
+ resolve(generatedRoot, 'public', HTML_SOURCE_DIRECTORY, `${sanitize(model.title)}.json`),
264
+ JSON.stringify(byScenario) + '\n',
265
+ ]);
266
+ }
267
+ }
268
+ outputs.push(manifest);
269
+ // Everything rendered: only now is the tree touched.
270
+ if (clean)
271
+ rmSync(generatedRoot, { recursive: true, force: true });
272
+ for (const target of targets) {
273
+ mkdirSync(directory[target], { recursive: true });
274
+ }
275
+ // Empty scratch registries so the previews' static scratch imports resolve;
276
+ // the scenario editor overwrites these on each edit (see emit/scratch.ts),
277
+ // so a kept tree keeps the story it holds.
278
+ if (clean || !existsSync(resolve(generatedRoot, 'scratch'))) {
279
+ writeScratchStubs(generatedRoot);
280
+ }
281
+ const written = outputs
282
+ .filter(([path, content]) => writeIfChanged(path, content))
283
+ .map(([path]) => path);
284
+ const produced = new Set(outputs.map(([path]) => path));
285
+ const removed = targets
286
+ .flatMap((target) => filesUnder(directory[target]))
287
+ .filter((path) => !produced.has(path));
288
+ for (const path of removed)
289
+ rmSync(path, { force: true });
290
+ const sourceSummary = sources
291
+ .map((source) => `${source.id}=${source.moduleBase}`)
292
+ .join(', ');
293
+ console.log(`[preview:generate] ${stories.length} components × ${context.targets.length} targets → .preview-generated/ (sources: ${sourceSummary})`);
294
+ if (editorOnly.length > 0)
295
+ console.log(`[preview:generate] ${editorOnly.length} not standalone (editor-only): ${editorOnly.map((model) => model.name).join(', ')}`);
296
+ const unlisted = stories.filter((model) => model.unlisted);
297
+ if (unlisted.length > 0)
298
+ console.log(`[preview:generate] unlisted ${unlisted.length} (reachable at their address): ${unlisted.map((model) => model.name).join(', ')}`);
299
+ if (omitted.length > 0)
300
+ console.log(`[preview:generate] omitted ${omitted.length} (by omit or omitPattern): ${omitted.join(', ')}`);
301
+ return { written, removed, themeSources };
302
+ }
@@ -0,0 +1,43 @@
1
+ import type { PreviewContext } from './context.js';
2
+ import type { HtmlSourceResponse } from './controller/html-source.js';
3
+ import type { HtmlSourceResult } from './emit/html-source.js';
4
+ import type { EnumeratedComponent } from './lib/types.js';
5
+ /** Where the kit's build writes the html target, relative to the kit root. */
6
+ export declare const HTML_DISTRIBUTION_DIRECTORY = "dist/html";
7
+ /**
8
+ * The `<style>` blocks of a page, joined in document order.
9
+ *
10
+ * @param page - A page's markup.
11
+ * @returns The CSS its style blocks hold, or `''` when it has none.
12
+ * @example
13
+ * ```ts
14
+ * styleBlocksOf('<style>.a { color: red; }</style><p class="a"></p>');
15
+ * // '.a { color: red; }'
16
+ * ```
17
+ */
18
+ export declare function styleBlocksOf(page: string): string;
19
+ /**
20
+ * The CSS the kit's build wrote for the html target of each named
21
+ * component, in the order given: the `<style>` blocks of its page and its
22
+ * own stylesheet, when it has one. A component with no built output adds
23
+ * nothing.
24
+ *
25
+ * @param context - The kit's preview context.
26
+ * @param components - Every component of the kit.
27
+ * @param names - The components whose styles to read, by name.
28
+ * @returns The CSS, one comment-headed section per component, or `''`.
29
+ */
30
+ export declare function htmlComponentStylesheet(context: PreviewContext, components: readonly EnumeratedComponent[], names: readonly string[]): string;
31
+ /**
32
+ * A printed story as the html pane receives it: its markup with the styles
33
+ * of the components it renders and the warnings for what it leaves out,
34
+ * those one component gives for one reason counted on a single line, or
35
+ * what keeps it from having markup.
36
+ *
37
+ * @param context - The kit's preview context.
38
+ * @param components - Every component of the kit.
39
+ * @param result - The printed story.
40
+ * @returns The response the development server answers and the static
41
+ * build stores.
42
+ */
43
+ export declare function htmlSourceResponse(context: PreviewContext, components: readonly EnumeratedComponent[], result: HtmlSourceResult): HtmlSourceResponse;
@@ -0,0 +1,145 @@
1
+ // The component styles the html pane shows its markup under: what the kit's
2
+ // build wrote for the html target, read from `dist/html` for the components a
3
+ // story renders. Under `in-file` each page carries its styles in `<style>`
4
+ // blocks; under `separate-file` each component has a stylesheet of its own,
5
+ // compiled when it is SCSS with the kit's own Sass and load paths. The markup
6
+ // is printed from the templates on request, so a component changed since the
7
+ // last build shows its last built styles until the kit builds again.
8
+ import { existsSync, readFileSync, statSync } from 'node:fs';
9
+ import { createRequire } from 'node:module';
10
+ import { dirname, resolve } from 'node:path';
11
+ import { summarizeHtmlWarnings } from './lib/html-warnings.js';
12
+ import { kitImporters, kitPackageDirectories } from './sass-importers.js';
13
+ /** Where the kit's build writes the html target, relative to the kit root. */
14
+ export const HTML_DISTRIBUTION_DIRECTORY = 'dist/html';
15
+ const STYLE_BLOCK = /<style\b[^>]*>([\s\S]*?)<\/style>/gi;
16
+ /**
17
+ * The `<style>` blocks of a page, joined in document order.
18
+ *
19
+ * @param page - A page's markup.
20
+ * @returns The CSS its style blocks hold, or `''` when it has none.
21
+ * @example
22
+ * ```ts
23
+ * styleBlocksOf('<style>.a { color: red; }</style><p class="a"></p>');
24
+ * // '.a { color: red; }'
25
+ * ```
26
+ */
27
+ export function styleBlocksOf(page) {
28
+ return [...page.matchAll(STYLE_BLOCK)]
29
+ .map((match) => match[1].trim())
30
+ .filter((css) => css !== '')
31
+ .join('\n');
32
+ }
33
+ /** A component name a built file can carry: an identifier, so it names a
34
+ * file in the html directory and nothing outside it. */
35
+ const BUILT_NAME = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
36
+ /** Each compiled SCSS sheet, by path, with the modification time it was
37
+ * compiled at. */
38
+ const compiledSheets = new Map();
39
+ /** The sheets already reported as left out, each reported once. */
40
+ const reportedSheets = new Set();
41
+ /** Compiles an SCSS file with the kit's own Sass, or says why it cannot.
42
+ * A sheet unchanged since it last compiled is not compiled again. */
43
+ function compileScss(path, context) {
44
+ const modified = statSync(path).mtimeMs;
45
+ const cached = compiledSheets.get(path);
46
+ if (cached && cached.modified === modified)
47
+ return { css: cached.css };
48
+ let sass;
49
+ try {
50
+ const kitRequire = createRequire(resolve(context.kitRoot, 'package.json'));
51
+ sass = kitRequire('sass');
52
+ }
53
+ catch {
54
+ return { problem: 'the kit has no sass installed to compile it' };
55
+ }
56
+ try {
57
+ const loadPaths = [
58
+ dirname(path),
59
+ ...context.sassLoadPathsAbsolute,
60
+ ...(context.configuration.scssLoadPaths ?? []).map((loadPath) => resolve(context.kitRoot, loadPath)),
61
+ ];
62
+ // The kit's own `pkg:` URLs resolve through its package.json exports,
63
+ // as its build resolves them, and any other through Sass's own importer.
64
+ const importers = [
65
+ ...kitImporters(context.kitRoot, kitPackageDirectories(context)),
66
+ ...(sass.NodePackageImporter
67
+ ? [new sass.NodePackageImporter(context.kitRoot)]
68
+ : []),
69
+ ];
70
+ const css = sass.compile(path, { loadPaths, importers }).css;
71
+ compiledSheets.set(path, { modified, css });
72
+ return { css };
73
+ }
74
+ catch (error) {
75
+ return { problem: error instanceof Error ? error.message : String(error) };
76
+ }
77
+ }
78
+ /**
79
+ * The CSS the kit's build wrote for the html target of each named
80
+ * component, in the order given: the `<style>` blocks of its page and its
81
+ * own stylesheet, when it has one. A component with no built output adds
82
+ * nothing.
83
+ *
84
+ * @param context - The kit's preview context.
85
+ * @param components - Every component of the kit.
86
+ * @param names - The components whose styles to read, by name.
87
+ * @returns The CSS, one comment-headed section per component, or `''`.
88
+ */
89
+ export function htmlComponentStylesheet(context, components, names) {
90
+ const directory = resolve(context.kitRoot, HTML_DISTRIBUTION_DIRECTORY);
91
+ if (!existsSync(directory))
92
+ return '';
93
+ const sections = [];
94
+ for (const name of names) {
95
+ if (!components.some((candidate) => candidate.name === name))
96
+ continue;
97
+ if (!BUILT_NAME.test(name))
98
+ continue;
99
+ const parts = [];
100
+ const page = resolve(directory, `${name}.html`);
101
+ if (existsSync(page))
102
+ parts.push(styleBlocksOf(readFileSync(page, 'utf8')));
103
+ const css = resolve(directory, `${name}.css`);
104
+ if (existsSync(css))
105
+ parts.push(readFileSync(css, 'utf8').trim());
106
+ const scss = resolve(directory, `${name}.scss`);
107
+ if (existsSync(scss)) {
108
+ const compiled = compileScss(scss, context);
109
+ if ('css' in compiled)
110
+ parts.push(compiled.css.trim());
111
+ else if (!reportedSheets.has(scss)) {
112
+ reportedSheets.add(scss);
113
+ console.warn(`[preview] ${name}: the html pane leaves out ${name}.scss, as ${compiled.problem}`);
114
+ }
115
+ }
116
+ const styles = parts.filter((part) => part !== '').join('\n');
117
+ if (styles !== '')
118
+ sections.push(`/* ${name} */\n${styles}`);
119
+ }
120
+ return sections.join('\n\n');
121
+ }
122
+ /**
123
+ * A printed story as the html pane receives it: its markup with the styles
124
+ * of the components it renders and the warnings for what it leaves out,
125
+ * those one component gives for one reason counted on a single line, or
126
+ * what keeps it from having markup.
127
+ *
128
+ * @param context - The kit's preview context.
129
+ * @param components - Every component of the kit.
130
+ * @param result - The printed story.
131
+ * @returns The response the development server answers and the static
132
+ * build stores.
133
+ */
134
+ export function htmlSourceResponse(context, components, result) {
135
+ if (result.markup === undefined)
136
+ return { missing: result.missing };
137
+ const stylesheet = htmlComponentStylesheet(context, components, result.components);
138
+ return {
139
+ markup: result.markup,
140
+ ...(stylesheet === '' ? {} : { stylesheet }),
141
+ ...(result.warnings.length === 0
142
+ ? {}
143
+ : { warnings: summarizeHtmlWarnings(result.warnings) }),
144
+ };
145
+ }
@@ -0,0 +1,18 @@
1
+ export { jsonProblems, loadPreviewContext, type PreviewContext, type ResolvedSource, } from './context.js';
2
+ export { generatePreview } from './generate.js';
3
+ export { checkPreview, type PreviewCheckOptions, type PreviewCheckReport, } from './check.js';
4
+ export { storySource, type SourceTarget, type StorySource, type StorySourceOptions, } from './story-source.js';
5
+ export { loadKit, kitPaneWidths, type KitPaneWidths, type LoadedComponent, type LoadedKit, } from './load.js';
6
+ export { readPropsFrom, resolveManualComponent, type PropsFromResult, } from './props-from.js';
7
+ export { applicationRoot, buildViteConfiguration, type DevelopmentServerOverrides, } from './vite-configuration.js';
8
+ export { enumerateComponents } from './enumerate.js';
9
+ export { resolveStory } from './model.js';
10
+ export { propTypeForProp, defaultPropForProp } from './prop-types.js';
11
+ export { loadStory, isStructurallyOmitted } from './story.js';
12
+ export { emitReactRegistry } from './emit/react.js';
13
+ export { emitVueRegistry } from './emit/vue.js';
14
+ export { emitSvelteRegistry, emitSvelteWrapper } from './emit/svelte.js';
15
+ export { buildManifest, type Manifest, type ManifestComponent, type ManifestSource, } from './emit/manifest.js';
16
+ export { writeScratch, writeScratchStubs, SCRATCH_ID, type ScratchPayload, } from './emit/scratch.js';
17
+ export * from './lib/types.js';
18
+ export * from './options.js';
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ // Programmatic surface: everything a consumer's own scripts (or tests) need -
2
+ // the context loader, the generator, the Vite configuration factory, and the model /
3
+ // emit layer the registries are built from.
4
+ export { jsonProblems, loadPreviewContext, } from './context.js';
5
+ export { generatePreview } from './generate.js';
6
+ export { checkPreview, } from './check.js';
7
+ export { storySource, } from './story-source.js';
8
+ export { loadKit, kitPaneWidths, } from './load.js';
9
+ export { readPropsFrom, resolveManualComponent, } from './props-from.js';
10
+ export { applicationRoot, buildViteConfiguration, } from './vite-configuration.js';
11
+ export { enumerateComponents } from './enumerate.js';
12
+ export { resolveStory } from './model.js';
13
+ export { propTypeForProp, defaultPropForProp } from './prop-types.js';
14
+ export { loadStory, isStructurallyOmitted } from './story.js';
15
+ export { emitReactRegistry } from './emit/react.js';
16
+ export { emitVueRegistry } from './emit/vue.js';
17
+ export { emitSvelteRegistry, emitSvelteWrapper } from './emit/svelte.js';
18
+ export { buildManifest, } from './emit/manifest.js';
19
+ export { writeScratch, writeScratchStubs, SCRATCH_ID, } from './emit/scratch.js';
20
+ export * from './lib/types.js';
21
+ export * from './options.js';
@@ -0,0 +1,16 @@
1
+ import type { PreviewLandingConfiguration, ResolvedStory } from './lib/types.js';
2
+ /**
3
+ * What is wrong with the landing entry a kit names, against its stories:
4
+ * a component with no story, or a scenario the story does not have. A
5
+ * view's id is not checked here. Empty when the entry is sound or unset.
6
+ *
7
+ * @param landing - The kit's `preview.landing`.
8
+ * @param stories - The kit's browseable stories: omitted components and those
9
+ * that are not standalone left out.
10
+ * @returns One message per problem.
11
+ * @example
12
+ * ```ts
13
+ * landingProblems({ component: 'components-button', scenario: 'primary' }, stories);
14
+ * ```
15
+ */
16
+ export declare function landingProblems(landing: PreviewLandingConfiguration | undefined, stories: readonly ResolvedStory[]): string[];
@@ -0,0 +1,45 @@
1
+ // The entry a kit names for the preview to open on (`preview.landing`),
2
+ // checked against the kit's stories: the generator and the check both refuse
3
+ // a story or scenario the kit has none of. A view's id is the views module's,
4
+ // which only the browser loads, so the preview's controller checks that one.
5
+ import { sanitize } from './lib/naming.js';
6
+ /** The id of the synthetic scenario that renders a story with no content. */
7
+ const EMPTY_SCENARIO_ID = 'empty';
8
+ /**
9
+ * What is wrong with the landing entry a kit names, against its stories:
10
+ * a component with no story, or a scenario the story does not have. A
11
+ * view's id is not checked here. Empty when the entry is sound or unset.
12
+ *
13
+ * @param landing - The kit's `preview.landing`.
14
+ * @param stories - The kit's browseable stories: omitted components and those
15
+ * that are not standalone left out.
16
+ * @returns One message per problem.
17
+ * @example
18
+ * ```ts
19
+ * landingProblems({ component: 'components-button', scenario: 'primary' }, stories);
20
+ * ```
21
+ */
22
+ export function landingProblems(landing, stories) {
23
+ if (!landing || !('component' in landing))
24
+ return [];
25
+ const story = stories.find((candidate) => sanitize(candidate.title) === landing.component);
26
+ if (!story)
27
+ return [
28
+ `preview.landing names component '${landing.component}', which has no story; a story's id is the one the preview's address carries as component=`,
29
+ ];
30
+ const scenario = landing.scenario;
31
+ if (scenario === undefined)
32
+ return [];
33
+ const hasContent = story.contentSlots.default || story.contentSlots.named.length > 0;
34
+ const scenarios = [
35
+ ...(hasContent ? [EMPTY_SCENARIO_ID] : []),
36
+ ...story.scenarios.map((candidate) => candidate.id),
37
+ ];
38
+ return scenarios.includes(scenario)
39
+ ? []
40
+ : [
41
+ `preview.landing names scenario '${scenario}' of '${landing.component}', which has ${scenarios.length > 0
42
+ ? `the scenarios ${scenarios.join(', ')}`
43
+ : 'no scenarios'}`,
44
+ ];
45
+ }
@@ -0,0 +1,42 @@
1
+ import type { Target } from './types.js';
2
+ /**
3
+ * The type names one module-scope line exports. A value-only export list
4
+ * (`export { a }`) names no type unless a member is marked `type`, as a value
5
+ * cannot be told from a type there.
6
+ *
7
+ * @param line - A verbatim module-scope line.
8
+ * @returns The type names it exports, in order.
9
+ */
10
+ export declare function exportedTypeNamesOf(line: string): string[];
11
+ /** The parts of a template the exported types are read from. */
12
+ export interface ExportingTemplate {
13
+ imports?: string[];
14
+ extensions?: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * The type names a template's generated module exports in one scripted
18
+ * target: those its module-scope lines declare, the target's own `imports`
19
+ * merged in (or in their place, with `importsStrategy: 'replace'`).
20
+ *
21
+ * @param template - The component's template.
22
+ * @param target - The scripted target.
23
+ * @returns The exported type names, each once.
24
+ * @example
25
+ * ```ts
26
+ * exportedTypeNames({ imports: ['export interface DateValue { day: string }'] }, 'react');
27
+ * // ['DateValue']
28
+ * ```
29
+ */
30
+ export declare function exportedTypeNames(template: ExportingTemplate, target: Target): string[];
31
+ /**
32
+ * The type names a component's generated module exports, per scripted
33
+ * target: none for a component written by hand, whose module the preview
34
+ * does not read.
35
+ *
36
+ * @param component - The component, with the template it was read from.
37
+ * @param targets - The scripted targets the kit builds.
38
+ * @returns The names per target that exports any, or `undefined` when none does.
39
+ */
40
+ export declare function exportedTypesOf(component: {
41
+ template?: unknown;
42
+ }, targets: readonly Target[]): Partial<Record<Target, string[]>> | undefined;