astro-tractstack 2.0.0-rc.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 (427) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +56 -0
  3. package/astro.d.ts +64 -0
  4. package/bin/create-tractstack.js +483 -0
  5. package/dist/config.js +80 -0
  6. package/dist/index.js +2129 -0
  7. package/package.json +89 -0
  8. package/templates/artpacks/kCz/captainBreakfast_1080px.webp +0 -0
  9. package/templates/artpacks/kCz/captainBreakfast_1920px.webp +0 -0
  10. package/templates/artpacks/kCz/captainBreakfast_600px.webp +0 -0
  11. package/templates/artpacks/kCz/cleanDrips_1080px.webp +0 -0
  12. package/templates/artpacks/kCz/cleanDrips_1920px.webp +0 -0
  13. package/templates/artpacks/kCz/cleanDrips_600px.webp +0 -0
  14. package/templates/artpacks/kCz/crispwaves_1080px.webp +0 -0
  15. package/templates/artpacks/kCz/crispwaves_1920px.webp +0 -0
  16. package/templates/artpacks/kCz/crispwaves_600px.webp +0 -0
  17. package/templates/artpacks/kCz/dragonSkin_1080px.webp +0 -0
  18. package/templates/artpacks/kCz/dragonSkin_1920px.webp +0 -0
  19. package/templates/artpacks/kCz/dragonSkin_600px.webp +0 -0
  20. package/templates/artpacks/kCz/dragon_1080px.webp +0 -0
  21. package/templates/artpacks/kCz/dragon_1920px.webp +0 -0
  22. package/templates/artpacks/kCz/dragon_600px.webp +0 -0
  23. package/templates/artpacks/kCz/nightcity_1080px.webp +0 -0
  24. package/templates/artpacks/kCz/nightcity_1920px.webp +0 -0
  25. package/templates/artpacks/kCz/nightcity_600px.webp +0 -0
  26. package/templates/artpacks/kCz/pattern1_1080px.webp +0 -0
  27. package/templates/artpacks/kCz/pattern1_1920px.webp +0 -0
  28. package/templates/artpacks/kCz/pattern1_600px.webp +0 -0
  29. package/templates/artpacks/kCz/pattern2_1080px.webp +0 -0
  30. package/templates/artpacks/kCz/pattern2_1920px.webp +0 -0
  31. package/templates/artpacks/kCz/pattern2_600px.webp +0 -0
  32. package/templates/artpacks/kCz/skindrips_1080px.webp +0 -0
  33. package/templates/artpacks/kCz/skindrips_1920px.webp +0 -0
  34. package/templates/artpacks/kCz/skindrips_600px.webp +0 -0
  35. package/templates/artpacks/kCz/slimetime_1080px.webp +0 -0
  36. package/templates/artpacks/kCz/slimetime_1920px.webp +0 -0
  37. package/templates/artpacks/kCz/slimetime_600px.webp +0 -0
  38. package/templates/artpacks/kCz/snake_1080px.webp +0 -0
  39. package/templates/artpacks/kCz/snake_1920px.webp +0 -0
  40. package/templates/artpacks/kCz/snake_600px.webp +0 -0
  41. package/templates/artpacks/kCz/toxicshock_1080px.webp +0 -0
  42. package/templates/artpacks/kCz/toxicshock_1920px.webp +0 -0
  43. package/templates/artpacks/kCz/toxicshock_600px.webp +0 -0
  44. package/templates/artpacks/kCz/tractstack_1080px.webp +0 -0
  45. package/templates/artpacks/kCz/tractstack_1920px.webp +0 -0
  46. package/templates/artpacks/kCz/tractstack_600px.webp +0 -0
  47. package/templates/artpacks/kCz/tripdrips_1080px.webp +0 -0
  48. package/templates/artpacks/kCz/tripdrips_1920px.webp +0 -0
  49. package/templates/artpacks/kCz/tripdrips_600px.webp +0 -0
  50. package/templates/artpacks/kCz/wavedrips_1080px.webp +0 -0
  51. package/templates/artpacks/kCz/wavedrips_1920px.webp +0 -0
  52. package/templates/artpacks/kCz/wavedrips_600px.webp +0 -0
  53. package/templates/artpacks/t8k/beach_1080px.webp +0 -0
  54. package/templates/artpacks/t8k/beach_1920px.webp +0 -0
  55. package/templates/artpacks/t8k/beach_600px.webp +0 -0
  56. package/templates/artpacks/t8k/blast_1080px.webp +0 -0
  57. package/templates/artpacks/t8k/blast_1920px.webp +0 -0
  58. package/templates/artpacks/t8k/blast_600px.webp +0 -0
  59. package/templates/artpacks/t8k/bokeh_1080px.webp +0 -0
  60. package/templates/artpacks/t8k/bokeh_1920px.webp +0 -0
  61. package/templates/artpacks/t8k/bokeh_600px.webp +0 -0
  62. package/templates/artpacks/t8k/cartoon_1080px.webp +0 -0
  63. package/templates/artpacks/t8k/cartoon_1920px.webp +0 -0
  64. package/templates/artpacks/t8k/cartoon_600px.webp +0 -0
  65. package/templates/artpacks/t8k/darkeggshell_1080px.webp +0 -0
  66. package/templates/artpacks/t8k/darkeggshell_1920px.webp +0 -0
  67. package/templates/artpacks/t8k/darkeggshell_600px.webp +0 -0
  68. package/templates/artpacks/t8k/explosion_1080px.webp +0 -0
  69. package/templates/artpacks/t8k/explosion_1920px.webp +0 -0
  70. package/templates/artpacks/t8k/explosion_600px.webp +0 -0
  71. package/templates/artpacks/t8k/floral_1080px.webp +0 -0
  72. package/templates/artpacks/t8k/floral_1920px.webp +0 -0
  73. package/templates/artpacks/t8k/floral_600px.webp +0 -0
  74. package/templates/artpacks/t8k/flower_1080px.webp +0 -0
  75. package/templates/artpacks/t8k/flower_1920px.webp +0 -0
  76. package/templates/artpacks/t8k/flower_600px.webp +0 -0
  77. package/templates/artpacks/t8k/foliage_1080px.webp +0 -0
  78. package/templates/artpacks/t8k/foliage_1920px.webp +0 -0
  79. package/templates/artpacks/t8k/foliage_600px.webp +0 -0
  80. package/templates/artpacks/t8k/mist_1080px.webp +0 -0
  81. package/templates/artpacks/t8k/mist_1920px.webp +0 -0
  82. package/templates/artpacks/t8k/mist_600px.webp +0 -0
  83. package/templates/artpacks/t8k/portal_1080px.webp +0 -0
  84. package/templates/artpacks/t8k/portal_1920px.webp +0 -0
  85. package/templates/artpacks/t8k/portal_600px.webp +0 -0
  86. package/templates/artpacks/t8k/storytime_1080px.webp +0 -0
  87. package/templates/artpacks/t8k/storytime_1920px.webp +0 -0
  88. package/templates/artpacks/t8k/storytime_600px.webp +0 -0
  89. package/templates/artpacks/t8k/tacky_1080px.webp +0 -0
  90. package/templates/artpacks/t8k/tacky_1920px.webp +0 -0
  91. package/templates/artpacks/t8k/tacky_600px.webp +0 -0
  92. package/templates/artpacks/t8k/wallpaper_1080px.webp +0 -0
  93. package/templates/artpacks/t8k/wallpaper_1920px.webp +0 -0
  94. package/templates/artpacks/t8k/wallpaper_600px.webp +0 -0
  95. package/templates/brand/favicon.ico +0 -0
  96. package/templates/brand/logo.svg +19 -0
  97. package/templates/brand/static.jpg +0 -0
  98. package/templates/brand/wordmark.svg +4 -0
  99. package/templates/css/custom.css +51 -0
  100. package/templates/css/frontend.css +3519 -0
  101. package/templates/css/storykeep.css +92872 -0
  102. package/templates/custom/minimal/CodeHook.astro +53 -0
  103. package/templates/custom/minimal/CustomRoutes.astro +46 -0
  104. package/templates/custom/with-examples/CodeHook.astro +49 -0
  105. package/templates/custom/with-examples/CustomHero.astro +13 -0
  106. package/templates/custom/with-examples/CustomRoutes.astro +39 -0
  107. package/templates/custom/with-examples/pages/Collections.astro +110 -0
  108. package/templates/env.example +8 -0
  109. package/templates/fonts/Inter-Black.woff2 +0 -0
  110. package/templates/fonts/Inter-Bold.woff2 +0 -0
  111. package/templates/fonts/Inter-Regular.woff2 +0 -0
  112. package/templates/icons/h2.svg +1 -0
  113. package/templates/icons/h3.svg +1 -0
  114. package/templates/icons/h4.svg +1 -0
  115. package/templates/icons/h5.svg +1 -0
  116. package/templates/icons/image.svg +7 -0
  117. package/templates/icons/text.svg +6 -0
  118. package/templates/socials/codepen.svg +1 -0
  119. package/templates/socials/discord.svg +1 -0
  120. package/templates/socials/facebook.svg +1 -0
  121. package/templates/socials/github.svg +1 -0
  122. package/templates/socials/instagram.svg +1 -0
  123. package/templates/socials/linkedin.svg +1 -0
  124. package/templates/socials/mail.svg +1 -0
  125. package/templates/socials/rumble.svg +1 -0
  126. package/templates/socials/tiktok.svg +1 -0
  127. package/templates/socials/twitch.svg +1 -0
  128. package/templates/socials/twitter.svg +1 -0
  129. package/templates/socials/x.svg +1 -0
  130. package/templates/socials/youtube.svg +1 -0
  131. package/templates/src/client/analytics-events.ts +213 -0
  132. package/templates/src/client/belief-events.ts +205 -0
  133. package/templates/src/client/sse.ts +667 -0
  134. package/templates/src/components/Footer.astro +246 -0
  135. package/templates/src/components/Fragment.astro +70 -0
  136. package/templates/src/components/Header.astro +458 -0
  137. package/templates/src/components/Menu.tsx +196 -0
  138. package/templates/src/components/codehooks/BunnyVideoSetup.tsx +692 -0
  139. package/templates/src/components/codehooks/BunnyVideoWrapper.astro +78 -0
  140. package/templates/src/components/codehooks/EpinetDurationSelector.tsx +1020 -0
  141. package/templates/src/components/codehooks/EpinetTableView.tsx +594 -0
  142. package/templates/src/components/codehooks/EpinetWrapper.tsx +424 -0
  143. package/templates/src/components/codehooks/FeaturedContent.astro +273 -0
  144. package/templates/src/components/codehooks/FeaturedContentSetup.tsx +738 -0
  145. package/templates/src/components/codehooks/ListContent.astro +460 -0
  146. package/templates/src/components/codehooks/ListContentSetup.tsx +649 -0
  147. package/templates/src/components/codehooks/SankeyDiagram.tsx +359 -0
  148. package/templates/src/components/compositor/Compositor.tsx +144 -0
  149. package/templates/src/components/compositor/Node.tsx +415 -0
  150. package/templates/src/components/compositor/NodeWithGuid.tsx +25 -0
  151. package/templates/src/components/compositor/PanelVisibilityWrapper.tsx +87 -0
  152. package/templates/src/components/compositor/elements/Belief.tsx +148 -0
  153. package/templates/src/components/compositor/elements/BgImage.tsx +118 -0
  154. package/templates/src/components/compositor/elements/BgVisualBreak.tsx +102 -0
  155. package/templates/src/components/compositor/elements/BunnyVideo.tsx +63 -0
  156. package/templates/src/components/compositor/elements/IdentifyAs.tsx +66 -0
  157. package/templates/src/components/compositor/elements/PlayButton.tsx +19 -0
  158. package/templates/src/components/compositor/elements/SignUp.tsx +179 -0
  159. package/templates/src/components/compositor/elements/Svg.tsx +33 -0
  160. package/templates/src/components/compositor/elements/ToggleBelief.tsx +36 -0
  161. package/templates/src/components/compositor/elements/YouTubeWrapper.tsx +33 -0
  162. package/templates/src/components/compositor/nodes/BgPaneWrapper.tsx +35 -0
  163. package/templates/src/components/compositor/nodes/GhostInsertBlock.tsx +189 -0
  164. package/templates/src/components/compositor/nodes/Markdown.tsx +179 -0
  165. package/templates/src/components/compositor/nodes/Pane.tsx +277 -0
  166. package/templates/src/components/compositor/nodes/Pane_eraser.tsx +69 -0
  167. package/templates/src/components/compositor/nodes/Pane_layout.tsx +77 -0
  168. package/templates/src/components/compositor/nodes/RenderChildren.tsx +19 -0
  169. package/templates/src/components/compositor/nodes/StoryFragment.tsx +35 -0
  170. package/templates/src/components/compositor/nodes/TagElement.tsx +14 -0
  171. package/templates/src/components/compositor/nodes/Widget.tsx +115 -0
  172. package/templates/src/components/compositor/nodes/tagElements/NodeA.tsx +4 -0
  173. package/templates/src/components/compositor/nodes/tagElements/NodeA_eraser.tsx +26 -0
  174. package/templates/src/components/compositor/nodes/tagElements/NodeAnchorComponent.tsx +248 -0
  175. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag.tsx +684 -0
  176. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_eraser.tsx +62 -0
  177. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_insert.tsx +120 -0
  178. package/templates/src/components/compositor/nodes/tagElements/NodeBasicTag_settings.tsx +62 -0
  179. package/templates/src/components/compositor/nodes/tagElements/NodeButton.tsx +5 -0
  180. package/templates/src/components/compositor/nodes/tagElements/NodeButton_eraser.tsx +26 -0
  181. package/templates/src/components/compositor/nodes/tagElements/NodeImg.tsx +28 -0
  182. package/templates/src/components/compositor/nodes/tagElements/NodeText.tsx +18 -0
  183. package/templates/src/components/compositor/nodes/tagElements/TabIndicator.tsx +51 -0
  184. package/templates/src/components/compositor/preview/FeaturedContentPreview.tsx +128 -0
  185. package/templates/src/components/compositor/preview/ListContentPreview.tsx +213 -0
  186. package/templates/src/components/compositor/preview/OgImagePreview.tsx +223 -0
  187. package/templates/src/components/compositor/preview/PaneSnapshotGenerator.tsx +199 -0
  188. package/templates/src/components/compositor/preview/PanesPreviewGenerator.tsx +123 -0
  189. package/templates/src/components/compositor/preview/VisualBreakPreview.tsx +154 -0
  190. package/templates/src/components/edit/Header.tsx +181 -0
  191. package/templates/src/components/edit/PanelSwitch.tsx +446 -0
  192. package/templates/src/components/edit/SettingsPanel.tsx +70 -0
  193. package/templates/src/components/edit/ToolBar.tsx +101 -0
  194. package/templates/src/components/edit/ToolMode.tsx +121 -0
  195. package/templates/src/components/edit/context/ContextPaneConfig.tsx +91 -0
  196. package/templates/src/components/edit/context/ContextPaneConfig_slug.tsx +174 -0
  197. package/templates/src/components/edit/context/ContextPaneConfig_title.tsx +186 -0
  198. package/templates/src/components/edit/pane/AddPanePanel.tsx +136 -0
  199. package/templates/src/components/edit/pane/AddPanePanel_break.tsx +470 -0
  200. package/templates/src/components/edit/pane/AddPanePanel_codehook.tsx +264 -0
  201. package/templates/src/components/edit/pane/AddPanePanel_new.tsx +623 -0
  202. package/templates/src/components/edit/pane/AddPanePanel_newAICopy.tsx +107 -0
  203. package/templates/src/components/edit/pane/AddPanePanel_newAICopy_modal.tsx +217 -0
  204. package/templates/src/components/edit/pane/AddPanePanel_newCopyMode.tsx +109 -0
  205. package/templates/src/components/edit/pane/AddPanePanel_newCustomCopy.tsx +39 -0
  206. package/templates/src/components/edit/pane/AddPanePanel_reuse.tsx +445 -0
  207. package/templates/src/components/edit/pane/ConfigPanePanel.tsx +245 -0
  208. package/templates/src/components/edit/pane/PageGen.tsx +485 -0
  209. package/templates/src/components/edit/pane/PageGenSelector.tsx +238 -0
  210. package/templates/src/components/edit/pane/PageGenSpecial.tsx +362 -0
  211. package/templates/src/components/edit/pane/PageGen_preview.tsx +495 -0
  212. package/templates/src/components/edit/pane/PanePanel_impression.tsx +258 -0
  213. package/templates/src/components/edit/pane/PanePanel_path.tsx +268 -0
  214. package/templates/src/components/edit/pane/PanePanel_slug.tsx +219 -0
  215. package/templates/src/components/edit/pane/PanePanel_title.tsx +142 -0
  216. package/templates/src/components/edit/panels/StyleBreakPanel.tsx +182 -0
  217. package/templates/src/components/edit/panels/StyleCodeHookPanel.tsx +439 -0
  218. package/templates/src/components/edit/panels/StyleElementPanel.tsx +177 -0
  219. package/templates/src/components/edit/panels/StyleElementPanel_add.tsx +349 -0
  220. package/templates/src/components/edit/panels/StyleElementPanel_remove.tsx +159 -0
  221. package/templates/src/components/edit/panels/StyleElementPanel_update.tsx +320 -0
  222. package/templates/src/components/edit/panels/StyleImagePanel.tsx +460 -0
  223. package/templates/src/components/edit/panels/StyleImagePanel_add.tsx +296 -0
  224. package/templates/src/components/edit/panels/StyleImagePanel_remove.tsx +153 -0
  225. package/templates/src/components/edit/panels/StyleImagePanel_update.tsx +312 -0
  226. package/templates/src/components/edit/panels/StyleLiElementPanel.tsx +273 -0
  227. package/templates/src/components/edit/panels/StyleLiElementPanel_add.tsx +301 -0
  228. package/templates/src/components/edit/panels/StyleLiElementPanel_remove.tsx +132 -0
  229. package/templates/src/components/edit/panels/StyleLiElementPanel_update.tsx +313 -0
  230. package/templates/src/components/edit/panels/StyleLinkPanel.tsx +346 -0
  231. package/templates/src/components/edit/panels/StyleLinkPanel_add.tsx +265 -0
  232. package/templates/src/components/edit/panels/StyleLinkPanel_config.tsx +240 -0
  233. package/templates/src/components/edit/panels/StyleLinkPanel_remove.tsx +94 -0
  234. package/templates/src/components/edit/panels/StyleLinkPanel_update.tsx +110 -0
  235. package/templates/src/components/edit/panels/StyleParentPanel.tsx +263 -0
  236. package/templates/src/components/edit/panels/StyleParentPanel_add.tsx +275 -0
  237. package/templates/src/components/edit/panels/StyleParentPanel_deleteLayer.tsx +112 -0
  238. package/templates/src/components/edit/panels/StyleParentPanel_remove.tsx +87 -0
  239. package/templates/src/components/edit/panels/StyleParentPanel_update.tsx +141 -0
  240. package/templates/src/components/edit/panels/StyleWidgetPanel.tsx +428 -0
  241. package/templates/src/components/edit/panels/StyleWidgetPanel_add.tsx +292 -0
  242. package/templates/src/components/edit/panels/StyleWidgetPanel_config.tsx +190 -0
  243. package/templates/src/components/edit/panels/StyleWidgetPanel_remove.tsx +152 -0
  244. package/templates/src/components/edit/panels/StyleWidgetPanel_update.tsx +308 -0
  245. package/templates/src/components/edit/state/SaveModal.tsx +811 -0
  246. package/templates/src/components/edit/state/StylesMemory.tsx +310 -0
  247. package/templates/src/components/edit/storyfragment/StoryFragmentConfigPanel.tsx +289 -0
  248. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_menu.tsx +320 -0
  249. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_og.tsx +888 -0
  250. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_slug.tsx +269 -0
  251. package/templates/src/components/edit/storyfragment/StoryFragmentPanel_title.tsx +190 -0
  252. package/templates/src/components/edit/widgets/BeliefWidget.tsx +183 -0
  253. package/templates/src/components/edit/widgets/BunnyWidget.tsx +134 -0
  254. package/templates/src/components/edit/widgets/IdentifyAsWidget.tsx +193 -0
  255. package/templates/src/components/edit/widgets/SignupWidget.tsx +177 -0
  256. package/templates/src/components/edit/widgets/ToggleWidget.tsx +152 -0
  257. package/templates/src/components/edit/widgets/YouTubeWidget.tsx +65 -0
  258. package/templates/src/components/fields/ActionBuilderTimeSelector.tsx +353 -0
  259. package/templates/src/components/fields/ArtpackImage.tsx +480 -0
  260. package/templates/src/components/fields/BackgroundImage.tsx +530 -0
  261. package/templates/src/components/fields/BackgroundImageWrapper.tsx +192 -0
  262. package/templates/src/components/fields/BooleanParam.tsx +67 -0
  263. package/templates/src/components/fields/BunnyMomentSelector.tsx +56 -0
  264. package/templates/src/components/fields/ColorPickerCombo.tsx +284 -0
  265. package/templates/src/components/fields/ImageUpload.tsx +405 -0
  266. package/templates/src/components/fields/MultiParam.tsx +75 -0
  267. package/templates/src/components/fields/PaneBreakCollectionSelector.tsx +97 -0
  268. package/templates/src/components/fields/PaneBreakShapeSelector.tsx +134 -0
  269. package/templates/src/components/fields/SelectedTailwindClass.tsx +44 -0
  270. package/templates/src/components/fields/SingleParam.tsx +73 -0
  271. package/templates/src/components/fields/ViewportComboBox.tsx +252 -0
  272. package/templates/src/components/form/ActionBuilderField.tsx +282 -0
  273. package/templates/src/components/form/ActionBuilderSlugSelector.tsx +182 -0
  274. package/templates/src/components/form/BooleanToggle.tsx +94 -0
  275. package/templates/src/components/form/ColorPicker.tsx +153 -0
  276. package/templates/src/components/form/DateTimeInput.tsx +638 -0
  277. package/templates/src/components/form/EnumSelect.tsx +88 -0
  278. package/templates/src/components/form/FileUpload.tsx +465 -0
  279. package/templates/src/components/form/MagicPathBuilder.tsx +546 -0
  280. package/templates/src/components/form/NumberInput.tsx +101 -0
  281. package/templates/src/components/form/ParagraphArrayInput.tsx +207 -0
  282. package/templates/src/components/form/StringArrayInput.tsx +163 -0
  283. package/templates/src/components/form/StringInput.tsx +88 -0
  284. package/templates/src/components/form/UnsavedChangesBar.tsx +295 -0
  285. package/templates/src/components/form/advanced/APIConfigSection.tsx +69 -0
  286. package/templates/src/components/form/advanced/AuthConfigSection.tsx +97 -0
  287. package/templates/src/components/form/brand/BrandAssetsSection.tsx +93 -0
  288. package/templates/src/components/form/brand/BrandColorsSection.tsx +201 -0
  289. package/templates/src/components/form/brand/SEOSection.tsx +101 -0
  290. package/templates/src/components/form/brand/SiteConfigSection.tsx +61 -0
  291. package/templates/src/components/form/brand/SocialLinksSection.tsx +393 -0
  292. package/templates/src/components/profile/ProfileConsent.tsx +65 -0
  293. package/templates/src/components/profile/ProfileCreate.tsx +462 -0
  294. package/templates/src/components/profile/ProfileEdit.tsx +409 -0
  295. package/templates/src/components/profile/ProfileSwitch.tsx +255 -0
  296. package/templates/src/components/profile/ProfileUnlock.tsx +221 -0
  297. package/templates/src/components/storykeep/Dashboard.tsx +160 -0
  298. package/templates/src/components/storykeep/Dashboard_Activity.tsx +56 -0
  299. package/templates/src/components/storykeep/Dashboard_Advanced.tsx +165 -0
  300. package/templates/src/components/storykeep/Dashboard_Analytics.tsx +451 -0
  301. package/templates/src/components/storykeep/Dashboard_Branding.tsx +95 -0
  302. package/templates/src/components/storykeep/Dashboard_Content.tsx +191 -0
  303. package/templates/src/components/storykeep/controls/UsageCell.tsx +71 -0
  304. package/templates/src/components/storykeep/controls/content/BeliefForm.tsx +378 -0
  305. package/templates/src/components/storykeep/controls/content/BeliefTable.tsx +329 -0
  306. package/templates/src/components/storykeep/controls/content/ContentBrowser.tsx +385 -0
  307. package/templates/src/components/storykeep/controls/content/ContentSummary.tsx +149 -0
  308. package/templates/src/components/storykeep/controls/content/KnownResourceForm.tsx +397 -0
  309. package/templates/src/components/storykeep/controls/content/KnownResourceTable.tsx +260 -0
  310. package/templates/src/components/storykeep/controls/content/ManageContent.tsx +439 -0
  311. package/templates/src/components/storykeep/controls/content/MenuForm.tsx +239 -0
  312. package/templates/src/components/storykeep/controls/content/MenuTable.tsx +332 -0
  313. package/templates/src/components/storykeep/controls/content/ResourceBulkIngest.tsx +724 -0
  314. package/templates/src/components/storykeep/controls/content/ResourceForm.tsx +355 -0
  315. package/templates/src/components/storykeep/controls/content/ResourceTable.tsx +222 -0
  316. package/templates/src/components/storykeep/controls/content/StoryFragmentTable.tsx +482 -0
  317. package/templates/src/components/storykeep/state/BrandingWrapper.tsx +42 -0
  318. package/templates/src/components/storykeep/state/FetchAnalytics.tsx +350 -0
  319. package/templates/src/components/storykeep/widgets/ResponsiveLine.tsx +319 -0
  320. package/templates/src/components/storykeep/widgets/Wizard.tsx +278 -0
  321. package/templates/src/components/tenant/RegistrationForm.tsx +447 -0
  322. package/templates/src/components/widgets/BunnyVideoHero.astro +775 -0
  323. package/templates/src/components/widgets/Impression.tsx +102 -0
  324. package/templates/src/components/widgets/ImpressionWrapper.tsx +214 -0
  325. package/templates/src/constants/beliefs.ts +61 -0
  326. package/templates/src/constants/brandThemes.ts +133 -0
  327. package/templates/src/constants/prompts.json +55 -0
  328. package/templates/src/constants/shapes.ts +556 -0
  329. package/templates/src/constants/stopWords.ts +116 -0
  330. package/templates/src/constants/tailwindColors.json +344 -0
  331. package/templates/src/constants.ts +274 -0
  332. package/templates/src/hooks/useFormState.ts +203 -0
  333. package/templates/src/layouts/Layout.astro +290 -0
  334. package/templates/src/lib/session.ts +126 -0
  335. package/templates/src/lib/storyData.ts +56 -0
  336. package/templates/src/middleware.ts +52 -0
  337. package/templates/src/pages/404.astro +54 -0
  338. package/templates/src/pages/[...slug]/edit.astro +216 -0
  339. package/templates/src/pages/[...slug].astro +148 -0
  340. package/templates/src/pages/api/auth/decode.ts +101 -0
  341. package/templates/src/pages/api/auth/login.ts +122 -0
  342. package/templates/src/pages/api/auth/logout.ts +37 -0
  343. package/templates/src/pages/api/auth/profile.ts +76 -0
  344. package/templates/src/pages/api/orphan-analysis.ts +106 -0
  345. package/templates/src/pages/api/tailwind.ts +116 -0
  346. package/templates/src/pages/collections/[param1].astro +65 -0
  347. package/templates/src/pages/context/[...contextSlug]/edit.astro +207 -0
  348. package/templates/src/pages/context/[...contextSlug].astro +161 -0
  349. package/templates/src/pages/llms.txt.ts +122 -0
  350. package/templates/src/pages/maint.astro +183 -0
  351. package/templates/src/pages/media/[...slug].astro +67 -0
  352. package/templates/src/pages/robots.txt.ts +36 -0
  353. package/templates/src/pages/sandbox/activate.astro +258 -0
  354. package/templates/src/pages/sandbox/register.astro +44 -0
  355. package/templates/src/pages/sandbox/success.astro +179 -0
  356. package/templates/src/pages/sitemap.xml.ts +119 -0
  357. package/templates/src/pages/storykeep/advanced.astro +69 -0
  358. package/templates/src/pages/storykeep/branding.astro +57 -0
  359. package/templates/src/pages/storykeep/content.astro +71 -0
  360. package/templates/src/pages/storykeep/init.astro +36 -0
  361. package/templates/src/pages/storykeep/login.astro +266 -0
  362. package/templates/src/pages/storykeep/logout.astro +84 -0
  363. package/templates/src/pages/storykeep/profile.astro +98 -0
  364. package/templates/src/pages/storykeep.astro +81 -0
  365. package/templates/src/stores/analytics.ts +171 -0
  366. package/templates/src/stores/backend.ts +16 -0
  367. package/templates/src/stores/navigation.ts +149 -0
  368. package/templates/src/stores/nodes.ts +2390 -0
  369. package/templates/src/stores/nodesHistory.ts +85 -0
  370. package/templates/src/stores/notificationSystem.ts +41 -0
  371. package/templates/src/stores/orphanAnalysis.ts +409 -0
  372. package/templates/src/stores/storykeep.ts +247 -0
  373. package/templates/src/types/astro.ts +86 -0
  374. package/templates/src/types/compositorTypes.ts +456 -0
  375. package/templates/src/types/formTypes.ts +281 -0
  376. package/templates/src/types/multiTenant.ts +77 -0
  377. package/templates/src/types/nodeProps.ts +66 -0
  378. package/templates/src/types/tractstack.ts +445 -0
  379. package/templates/src/utils/aai/getTitleSlug.ts +72 -0
  380. package/templates/src/utils/actions/actionButton.ts +101 -0
  381. package/templates/src/utils/actions/lispLexer.ts +57 -0
  382. package/templates/src/utils/actions/preParse_Action.ts +85 -0
  383. package/templates/src/utils/actions/preParse_Bunny.ts +50 -0
  384. package/templates/src/utils/actions/preParse_Clicked.ts +87 -0
  385. package/templates/src/utils/actions/preParse_Impression.ts +71 -0
  386. package/templates/src/utils/api/advancedConfig.ts +66 -0
  387. package/templates/src/utils/api/advancedHelpers.ts +134 -0
  388. package/templates/src/utils/api/beliefConfig.ts +87 -0
  389. package/templates/src/utils/api/beliefHelpers.ts +196 -0
  390. package/templates/src/utils/api/brandConfig.ts +126 -0
  391. package/templates/src/utils/api/brandHelpers.ts +155 -0
  392. package/templates/src/utils/api/fileHelpers.ts +306 -0
  393. package/templates/src/utils/api/menuConfig.ts +57 -0
  394. package/templates/src/utils/api/menuHelpers.ts +156 -0
  395. package/templates/src/utils/api/resourceConfig.ts +158 -0
  396. package/templates/src/utils/api/resourceHelpers.ts +72 -0
  397. package/templates/src/utils/api/tenantConfig.ts +97 -0
  398. package/templates/src/utils/api/tenantHelpers.ts +172 -0
  399. package/templates/src/utils/api.ts +183 -0
  400. package/templates/src/utils/auth.ts +150 -0
  401. package/templates/src/utils/backend.ts +243 -0
  402. package/templates/src/utils/compositor/TemplateMarkdowns.ts +118 -0
  403. package/templates/src/utils/compositor/TemplateNodes.ts +138 -0
  404. package/templates/src/utils/compositor/TemplatePanes.ts +100 -0
  405. package/templates/src/utils/compositor/allowInsert.ts +100 -0
  406. package/templates/src/utils/compositor/domHelpers.ts +37 -0
  407. package/templates/src/utils/compositor/handleClickEvent.ts +131 -0
  408. package/templates/src/utils/compositor/nodesHelper.ts +491 -0
  409. package/templates/src/utils/compositor/nodesMarkdownGenerator.ts +292 -0
  410. package/templates/src/utils/compositor/processMarkdown.ts +431 -0
  411. package/templates/src/utils/compositor/reduceNodesClassNames.ts +192 -0
  412. package/templates/src/utils/compositor/tailwindClasses.ts +1795 -0
  413. package/templates/src/utils/compositor/tailwindColors.ts +227 -0
  414. package/templates/src/utils/compositor/templateMarkdownStyles.ts +1265 -0
  415. package/templates/src/utils/compositor/typeGuards.ts +193 -0
  416. package/templates/src/utils/etl/extractor.ts +119 -0
  417. package/templates/src/utils/etl/index.ts +88 -0
  418. package/templates/src/utils/etl/loader.ts +36 -0
  419. package/templates/src/utils/etl/transformer.ts +286 -0
  420. package/templates/src/utils/helpers.ts +435 -0
  421. package/templates/src/utils/layout.ts +209 -0
  422. package/templates/src/utils/profileStorage.ts +306 -0
  423. package/templates/src/utils/useInterval.ts +27 -0
  424. package/templates/tailwind.config.cjs +169 -0
  425. package/utils/create-resolver.ts +10 -0
  426. package/utils/inject-files.ts +2140 -0
  427. package/utils/validate-config.ts +43 -0
