@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,105 @@
1
+ // The preview controller and what a shell reads from it: the catalog, the
2
+ // state, the editor's tree types and operations, the regeneration transport, and the
3
+ // query parameters it keeps its state in.
4
+ // Browser-safe: no node imports.
5
+
6
+ export {
7
+ createPreviewController,
8
+ PREVIEW_FRAME_SHOWN_ATTRIBUTE,
9
+ REGENERATION_DEBOUNCE_MILLISECONDS,
10
+ SCRATCH_STORY_ID,
11
+ type PreviewController,
12
+ type PreviewControllerOptions,
13
+ type PreviewEditorState,
14
+ type PreviewEvent,
15
+ type PreviewFrameReadiness,
16
+ type PreviewFrameTarget,
17
+ type PreviewHtmlSource,
18
+ type PreviewInsertTarget,
19
+ type PreviewNodeRequest,
20
+ type PreviewOptionDescriptor,
21
+ type PreviewRegenerationStatus,
22
+ type PreviewSelection,
23
+ type PreviewSortableDrop,
24
+ type PreviewCode,
25
+ type PreviewState,
26
+ type PreviewTimers,
27
+ } from './create-preview-controller.js';
28
+ export { printStorySource, type PreviewTargetCode } from './source.js';
29
+ export {
30
+ createFetchHtmlSourceTransport,
31
+ createStaticHtmlSourceLoader,
32
+ HTML_SOURCE_DIRECTORY,
33
+ HTML_SOURCE_ENDPOINT,
34
+ type HtmlSourceRequest,
35
+ type HtmlSourceResponse,
36
+ type HtmlSourceTransport,
37
+ type ScenarioHtmlSourceLoader,
38
+ } from './html-source.js';
39
+ export { previewStore, type PreviewStore } from './store.js';
40
+ export type { PreviewPaneWidth } from '../lib/types.js';
41
+ export {
42
+ catalogFromManifest,
43
+ DEFAULT_PANE_WIDTHS,
44
+ defaultScenarioId,
45
+ nodeAddSlots,
46
+ nodeSlots,
47
+ scenarioChoices,
48
+ storyFrameKey,
49
+ type CatalogManifest,
50
+ type PreviewBinding,
51
+ type PreviewCatalog,
52
+ type PreviewCatalogView,
53
+ type PreviewComponent,
54
+ type PreviewImport,
55
+ type PreviewLanding,
56
+ type PreviewNavigationNode,
57
+ type PreviewPropType,
58
+ type PreviewScenario,
59
+ type PreviewSource,
60
+ type PreviewStoryReference,
61
+ type ScenarioChoice,
62
+ } from './catalog.js';
63
+ export {
64
+ acceptsPropValue,
65
+ changedProps,
66
+ isPaneWidth,
67
+ MAXIMUM_PANE_WIDTH,
68
+ parseTargets,
69
+ parseOptionValue,
70
+ parsePaneWidth,
71
+ parseProps,
72
+ readUrlState,
73
+ storageKey,
74
+ URL_PARAMETER,
75
+ writeUrlState,
76
+ type PreviewStorage,
77
+ type UrlState,
78
+ type UrlStateToWrite,
79
+ } from './persistence.js';
80
+ export {
81
+ createFetchRegenerationTransport,
82
+ REGENERATION_ENDPOINT,
83
+ type RegenerationPayload,
84
+ type RegenerationTransport,
85
+ } from './regeneration.js';
86
+ export {
87
+ childPath,
88
+ cleanRecord,
89
+ DEFAULT_SLOT,
90
+ HTML_TAGS,
91
+ isContainer,
92
+ nodeAt,
93
+ pathKey,
94
+ seedNode,
95
+ type AroundFill,
96
+ type ContainerNode,
97
+ type DropTarget,
98
+ type EditorNode,
99
+ type EditorState,
100
+ type NodePath,
101
+ type OpaqueFill,
102
+ type SortableListAddress,
103
+ type Step,
104
+ type StoryAround,
105
+ } from './editor-tree.js';
@@ -0,0 +1,403 @@
1
+ // Where the controller keeps what a person chose: the host page's query
2
+ // parameters, which make a link a deep link into the preview, and, when the
3
+ // kit asks for it, the browser's local storage, which remembers the global
4
+ // option values across sessions. Everything read back is checked against the
5
+ // catalog and the options, so a stale or hand-edited value is ignored.
6
+ // Browser-safe: no node imports.
7
+
8
+ import type { PreviewPropType } from '../lib/types.js';
9
+ import { stableStringify } from './editor-tree.js';
10
+ import {
11
+ acceptsOptionValue,
12
+ type OptionValue,
13
+ type PreviewOption,
14
+ } from '../options.js';
15
+ import type { PreviewTarget } from '../protocol.js';
16
+
17
+ /** The host page's query parameters the controller reads and writes. */
18
+ export const URL_PARAMETER = {
19
+ /** The selected component story's id. */
20
+ component: 'component',
21
+ /** The selected custom view's id. */
22
+ view: 'view',
23
+ /** The selected scenario's id. */
24
+ scenario: 'scenario',
25
+ /** The story's root props that differ from its scenario's, as JSON. */
26
+ props: 'props',
27
+ /** The visible targets, comma-separated, when not every one is visible. */
28
+ targets: 'targets',
29
+ /** The width the story panes are laid out at, in CSS pixels, when they
30
+ * are not fitted to the space the shell gives them. */
31
+ width: 'width',
32
+ /** The prefix of an option's parameter: `option.<id>=<value>`. */
33
+ optionPrefix: 'option.',
34
+ } as const;
35
+
36
+ /** The part of the Web Storage interface the controller uses. */
37
+ export type PreviewStorage = Pick<
38
+ Storage,
39
+ 'getItem' | 'setItem' | 'removeItem'
40
+ >;
41
+
42
+ /** What the query parameters say, before it is checked against the catalog. */
43
+ export interface UrlState {
44
+ component?: string;
45
+ view?: string;
46
+ scenario?: string;
47
+ /** The root props as written: JSON, unparsed. */
48
+ props?: string;
49
+ /** The visible targets as written: a comma-separated list. */
50
+ targets?: string;
51
+ /** The story panes' width as written. */
52
+ width?: string;
53
+ /** Option values as written, keyed by option id. */
54
+ options: Record<string, string>;
55
+ }
56
+
57
+ /** What the controller writes to the query parameters. */
58
+ export interface UrlStateToWrite {
59
+ selection: { kind: 'component' | 'view'; id: string };
60
+ /** The scenario, when it is not the story's default. */
61
+ scenario?: string;
62
+ /** The root props that differ from the scenario's, a prop of the
63
+ * scenario's the story leaves out set to `null`. */
64
+ props?: Record<string, unknown>;
65
+ /** The visible targets, `html` among them, when not every one of the
66
+ * kit's is visible. */
67
+ targets?: readonly PreviewTarget[];
68
+ /** The story panes' width in CSS pixels, when they are not fitted. */
69
+ width?: number;
70
+ /** The option values to keep, keyed by option id. */
71
+ options: Record<string, OptionValue>;
72
+ }
73
+
74
+ /**
75
+ * Read the controller's parameters from a query string.
76
+ *
77
+ * @param search - The query string, with or without its leading `?`.
78
+ * @returns The parameters, unchecked.
79
+ */
80
+ export function readUrlState(search: string): UrlState {
81
+ const parameters = new URLSearchParams(search);
82
+ const options: Record<string, string> = {};
83
+ for (const [key, value] of parameters) {
84
+ if (key.startsWith(URL_PARAMETER.optionPrefix))
85
+ options[key.slice(URL_PARAMETER.optionPrefix.length)] = value;
86
+ }
87
+ const value = (key: string) => parameters.get(key) ?? undefined;
88
+ return {
89
+ component: value(URL_PARAMETER.component),
90
+ view: value(URL_PARAMETER.view),
91
+ scenario: value(URL_PARAMETER.scenario),
92
+ props: value(URL_PARAMETER.props),
93
+ targets: value(URL_PARAMETER.targets),
94
+ width: value(URL_PARAMETER.width),
95
+ options,
96
+ };
97
+ }
98
+
99
+ /**
100
+ * An option's value as written in a query parameter or storage: `true` or
101
+ * `false` for a boolean, one of its values for a choice.
102
+ *
103
+ * @param option - The option.
104
+ * @param raw - The value as written.
105
+ * @returns The value, or `undefined` when the option cannot hold it.
106
+ */
107
+ export function parseOptionValue(
108
+ option: Pick<PreviewOption, 'values'>,
109
+ raw: unknown
110
+ ): OptionValue | undefined {
111
+ if (option.values === undefined) {
112
+ if (raw === 'true' || raw === true) return true;
113
+ if (raw === 'false' || raw === false) return false;
114
+ return undefined;
115
+ }
116
+ return acceptsOptionValue(option, raw) ? raw : undefined;
117
+ }
118
+
119
+ /**
120
+ * The visible targets a query parameter names, among the kit's, `html`
121
+ * included where the kit builds it. An empty parameter names none; one that
122
+ * names none of the kit's is ignored.
123
+ *
124
+ * @param raw - The parameter as written: a comma-separated list.
125
+ * @param targets - The kit's targets (`PreviewCatalog.targets`).
126
+ * @returns The targets in the kit's order, or `undefined` when the
127
+ * parameter is to be ignored.
128
+ */
129
+ export function parseTargets(
130
+ raw: string,
131
+ targets: readonly PreviewTarget[]
132
+ ): PreviewTarget[] | undefined {
133
+ const named = raw.split(',').map((name) => name.trim());
134
+ const known = targets.filter((target) => named.includes(target));
135
+ if (raw.trim() === '') return [];
136
+ return known.length > 0 ? known : undefined;
137
+ }
138
+
139
+ /** The widest a story pane is laid out at, in CSS pixels: an 8K screen's width. */
140
+ export const MAXIMUM_PANE_WIDTH = 7680;
141
+
142
+ /**
143
+ * Whether `value` can be a story pane's width: a whole number of CSS pixels,
144
+ * from 1 to `MAXIMUM_PANE_WIDTH`.
145
+ *
146
+ * @param value - The candidate width.
147
+ * @returns Whether it is one.
148
+ */
149
+ export function isPaneWidth(value: unknown): value is number {
150
+ return (
151
+ typeof value === 'number' &&
152
+ Number.isInteger(value) &&
153
+ value > 0 &&
154
+ value <= MAXIMUM_PANE_WIDTH
155
+ );
156
+ }
157
+
158
+ /**
159
+ * The story panes' width a query parameter names: a whole number of CSS
160
+ * pixels, from 1 to `MAXIMUM_PANE_WIDTH`.
161
+ *
162
+ * @param raw - The parameter as written, such as `768`.
163
+ * @returns The width, or `undefined` when the parameter is to be ignored.
164
+ */
165
+ export function parsePaneWidth(raw: string): number | undefined {
166
+ if (!/^\d+$/.test(raw.trim())) return undefined;
167
+ const width = Number(raw.trim());
168
+ return isPaneWidth(width) ? width : undefined;
169
+ }
170
+
171
+ /**
172
+ * Whether a prop's control can hold `value`: a boolean for a toggle, a
173
+ * finite number for a number input, one of its values for a select, one of
174
+ * the color tokens for a color select, and a string or a number for a text
175
+ * input.
176
+ *
177
+ * @param propType - The prop.
178
+ * @param value - The candidate value.
179
+ * @param colorTokens - The color tokens a color select offers.
180
+ * @returns Whether the prop accepts the value.
181
+ */
182
+ export function acceptsPropValue(
183
+ propType: Pick<PreviewPropType, 'control' | 'options'>,
184
+ value: unknown,
185
+ colorTokens: readonly (string | null)[]
186
+ ): boolean {
187
+ switch (propType.control) {
188
+ case 'boolean':
189
+ return typeof value === 'boolean';
190
+ case 'number':
191
+ return typeof value === 'number' && Number.isFinite(value);
192
+ case 'select':
193
+ return (
194
+ (typeof value === 'string' || typeof value === 'boolean') &&
195
+ (propType.options ?? []).includes(value)
196
+ );
197
+ case 'color-select':
198
+ return typeof value === 'string' && colorTokens.includes(value);
199
+ case 'text':
200
+ return (
201
+ typeof value === 'string' ||
202
+ (typeof value === 'number' && Number.isFinite(value))
203
+ );
204
+ }
205
+ }
206
+
207
+ /**
208
+ * The props that differ from `base`, as the address holds them: each prop
209
+ * whose value differs, and each prop of `base` the props leave out, as
210
+ * `null`, so a link opens on what renders. {@link parseProps} reads them
211
+ * back over the same `base`.
212
+ *
213
+ * @param props - The props the story renders with.
214
+ * @param base - The props the story starts from: its scenario's.
215
+ * @param marksMissing - Whether a prop of `base` the props leave out is
216
+ * written as `null`.
217
+ * @returns The props that differ, in their order, then those left out.
218
+ * @example
219
+ * ```ts
220
+ * changedProps({ selected: 'b', items }, { selected: 'a', items, icon: 'plus' }, () => true);
221
+ * // { selected: 'b', icon: null }
222
+ * ```
223
+ */
224
+ export function changedProps(
225
+ props: Record<string, unknown>,
226
+ base: Record<string, unknown>,
227
+ marksMissing: (name: string) => boolean
228
+ ): Record<string, unknown> {
229
+ const changed: Record<string, unknown> = {};
230
+ for (const [name, value] of Object.entries(props))
231
+ if (
232
+ value !== undefined &&
233
+ stableStringify(value) !== stableStringify(base[name])
234
+ )
235
+ changed[name] = value;
236
+ for (const [name, value] of Object.entries(base))
237
+ if (value !== undefined && props[name] === undefined && marksMissing(name))
238
+ changed[name] = null;
239
+ return changed;
240
+ }
241
+
242
+ /**
243
+ * The root props a query parameter gives, checked against the component's
244
+ * props. The parameter holds the props that differ from the scenario's: a
245
+ * prop it leaves out takes its value in `defaults`, the scenario's props, as
246
+ * a freshly picked scenario does, and a prop it sets to `null` is left out
247
+ * of the result, unless `fallback` holds `null` for it, which keeps the
248
+ * `null`.
249
+ * Only props the component declares, with a value its control
250
+ * accepts, are kept; a declared prop whose value is refused keeps its value
251
+ * in `fallback`, the scenario's props, or else its default. A parameter that
252
+ * is not a JSON object is ignored.
253
+ *
254
+ * @param raw - The parameter as written.
255
+ * @param propTypes - The component's props.
256
+ * @param defaults - The props a prop left out keeps: the scenario's.
257
+ * @param fallback - The scenario's props, for a refused value.
258
+ * @param colorTokens - The color tokens a color select offers.
259
+ * @returns The props, or `undefined` when the parameter is to be ignored.
260
+ * @example
261
+ * ```ts
262
+ * parseProps('{"variant":"ghost","icon":null}', propTypes, { size: 'md', icon: 'plus' }, {}, []);
263
+ * // { size: 'md', variant: 'ghost' }
264
+ * ```
265
+ */
266
+ export function parseProps(
267
+ raw: string,
268
+ propTypes: readonly Pick<PreviewPropType, 'name' | 'control' | 'options'>[],
269
+ defaults: Record<string, unknown>,
270
+ fallback: Record<string, unknown>,
271
+ colorTokens: readonly (string | null)[]
272
+ ): Record<string, unknown> | undefined {
273
+ let parsed: unknown;
274
+ try {
275
+ parsed = JSON.parse(raw);
276
+ } catch {
277
+ return undefined;
278
+ }
279
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
280
+ return undefined;
281
+ const props: Record<string, unknown> = { ...defaults };
282
+ for (const [name, value] of Object.entries(parsed)) {
283
+ const propType = propTypes.find((candidate) => candidate.name === name);
284
+ if (!propType) continue;
285
+ if (value === null) {
286
+ if (fallback[name] === null) props[name] = null;
287
+ else delete props[name];
288
+ } else if (acceptsPropValue(propType, value, colorTokens))
289
+ props[name] = value;
290
+ else if (fallback[name] !== undefined) props[name] = fallback[name];
291
+ }
292
+ return props;
293
+ }
294
+
295
+ /**
296
+ * Write the controller's parameters into a query string, keeping every
297
+ * parameter that is not the controller's.
298
+ *
299
+ * @param search - The current query string.
300
+ * @param state - What to write.
301
+ * @returns The new query string, without its leading `?`.
302
+ */
303
+ export function writeUrlState(search: string, state: UrlStateToWrite): string {
304
+ const parameters = new URLSearchParams(search);
305
+ for (const key of [...parameters.keys()]) {
306
+ if (
307
+ key === URL_PARAMETER.component ||
308
+ key === URL_PARAMETER.view ||
309
+ key === URL_PARAMETER.scenario ||
310
+ key === URL_PARAMETER.props ||
311
+ key === URL_PARAMETER.targets ||
312
+ key === URL_PARAMETER.width ||
313
+ key.startsWith(URL_PARAMETER.optionPrefix)
314
+ ) {
315
+ parameters.delete(key);
316
+ }
317
+ }
318
+ parameters.set(
319
+ state.selection.kind === 'view'
320
+ ? URL_PARAMETER.view
321
+ : URL_PARAMETER.component,
322
+ state.selection.id
323
+ );
324
+ if (state.scenario !== undefined)
325
+ parameters.set(URL_PARAMETER.scenario, state.scenario);
326
+ if (state.props !== undefined)
327
+ parameters.set(URL_PARAMETER.props, JSON.stringify(state.props));
328
+ if (state.targets !== undefined)
329
+ parameters.set(URL_PARAMETER.targets, state.targets.join(','));
330
+ if (state.width !== undefined)
331
+ parameters.set(URL_PARAMETER.width, String(state.width));
332
+ for (const [id, value] of Object.entries(state.options)) {
333
+ parameters.set(`${URL_PARAMETER.optionPrefix}${id}`, String(value));
334
+ }
335
+ // A comma and a colon need no escaping in a query string: left as they
336
+ // are, a list of targets and a story's props stay readable.
337
+ return parameters.toString().replace(/%2C/gi, ',').replace(/%3A/gi, ':');
338
+ }
339
+
340
+ /**
341
+ * The local-storage key a kit's remembered option values live under.
342
+ *
343
+ * @param kitName - The kit's name.
344
+ * @returns The key.
345
+ */
346
+ export function storageKey(kitName: string): string {
347
+ return `scaffold-ui-kit-preview:${kitName}:options`;
348
+ }
349
+
350
+ /**
351
+ * The option values remembered under `key`, those the options can still
352
+ * hold. Storage that cannot be read, or holds something else, gives none.
353
+ *
354
+ * @param storage - The storage.
355
+ * @param key - The key.
356
+ * @param options - The options the values may belong to.
357
+ * @returns The values, keyed by option id.
358
+ */
359
+ export function readStoredOptions(
360
+ storage: PreviewStorage,
361
+ key: string,
362
+ options: Array<Pick<PreviewOption, 'id' | 'values'>>
363
+ ): Record<string, OptionValue> {
364
+ let stored: unknown;
365
+ try {
366
+ const text = storage.getItem(key);
367
+ stored = text === null ? undefined : JSON.parse(text);
368
+ } catch {
369
+ return {};
370
+ }
371
+ if (typeof stored !== 'object' || stored === null || Array.isArray(stored))
372
+ return {};
373
+ const values: Record<string, OptionValue> = {};
374
+ for (const option of options) {
375
+ const value = parseOptionValue(
376
+ option,
377
+ (stored as Record<string, unknown>)[option.id]
378
+ );
379
+ if (value !== undefined) values[option.id] = value;
380
+ }
381
+ return values;
382
+ }
383
+
384
+ /**
385
+ * Remember option values under `key`; with none, forget them. A storage that
386
+ * refuses the write (private browsing, a full or blocked store) is ignored.
387
+ *
388
+ * @param storage - The storage.
389
+ * @param key - The key.
390
+ * @param values - The values to remember, keyed by option id.
391
+ */
392
+ export function writeStoredOptions(
393
+ storage: PreviewStorage,
394
+ key: string,
395
+ values: Record<string, OptionValue>
396
+ ): void {
397
+ try {
398
+ if (Object.keys(values).length === 0) storage.removeItem(key);
399
+ else storage.setItem(key, JSON.stringify(values));
400
+ } catch {
401
+ // Nothing to do: the values simply are not remembered.
402
+ }
403
+ }
@@ -0,0 +1,55 @@
1
+ // How the controller regenerates the scratch story: the payload it sends and
2
+ // the transport that carries it. The development server answers the request;
3
+ // a static build has no endpoint, so a controller created without a transport
4
+ // reports regeneration as unavailable. Browser-safe.
5
+
6
+ import type { JsonValue, SlotPlan, StoryAround } from '../lib/types.js';
7
+
8
+ /** The scratch story to regenerate: the root component, its props and its slot content. */
9
+ export interface RegenerationPayload {
10
+ /** The root component's export name. */
11
+ rootComponent: string;
12
+ /** The root's own props. */
13
+ props: Record<string, JsonValue>;
14
+ /** The root's slot content: its default slot and its named slots. */
15
+ slots?: SlotPlan;
16
+ /** The content beside the root, as its siblings: `before` and `after` it. */
17
+ around?: StoryAround;
18
+ }
19
+
20
+ /**
21
+ * Carries a regeneration payload to whatever writes the scratch story. It resolves
22
+ * once the story is written and rejects with the reason it was not; the
23
+ * controller reports the rejection's message.
24
+ */
25
+ export type RegenerationTransport = (
26
+ payload: RegenerationPayload
27
+ ) => Promise<void>;
28
+
29
+ /** The path the preview's development server answers regeneration requests on. */
30
+ export const REGENERATION_ENDPOINT = '/__preview_regenerate';
31
+
32
+ /**
33
+ * A transport that POSTs the payload as JSON to the development server's
34
+ * regeneration endpoint. A response that is not ok rejects with the response's text,
35
+ * or its status when the text is empty.
36
+ *
37
+ * @param endpoint - The endpoint's path; the development server's by default.
38
+ * @param fetchImplementation - The `fetch` to use; the global one by default.
39
+ * @returns The transport.
40
+ */
41
+ export function createFetchRegenerationTransport(
42
+ endpoint: string = REGENERATION_ENDPOINT,
43
+ fetchImplementation: typeof fetch = (...parameters) => fetch(...parameters)
44
+ ): RegenerationTransport {
45
+ return async (payload) => {
46
+ const response = await fetchImplementation(endpoint, {
47
+ method: 'POST',
48
+ body: JSON.stringify(payload),
49
+ });
50
+ if (!response.ok) {
51
+ const text = await response.text().catch(() => '');
52
+ throw new Error(text || `HTTP ${response.status}`);
53
+ }
54
+ };
55
+ }