@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,778 @@
1
+ // Shared data shapes for the story generator. Everything here is
2
+ // framework-agnostic - the emitters (emit/<target>.ts) translate these into
3
+ // each framework's own syntax.
4
+
5
+ import type { Template, TemplateNode } from '@js-template-engine/types';
6
+ import type {
7
+ PreviewCanvasConfiguration,
8
+ PreviewMountNode,
9
+ PreviewOption,
10
+ PreviewViewCanvasConfiguration,
11
+ } from '../options.js';
12
+ // The preview block's type, which this package gives scaffold-ui-kit's.
13
+ import type {} from 'scaffold-ui-kit';
14
+
15
+ export type JsonValue =
16
+ | string
17
+ | number
18
+ | boolean
19
+ | null
20
+ | undefined
21
+ | JsonValue[]
22
+ | { [key: string]: JsonValue };
23
+
24
+ /** A scripted target the preview can render a component into. A component declares the
25
+ * subset it supports (`targets`); most support all three, but one bound to a
26
+ * single-framework library (a React-only toast package, say) supports fewer - the
27
+ * generator emits only those registries and the host shows only those panes. */
28
+ export type Target = 'react' | 'vue' | 'svelte';
29
+
30
+ /** The default: a component renders in every target unless it narrows the set. */
31
+ export const ALL_TARGETS: Target[] = ['react', 'vue', 'svelte'];
32
+
33
+ /** A control derived from one component prop. */
34
+ export interface PropTypeSpecification {
35
+ name: string;
36
+ control: 'text' | 'boolean' | 'number' | 'select' | 'color-select';
37
+ /** For `select`: its values, each a string or a boolean, and `undefined`
38
+ * for the unset choice. `color-select` draws its options from the shared
39
+ * token list. */
40
+ options?: (string | boolean | undefined)[];
41
+ /** For `number`. */
42
+ number?: { min?: number; max?: number; step?: number };
43
+ /** false → omit from the controls table (driver-internal / complex props). */
44
+ include: boolean;
45
+ /** The prop's description from its template, in markdown, shown on its control. */
46
+ description?: string;
47
+ }
48
+
49
+ /**
50
+ * What a component declares about one prop, as its template (or, for a
51
+ * component written by hand, its props type) writes it.
52
+ */
53
+ export interface PropDeclaration {
54
+ /** The prop's type as written, such as `"'solid' | 'ghost'"` or `'boolean'`. */
55
+ declaredType: string;
56
+ /** Whether the component requires the prop. */
57
+ required: boolean;
58
+ /** The component's own default for the prop, absent when it declares none.
59
+ * A story's `defaultProps` start from it, then add the kit's hints and the
60
+ * story file's `defaultProps`, so the two can differ. */
61
+ declaredDefault?: JsonValue;
62
+ /** A default the component applies without declaring it, as the code a
63
+ * consumer reads (`"'start'"`), for showing beside the control. Absent
64
+ * when the component documents none. */
65
+ documentedDefault?: string;
66
+ }
67
+
68
+ /**
69
+ * One prop of a component: the control the preview derives for it and what
70
+ * the component declares about it.
71
+ *
72
+ * - `name`, `control`, `options` (a select's values), `number` (a number
73
+ * input's range), `include` (`false` for a prop shown no control) and
74
+ * `description` (markdown) describe the control.
75
+ * - `declaredType` is the prop's type as the component writes it, `required`
76
+ * whether the component requires it, `declaredDefault` the component's
77
+ * own default, absent when it declares none, and `documentedDefault` a
78
+ * default it applies without declaring, as the code a consumer reads.
79
+ *
80
+ * `declaredDefault` is the component's default as a consumer gets it. The
81
+ * story's starting value is in its `defaultProps`, which adds the kit's hints
82
+ * and the story file's `defaultProps` over it.
83
+ */
84
+ export type PreviewPropType = PropTypeSpecification & PropDeclaration;
85
+
86
+ /**
87
+ * A two-way prop a component declares (a prop whose `bindable` is an
88
+ * object): the component keeps its own value while the prop is not given,
89
+ * and calls `changeProp` with each new value. A story that gives `prop` is
90
+ * controlled: when a pane reports `changeProp`, the controller takes the
91
+ * value as the story's new `prop`.
92
+ */
93
+ export interface PreviewBinding {
94
+ /** The two-way prop. */
95
+ prop: string;
96
+ /** The prop the component's own value starts from, if any. */
97
+ defaultProp?: string;
98
+ /** The event prop called with each new value, if any. A story that gives
99
+ * `prop` takes the value it reports as its new `prop`. */
100
+ changeProp?: string;
101
+ /** Whether a Vue consumer binds the prop with a bare `v-model` (the
102
+ * template's `extensions.vue.model`), beside `v-model:<prop>`. */
103
+ vueModel?: boolean;
104
+ /** Whether the component takes type parameters (its template's
105
+ * `typeParameters`), so a consumer's state for the prop infers its type
106
+ * from the value rather than naming it. */
107
+ generic?: boolean;
108
+ }
109
+
110
+ /**
111
+ * How to fill a slot when rendering a demo. A recursive node tree - a slot fill
112
+ * *is*, in effect, an anonymous template subtree whose leaves are real
113
+ * components. Single-source; the emitters translate it to each target's markup.
114
+ * Field names are a deliberate subset of `@js-template-engine/types`
115
+ * `TemplateNode` (`slots`, `children`, `tag`).
116
+ *
117
+ * - `element` carries a component's `props`, its default-slot `children`, **and**
118
+ * its **named** `slots` (e.g. an `IconLabel` with its `icon` slot filled).
119
+ * - `html` is a plain DOM tag (`<section>`/`<div>` wrappers) - props + children,
120
+ * no named slots.
121
+ */
122
+ export type SlotFill =
123
+ | { kind: 'text'; value: string }
124
+ | {
125
+ kind: 'element';
126
+ component: string;
127
+ props?: Record<string, JsonValue>;
128
+ slots?: Record<string, SlotFill>;
129
+ children?: SlotFill;
130
+ }
131
+ | {
132
+ kind: 'html';
133
+ tag: string;
134
+ props?: Record<string, JsonValue>;
135
+ children?: SlotFill;
136
+ }
137
+ | { kind: 'fragment'; children: SlotFill[] }
138
+ | {
139
+ kind: 'raw';
140
+ react: string;
141
+ vue: string;
142
+ svelte: string;
143
+ /** What it renders to, for the story's html source: markup, or template
144
+ * nodes, which render as the kit's templates do - a kit component
145
+ * among them included. Without it, the story has no html source. */
146
+ html?: string | TemplateNode[];
147
+ /** Kit components the raw strings reference, so the generated registry imports
148
+ * them (a raw string is opaque - unlike `element`, its imports can't be walked).
149
+ * e.g. a `renderCell` raw that returns `<TextInput/>` declares `['TextInput']`. */
150
+ imports?: string[];
151
+ }
152
+ | {
153
+ /**
154
+ * A **scoped** slot fill - content the *parent* parameterizes with runtime
155
+ * values (a row, an index, a setter), the cross-framework generalization of a
156
+ * React render-prop. Only valid at a top-level named-slot position (it needs the
157
+ * host component to supply the scope), never nested inside another fill.
158
+ *
159
+ * Its target name differs per framework because the same scoped slot is a render-prop
160
+ * in React but a scoped slot / snippet in Vue/Svelte (e.g. a table's
161
+ * `renderCell` prop is a `#cell` slot in Vue and a `cell` snippet in Svelte). The
162
+ * emitters translate one fill into: React `name={({ parameters }) => (body)}` (prop),
163
+ * Vue `<template #name="{ parameters }">body</template>`, Svelte
164
+ * `{#snippet name({ parameters })} body{/snippet}` - one `parameters` list, spelled the
165
+ * same way in every target unless `reactScope` says the React side is
166
+ * positional.
167
+ */
168
+ kind: 'scoped';
169
+ /** The slot's identifier per target: the React render-prop name, the Vue scoped-slot
170
+ * name, the Svelte snippet name (they differ - see above). */
171
+ slot: { react: string; vue: string; svelte: string };
172
+ /** The scope parameter names the host passes, destructured in each target
173
+ * (e.g. `['column', 'row', 'index', 'setField']`). */
174
+ parameters: string[];
175
+ /**
176
+ * How the React side receives the scope. Vue and Svelte always destructure
177
+ * `parameters` off one scope object; React can do either, and the two shapes are
178
+ * indistinguishable in the generated source - both compile, and the wrong one
179
+ * binds the whole scope to the first name.
180
+ *
181
+ * - `'object'` (the default) - React destructures one scope object,
182
+ * `name={({ a, b }) => body}`. This is what a generated component's scoped
183
+ * slot supplies: its render prop is always called with a single object, so
184
+ * one `parameters` list stays correct across all three emitters.
185
+ * - `'positional'` - React takes the names as separate parameters,
186
+ * `name={(a, b) => body}`. For a hand-written component whose React prop really
187
+ * is positional (a table's `renderCell(column, row, index, setField)`),
188
+ * where its Vue and Svelte counterparts are still one destructured object.
189
+ */
190
+ reactScope?: 'object' | 'positional';
191
+ /** Per-target body referencing `parameters`. React is a JSX expression, or
192
+ * JSX content (sibling roots, text), which it returns in a fragment; Vue
193
+ * and Svelte are markup fragments. An empty string omits that target's
194
+ * slot. */
195
+ react: string;
196
+ vue: string;
197
+ svelte: string;
198
+ /** What the body renders to at rest, for the story's html source:
199
+ * markup, or template nodes, which also read the values the slot
200
+ * exposes under `parameters` (one the slot cannot give reads every
201
+ * property as `undefined`). Without it, the story has no html source. */
202
+ html?: string | TemplateNode[];
203
+ /** Components the bodies reference, imported into the generated registry (opaque
204
+ * strings can't be walked - as `raw`). */
205
+ imports?: string[];
206
+ }
207
+ | {
208
+ /**
209
+ * A call to a **part**: content the story declares once, by name, outside
210
+ * its markup, and calls here with `props`. Its body may call the part
211
+ * again, so content shaped like its data - a tree, lists nested in each
212
+ * other's items - renders to any depth, ending where the data does.
213
+ *
214
+ * Each target declares the part as it would by hand: React a function
215
+ * component, Vue a component (a single-file component of its own in the
216
+ * story's source), Svelte a snippet at the top of the markup. A call is
217
+ * `<Name ... />` in React and Vue and `{@render Name({ ... })}` in Svelte,
218
+ * spelled the same way inside a body, where the props are expressions.
219
+ * The declaration rides on every call; two calls of one name must carry
220
+ * the same one.
221
+ */
222
+ kind: 'part';
223
+ /** The part's name: a component's name in React and Vue, the snippet's in Svelte. */
224
+ name: string;
225
+ /** The props the part takes, read by name in its bodies. */
226
+ parameters: string[];
227
+ /** A TypeScript type per parameter, for the story's printed source: React's
228
+ * props and Svelte's snippet take them, a parameter without one is `any`,
229
+ * and Vue's `defineProps` is typed once any is given. A type a kit names
230
+ * (`Folder[]`) is the reader's to declare or import. */
231
+ parameterTypes?: Record<string, string>;
232
+ /** The props this call passes. */
233
+ props?: Record<string, JsonValue>;
234
+ /** The body per target, reading `parameters`. React is a JSX expression,
235
+ * or JSX content (sibling roots, text), which it returns in a fragment;
236
+ * Vue and Svelte are markup fragments. */
237
+ react: string;
238
+ vue: string;
239
+ svelte: string;
240
+ /** What the body renders to, for the story's html source: template
241
+ * nodes reading `parameters`, a call to the part among them rendering
242
+ * it again. Without it, the story has no html source. */
243
+ html?: TemplateNode[];
244
+ /** Kit components the bodies reference, imported where the part is declared. */
245
+ imports?: string[];
246
+ };
247
+
248
+ /** A call to a part (see the `part` slot fill). */
249
+ export type PartFill = Extract<SlotFill, { kind: 'part' }>;
250
+
251
+ export interface SlotPlan {
252
+ default?: SlotFill;
253
+ named?: Record<string, SlotFill>;
254
+ }
255
+
256
+ /** Content a story renders beside its component: any slot fill but a
257
+ * `scoped` one, which needs a slot to give it values. */
258
+ export type AroundFill = Exclude<SlotFill, { kind: 'scoped' }>;
259
+
260
+ /** What a story renders beside its component, as its siblings: `before` it
261
+ * and `after` it, such as a hint element whose id the component's
262
+ * `aria-describedby` names. */
263
+ export interface StoryAround {
264
+ before?: AroundFill;
265
+ after?: AroundFill;
266
+ }
267
+
268
+ export interface Scenario {
269
+ id: string;
270
+ /** Display label in the scenario picker. Defaults to `id` when omitted. */
271
+ label?: string;
272
+ /** What the scenario shows and why it is worth a look, for a shell to show
273
+ * beside it. Markdown allowed. */
274
+ description?: string;
275
+ props?: Record<string, JsonValue>;
276
+ /** Slot content of the scenario's own, in the shape of the story's
277
+ * `slots`: a slot it fills takes the scenario's fill in place of the
278
+ * story's, and every other slot keeps the story's. For a scenario whose
279
+ * point is what the component holds, such as a message's text per
280
+ * severity. */
281
+ slots?: SlotPlan;
282
+ /** Values for the kit's preview options, keyed by option id, that picking
283
+ * the scenario sets: the setting it shows the component in, such as
284
+ * `{ mode: 'dark', surface: '3' }`. A global option keeps its value after
285
+ * another scenario is picked, as if it were set by hand; a story option
286
+ * keeps it until another story is selected. */
287
+ options?: Record<string, string | boolean>;
288
+ /** Mark the baseline configuration: shown as "<label> (default)" and selected
289
+ * initially, instead of the anonymous "(default)". At most one per component. */
290
+ default?: boolean;
291
+ /** Generated from one enum value or boolean (see Story.generate), not curated.
292
+ * Set by the generator; listed after the curated scenarios. */
293
+ generated?: boolean;
294
+ }
295
+
296
+ /**
297
+ * A component's story file (`<Name>.story.ts` in its source's stories
298
+ * directory, default-exported): what its story shows - props, controls, slot
299
+ * content, scenarios, options - and whether it has one. Absent, the story is
300
+ * the component's defaults. The single home for per-component curation, never
301
+ * per target.
302
+ */
303
+ export interface Story {
304
+ omit?: boolean;
305
+ /**
306
+ * Whether the component has a story of its own. Default `true`. A
307
+ * component set `false` (a compound's subcomponent such as `TabList`,
308
+ * `Tab` or `TabPanel`, meaningful only nested inside its parent, or a
309
+ * shared building block) is left out of the story navigation but stays in
310
+ * the manifest for the editor's component picker, so its node, props and
311
+ * slots can be authored in a parent's content tree. Unlike `omit`, which
312
+ * drops it from the manifest entirely. A component its compound's root
313
+ * lists in `parts` (in the root's template, or in the kit configuration's
314
+ * `parts` for a root with no template) is `standalone: false` without the
315
+ * flag; `check` warns of the flag on a component no root lists, unless the
316
+ * component is no one compound's part: two or more templates render it, a
317
+ * story of its source labeled with its name stands in for it, or it lists
318
+ * parts of its own. A manual spec's `standalone` is not checked; its story
319
+ * file's is.
320
+ */
321
+ standalone?: boolean;
322
+ /**
323
+ * An *unlisted* story: generated, rendered in every target and reachable
324
+ * at its address (`?component=<id>`) and through the testing helpers, as
325
+ * any story is, but left out of what a reader browses - the navigation,
326
+ * the editor's component picker, the component count, and the catalog a
327
+ * custom view reads. For a story that exists for a kit's own tests, such as
328
+ * a fixture a browser test drives. The catalog keeps it, flagged
329
+ * `unlisted`. A component that is `omit` or `standalone: false` has no
330
+ * story to leave unlisted, so `check` reports `unlisted` beside either as
331
+ * an error.
332
+ */
333
+ unlisted?: boolean;
334
+ category?: string;
335
+ /** The name shown in the navigation, when it should differ from the component's
336
+ * (import) name - e.g. a playground fixture of another package whose export must stay unique
337
+ * in the shared registry (`ToastExample`) but reads better as `Toast`. Display only;
338
+ * the import identifier and editor root stay the component's real `name`.
339
+ * A story labeled with the name of a component in its source that is
340
+ * `standalone: false` is that component's story. */
341
+ label?: string;
342
+ defaultProps?: Record<string, JsonValue>;
343
+ /** Control tweaks per prop (a number range, a select's options). `false` excludes
344
+ * the prop: no control, no generated scenario, no coverage warning. */
345
+ controls?: Record<string, Partial<PropTypeSpecification> | false>;
346
+ /** Props always passed with this value and never shown as controls. A scenario
347
+ * may not set one. */
348
+ fixed?: Record<string, JsonValue>;
349
+ /** Scenario generation: by default one scenario per enum value other than the
350
+ * default and one per boolean flipped from its default, for every select and
351
+ * boolean control. `false` turns it off; a list of prop names narrows it to
352
+ * those props; `{ exclude }` generates every prop but those. A curated
353
+ * scenario setting exactly one such value stands in for its generated one, and
354
+ * a curated scenario taking a generated id (`<prop>-<value>`, or the prop for
355
+ * a boolean) replaces it, so it should set that value. */
356
+ generate?: false | string[] | { exclude: string[] };
357
+ slots?: SlotPlan;
358
+ /** Content rendered beside the component, as its siblings, in every pane
359
+ * and the story's code: `before` it and `after` it. Shared by the
360
+ * scenarios, as `slots` is. */
361
+ around?: StoryAround;
362
+ scenarios?: Scenario[];
363
+ /** Per-story defaults for story-scoped preview options (the kit's
364
+ * `options`, such as a box or padding around the component), keyed by option id. A value seeds that option's starting value
365
+ * for this component; `false` marks the option *unavailable* here (no control
366
+ * shown, and held at its option default) - e.g. a full-page template is edge-to-edge
367
+ * so `{ box: false, padded: false }`. Options omitted here use their config default. */
368
+ options?: Record<string, JsonValue | false>;
369
+ }
370
+
371
+ /** What content a component accepts - its default slot and any named slots.
372
+ * Surfaced to the host so the editor can offer the right add-targets. */
373
+ export interface ContentSlots {
374
+ /** Whether the component exposes an unnamed (default) slot. */
375
+ default: boolean;
376
+ /** Named slot names the component exposes (e.g. `icon`, `navigation`). */
377
+ named: string[];
378
+ /** The slots among them whose content must take their scope, the default
379
+ * slot as `default`: they hold content like any other, but take only a
380
+ * scoped fill, so the editor offers no plain content for them. */
381
+ scopeRequired?: string[];
382
+ }
383
+
384
+ /** The framework-agnostic intermediate an emitter consumes. */
385
+ export interface ResolvedStory {
386
+ name: string;
387
+ title: string;
388
+ /** What the component is: its template's `description`, or its manual
389
+ * spec's. Markdown allowed. */
390
+ description?: string;
391
+ omit: boolean;
392
+ /** Whether the component has a story of its own. One that is not stays in
393
+ * the manifest for the editor, hidden from the story navigation and the
394
+ * per-target registries (see Story.standalone). */
395
+ standalone: boolean;
396
+ /** A story left out of the navigation, the editor's picker and the counts,
397
+ * still generated and reachable at its address (see Story.unlisted).
398
+ * Never set on one that is `omit` or not `standalone`. */
399
+ unlisted: boolean;
400
+ propTypes: PreviewPropType[];
401
+ /** The props that are events: functions returning nothing, which the
402
+ * component calls as things happen. */
403
+ events?: string[];
404
+ /** The component's two-way props. */
405
+ bindings?: PreviewBinding[];
406
+ defaultProps: Record<string, JsonValue>;
407
+ /** The values in `defaultProps` that neither the component declares nor its
408
+ * story file sets: the preview's own starting values, from the kit's control
409
+ * hints. A consumer's source leaves them out. */
410
+ previewDefaults?: Record<string, JsonValue>;
411
+ slots?: SlotPlan;
412
+ /** The content rendered beside the component (see Story.around). */
413
+ around?: StoryAround;
414
+ scenarios: Scenario[];
415
+ /** Extra component names referenced by slot fills and the content beside
416
+ * the component, to import in the story. */
417
+ slotComponents: string[];
418
+ /** The slots the component accepts (for the editor's add-content targets). */
419
+ contentSlots: ContentSlots;
420
+ /** Per-story preview-option defaults / availability (see Story.options). */
421
+ options?: Record<string, JsonValue | false>;
422
+ /** The id of the preview source this story belongs to - groups it under its
423
+ * navigation section. Assigned by the generator; defaults to 'core'. */
424
+ source?: string;
425
+ /** The targets this story renders into (default all three). A React-only
426
+ * fixture narrows this to `['react']`, so the generator emits only the
427
+ * React registry and the host shows only the React pane. */
428
+ targets: Target[];
429
+ /** Set on the story of one scenario with slot content of its own, which
430
+ * the generator renders beside the component's story: the id the panes
431
+ * mount it by and the name its render unit takes, in place of the ones
432
+ * derived from the title and the component's name. */
433
+ scenarioStory?: { id: string; renderName: string };
434
+ }
435
+
436
+ /** One enumerated component: a globbed template, or a resolved manual spec. */
437
+ export interface EnumeratedComponent {
438
+ name: string;
439
+ file: string;
440
+ /** The template a globbed component was read from; a manual spec has none. */
441
+ template?: Template;
442
+ /** What the component is: the template's `description`, or, for a manual
443
+ * spec, written beside it. Markdown allowed. */
444
+ description?: string;
445
+ props: Record<
446
+ string,
447
+ {
448
+ type: string;
449
+ /** `type` with the named types it uses expanded through the template's
450
+ * imports, when that differs: what the prop's control is read from,
451
+ * while `type` stays as written. */
452
+ resolvedType?: string;
453
+ default?: JsonValue;
454
+ documentedDefault?: string;
455
+ required?: boolean;
456
+ description?: string;
457
+ }
458
+ >;
459
+ hasDefaultSlot: boolean;
460
+ /** Whether the default slot exposes values to its content (a scoped slot):
461
+ * the preview then seeds no placeholder text into it, so its fallback
462
+ * renders. */
463
+ defaultSlotScoped?: boolean;
464
+ /** Named slots the component declares (`{ type: 'slot', name }`). */
465
+ slotNames: string[];
466
+ /** The slots whose content must take their scope (a template slot's
467
+ * `scopeRequired`), by name, the default slot as `default`: a story fills
468
+ * them only with a `scoped` fill, React's render function, and the editor
469
+ * offers them no plain content. */
470
+ scopeRequiredSlots?: string[];
471
+ /** Whether the component's root forwards native attributes (a template's
472
+ * `passthrough` element): the check then accepts HTML attribute names too. */
473
+ passthrough?: boolean;
474
+ /** Where the component gathers a consumer's leftover attributes (a
475
+ * template's `rest`), and the tag they are typed as: the check then
476
+ * accepts HTML attribute names too, as for `passthrough`. */
477
+ rest?: { tag: string };
478
+ /** Whether the component has a story of its own (a manual spec's). Default
479
+ * `true`; `false` makes it editor-only. See Story.standalone. */
480
+ standalone?: boolean;
481
+ /** A story reachable at its address but left out of the navigation, the
482
+ * editor's picker and the counts (a manual spec's). See Story.unlisted. */
483
+ unlisted?: boolean;
484
+ /** The targets this component renders into (default all three - `ALL_TARGETS`).
485
+ * A manual spec bound to a React-only library sets `['react']`. */
486
+ targets?: Target[];
487
+ /** Override the module each target imports this component from, when it is NOT the
488
+ * source's module for the target - e.g. a preview-internal playground fixture that
489
+ * lives beside another package's code rather than in its published barrel. Keyed by
490
+ * target; a target absent from the map falls back to the source default. */
491
+ importModule?: Partial<Record<Target, string>>;
492
+ /** The identifier the module actually **exports**, when it differs from `name` (the
493
+ * unique preview identity used for addressing + as the local binding). Another
494
+ * package's components export clean, unprefixed names that collide with the kit's - a toast package exporting
495
+ * `Toast`, a forms package its own `TextInput` - so the preview names the
496
+ * component uniquely (`NoticeToast`) and the generator imports `{ Toast as NoticeToast }`.
497
+ * Defaults to `name` (no alias). */
498
+ exportName?: string;
499
+ /** Members read from a manual spec's `propsFrom` interface whose type is not a
500
+ * control (a function, an object, a type from another file): the check lists
501
+ * them, so the hiding is visible. */
502
+ hiddenProps?: string[];
503
+ /** Every member name read from `propsFrom` - in React a named or scoped slot is
504
+ * a prop, so the check accepts these as named-slot keys. */
505
+ memberNames?: string[];
506
+ }
507
+
508
+ /**
509
+ * A manual (non-template) component spec, as a source's `manualModule` returns it:
510
+ * an EnumeratedComponent whose props are either written by hand (a preview-only
511
+ * fixture) or read from code. `propsFrom` names the React driver's props
512
+ * interface as `'<file relative to the kit root>#<InterfaceName>'`; its own
513
+ * members (not what it extends) become the props, and a `children` member marks
514
+ * the default slot. Give `props` or `propsFrom`, not both.
515
+ */
516
+ export interface ManualComponentSpecification
517
+ extends Omit<EnumeratedComponent, 'props' | 'hasDefaultSlot' | 'slotNames'> {
518
+ props?: EnumeratedComponent['props'];
519
+ propsFrom?: string;
520
+ /** Defaults to whether `propsFrom` declares a non-function `children`, else false. */
521
+ hasDefaultSlot?: boolean;
522
+ /** Whether the default slot exposes values to its content (a scoped slot).
523
+ * Defaults to whether `propsFrom` takes it from a template component
524
+ * whose default slot does, else false. */
525
+ defaultSlotScoped?: boolean;
526
+ /** Defaults to none. */
527
+ slotNames?: string[];
528
+ }
529
+
530
+ // ─── The preview block ───
531
+
532
+ /** Imports a kit-authored TypeScript module by absolute path (jiti under the
533
+ * built CLI - kit files are TS source the CLI must compile on the fly). */
534
+ export type ModuleImporter = (absolutePath: string) => Promise<unknown>;
535
+
536
+ /**
537
+ * What a hand-written component renders as in a story's html source:
538
+ * `'content'`, a template's name, or `{ template, slots }`, where `slots`
539
+ * names the template slot each of the component's slots fills when they
540
+ * differ (`{ default: 'inner' }`; `default` is the default slot).
541
+ */
542
+ export type HandWrittenMapping =
543
+ | string
544
+ | { template: string; slots?: Record<string, string> };
545
+
546
+ /** One preview source: a package whose components + story files the generator
547
+ * renders under its own navigation section. Fundamentally a source is *where its
548
+ * components import from* (`moduleBase` → `${moduleBase}/${target}`, or the
549
+ * base with `{target}` replaced when it names one) plus a
550
+ * navigation identity. The kit's own components are a source like any other -
551
+ * the first source (lowest `order`) is the default module for slot children
552
+ * that belong to no registered source. */
553
+ export interface PreviewSourceConfiguration {
554
+ /** Stable id - groups this source's stories in the manifest + navigation. */
555
+ id: string;
556
+ /** Navigation heading. */
557
+ label: string;
558
+ /** Navigation order - the kit's own source first, other packages after. */
559
+ order: number;
560
+ /** Where the emitters import this source's components from: `${moduleBase}/${target}`,
561
+ * or, when it contains `{target}`, the base with the target in its place
562
+ * (`'@acme/{target}'` imports `'@acme/react'`). */
563
+ moduleBase: string;
564
+ /** The directory of component templates to read, relative to the kit
565
+ * root (omit for a source of manual specs alone). */
566
+ templatesDirectory?: string;
567
+ /** Module (relative to the kit root) whose default/named export supplies the
568
+ * source's manual (non-template) component specs: `() => EnumeratedComponent[]`. */
569
+ manualModule?: string;
570
+ /** This source's stories directory, relative to the kit root. */
571
+ storiesDirectory?: string;
572
+ }
573
+
574
+ /** A shipped theme: the compiled stylesheet (and optional asset dir - e.g.
575
+ * self-hosted fonts referenced by relative `url()`) are file paths relative to
576
+ * the kit root; the generator copies them into the served tree, so the map is
577
+ * pure config (no bundler import constraints). */
578
+ export interface PreviewThemeConfiguration {
579
+ id: string;
580
+ label: string;
581
+ /** The compiled stylesheet path (relative to the kit root). */
582
+ css: string;
583
+ /** Optional asset directory copied beside the stylesheet (fonts). */
584
+ assets?: string;
585
+ }
586
+
587
+ /** The kit's control hints - the token-config hook feeding prop controls,
588
+ * the preview block's `controlHints`, read in Node only, so its hook may be
589
+ * a function in `scaffold-ui-kit.ts`. Everything is optional (a kit without
590
+ * color tokens gets no color-select controls, and its color props are treated
591
+ * by their declared types). */
592
+ export interface PreviewControlHints {
593
+ /** The kit's color tokens. When it holds any, a string-typed prop whose
594
+ * name ends in `color`, in any case (`color`, `borderColor`), gets a
595
+ * select of these tokens (the
596
+ * color-select control) in place of the control its type gives. `null`
597
+ * (or `undefined`) is the select's unset choice. */
598
+ colorTokens?: (string | null | undefined)[];
599
+ /** Component-scoped size default in rem (e.g. Badge → 0.75), or undefined. */
600
+ componentSizeRem?: (componentName: string) => number | undefined;
601
+ }
602
+
603
+ /** The host's own copy, so it can follow the kit's casing: the preview
604
+ * block's `labels`, read in Node only, so `generatedScenario` may be a
605
+ * function in `scaffold-ui-kit.ts`. Each label falls back to its default. */
606
+ export interface PreviewLabels {
607
+ /** The category a component without a story file `category` sits in. Default `Components`. */
608
+ category?: string;
609
+ /** The synthetic scenario that renders a component with no content. Default `Empty`. */
610
+ emptyScenario?: string;
611
+ /** The label of a generated scenario, from the prop and the value it sets.
612
+ * Default `prop: value`, or the bare prop for a boolean turned on. */
613
+ generatedScenario?: (prop: string, value: string | boolean) => string;
614
+ }
615
+
616
+ /** Where the preview remembers what a person chose. `'url'` keeps the
617
+ * selection, the scenario and the option values in the page's query
618
+ * parameters, so a link opens the preview as it was; `'url-and-local-storage'`
619
+ * also remembers the global option values in the browser, per kit name,
620
+ * across sessions - a value in the URL winning over a remembered one. */
621
+ export type PreviewPersistence = 'url' | 'url-and-local-storage';
622
+
623
+ /** A width the preview offers to lay a story's panes out at, so a component
624
+ * that responds to its width can be seen on a small screen or a large one. */
625
+ export interface PreviewPaneWidth {
626
+ /** What a reader picks it by, such as `small`. */
627
+ label: string;
628
+ /** The width in CSS pixels: a whole number greater than zero. */
629
+ width: number;
630
+ }
631
+
632
+ /** The entry the preview opens on when its address names none: a custom
633
+ * view by its id, or a component's story by its id, on one of its
634
+ * scenarios or its baseline. The ids are the ones the preview's address
635
+ * carries (`view=`, `component=`, `scenario=`). */
636
+ export type PreviewLandingConfiguration =
637
+ | { view: string }
638
+ | { component: string; scenario?: string };
639
+
640
+ /**
641
+ * The keys of the preview block the preview's pages read: data, which the
642
+ * preview checks can be sent as JSON and serves to the browser.
643
+ */
644
+ export interface PreviewBrowserConfiguration {
645
+ /** The kit's options, such as a color mode, and how each reaches a story. */
646
+ options: PreviewOption[];
647
+ /** The name prefix, page background and extra CSS each frame paints with. */
648
+ canvas: PreviewCanvasConfiguration;
649
+ /** The kit's theme stylesheets; the first is the default. */
650
+ themes: PreviewThemeConfiguration[];
651
+ /** The wrapper tree rendered around each story's mount; omitted, the mount
652
+ * is a direct child of `<body>`. */
653
+ mount?: PreviewMountNode;
654
+ /** The canvas of a custom view's frame. */
655
+ viewCanvas?: PreviewViewCanvasConfiguration;
656
+ }
657
+
658
+ /** The keys of the preview block its pages read, which must be JSON. */
659
+ export const PREVIEW_BROWSER_KEYS = [
660
+ 'options',
661
+ 'canvas',
662
+ 'themes',
663
+ 'mount',
664
+ 'viewCanvas',
665
+ ] as const satisfies readonly (keyof PreviewBrowserConfiguration)[];
666
+
667
+ /** The kit's shell with its page named: the long form of `preview.shell`. */
668
+ export interface PreviewShellSetting {
669
+ /** The shell module: a package specifier, or a module path relative to
670
+ * the kit root, whose default export is a shell. */
671
+ module: string;
672
+ /** The shell's page module, which supplies the host page's static start:
673
+ * a package specifier, or a module path relative to the kit root, whose
674
+ * default export is a shell page. Left out, a shell named as a package
675
+ * specifier uses the module at that specifier followed by `/page`, when
676
+ * the package has one. */
677
+ page?: string;
678
+ }
679
+
680
+ /** The `preview` block of the kit configuration (`scaffold-ui-kit.ts` or
681
+ * `scaffold-ui-kit.json`): plain data, plus module paths for the parts that
682
+ * are code. The keys the preview's pages read are served to the browser as
683
+ * JSON; `controlHints` and `labels` stay in Node, so in `scaffold-ui-kit.ts`
684
+ * their hooks may be functions. The build never reads this block; the
685
+ * preview owns and validates it. */
686
+ export interface PreviewConfiguration {
687
+ sources: PreviewSourceConfiguration[];
688
+ /** The kit's options (see {@link PreviewBrowserConfiguration}). */
689
+ options?: PreviewOption[];
690
+ /** How each frame paints: a name prefix for the names the preview sets,
691
+ * and optionally a page background and extra CSS. Omitted, the name
692
+ * prefix is the kit's name, its characters other than letters, digits,
693
+ * `-` and `_` made `-`, and the frames paint nothing of their own. */
694
+ canvas?: PreviewCanvasConfiguration;
695
+ /** The kit's compiled theme stylesheets; the first is the default. */
696
+ themes?: PreviewThemeConfiguration[];
697
+ /** The wrapper tree rendered around each story's mount. */
698
+ mount?: PreviewMountNode;
699
+ /** The canvas of a custom view's frame; without it a view gets
700
+ * `canvas.pageBackground` and nothing else. */
701
+ viewCanvas?: PreviewViewCanvasConfiguration;
702
+ /** The widths a shell offers to lay a story's panes out at, in place of
703
+ * the preview's own (`small` 375, `medium` 768 and `large` 1280), so a
704
+ * kit can derive them from its own breakpoints. An empty list offers
705
+ * none. */
706
+ paneWidths?: PreviewPaneWidth[];
707
+ /** The hints feeding prop controls, read in Node only. */
708
+ controlHints?: PreviewControlHints;
709
+ /** The host's own copy, read in Node only. */
710
+ labels?: PreviewLabels;
711
+ /** The shell that renders the preview's interface around the iframes: a
712
+ * package specifier, or a module path relative to the kit root, whose
713
+ * default export is a shell; or the shell's module with its page module
714
+ * named beside it. Required; `@scaffold-ui-kit/preview/shells/charcell`
715
+ * is the one shipped with the preview. */
716
+ shell: string | PreviewShellSetting;
717
+ /** Kit-authored module exporting the custom-view registry. */
718
+ viewsModule?: string;
719
+ /** Preview-only import aliases (playground fixtures outside published barrels). */
720
+ aliases?: Record<string, string>;
721
+ /** Per-target setup modules (side effects only): ambient providers a story
722
+ * assumes mounted (a toast container), another package's stylesheets. Each is
723
+ * imported once by that target's preview iframe. */
724
+ setupModules?: Partial<Record<Target, string>>;
725
+ /** Stylesheets (relative to the kit root) the html pane loads beside the
726
+ * theme's: what a framework's setup module brings in as CSS, such as a
727
+ * preflight or another package's sheet, since the html pane runs no script. */
728
+ htmlStylesheets?: string[];
729
+ /** The kit's own code block for the code view: a module (relative to the
730
+ * kit root) whose default export is a `CodeBlockMount`, and the framework
731
+ * it mounts with, whose setup module loads first (`dom`, the default,
732
+ * loads none). The preview mounts it in an iframe per code pane, in place
733
+ * of the shell's own. */
734
+ codeBlock?: {
735
+ module: string;
736
+ framework?: 'react' | 'vue' | 'svelte' | 'dom';
737
+ };
738
+ /** Extra SCSS load paths (relative to the kit root) for per-component SCSS. */
739
+ scssLoadPaths?: string[];
740
+ /** Package names Vite must not esbuild-prebundle (raw `.svelte` shippers etc.). */
741
+ optimizeDepsExclude?: string[];
742
+ /** Packages the preview loads one copy of, resolved from the kit root
743
+ * wherever they are imported, beside the framework runtimes it always
744
+ * loads once: a package the shell and the kit's components both import,
745
+ * whose instances must be shared (a library with a plugin registry or
746
+ * module-level state). Each must resolve from the kit root. */
747
+ dedupe?: string[];
748
+ /** A regular expression (as a string) matched against each component's name:
749
+ * a match gets no story, the way a story file's `omit` does - for a kit whose
750
+ * naming marks a compound's parts, such as `"(Driver|Visual)$"`. Unset, no
751
+ * component is left out by name. */
752
+ omitPattern?: string;
753
+ /** What each component written by hand renders as in a story's html
754
+ * source: `'content'` for one that renders only the content passed into it
755
+ * (a driver adding behavior to markup it is given), or the template it
756
+ * renders, which then takes its props and content. Either way one comment
757
+ * around it says its behavior is not included. A component with no
758
+ * template that is not listed leaves the story with no html source. */
759
+ handWrittenComponents?: Record<string, HandWrittenMapping>;
760
+ /** Dev-server port (default 6100; `dev --port` overrides it). If it is taken, the server takes the next free one. */
761
+ port?: number;
762
+ /** The addresses the dev server listens on: an address such as
763
+ * `'0.0.0.0'`, or `true` for every address, so another device on the
764
+ * network can open the preview. Default: this machine only;
765
+ * `dev --host` overrides it. */
766
+ host?: string | boolean;
767
+ /** Where the preview remembers what a person chose. Default `'url'`. */
768
+ persistence?: PreviewPersistence;
769
+ /** The entry the preview opens on when its address names no view or
770
+ * story, such as a foundations view: `{ view }` or
771
+ * `{ component, scenario? }`. Unset, it opens on the first listed story. */
772
+ landing?: PreviewLandingConfiguration;
773
+ }
774
+
775
+ declare module 'scaffold-ui-kit' {
776
+ /** The preview's settings in the kit configuration, typed by this package. */
777
+ interface KitPreviewConfiguration extends PreviewConfiguration {}
778
+ }