@@ -0,0 +1,292 @@
1
+ import { useState, useCallback, useMemo } from 'react';
2
+ import { Combobox } from '@ark-ui/react';
3
+ import { createListCollection } from '@ark-ui/react/collection';
4
+ import ChevronUpDownIcon from '@heroicons/react/24/outline/ChevronUpDownIcon';
5
+ import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
6
+ import { settingsPanelStore } from '@/stores/storykeep';
7
+ import { getCtx } from '@/stores/nodes';
8
+ import { tailwindClasses } from '@/utils/compositor/tailwindClasses';
9
+ import { isMarkdownPaneFragmentNode } from '@/utils/compositor/typeGuards';
10
+ import type { BasePanelProps } from '@/types/compositorTypes';
11
+
12
+ // Recommended styles for widget containers (li)
13
+ const CONTAINER_STYLES = [
14
+ { key: 'bgCOLOR', title: 'Background Color' },
15
+ { key: 'borderCOLOR', title: 'Border Color' },
16
+ { key: 'borderSTYLE', title: 'Border Style' },
17
+ { key: 'borderWIDTH', title: 'Border Width' },
18
+ { key: 'rounded', title: 'Border Radius' },
19
+ { key: 'shadow', title: 'Box Shadow' },
20
+ { key: 'p', title: 'Padding' },
21
+ { key: 'px', title: 'Padding X' },
22
+ { key: 'py', title: 'Padding Y' },
23
+ { key: 'm', title: 'Margin' },
24
+ { key: 'mx', title: 'Margin X' },
25
+ { key: 'my', title: 'Margin Y' },
26
+ ];
27
+
28
+ // Recommended styles for outer containers (ul/ol)
29
+ const OUTER_CONTAINER_STYLES = [
30
+ { key: 'bgCOLOR', title: 'Background Color' },
31
+ { key: 'maxW', title: 'Max Width' },
32
+ { key: 'rounded', title: 'Border Radius' },
33
+ { key: 'shadow', title: 'Box Shadow' },
34
+ { key: 'p', title: 'Padding' },
35
+ { key: 'm', title: 'Margin' },
36
+ { key: 'gap', title: 'Gap Between Items' },
37
+ { key: 'columns', title: 'Column Layout' },
38
+ ];
39
+
40
+ const getFilteredStyles = (
41
+ showAdvanced: boolean,
42
+ existingClasses: Set<string>
43
+ ) => {
44
+ return Object.entries(tailwindClasses)
45
+ .filter(
46
+ ([key, details]) =>
47
+ (showAdvanced || details.priority <= 1) && !existingClasses.has(key)
48
+ )
49
+ .map(([key, details]) => ({
50
+ key,
51
+ title: details.title,
52
+ className: details.className,
53
+ prefix: details.prefix,
54
+ values: details.values,
55
+ }))
56
+ .sort((a, b) => a.title.localeCompare(b.title));
57
+ };
58
+
59
+ interface StyleOption {
60
+ key: string;
61
+ title: string;
62
+ className: string;
63
+ prefix: string;
64
+ values: string[];
65
+ }
66
+
67
+ const StyleWidgetPanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
68
+ const [query, setQuery] = useState('');
69
+ const [showAdvanced, setShowAdvanced] = useState(false);
70
+ const [selectedStyle, setSelectedStyle] = useState<string | null>(null);
71
+
72
+ if (!node?.tagName || !parentNode || !isMarkdownPaneFragmentNode(parentNode))
73
+ return null;
74
+
75
+ const isOuterContainer = node.tagName === 'ul' || node.tagName === 'ol';
76
+ const isContainer = node.tagName === 'li';
77
+ const isWidget = node.tagName === 'code';
78
+
79
+ const ctx = getCtx();
80
+ const allNodes = ctx.allNodes.get();
81
+
82
+ // When styling container or outer container, use their IDs directly
83
+ const targetNode = allNodes.get(node.id);
84
+ if (!targetNode) return null;
85
+
86
+ const currentClasses = new Set<string>();
87
+
88
+ // Get existing classes from default classes in parent for THIS element type
89
+ if (parentNode.defaultClasses?.[node.tagName]) {
90
+ const defaults = parentNode.defaultClasses[node.tagName];
91
+ Object.keys(defaults.mobile).forEach((key) => currentClasses.add(key));
92
+ if (defaults.tablet)
93
+ Object.keys(defaults.tablet).forEach((key) => currentClasses.add(key));
94
+ if (defaults.desktop)
95
+ Object.keys(defaults.desktop).forEach((key) => currentClasses.add(key));
96
+ }
97
+
98
+ // Get existing override classes for THIS element
99
+ if (`overrideClasses` in targetNode && targetNode.overrideClasses) {
100
+ Object.values(targetNode.overrideClasses).forEach((viewportClasses) => {
101
+ Object.keys(viewportClasses).forEach((key) => currentClasses.add(key));
102
+ });
103
+ }
104
+
105
+ const styles = getFilteredStyles(showAdvanced, currentClasses);
106
+ const filteredStyles =
107
+ query === ''
108
+ ? styles
109
+ : styles.filter(
110
+ (style) =>
111
+ style.title.toLowerCase().includes(query.toLowerCase()) ||
112
+ style.key.toLowerCase().includes(query.toLowerCase())
113
+ );
114
+
115
+ // Create collection for Ark UI Combobox
116
+ const collection = useMemo(
117
+ () =>
118
+ createListCollection({
119
+ items: filteredStyles,
120
+ itemToValue: (item: StyleOption) => item.key,
121
+ itemToString: (item: StyleOption) => item.title,
122
+ }),
123
+ [filteredStyles]
124
+ );
125
+
126
+ // Get appropriate recommended styles based on element type
127
+ const recommendedStyles = isOuterContainer
128
+ ? OUTER_CONTAINER_STYLES
129
+ : isContainer
130
+ ? CONTAINER_STYLES
131
+ : [];
132
+
133
+ const availableRecommendedStyles = recommendedStyles.filter(
134
+ (style) => !currentClasses.has(style.key)
135
+ );
136
+
137
+ const handleSelect = useCallback(
138
+ (details: { value: string[] }) => {
139
+ const styleKey = details.value[0] || '';
140
+ if (!styleKey) return;
141
+
142
+ setSelectedStyle(styleKey);
143
+ settingsPanelStore.set({
144
+ action: isOuterContainer
145
+ ? 'style-code-outer-update'
146
+ : isContainer
147
+ ? 'style-code-container-update'
148
+ : 'style-code-update',
149
+ nodeId: node.id,
150
+ childId, // Preserve childId for container context
151
+ className: styleKey,
152
+ expanded: true,
153
+ });
154
+ },
155
+ [node.id, childId, isOuterContainer, isContainer, isWidget]
156
+ );
157
+
158
+ const handleCancel = () => {
159
+ // Return to main panel with correct context
160
+ settingsPanelStore.set({
161
+ action: 'style-widget',
162
+ nodeId: childId || node.id, // Use childId when available for context
163
+ expanded: true,
164
+ });
165
+ };
166
+
167
+ const elementTypeTitle = isOuterContainer
168
+ ? 'Outer Container'
169
+ : isContainer
170
+ ? 'Container'
171
+ : 'Widget';
172
+
173
+ // CSS to properly style the combobox items with hover and selection
174
+ const comboboxItemStyles = `
175
+ .style-item[data-highlighted] {
176
+ background-color: #0891b2; /* bg-cyan-600 */
177
+ color: white;
178
+ }
179
+ .style-item[data-highlighted] .style-indicator {
180
+ color: white;
181
+ }
182
+ .style-item[data-state="checked"] .style-indicator {
183
+ display: flex;
184
+ }
185
+ .style-item .style-indicator {
186
+ display: none;
187
+ }
188
+ .style-item[data-state="checked"] {
189
+ font-weight: bold;
190
+ }
191
+ `;
192
+
193
+ return (
194
+ <div className="min-h-[400px] max-w-md space-y-4">
195
+ <style>{comboboxItemStyles}</style>
196
+
197
+ <div className="flex flex-row flex-nowrap justify-between">
198
+ <h3 className="text-xl font-bold">Add Style ({elementTypeTitle})</h3>
199
+ <button
200
+ title="Return to preview pane"
201
+ onClick={handleCancel}
202
+ className="text-myblue hover:text-black"
203
+ >
204
+ Go Back
205
+ </button>
206
+ </div>
207
+
208
+ <div className="mb-4 flex items-center gap-2">
209
+ <input
210
+ type="checkbox"
211
+ id="show-advanced"
212
+ checked={showAdvanced}
213
+ onChange={(e) => setShowAdvanced(e.target.checked)}
214
+ className="border-mydarkgrey h-4 w-4 rounded text-cyan-600 focus:ring-cyan-600"
215
+ />
216
+ <label htmlFor="show-advanced" className="text-mydarkgrey text-sm">
217
+ Show Advanced Styles
218
+ </label>
219
+ </div>
220
+
221
+ <div className="relative w-full">
222
+ <Combobox.Root
223
+ collection={collection}
224
+ value={selectedStyle ? [selectedStyle] : []}
225
+ onValueChange={handleSelect}
226
+ loopFocus={true}
227
+ openOnKeyPress={true}
228
+ composite={true}
229
+ >
230
+ <div className="relative">
231
+ <Combobox.Input
232
+ className="border-mydarkgrey focus:border-myblue focus:ring-myblue w-full rounded-md py-2 pl-3 pr-10 text-xl shadow-sm"
233
+ onChange={(e) => setQuery(e.target.value)}
234
+ placeholder="Search styles..."
235
+ />
236
+ <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
237
+ <ChevronUpDownIcon
238
+ className="text-mydarkgrey h-5 w-5"
239
+ aria-hidden="true"
240
+ />
241
+ </Combobox.Trigger>
242
+ </div>
243
+
244
+ <Combobox.Content className="absolute z-50 mt-1 max-h-64 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
245
+ {collection.items.length === 0 ? (
246
+ <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
247
+ Nothing found.
248
+ </div>
249
+ ) : (
250
+ collection.items.map((style) => (
251
+ <Combobox.Item
252
+ key={style.key}
253
+ item={style}
254
+ className="style-item relative cursor-default select-none py-2 pl-10 pr-4 text-black"
255
+ >
256
+ <span className="block truncate">
257
+ {style.title}
258
+ <span className="ml-2 text-sm opacity-60">
259
+ {style.className}
260
+ </span>
261
+ </span>
262
+ <span className="style-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
263
+ <CheckIcon className="h-5 w-5" aria-hidden="true" />
264
+ </span>
265
+ </Combobox.Item>
266
+ ))
267
+ )}
268
+ </Combobox.Content>
269
+ </Combobox.Root>
270
+ </div>
271
+
272
+ {availableRecommendedStyles.length > 0 && (
273
+ <div className="mt-8">
274
+ <h3 className="mb-3 text-lg font-bold">Recommended Styles</h3>
275
+ <div className="flex flex-wrap gap-2">
276
+ {availableRecommendedStyles.map((style) => (
277
+ <button
278
+ key={style.key}
279
+ onClick={() => handleSelect({ value: [style.key] })}
280
+ className="hover:bg-mygreen/20 inline-flex items-center rounded-md bg-slate-50 px-3 py-2 text-sm text-black transition-colors duration-200"
281
+ >
282
+ <span className="font-bold">{style.title}</span>
283
+ </button>
284
+ ))}
285
+ </div>
286
+ </div>
287
+ )}
288
+ </div>
289
+ );
290
+ };
291
+
292
+ export default StyleWidgetPanelAdd;
@@ -0,0 +1,190 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { getCtx } from '@/stores/nodes';
3
+ import { cloneDeep } from '@/utils/helpers';
4
+ import { widgetMeta } from '@/constants';
5
+ import SingleParam from '@/components/fields/SingleParam';
6
+ import BooleanParam from '@/components/fields/BooleanParam';
7
+ import MultiParam from '@/components/fields/MultiParam';
8
+ import BeliefWidget from '@/components/edit/widgets/BeliefWidget';
9
+ import BunnyWidget from '@/components/edit/widgets/BunnyWidget';
10
+ import IdentifyAsWidget from '@/components/edit/widgets/IdentifyAsWidget';
11
+ import SignupWidget from '@/components/edit/widgets/SignupWidget';
12
+ import ToggleWidget from '@/components/edit/widgets/ToggleWidget';
13
+ import YouTubeWidget from '@/components/edit/widgets/YouTubeWidget';
14
+ import type { FlatNode } from '@/types/compositorTypes';
15
+
16
+ interface StyleWidgetConfigPanelProps {
17
+ node: FlatNode;
18
+ }
19
+
20
+ function StyleWidgetConfigPanel({ node }: StyleWidgetConfigPanelProps) {
21
+ const [init, setInit] = useState(false);
22
+
23
+ useEffect(() => {
24
+ if (!init) setInit(true);
25
+ }, []);
26
+
27
+ if (!node || !('copy' in node) || typeof node.copy !== 'string') return null;
28
+
29
+ // Extract the widget type from the node's copy
30
+ const regexpHook =
31
+ /^(identifyAs|youtube|bunny|bunnyContext|toggle|resource|belief|signup)\((.*)\)$/;
32
+ const hookMatch = node.copy?.match(regexpHook);
33
+ if (!hookMatch) return null;
34
+
35
+ const widgetType = hookMatch[1];
36
+ const widgetInfo = widgetMeta[widgetType];
37
+
38
+ // If widget is not found in widgetMeta, display error message
39
+ if (!widgetInfo) {
40
+ return (
41
+ <div className="rounded-md bg-red-50 p-4 text-red-800">
42
+ Widget type '{widgetType}' not found in configuration. Please check the
43
+ widget type.
44
+ </div>
45
+ );
46
+ }
47
+
48
+ // Get params from node and ensure they match the expected count from metadata
49
+ const existingParams = node.codeHookParams?.map((p) => String(p)) || [];
50
+ const expectedParamCount = widgetInfo.parameters.length;
51
+
52
+ // Ensure params array is the right length with default values if needed
53
+ const params = Array(expectedParamCount)
54
+ .fill('')
55
+ .map((_, index) => {
56
+ if (
57
+ index < existingParams.length &&
58
+ existingParams[index] !== undefined
59
+ ) {
60
+ return existingParams[index];
61
+ }
62
+ return widgetInfo.parameters[index].defaultValue;
63
+ });
64
+
65
+ const handleParamUpdate = (updatedParams: string[]) => {
66
+ if (!init) return;
67
+
68
+ // Create a copy of the node to avoid direct mutation
69
+ const newNode = cloneDeep(node);
70
+
71
+ // Ensure all parameters are strings
72
+ const stringParams = updatedParams.map((param) => String(param));
73
+
74
+ // Update the codeHookParams
75
+ newNode.codeHookParams = stringParams;
76
+
77
+ // Update the copy field to match the new params
78
+ newNode.copy = `${widgetType}(${stringParams.join('|')})`;
79
+
80
+ // Mark the node as changed
81
+ newNode.isChanged = true;
82
+
83
+ // Update the node in the store
84
+ getCtx().modifyNodes([newNode]);
85
+ };
86
+
87
+ // Specialized widget editors for specific widget types
88
+ const specializedEditors = {
89
+ belief: () => <BeliefWidget node={node} onUpdate={handleParamUpdate} />,
90
+ bunny: () => <BunnyWidget node={node} onUpdate={handleParamUpdate} />,
91
+ identifyAs: () => (
92
+ <IdentifyAsWidget node={node} onUpdate={handleParamUpdate} />
93
+ ),
94
+ signup: () => <SignupWidget node={node} onUpdate={handleParamUpdate} />,
95
+ toggle: () => <ToggleWidget node={node} onUpdate={handleParamUpdate} />,
96
+ youtube: () => <YouTubeWidget node={node} onUpdate={handleParamUpdate} />,
97
+ };
98
+
99
+ // Generic parameter editor for widget types without specific editors
100
+ const GenericParamEditor = () => (
101
+ <div className="space-y-4">
102
+ {widgetInfo.parameters.map((param, index) => {
103
+ const paramValue = params[index] || param.defaultValue;
104
+
105
+ switch (param.type) {
106
+ case 'boolean':
107
+ return (
108
+ <BooleanParam
109
+ key={index}
110
+ label={param.label}
111
+ value={paramValue === 'true'}
112
+ onChange={(value) => {
113
+ const newParams = [...params];
114
+ newParams[index] = value ? 'true' : 'false';
115
+ handleParamUpdate(newParams);
116
+ }}
117
+ />
118
+ );
119
+ case 'multi-string':
120
+ return (
121
+ <MultiParam
122
+ key={index}
123
+ label={param.label}
124
+ values={paramValue ? paramValue.split(',').filter(Boolean) : []}
125
+ onChange={(values) => {
126
+ const newParams = [...params];
127
+ newParams[index] = values.join(',');
128
+ handleParamUpdate(newParams);
129
+ }}
130
+ />
131
+ );
132
+ case 'scale':
133
+ // Scale parameters have special rendering requirements but still use string storage
134
+ return (
135
+ <SingleParam
136
+ key={index}
137
+ label={param.label}
138
+ value={paramValue}
139
+ disabled={true}
140
+ onChange={(value) => {
141
+ const newParams = [...params];
142
+ newParams[index] = value;
143
+ handleParamUpdate(newParams);
144
+ }}
145
+ />
146
+ );
147
+ case 'string':
148
+ default:
149
+ return (
150
+ <SingleParam
151
+ key={index}
152
+ label={param.label}
153
+ value={paramValue}
154
+ onChange={(value) => {
155
+ const newParams = [...params];
156
+ newParams[index] = value;
157
+ handleParamUpdate(newParams);
158
+ }}
159
+ />
160
+ );
161
+ }
162
+ })}
163
+ </div>
164
+ );
165
+
166
+ // Render the editor (either specialized or generic)
167
+ const renderEditor = () => {
168
+ // Check if we have a specialized editor for this widget type
169
+ if (widgetType in specializedEditors) {
170
+ return specializedEditors[
171
+ widgetType as keyof typeof specializedEditors
172
+ ]();
173
+ }
174
+
175
+ // Fall back to generic editor
176
+ return <GenericParamEditor />;
177
+ };
178
+
179
+ return (
180
+ <div className="space-y-4">
181
+ <h3 className="text-lg font-bold">{widgetInfo.title}</h3>
182
+ <p className="text-sm text-gray-600">
183
+ Configure the parameters for this {widgetType} widget.
184
+ </p>
185
+ {renderEditor()}
186
+ </div>
187
+ );
188
+ }
189
+
190
+ export default StyleWidgetConfigPanel;
@@ -0,0 +1,152 @@
1
+ import { settingsPanelStore } from '@/stores/storykeep';
2
+ import { getCtx } from '@/stores/nodes';
3
+ import { tailwindClasses } from '@/utils/compositor/tailwindClasses';
4
+ import { isMarkdownPaneFragmentNode } from '@/utils/compositor/typeGuards';
5
+ import { cloneDeep } from '@/utils/helpers';
6
+ import type { BasePanelProps, FlatNode } from '@/types/compositorTypes';
7
+
8
+ const StyleWidgetRemovePanel = ({
9
+ node,
10
+ parentNode,
11
+ className,
12
+ childId,
13
+ }: BasePanelProps) => {
14
+ if (
15
+ !className ||
16
+ !node?.tagName ||
17
+ !parentNode ||
18
+ !isMarkdownPaneFragmentNode(parentNode)
19
+ ) {
20
+ return null;
21
+ }
22
+ const friendlyName = tailwindClasses[className]?.title || className;
23
+ const isOuterContainer = node.tagName === 'ul' || node.tagName === 'ol';
24
+ const isContainer = node.tagName === 'li';
25
+
26
+ const elementTypeTitle = isOuterContainer
27
+ ? 'Outer Container'
28
+ : isContainer
29
+ ? 'Container'
30
+ : 'Widget';
31
+
32
+ const resetStore = () => {
33
+ if (node?.id)
34
+ settingsPanelStore.set({
35
+ action: 'style-widget',
36
+ nodeId: isOuterContainer || isContainer ? childId || node.id : node.id,
37
+ expanded: true,
38
+ });
39
+ };
40
+
41
+ const handleYesClick = () => {
42
+ if (!node || !className) {
43
+ console.error('Missing required properties for class removal');
44
+ return;
45
+ }
46
+
47
+ const ctx = getCtx();
48
+ const allNodes = ctx.allNodes.get();
49
+
50
+ const targetNode = cloneDeep(allNodes.get(node.id)) as FlatNode;
51
+ const deepParentClone = cloneDeep(parentNode);
52
+
53
+ if (!targetNode) return;
54
+
55
+ // Remove from defaultClasses if present
56
+ if (deepParentClone.defaultClasses?.[targetNode.tagName]) {
57
+ const defaultClasses = deepParentClone.defaultClasses[targetNode.tagName];
58
+ if (className in defaultClasses.mobile)
59
+ delete defaultClasses.mobile[className];
60
+ if (className in defaultClasses.tablet)
61
+ delete defaultClasses.tablet[className];
62
+ if (className in defaultClasses.desktop)
63
+ delete defaultClasses.desktop[className];
64
+ }
65
+
66
+ // Remove from overrideClasses if present
67
+ if (targetNode.overrideClasses) {
68
+ if (
69
+ targetNode.overrideClasses.mobile &&
70
+ className in targetNode.overrideClasses.mobile
71
+ ) {
72
+ delete targetNode.overrideClasses.mobile[className];
73
+ }
74
+ if (
75
+ targetNode.overrideClasses.tablet &&
76
+ className in targetNode.overrideClasses.tablet
77
+ ) {
78
+ delete targetNode.overrideClasses.tablet[className];
79
+ }
80
+ if (
81
+ targetNode.overrideClasses.desktop &&
82
+ className in targetNode.overrideClasses.desktop
83
+ ) {
84
+ delete targetNode.overrideClasses.desktop[className];
85
+ }
86
+
87
+ // If there are no overrides left, remove the overrideClasses object
88
+ const overrides =
89
+ `overrideClasses` in targetNode && targetNode.overrideClasses;
90
+ const hasRemainingOverrides =
91
+ (overrides &&
92
+ `mobile` in overrides &&
93
+ typeof overrides.mobile !== `undefined` &&
94
+ Object.keys(overrides.mobile).length > 0) ||
95
+ (overrides &&
96
+ `tablet` in overrides &&
97
+ typeof overrides.tablet !== `undefined` &&
98
+ Object.keys(overrides.tablet).length > 0) ||
99
+ (overrides &&
100
+ `desktop` in overrides &&
101
+ typeof overrides.desktop !== `undefined` &&
102
+ Object.keys(overrides.desktop).length > 0);
103
+
104
+ if (!hasRemainingOverrides) {
105
+ delete targetNode.overrideClasses;
106
+ }
107
+ }
108
+ ctx.modifyNodes([
109
+ { ...targetNode, isChanged: true },
110
+ { ...deepParentClone, isChanged: true },
111
+ ]);
112
+ resetStore();
113
+ };
114
+
115
+ const handleNoClick = () => {
116
+ resetStore();
117
+ };
118
+
119
+ return (
120
+ <div className="space-y-4">
121
+ <h3 className="text-xl font-bold">
122
+ Remove <span className="font-bold">{friendlyName}</span>
123
+ <span className="ml-1">from {elementTypeTitle}?</span>
124
+ </h3>
125
+ <div className="space-y-4 rounded bg-slate-50 p-6">
126
+ <ul className="text-mydarkgrey flex flex-wrap gap-x-4 gap-y-1">
127
+ <li>
128
+ <em>Are you sure?</em>
129
+ </li>
130
+ <li>
131
+ <button
132
+ onClick={handleYesClick}
133
+ className="font-bold underline hover:text-black"
134
+ >
135
+ Yes
136
+ </button>
137
+ </li>
138
+ <li>
139
+ <button
140
+ onClick={handleNoClick}
141
+ className="font-bold underline hover:text-black"
142
+ >
143
+ No / Cancel
144
+ </button>
145
+ </li>
146
+ </ul>
147
+ </div>
148
+ </div>
149
+ );
150
+ };
151
+
152
+ export default StyleWidgetRemovePanel;