@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,99 @@
1
+ // The component stage's body: its rows, top to bottom, in a stacked charcell
2
+ // Splitter - the scenario row while the scenario view shows, the grid of the
3
+ // output and code rows (PreviewGrid) while either shows, and the events row
4
+ // while the events view shows - each handle between two rows dragging the
5
+ // boundary a whole row at a time. A row after the first is headed on its
6
+ // handle's row, its heading at the start and its controls at the end, around
7
+ // the grip; a headed row with no row above has the same row to itself,
8
+ // without a grip. SplitGrid has no cell spanning its columns, so the scenario
9
+ // and events rows sit over and under the grid rather than in it.
10
+ //
11
+ // The scenario row starts at its content's height - its picker row and, where
12
+ // the preview can regenerate, the editor's tree - and keeps at least its ring
13
+ // and one row inside it; the events row starts a few rows tall. The grid
14
+ // takes the rest. The split measures the scenario row, and measures again as
15
+ // its content changes, unless the reader has moved the boundary since.
16
+ //
17
+ // The grid's panel stays in the split while the grid has no row showing,
18
+ // hidden and out of the split's panels, and the whole split is hidden while
19
+ // no view shows, so the panes keep their place in the tree, and their frames,
20
+ // whichever views open and close.
21
+ import { Fragment, useMemo, type ReactNode } from 'react';
22
+ import {
23
+ SplitterDriver,
24
+ SplitterHandle,
25
+ SplitterHandleRow,
26
+ SplitterPanel,
27
+ SplitterVisual,
28
+ } from 'charcell/react/unlinked';
29
+ import './index.css';
30
+
31
+ /** The fewest rows the scenario and events rows keep: a ring and one row inside. */
32
+ const LEAST_ROWS = 3;
33
+
34
+ /** The rows the events row starts at beside the others. */
35
+ const EVENTS_ROWS = 8;
36
+
37
+ /** One of the stage's rows, as the split holds it. */
38
+ export interface StageRow {
39
+ id: 'scenario' | 'grid' | 'events';
40
+ content: ReactNode;
41
+ shown: boolean;
42
+ /** The row's heading and controls, on the row above it; the scenario row
43
+ * heads itself. */
44
+ heading?: ReactNode;
45
+ controls?: ReactNode;
46
+ /** The handle above it, named for a reader. */
47
+ label?: string;
48
+ }
49
+
50
+ export function StageSplit({ rows }: { rows: StageRow[] }) {
51
+ const shown = rows.filter((row) => row.shown);
52
+ const key = shown.map((row) => row.id).join(',');
53
+ // The panels follow which rows show, and nothing else.
54
+ const panels = useMemo(() => {
55
+ const ids = key === '' ? [] : key.split(',');
56
+ return ids.map((id) =>
57
+ ids.length === 1
58
+ ? { id }
59
+ : id === 'scenario'
60
+ ? { id, minimumCells: LEAST_ROWS, defaultCells: 'content' as const }
61
+ : id === 'events'
62
+ ? { id, minimumCells: LEAST_ROWS, defaultCells: EVENTS_ROWS }
63
+ : { id },
64
+ );
65
+ }, [key]);
66
+ return (
67
+ <div className="StageSplit" hidden={shown.length === 0}>
68
+ <SplitterDriver orientation="vertical" panels={panels}>
69
+ {({ api }) => (
70
+ <SplitterVisual orientation="vertical" fill {...api.getRootProps()}>
71
+ {rows.map((row) => {
72
+ const index = shown.indexOf(row);
73
+ const above = index > 0 ? shown[index - 1] : undefined;
74
+ // The grid stays in the tree while hidden, in the same place,
75
+ // so its panes keep their frames; another row leaves.
76
+ if (!row.shown && row.id !== 'grid') return null;
77
+ return (
78
+ <Fragment key={row.id}>
79
+ {above && (
80
+ <SplitterHandle
81
+ label={row.label ?? `resize ${above.id} and ${row.id}`}
82
+ {...api.getResizeTriggerProps({ id: `${above.id}:${row.id}` })}
83
+ />
84
+ )}
85
+ {row.shown && row.heading !== undefined && (
86
+ <SplitterHandleRow start={row.heading} end={row.controls} />
87
+ )}
88
+ <SplitterPanel {...(row.shown ? api.getPanelProps({ id: row.id }) : { hidden: true })}>
89
+ {row.content}
90
+ </SplitterPanel>
91
+ </Fragment>
92
+ );
93
+ })}
94
+ </SplitterVisual>
95
+ )}
96
+ </SplitterDriver>
97
+ </div>
98
+ );
99
+ }
@@ -0,0 +1,30 @@
1
+ // The shell's bottom status bar: the panes' state (PaneStatus) and a copy of
2
+ // the preview's address (CopyLink) at the start; at the end, the options
3
+ // placed in the status bar (a global option of a group of the kit's own
4
+ // naming, unless the kit places it elsewhere), the kit's `status-bar` slot,
5
+ // and a hint of the shell's keys.
6
+ import { Bar } from '../Bar';
7
+ import { CopyLink } from '../CopyLink';
8
+ import { KeyHints } from '../KeyHints';
9
+ import { OptionControls } from '../OptionControls';
10
+ import { PaneStatus } from '../PaneStatus';
11
+ import { SlotOutlet } from '../SlotOutlet';
12
+
13
+ export function StatusBar() {
14
+ return (
15
+ <Bar
16
+ variant="status"
17
+ joined
18
+ end={
19
+ <>
20
+ <OptionControls placement="status-bar" />
21
+ <SlotOutlet name="status-bar" />
22
+ <KeyHints />
23
+ </>
24
+ }
25
+ >
26
+ <PaneStatus />
27
+ <CopyLink />
28
+ </Bar>
29
+ );
30
+ }
@@ -0,0 +1,15 @@
1
+ @layer charcell.components {
2
+ /* The options, the slot and the view's own control, spaced as a band's
3
+ items are. */
4
+ .ViewControls {
5
+ display: flex;
6
+ align-items: center;
7
+ gap: 2ch;
8
+ }
9
+ /* In a popover, the options a row each. */
10
+ .ViewControls__options {
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: flex-start;
14
+ }
15
+ }
@@ -0,0 +1,58 @@
1
+ // The end of a view's heading row: the options placed in the view's region,
2
+ // with the view's own options after them (the output's width), the kit's
3
+ // slot for the view (`<view>-end`), and the view's own control (the wrap
4
+ // toggle, the events' clear). A view the shell's `popovers` names, the
5
+ // output by default, holds its options in a charcell Popover; any other lays
6
+ // them in the row. No options, no popover. Styled in its index.css.
7
+ import { Button, Popover } from 'charcell/react/unlinked';
8
+ import { Hint } from '../Hint';
9
+ import type { ReactNode } from 'react';
10
+ import type { CharcellView } from '../../configuration';
11
+ import { useShellConfiguration } from '../../controller-context';
12
+ import { OptionControls, useHasOptionControls } from '../OptionControls';
13
+ import { SlotOutlet } from '../SlotOutlet';
14
+ import './index.css';
15
+
16
+ /** The views whose options sit in a popover unless the kit says otherwise. */
17
+ const POPOVER_VIEWS: CharcellView[] = ['output'];
18
+
19
+ export function ViewControls({
20
+ view,
21
+ options: ownOptions,
22
+ children,
23
+ }: {
24
+ view: CharcellView;
25
+ /** The view's own options, shown after the kit's; omit when it has none. */
26
+ options?: ReactNode;
27
+ children?: ReactNode;
28
+ }) {
29
+ const popover = useShellConfiguration().popovers?.[view] ?? POPOVER_VIEWS.includes(view);
30
+ const hasOptions = useHasOptionControls(view) || ownOptions !== undefined;
31
+ const options = !hasOptions ? null : popover ? (
32
+ <Popover
33
+ label={`${view} options`}
34
+ trigger={({ triggerProps }) => (
35
+ <Hint text={`the ${view}'s options`} triggerProps={triggerProps}>
36
+ {(props) => <Button variant="dense" label="options…" {...props} />}
37
+ </Hint>
38
+ )}
39
+ >
40
+ <div className="ViewControls__options">
41
+ <OptionControls placement={view} />
42
+ {ownOptions}
43
+ </div>
44
+ </Popover>
45
+ ) : (
46
+ <>
47
+ <OptionControls placement={view} />
48
+ {ownOptions}
49
+ </>
50
+ );
51
+ return (
52
+ <span className="ViewControls">
53
+ {options}
54
+ <SlotOutlet name={`${view}-end`} />
55
+ {children}
56
+ </span>
57
+ );
58
+ }
@@ -0,0 +1,13 @@
1
+ @layer charcell.components {
2
+ /* A row tall, its name bold. The row it sits on places it a cell in from
3
+ the row's start. charcell's reset flattens headings, so the weight is
4
+ stated here. */
5
+ .ViewHeading {
6
+ margin: 0;
7
+ min-height: var(--charcell-row);
8
+ display: flex;
9
+ align-items: center;
10
+ font: inherit;
11
+ font-weight: 700;
12
+ }
13
+ }
@@ -0,0 +1,8 @@
1
+ // A view's heading on the row above it: the view's name, as the top bar's
2
+ // view toggle names it - on the handle row between it and the view above, or
3
+ // on a row of its own. Styled in its index.css.
4
+ import './index.css';
5
+
6
+ export function ViewHeading({ children }: { children: string }) {
7
+ return <h2 className="ViewHeading">{children}</h2>;
8
+ }
@@ -0,0 +1,9 @@
1
+ @layer charcell.components {
2
+ /* A custom view's one pane, its Frame filling the stage's place as the
3
+ grid's panes do (charcell's `fill`). */
4
+ .ViewStage {
5
+ flex: 1;
6
+ display: flex;
7
+ min-height: 0;
8
+ }
9
+ }
@@ -0,0 +1,25 @@
1
+ // A custom view: the stage bar (StageBar), the output heading with its
2
+ // controls (ViewControls), then the view, rendered through
3
+ // the generic view iframe, which the controller mounts and drives (the ready
4
+ // handshake delivers the current options, replayed on reload). One branch
5
+ // serves every registered view - no special-casing.
6
+ import { usePreviewController } from '../../controller-context';
7
+ import { PreviewPane } from '../PreviewPane';
8
+ import { HeadingRow } from '../HeadingRow';
9
+ import { ViewControls } from '../ViewControls';
10
+ import { StageBar } from '../StageBar';
11
+ import './index.css';
12
+
13
+ export function ViewStage({ viewId }: { viewId: string }) {
14
+ const controller = usePreviewController();
15
+ const view = controller.catalog.views.find((candidate) => candidate.id === viewId);
16
+ return (
17
+ <>
18
+ <StageBar />
19
+ <HeadingRow heading="output" end={<ViewControls view="output" />} />
20
+ <div className="ViewStage">
21
+ <PreviewPane title={(view?.label ?? viewId).toLowerCase()} viewId={viewId} />
22
+ </div>
23
+ </>
24
+ );
25
+ }
@@ -0,0 +1,27 @@
1
+ // The code panes' wrap toggle, one for every pane, at the end of the code
2
+ // view's heading row: the shell's `wrap` option, so the address keeps it.
3
+ // On, a long line wraps at its pane's edge; off, it runs on and the source
4
+ // scrolls across. A kit's own code block follows it too, told through the
5
+ // controller (KitCodeBlock).
6
+ import { Toggle } from 'charcell/react/unlinked';
7
+ import { usePreviewController, usePreviewState } from '../../controller-context';
8
+ import { WRAP_OPTION } from '../../shell-options';
9
+ import { Hint } from '../Hint';
10
+
11
+ export function WrapToggle() {
12
+ const controller = usePreviewController();
13
+ const wrapped = usePreviewState((state) => state.options[WRAP_OPTION] !== false);
14
+ return (
15
+ <Hint text="wrap long lines in every code pane" around>
16
+ {(hint) => (
17
+ <Toggle
18
+ variant="dense"
19
+ {...hint}
20
+ label="wrap"
21
+ pressed={wrapped}
22
+ onPressedChange={() => controller.actions.setOption(WRAP_OPTION, !wrapped)}
23
+ />
24
+ )}
25
+ </Hint>
26
+ );
27
+ }
@@ -0,0 +1,45 @@
1
+ // What a kit configures the charcell shell with: content for its named slots
2
+ // and where each option group goes. The types alone; `index.tsx` takes them.
3
+ import type { PreviewController } from '../../../src/shell';
4
+
5
+ /** One of the stage's views, each headed by a row whose end holds its
6
+ * options, its slot and its own control. */
7
+ export type CharcellView = 'scenario' | 'output' | 'code' | 'events';
8
+
9
+ /** A region of the charcell shell an option group can be placed in: the top
10
+ * bar, the end of the stage bar (the bar with the component select), the
11
+ * end of a view's heading row, and the status bar. */
12
+ export type CharcellRegion = 'top-bar' | 'stage-bar' | CharcellView | 'status-bar';
13
+
14
+ /** A named slot of the charcell shell: the end of the top bar, the end of the
15
+ * stage bar, the end of a view's heading row, and the status bar. */
16
+ export type CharcellSlotName =
17
+ | 'top-bar-end'
18
+ | 'stage-bar-end'
19
+ | 'scenario-end'
20
+ | 'output-end'
21
+ | 'code-end'
22
+ | 'events-end'
23
+ | 'status-bar';
24
+
25
+ /**
26
+ * Content for a slot: mounts into `element` when the shell renders the slot
27
+ * and may return a function that unmounts it. Written in any framework or in
28
+ * plain DOM; `reactFill` wraps a React render function.
29
+ */
30
+ export type CharcellSlotFill = (element: HTMLElement, controller: PreviewController) => (() => void) | void;
31
+
32
+ /** What `charcellShell` takes. */
33
+ export interface CharcellShellConfiguration {
34
+ /** Content for the shell's named slots. */
35
+ slots?: Partial<Record<CharcellSlotName, CharcellSlotFill>>;
36
+ /** Where each option group goes, by group name, over the shell's own
37
+ * placement: a story option, and a global option of the `context` group
38
+ * (or of none), in the output view's region; a global option of the `kit`
39
+ * group in the top bar, and of any other group in the status bar. */
40
+ groups?: Record<string, CharcellRegion>;
41
+ /** Which views hold their options in a popover at the end of
42
+ * their heading row, rather than in the row itself: the output's by
43
+ * default. */
44
+ popovers?: Partial<Record<CharcellView, boolean>>;
45
+ }
@@ -0,0 +1,27 @@
1
+ // The shell's own way of reaching its controller and its configuration: two
2
+ // React contexts the root provides, and hooks over them. The controller SDK
3
+ // holds no context of its own; these belong to this shell.
4
+ import { createContext, useContext } from 'react';
5
+ import type { PreviewController, PreviewState } from '../../../src/shell';
6
+ import { usePreview } from '../../../src/react';
7
+ import type { CharcellShellConfiguration } from './configuration';
8
+
9
+ export const PreviewControllerContext = createContext<PreviewController | null>(null);
10
+
11
+ export const ShellConfigurationContext = createContext<CharcellShellConfiguration>({});
12
+
13
+ export function usePreviewController(): PreviewController {
14
+ const controller = useContext(PreviewControllerContext);
15
+ if (!controller) throw new Error('The charcell shell is rendered outside its controller context.');
16
+ return controller;
17
+ }
18
+
19
+ /** A slice of the controller's state, re-rendering when it changes. */
20
+ export function usePreviewState<Selected>(selector: (state: PreviewState) => Selected): Selected {
21
+ return usePreview(usePreviewController(), selector);
22
+ }
23
+
24
+ /** The slot fills and group placement the shell was made with. */
25
+ export function useShellConfiguration(): CharcellShellConfiguration {
26
+ return useContext(ShellConfigurationContext);
27
+ }
@@ -0,0 +1,42 @@
1
+ // A row of short labels cut to a number of cells, a whole cell at a time, for
2
+ // controls that must never show a fraction of a character.
3
+
4
+ /** What stands for the letters a cut label has lost: the one ellipsis glyph,
5
+ * a single cell where three dots would take three. */
6
+ const ELLIPSIS = '\u2026';
7
+
8
+ /** The fewest cells a cut label's text takes: one letter and the ellipsis. */
9
+ const LEAST_CUT_CELLS = 2;
10
+
11
+ /** The cells a label takes beside its text: one of padding at each side. */
12
+ const PADDING_CELLS = 2;
13
+
14
+ /**
15
+ * Fit padded labels, side by side, into a number of cells. The last label
16
+ * gives way first: it loses a letter at a time behind an ellipsis, and once
17
+ * only a letter and the ellipsis would be left it goes, and the one before it
18
+ * starts giving way.
19
+ *
20
+ * @param labels - The labels, in their reading order.
21
+ * @param cells - The cells there are, or `undefined` before they are known.
22
+ * @returns The labels that fit, as they should read; empty if none does.
23
+ * @example
24
+ * ```ts
25
+ * fitLabels(['reload', 'open'], 14); // ['reload', 'open']
26
+ * fitLabels(['reload', 'open'], 11); // ['reload']
27
+ * fitLabels(['reload', 'open'], 8); // ['reload']
28
+ * fitLabels(['reload', 'open'], 3); // []
29
+ * ```
30
+ */
31
+ export function fitLabels(labels: readonly string[], cells: number | undefined): string[] {
32
+ if (cells === undefined) return [...labels];
33
+ for (let last = labels.length - 1; last >= 0; last -= 1) {
34
+ const before = labels.slice(0, last);
35
+ const taken = before.reduce((sum, label) => sum + [...label].length + PADDING_CELLS, 0);
36
+ const room = cells - taken - PADDING_CELLS;
37
+ const letters = [...labels[last]!];
38
+ if (room >= letters.length) return [...before, labels[last]!];
39
+ if (room >= LEAST_CUT_CELLS) return [...before, `${letters.slice(0, room - 1).join('')}${ELLIPSIS}`];
40
+ }
41
+ return [];
42
+ }
@@ -0,0 +1,18 @@
1
+ // What the html pane and the html code pane say about the expressions the
2
+ // story's html could not evaluate at rest: a count, and a hint that says what
3
+ // that means before listing them, one to a line.
4
+
5
+ /** The count the html's warnings show as: `1 warning`, `2 warnings`. */
6
+ export function htmlWarningsLabel(warnings: readonly string[]): string {
7
+ return `${warnings.length} ${warnings.length === 1 ? 'warning' : 'warnings'}`;
8
+ }
9
+
10
+ /** The hint over the count, in markdown: what the html leaves out, then
11
+ * each warning as code on a line of its own. */
12
+ export function htmlWarningsHint(warnings: readonly string[]): string {
13
+ return [
14
+ 'The html leaves out what it cannot evaluate at rest, so the parts it decides show at a default or not at all:',
15
+ '',
16
+ ...warnings.map((warning) => `- \`${warning.replace(/`/g, "'")}\``),
17
+ ].join('\n');
18
+ }
@@ -0,0 +1,82 @@
1
+ // The charcell shell: the preview's interface drawn in charcell's terminal
2
+ // look. `charcellShell(configuration)` makes a shell with fills for its named
3
+ // slots and a mapping of option groups to its regions; the module's default
4
+ // export is the shell with no configuration, so a kit can name this module
5
+ // as its `preview.shell`. The shell is built on the preview's
6
+ // public shell contract and React bindings alone.
7
+ import { createElement, type ReactNode } from 'react';
8
+ import { createRoot } from 'react-dom/client';
9
+ import { defineShell, PREVIEW_SHELL_API_VERSION, type PreviewController, type PreviewShell } from '../../../src/shell';
10
+ import { CharcellApplication } from './shell';
11
+ import type { CharcellRegion, CharcellShellConfiguration, CharcellSlotFill, CharcellSlotName } from './configuration';
12
+
13
+ export type { CharcellRegion, CharcellShellConfiguration, CharcellSlotFill, CharcellSlotName };
14
+
15
+ /**
16
+ * Make the charcell shell, with content for its slots and a placement for
17
+ * the kit's option groups.
18
+ *
19
+ * @param configuration - The slot fills and the group placement.
20
+ * @returns The shell, for a kit's shell module to default-export.
21
+ * @example
22
+ * ```tsx
23
+ * import { charcellShell, reactFill } from '@scaffold-ui-kit/preview/shells/charcell';
24
+ *
25
+ * export default charcellShell({
26
+ * slots: {
27
+ * 'top-bar-end': reactFill((controller) => <KitVersionPicker controller={controller} />),
28
+ * 'status-bar': (element, controller) => mountBadge(element, controller),
29
+ * },
30
+ * groups: { canvas: 'status-bar' },
31
+ * });
32
+ * ```
33
+ */
34
+ export function charcellShell(configuration: CharcellShellConfiguration = {}): PreviewShell {
35
+ return defineShell({
36
+ apiVersion: PREVIEW_SHELL_API_VERSION,
37
+ // Whether the navigation shows, which of the stage's four views show (the
38
+ // scenario row, the preview panes, the code panes and the events log),
39
+ // and whether the code panes wrap their lines, kept in the address.
40
+ options: [
41
+ { id: 'navigation', label: 'navigation', default: true },
42
+ { id: 'scenario', label: 'scenario', default: false },
43
+ { id: 'output', label: 'output', default: true },
44
+ { id: 'code', label: 'code', default: false },
45
+ { id: 'events', label: 'events', default: false },
46
+ { id: 'wrap', label: 'wrap', default: true },
47
+ ],
48
+ mount(root, controller) {
49
+ const reactRoot = createRoot(root);
50
+ reactRoot.render(createElement(CharcellApplication, { controller, configuration }));
51
+ return () => reactRoot.unmount();
52
+ },
53
+ });
54
+ }
55
+
56
+ /**
57
+ * A slot fill written in React: `render` runs as a component of its own
58
+ * React tree inside the slot's element, so it may use hooks, such as
59
+ * `usePreview(controller, selector)` from `@scaffold-ui-kit/preview/react`.
60
+ *
61
+ * @param render - Renders the fill for the preview's controller.
62
+ * @returns The fill, for a slot of {@link charcellShell}.
63
+ * @example
64
+ * ```tsx
65
+ * reactFill((controller) => <span>{controller.catalog.kitName}</span>)
66
+ * ```
67
+ */
68
+ export function reactFill(render: (controller: PreviewController) => ReactNode): CharcellSlotFill {
69
+ return (element, controller) => {
70
+ const root = createRoot(element);
71
+ root.render(createElement(ReactFill, { controller, render }));
72
+ // The shell unmounts its slots from inside its own React commit, and a
73
+ // root cannot be unmounted while another is rendering: so, just after.
74
+ return () => queueMicrotask(() => root.unmount());
75
+ };
76
+ }
77
+
78
+ function ReactFill(props: { controller: PreviewController; render: (controller: PreviewController) => ReactNode }) {
79
+ return props.render(props.controller);
80
+ }
81
+
82
+ export default charcellShell();
@@ -0,0 +1,57 @@
1
+ <!-- What the host page shows under this shell until the shell mounts over
2
+ it: the shell's page module gives this file as the page's root. -->
3
+ <style>
4
+ /* Nothing at all for the first 300ms, so a quick load has no flash, and
5
+ then a note in the middle of the page, its dots counting up. Spaces
6
+ hold the dots' place, so the word stays put. The note is set as the
7
+ shell's text is, in charcell's face at its size on a cell one character
8
+ wide and two tall, and sits on a whole cell counted from the page's
9
+ corner, the one nearest the middle, so it stands where the shell's own
10
+ text will. The page's head declares the face and preloads its font. */
11
+ .PreviewPageLoading {
12
+ position: fixed;
13
+ inset: 0;
14
+ font:
15
+ 0.875rem/2ch 'Charcell Overpass Mono',
16
+ ui-monospace,
17
+ monospace;
18
+ color: #808080;
19
+ }
20
+ .PreviewPageLoading::after {
21
+ content: 'loading';
22
+ position: absolute;
23
+ left: round(down, calc((100% - 10ch) / 2), 1ch);
24
+ top: round(down, calc((100% - 2ch) / 2), 2ch);
25
+ white-space: pre;
26
+ visibility: hidden;
27
+ animation:
28
+ PreviewPageLoading-show 0s 300ms forwards,
29
+ PreviewPageLoading-dots 1.2s 300ms steps(1, end) infinite;
30
+ }
31
+ @keyframes PreviewPageLoading-show {
32
+ to {
33
+ visibility: visible;
34
+ }
35
+ }
36
+ @keyframes PreviewPageLoading-dots {
37
+ 0% {
38
+ content: 'loading\00a0\00a0\00a0';
39
+ }
40
+ 25% {
41
+ content: 'loading.\00a0\00a0';
42
+ }
43
+ 50% {
44
+ content: 'loading..\00a0';
45
+ }
46
+ 75%,
47
+ 100% {
48
+ content: 'loading...';
49
+ }
50
+ }
51
+ @media (prefers-reduced-motion: reduce) {
52
+ .PreviewPageLoading::after {
53
+ animation: PreviewPageLoading-show 0s 300ms forwards;
54
+ }
55
+ }
56
+ </style>
57
+ <div class="PreviewPageLoading" role="status" aria-label="loading"></div>
@@ -0,0 +1,24 @@
1
+ // Where this shell shows an option's control: a story option and a global
2
+ // option of the context group (the group of an option that names none) in
3
+ // the output view's region, the context the panes show the story in; a
4
+ // global option of the kit's group in the top bar, and of any other group in
5
+ // the status bar - unless the kit's `groups` mapping places the option's
6
+ // group elsewhere.
7
+ import { CONTEXT_OPTION_GROUP, KIT_OPTION_GROUP, optionGroup, type PreviewOptionDescriptor } from '../../../src/shell';
8
+ import type { CharcellRegion } from './configuration';
9
+
10
+ /**
11
+ * The region an option's control renders in. A group named in `groups` goes
12
+ * where the mapping says, whatever the option's scope.
13
+ */
14
+ export function optionPlacement(
15
+ option: Pick<PreviewOptionDescriptor, 'scope' | 'group'>,
16
+ groups: Record<string, CharcellRegion> = {},
17
+ ): CharcellRegion {
18
+ const group = optionGroup(option);
19
+ const mapped = groups[group];
20
+ if (mapped) return mapped;
21
+ if (option.scope === 'story') return 'output';
22
+ if (group === KIT_OPTION_GROUP) return 'top-bar';
23
+ return group === CONTEXT_OPTION_GROUP ? 'output' : 'status-bar';
24
+ }
@@ -0,0 +1,23 @@
1
+ // The ids of the shell's own options, as the controller's state keys them.
2
+ import { shellOptionId } from '../../../src/shell';
3
+
4
+ /** Whether the navigation shows. */
5
+ export const NAVIGATION_OPTION = shellOptionId('navigation');
6
+
7
+ /** Whether the scenario view shows: the stage's top row, holding the
8
+ * scenario picker, the story's context and the editor. */
9
+ export const SCENARIO_VIEW_OPTION = shellOptionId('scenario');
10
+
11
+ /** Whether the output view shows: the row of preview panes. */
12
+ export const OUTPUT_VIEW_OPTION = shellOptionId('output');
13
+
14
+ /** Whether the code view shows: the row of code panes, each target's source
15
+ * under its preview pane. */
16
+ export const CODE_VIEW_OPTION = shellOptionId('code');
17
+
18
+ /** Whether the events view shows: the log of the events the story's panes
19
+ * recorded. */
20
+ export const EVENTS_VIEW_OPTION = shellOptionId('events');
21
+
22
+ /** Whether the code panes wrap their source's long lines: on by default. */
23
+ export const WRAP_OPTION = shellOptionId('wrap');
@@ -0,0 +1,37 @@
1
+ /*
2
+ * The charcell shell's own styling. The terminal look itself is charcell
3
+ * (`charcell/css/full`: tokens, reset, base, and the Tree / Frame / Select /
4
+ * Splitter / Toggle / Button / Field / TextInput components the shell
5
+ * composes) - the shell's stylesheets carry only what is the shell's: the
6
+ * viewport layout, the bands, the layout zones, the slots, the editor
7
+ * panel's internals, and the controls' fields. This one declares the layers
8
+ * and styles the page; each component styles itself, in an `index.css` beside
9
+ * its `index.tsx` that the component imports. All values ride charcell's
10
+ * tokens; no palette of its own. The custom properties are the one styling surface the
11
+ * shell promises; its class names and markup are its own.
12
+ *
13
+ * Each of the shell's components is a block of its own, named as the
14
+ * component is (`Application`, `Bar`, `EditorPanel`), with `Block__element`
15
+ * and `Block--modifier` classes. A block styles its own elements only: a
16
+ * charcell component that fills its place in a layout takes charcell's own
17
+ * `fill`, and where one needs any other size or place, the shell wraps it in
18
+ * an element of its own and styles that.
19
+ *
20
+ * The rules sit in charcell's cascade layers, as a charcell component's do:
21
+ * the page's in `charcell.base`, the blocks in `charcell.components`. A kit
22
+ * that adjusts the shell writes its rules in `charcell.overrides`, or outside
23
+ * any layer, and they win without a fight over specificity.
24
+ */
25
+
26
+ @layer charcell.reset, charcell.base, charcell.components, charcell.overrides;
27
+
28
+ /* The page: the screen (Application) sits centered in it, by margins of its
29
+ own; the body is a flex container only so those margins stay the screen's
30
+ rather than collapsing into the body's. */
31
+ @layer charcell.base {
32
+ body {
33
+ height: 100vh;
34
+ display: flex;
35
+ overflow: hidden;
36
+ }
37
+ }