@qwickapps/react-framework 1.3.5 → 1.4.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 (320) hide show
  1. package/README.md +1681 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  28. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  30. package/dist/components/blocks/Footer.d.ts.map +1 -1
  31. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  32. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  33. package/dist/components/blocks/Image.d.ts +41 -0
  34. package/dist/components/blocks/Image.d.ts.map +1 -0
  35. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  36. package/dist/components/blocks/Section.d.ts +16 -2
  37. package/dist/components/blocks/Section.d.ts.map +1 -1
  38. package/dist/components/blocks/Text.d.ts +41 -0
  39. package/dist/components/blocks/Text.d.ts.map +1 -0
  40. package/dist/components/blocks/index.d.ts +4 -0
  41. package/dist/components/blocks/index.d.ts.map +1 -1
  42. package/dist/components/buttons/Button.d.ts +23 -7
  43. package/dist/components/buttons/Button.d.ts.map +1 -1
  44. package/dist/components/forms/FormBlock.d.ts +19 -13
  45. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  46. package/dist/components/index.d.ts +4 -0
  47. package/dist/components/index.d.ts.map +1 -1
  48. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  49. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  50. package/dist/components/input/HtmlInputField.d.ts +17 -11
  51. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  52. package/dist/components/input/SelectInputField.d.ts +16 -10
  53. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  54. package/dist/components/input/SwitchInputField.d.ts +16 -10
  55. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  56. package/dist/components/input/TextField.d.ts.map +1 -1
  57. package/dist/components/input/TextInputField.d.ts +16 -11
  58. package/dist/components/input/TextInputField.d.ts.map +1 -1
  59. package/dist/components/layout/GridCell.d.ts +23 -6
  60. package/dist/components/layout/GridCell.d.ts.map +1 -1
  61. package/dist/components/layout/GridLayout.d.ts +24 -23
  62. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  63. package/dist/components/pages/FormPage.d.ts.map +1 -1
  64. package/dist/components/pages/Page.d.ts +49 -87
  65. package/dist/components/pages/Page.d.ts.map +1 -1
  66. package/dist/components/pages/index.d.ts +2 -2
  67. package/dist/components/pages/index.d.ts.map +1 -1
  68. package/dist/config/AppConfig.d.ts +49 -0
  69. package/dist/config/AppConfig.d.ts.map +1 -0
  70. package/dist/config/AppConfigBuilder.d.ts +75 -0
  71. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  72. package/dist/config/index.d.ts +13 -0
  73. package/dist/config/index.d.ts.map +1 -0
  74. package/dist/config/types.d.ts +130 -0
  75. package/dist/config/types.d.ts.map +1 -0
  76. package/dist/config.d.ts +15 -0
  77. package/dist/config.d.ts.map +1 -0
  78. package/dist/config.esm.js +451 -0
  79. package/dist/config.js +455 -0
  80. package/dist/contexts/PrintModeContext.d.ts +27 -0
  81. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  82. package/dist/contexts/QwickAppContext.d.ts +2 -2
  83. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  84. package/dist/contexts/index.d.ts +2 -0
  85. package/dist/contexts/index.d.ts.map +1 -1
  86. package/dist/hooks/index.d.ts +2 -0
  87. package/dist/hooks/index.d.ts.map +1 -1
  88. package/dist/hooks/usePrintMode.d.ts +39 -0
  89. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  90. package/dist/index.css +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.esm.css +1 -1
  94. package/dist/index.esm.js +10951 -6238
  95. package/dist/index.js +11014 -6287
  96. package/dist/schemas/CodeSchema.d.ts +2 -1
  97. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  98. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  99. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  100. package/dist/schemas/ContentSchema.d.ts +2 -1
  101. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  102. package/dist/schemas/GridCellSchema.d.ts +25 -0
  103. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  104. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  105. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  106. package/dist/schemas/HtmlSchema.d.ts +14 -0
  107. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  108. package/dist/schemas/ImageSchema.d.ts +32 -0
  109. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  110. package/dist/schemas/LogoSchema.d.ts +35 -0
  111. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  112. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  113. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  114. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  115. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  116. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  117. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  118. package/dist/schemas/SectionSchema.d.ts +2 -1
  119. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  120. package/dist/schemas/TextSchema.d.ts +37 -0
  121. package/dist/schemas/TextSchema.d.ts.map +1 -0
  122. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  123. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  124. package/dist/schemas/index.d.ts +15 -1
  125. package/dist/schemas/index.d.ts.map +1 -1
  126. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  127. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  128. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  129. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  130. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  131. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  132. package/dist/schemas/transformers/registry.d.ts +15 -0
  133. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  134. package/dist/schemas/types/Serializable.d.ts +46 -0
  135. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  136. package/dist/utils/htmlTransform.d.ts.map +1 -1
  137. package/dist/utils/reactUtils.d.ts +12 -3
  138. package/dist/utils/reactUtils.d.ts.map +1 -1
  139. package/package.json +17 -3
  140. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  141. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  142. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  143. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  145. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  148. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  150. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  152. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  154. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  155. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  156. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  158. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  159. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  160. package/src/__tests__/components/Logo.test.js +3 -3
  161. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  162. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  163. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  165. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  166. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  167. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  168. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  169. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  172. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  173. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  174. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  175. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  176. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  177. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  178. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  179. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  180. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  181. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  182. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  183. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  184. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  185. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  186. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  187. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  188. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  189. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  190. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  191. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  192. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  193. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  194. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  195. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  196. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  197. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  198. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  199. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  200. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  201. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  202. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  203. package/src/components/ErrorBoundary.tsx +8 -8
  204. package/src/components/Html.tsx +147 -44
  205. package/src/components/Logo.tsx +198 -100
  206. package/src/components/Markdown.tsx +125 -16
  207. package/src/components/QwickApp.tsx +64 -31
  208. package/src/components/QwickIcon.tsx +59 -0
  209. package/src/components/SafeSpan.tsx +65 -10
  210. package/src/components/Scaffold.tsx +2 -8
  211. package/src/components/base/ModelView.tsx +199 -0
  212. package/src/components/base/index.ts +11 -0
  213. package/src/components/blocks/Article.tsx +57 -18
  214. package/src/components/blocks/Code.md +529 -0
  215. package/src/components/blocks/Code.tsx +102 -15
  216. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  217. package/src/components/blocks/FeatureCard.tsx +1 -2
  218. package/src/components/blocks/FeatureGrid.tsx +19 -1
  219. package/src/components/blocks/Footer.tsx +13 -1
  220. package/src/components/blocks/HeroBlock.tsx +87 -20
  221. package/src/components/blocks/Image.tsx +395 -0
  222. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  223. package/src/components/blocks/ProductCard.tsx +1 -1
  224. package/src/components/blocks/Section.tsx +113 -8
  225. package/src/components/blocks/Text.tsx +285 -0
  226. package/src/components/blocks/index.ts +4 -0
  227. package/src/components/buttons/Button.tsx +184 -15
  228. package/src/components/forms/FormBlock.tsx +70 -17
  229. package/src/components/index.ts +5 -0
  230. package/src/components/input/ChoiceInputField.tsx +48 -18
  231. package/src/components/input/HtmlInputField.tsx +48 -18
  232. package/src/components/input/SelectInputField.tsx +48 -16
  233. package/src/components/input/SwitchInputField.tsx +48 -17
  234. package/src/components/input/TextField.tsx +41 -1
  235. package/src/components/input/TextInputField.tsx +52 -18
  236. package/src/components/layout/GridCell.tsx +118 -9
  237. package/src/components/layout/GridLayout.tsx +125 -24
  238. package/src/components/pages/FormPage.tsx +0 -1
  239. package/src/components/pages/Page.css +304 -332
  240. package/src/components/pages/Page.tsx +307 -255
  241. package/src/components/pages/index.ts +2 -2
  242. package/src/config/AppConfig.ts +133 -0
  243. package/src/config/AppConfigBuilder.ts +421 -0
  244. package/src/config/__tests__/AppConfig.test.ts +385 -0
  245. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  246. package/src/config/index.ts +24 -0
  247. package/src/config/types.ts +170 -0
  248. package/src/config.ts +25 -0
  249. package/src/contexts/PrintModeContext.tsx +332 -0
  250. package/src/contexts/QwickAppContext.tsx +2 -2
  251. package/src/contexts/index.ts +2 -0
  252. package/src/hooks/index.ts +5 -1
  253. package/src/hooks/usePrintMode.ts +73 -0
  254. package/src/index.ts +3 -0
  255. package/src/schemas/CodeSchema.ts +3 -3
  256. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  257. package/src/schemas/ContentSchema.ts +2 -1
  258. package/src/schemas/GridCellSchema.ts +164 -0
  259. package/src/schemas/GridLayoutSchema.ts +133 -0
  260. package/src/schemas/HtmlSchema.ts +47 -0
  261. package/src/schemas/ImageSchema.ts +235 -0
  262. package/src/schemas/LogoSchema.ts +241 -0
  263. package/src/schemas/MarkdownSchema.ts +47 -0
  264. package/src/schemas/PageTemplateSchema.ts +186 -0
  265. package/src/schemas/PrintConfigSchema.ts +207 -0
  266. package/src/schemas/README.md +661 -0
  267. package/src/schemas/SectionSchema.ts +2 -1
  268. package/src/schemas/TextSchema.ts +329 -0
  269. package/src/schemas/ViewModelSchema.ts +115 -0
  270. package/src/schemas/index.ts +21 -2
  271. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  272. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  273. package/src/schemas/transformers/registry.ts +72 -0
  274. package/src/schemas/types/Serializable.ts +51 -0
  275. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  276. package/src/stories/Article.stories.tsx +433 -433
  277. package/src/stories/Button.stories.tsx +1 -1
  278. package/src/stories/CardListGrid.stories.tsx +451 -451
  279. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  280. package/src/stories/Code.stories.tsx +1 -1
  281. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  282. package/src/stories/Content.stories.tsx +393 -393
  283. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  284. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  285. package/src/stories/DataProvider.stories.tsx +1192 -1192
  286. package/src/stories/FeatureCard.stories.tsx +557 -557
  287. package/src/stories/FeatureGrid.stories.tsx +594 -594
  288. package/src/stories/Footer.stories.tsx +640 -640
  289. package/src/stories/FormBlock.stories.tsx +760 -760
  290. package/src/stories/FormComponents.stories.tsx +349 -541
  291. package/src/stories/GridCell.stories.tsx +417 -0
  292. package/src/stories/GridLayout.stories.tsx +353 -0
  293. package/src/stories/HeroBlock.stories.tsx +862 -373
  294. package/src/stories/HtmlInputField.stories.tsx +474 -474
  295. package/src/stories/Image.stories.tsx +819 -0
  296. package/src/stories/Introduction.stories.tsx +667 -667
  297. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  298. package/src/stories/Logo.stories.tsx +165 -6
  299. package/src/stories/Markdown.stories.tsx +137 -137
  300. package/src/stories/ModelView.stories.tsx +477 -0
  301. package/src/stories/Page.stories.tsx +688 -688
  302. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  303. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  304. package/src/stories/ProductCard.stories.tsx +424 -424
  305. package/src/stories/QwickApp.stories.tsx +368 -368
  306. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  307. package/src/stories/SafeSpan.stories.tsx +531 -531
  308. package/src/stories/Section.stories.tsx +90 -2
  309. package/src/stories/SelectInputField.stories.tsx +524 -524
  310. package/src/stories/Text.stories.tsx +560 -0
  311. package/src/stories/TextInputField.stories.tsx +443 -443
  312. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  313. package/src/utils/htmlTransform.tsx +74 -53
  314. package/src/utils/reactUtils.tsx +57 -6
  315. package/dist/index.bundled.css +0 -12
  316. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  317. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  318. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  319. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  320. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -4,72 +4,74 @@
4
4
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
5
  */
6
6
 
7
- import { Box, Typography } from '@mui/material';
7
+ import { Box, Typography, Alert, Paper } from '@mui/material';
8
8
  import { JsonDataProvider } from '@qwickapps/schema';
9
9
  import type { Meta, StoryObj } from '@storybook/react';
10
10
  import QwickApp from '../components/QwickApp';
11
11
  import { Code } from '../components/blocks';
12
12
  import HeroBlock from '../components/blocks/HeroBlock';
13
13
  import { DataProvider } from '../contexts/DataContext';
14
+ import { ComponentTransformer } from '../schemas/transformers/ComponentTransformer';
15
+ import React from 'react';
14
16
 
15
17
  // Sample CMS data for data binding stories
16
18
  const sampleCmsData = {
17
- 'heroes': {
18
- 'home': {
19
- title: 'Build Apps 10x Faster with QwickApps',
20
- subtitle: 'The most developer-friendly React framework that turns complex UI development into a joy. Build production-ready applications in hours, not weeks.',
21
- backgroundGradient: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
22
- actions: [
23
- { label: 'Get Started Free', variant: 'primary', buttonSize: 'large' },
24
- { label: 'Watch Demo', variant: 'outlined', buttonSize: 'large', icon: '▶️' }
25
- ],
26
- textAlign: 'center',
27
- blockHeight: 'large',
28
- overlayOpacity: 0.6
29
- },
30
- 'product-launch': {
31
- title: '🚀 Revolutionary New Framework',
32
- subtitle: 'Skip months of boilerplate setup. Focus on what makes your application unique.',
33
- backgroundImage: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80',
34
- actions: [
35
- { label: 'Launch Now', variant: 'primary', buttonSize: 'large' },
36
- { label: 'View Features', variant: 'text', buttonSize: 'large' }
37
- ],
38
- textAlign: 'center',
39
- blockHeight: 'viewport',
40
- overlayOpacity: 0.7
41
- },
42
- 'about': {
43
- title: 'Empowering Developers Worldwide',
44
- subtitle: 'Our mission is to make web development accessible, enjoyable, and productive for everyone.',
45
- backgroundColor: 'primary',
46
- actions: [
47
- { label: 'Our Story', variant: 'secondary', buttonSize: 'medium' },
48
- { label: 'Join Team', variant: 'outlined', buttonSize: 'medium' }
49
- ],
50
- textAlign: 'left',
51
- blockHeight: 'medium'
52
- },
53
- 'minimal': {
54
- title: 'Simple. Powerful. Elegant.',
55
- subtitle: 'Everything you need, nothing you don\'t.',
56
- backgroundColor: 'surface',
57
- blockHeight: 'small',
58
- textAlign: 'center'
59
- }
60
- }
19
+ 'heroes': {
20
+ 'home': {
21
+ title: 'Build Apps 10x Faster with QwickApps',
22
+ subtitle: 'The most developer-friendly React framework that turns complex UI development into a joy. Build production-ready applications in hours, not weeks.',
23
+ backgroundGradient: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
24
+ actions: [
25
+ { label: 'Get Started Free', variant: 'primary', buttonSize: 'large' },
26
+ { label: 'Watch Demo', variant: 'outlined', buttonSize: 'large', icon: '' }
27
+ ],
28
+ textAlign: 'center',
29
+ blockHeight: 'large',
30
+ overlayOpacity: 0.6
31
+ },
32
+ 'product-launch': {
33
+ title: ' Revolutionary New Framework',
34
+ subtitle: 'Skip months of boilerplate setup. Focus on what makes your application unique.',
35
+ backgroundImage: 'https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80',
36
+ actions: [
37
+ { label: 'Launch Now', variant: 'primary', buttonSize: 'large' },
38
+ { label: 'View Features', variant: 'text', buttonSize: 'large' }
39
+ ],
40
+ textAlign: 'center',
41
+ blockHeight: 'viewport',
42
+ overlayOpacity: 0.7
43
+ },
44
+ 'about': {
45
+ title: 'Empowering Developers Worldwide',
46
+ subtitle: 'Our mission is to make web development accessible, enjoyable, and productive for everyone.',
47
+ backgroundColor: 'primary',
48
+ actions: [
49
+ { label: 'Our Story', variant: 'secondary', buttonSize: 'medium' },
50
+ { label: 'Join Team', variant: 'outlined', buttonSize: 'medium' }
51
+ ],
52
+ textAlign: 'left',
53
+ blockHeight: 'medium'
54
+ },
55
+ 'minimal': {
56
+ title: 'Simple. Powerful. Elegant.',
57
+ subtitle: 'Everything you need, nothing you don\'t.',
58
+ backgroundColor: 'surface',
59
+ blockHeight: 'small',
60
+ textAlign: 'center'
61
+ }
62
+ }
61
63
  };
62
64
 
63
65
  const dataProvider = new JsonDataProvider({ data: sampleCmsData });
64
66
 
65
67
  const meta = {
66
- title: 'Blocks/HeroBlock',
67
- component: HeroBlock,
68
- parameters: {
69
- layout: 'fullscreen',
70
- docs: {
71
- description: {
72
- component: `HeroBlock is a powerful full-width hero section component that supports both traditional props and data binding through dataSource.
68
+ title: 'Blocks/HeroBlock',
69
+ component: HeroBlock,
70
+ parameters: {
71
+ layout: 'fullscreen',
72
+ docs: {
73
+ description: {
74
+ component: `HeroBlock is a powerful full-width hero section component that supports both traditional props and data binding through dataSource.
73
75
 
74
76
  **Key Features:**
75
77
  - **Flexible Backgrounds**: Support for images, gradients, and theme colors
@@ -83,13 +85,13 @@ const meta = {
83
85
  **Perfect For:**
84
86
  - Landing page heroes and primary messaging
85
87
  - Product launch announcements
86
- - Marketing campaigns and promotions
88
+ - Marketing campaigns and promotions
87
89
  - About pages and company messaging
88
90
  - Feature highlights and value propositions`,
89
- },
90
- },
91
- },
92
- tags: ['autodocs'],
91
+ },
92
+ },
93
+ },
94
+ tags: ['autodocs'],
93
95
  } satisfies Meta<typeof HeroBlock>;
94
96
 
95
97
  export default meta;
@@ -97,346 +99,833 @@ type Story = StoryObj<typeof meta>;
97
99
 
98
100
  // Traditional Usage Examples
99
101
  export const BasicHero: Story = {
100
- render: () => (
101
- <QwickApp appId="heroblock-basic" appName='Basic HeroBlock'>
102
- <HeroBlock
103
- title="Welcome to Our Platform"
104
- subtitle="Build amazing applications with our comprehensive toolkit"
105
- backgroundColor="primary"
106
- textAlign="center"
107
- blockHeight="medium"
108
- actions={[
109
- { label: 'Get Started', variant: 'primary', buttonSize: 'large' },
110
- { label: 'Learn More', variant: 'outlined', buttonSize: 'large' }
111
- ]}
112
- />
113
- </QwickApp>
114
- ),
115
- parameters: {
116
- docs: {
117
- description: {
118
- story: 'Basic HeroBlock with traditional props - title, subtitle, actions, and theme background.',
119
- },
120
- },
121
- },
102
+ render: () => (
103
+ <QwickApp appId="heroblock-basic" appName='Basic HeroBlock'>
104
+ <HeroBlock
105
+ title="Welcome to Our Platform"
106
+ subtitle="Build amazing applications with our comprehensive toolkit"
107
+ backgroundColor="primary"
108
+ textAlign="center"
109
+ blockHeight="medium"
110
+ actions={[
111
+ { label: 'Get Started', variant: 'primary', buttonSize: 'large' },
112
+ { label: 'Learn More', variant: 'outlined', buttonSize: 'large' }
113
+ ]}
114
+ />
115
+ </QwickApp>
116
+ ),
117
+ parameters: {
118
+ docs: {
119
+ description: {
120
+ story: 'Basic HeroBlock with traditional props - title, subtitle, actions, and theme background.',
121
+ },
122
+ },
123
+ },
122
124
  };
123
125
 
124
126
  export const BackgroundVariants: Story = {
125
- render: () => (
126
- <QwickApp appId="heroblock-backgrounds" appName='HeroBlock Backgrounds'>
127
- <Box sx={{ '& > *:not(:last-child)': { mb: 2 } }}>
128
-
129
- <HeroBlock
130
- title="Gradient Background Hero"
131
- subtitle="Beautiful gradients create visual impact"
132
- backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
133
- blockHeight="medium"
134
- actions={[{ label: 'Explore', variant: 'primary', buttonSize: 'large' }]}
135
- />
136
-
137
- <HeroBlock
138
- title="Image Background Hero"
139
- subtitle="High-quality images with customizable overlay"
140
- backgroundImage="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80"
141
- overlayOpacity={0.6}
142
- blockHeight="medium"
143
- actions={[{ label: 'Discover', variant: 'primary', buttonSize: 'large' }]}
144
- />
145
-
146
- <HeroBlock
147
- title="Theme Color Background"
148
- subtitle="Consistent with your application theme"
149
- backgroundColor="secondary"
150
- blockHeight="medium"
151
- actions={[{ label: 'Continue', variant: 'primary', buttonSize: 'large' }]}
152
- />
153
-
154
- </Box>
155
- </QwickApp>
156
- ),
157
- parameters: {
158
- docs: {
159
- description: {
160
- story: 'Different background options: gradients, images with overlay, and theme colors.',
161
- },
162
- },
163
- },
127
+ render: () => (
128
+ <QwickApp appId="heroblock-backgrounds" appName='HeroBlock Backgrounds'>
129
+ <Box sx={{ '& > *:not(:last-child)': { mb: 2 } }}>
130
+
131
+ <HeroBlock
132
+ title="Gradient Background Hero"
133
+ subtitle="Beautiful gradients create visual impact"
134
+ backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
135
+ blockHeight="medium"
136
+ actions={[{ label: 'Explore', variant: 'primary', buttonSize: 'large' }]}
137
+ />
138
+
139
+ <HeroBlock
140
+ title="Image Background Hero"
141
+ subtitle="High-quality images with customizable overlay"
142
+ backgroundImage="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-4.0.3&auto=format&fit=crop&w=1200&q=80"
143
+ overlayOpacity={0.6}
144
+ blockHeight="medium"
145
+ actions={[{ label: 'Discover', variant: 'primary', buttonSize: 'large' }]}
146
+ />
147
+
148
+ <HeroBlock
149
+ title="Theme Color Background"
150
+ subtitle="Consistent with your application theme"
151
+ backgroundColor="secondary"
152
+ blockHeight="medium"
153
+ actions={[{ label: 'Continue', variant: 'primary', buttonSize: 'large' }]}
154
+ />
155
+
156
+ </Box>
157
+ </QwickApp>
158
+ ),
159
+ parameters: {
160
+ docs: {
161
+ description: {
162
+ story: 'Different background options: gradients, images with overlay, and theme colors.',
163
+ },
164
+ },
165
+ },
164
166
  };
165
167
 
166
168
  export const HeightVariants: Story = {
167
- render: () => (
168
- <QwickApp appId="heroblock-heights" appName='HeroBlock Heights'>
169
- <Box sx={{ '& > *:not(:last-child)': { mb: 1 } }}>
170
-
171
- <HeroBlock
172
- title="Small Height Hero"
173
- subtitle="Compact hero for minimal messaging"
174
- backgroundColor="primary"
175
- blockHeight="small"
176
- textAlign="center"
177
- />
178
-
179
- <HeroBlock
180
- title="Medium Height Hero (Default)"
181
- subtitle="Balanced height for most use cases"
182
- backgroundColor="secondary"
183
- blockHeight="medium"
184
- textAlign="center"
185
- />
186
-
187
- <HeroBlock
188
- title="Large Height Hero"
189
- subtitle="Expansive hero for maximum impact"
190
- backgroundGradient="linear-gradient(45deg, #2196F3, #21CBF3)"
191
- blockHeight="large"
192
- textAlign="center"
193
- />
194
-
195
- <Box sx={{ height: '50vh', overflow: 'hidden' }}>
196
- <HeroBlock
197
- title="Viewport Height Hero"
198
- subtitle="Full-screen dramatic effect"
199
- backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
200
- blockHeight="viewport"
201
- textAlign="center"
202
- />
203
- </Box>
204
-
205
- </Box>
206
- </QwickApp>
207
- ),
208
- parameters: {
209
- docs: {
210
- description: {
211
- story: 'Available height options: small (300px), medium (400px), large (600px), and viewport (100vh).',
212
- },
213
- },
214
- },
169
+ render: () => (
170
+ <QwickApp appId="heroblock-heights" appName='HeroBlock Heights'>
171
+ <Box sx={{ '& > *:not(:last-child)': { mb: 1 } }}>
172
+
173
+ <HeroBlock
174
+ title="Small Height Hero"
175
+ subtitle="Compact hero for minimal messaging"
176
+ backgroundColor="primary"
177
+ blockHeight="small"
178
+ textAlign="center"
179
+ />
180
+
181
+ <HeroBlock
182
+ title="Medium Height Hero (Default)"
183
+ subtitle="Balanced height for most use cases"
184
+ backgroundColor="secondary"
185
+ blockHeight="medium"
186
+ textAlign="center"
187
+ />
188
+
189
+ <HeroBlock
190
+ title="Large Height Hero"
191
+ subtitle="Expansive hero for maximum impact"
192
+ backgroundGradient="linear-gradient(45deg, #2196F3, #21CBF3)"
193
+ blockHeight="large"
194
+ textAlign="center"
195
+ />
196
+
197
+ <Box sx={{ height: '50vh', overflow: 'hidden' }}>
198
+ <HeroBlock
199
+ title="Viewport Height Hero"
200
+ subtitle="Full-screen dramatic effect"
201
+ backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
202
+ blockHeight="viewport"
203
+ textAlign="center"
204
+ />
205
+ </Box>
206
+
207
+ </Box>
208
+ </QwickApp>
209
+ ),
210
+ parameters: {
211
+ docs: {
212
+ description: {
213
+ story: 'Available height options: small (300px), medium (400px), large (600px), and viewport (100vh).',
214
+ },
215
+ },
216
+ },
215
217
  };
216
218
 
217
219
  export const TextAlignment: Story = {
218
- render: () => (
219
- <QwickApp appId="heroblock-alignment" appName='HeroBlock Text Alignment'>
220
- <Box sx={{ '& > *:not(:last-child)': { mb: 2 } }}>
221
-
222
- <HeroBlock
223
- title="Left Aligned Hero"
224
- subtitle="Content-heavy heroes work well with left alignment"
225
- backgroundColor="surface"
226
- textAlign="left"
227
- blockHeight="medium"
228
- actions={[{ label: 'Read More', variant: 'primary' }]}
229
- />
230
-
231
- <HeroBlock
232
- title="Center Aligned Hero"
233
- subtitle="Traditional center alignment for maximum impact"
234
- backgroundGradient="linear-gradient(45deg, #2196F3, #21CBF3)"
235
- textAlign="center"
236
- blockHeight="medium"
237
- actions={[{ label: 'Get Started', variant: 'primary' }]}
238
- />
239
-
240
- <HeroBlock
241
- title="Right Aligned Hero"
242
- subtitle="Unique visual balance with right alignment"
243
- backgroundColor="secondary"
244
- textAlign="right"
245
- blockHeight="medium"
246
- actions={[{ label: 'Learn More', variant: 'primary' }]}
247
- />
248
-
249
- </Box>
250
- </QwickApp>
251
- ),
252
- parameters: {
253
- docs: {
254
- description: {
255
- story: 'Text alignment options: left (content-heavy), center (traditional), right (unique balance).',
256
- },
257
- },
258
- },
220
+ render: () => (
221
+ <QwickApp appId="heroblock-alignment" appName='HeroBlock Text Alignment'>
222
+ <Box sx={{ '& > *:not(:last-child)': { mb: 2 } }}>
223
+
224
+ <HeroBlock
225
+ title="Left Aligned Hero"
226
+ subtitle="Content-heavy heroes work well with left alignment"
227
+ backgroundColor="surface"
228
+ textAlign="left"
229
+ blockHeight="medium"
230
+ actions={[{ label: 'Read More', variant: 'primary' }]}
231
+ />
232
+
233
+ <HeroBlock
234
+ title="Center Aligned Hero"
235
+ subtitle="Traditional center alignment for maximum impact"
236
+ backgroundGradient="linear-gradient(45deg, #2196F3, #21CBF3)"
237
+ textAlign="center"
238
+ blockHeight="medium"
239
+ actions={[{ label: 'Get Started', variant: 'primary' }]}
240
+ />
241
+
242
+ <HeroBlock
243
+ title="Right Aligned Hero"
244
+ subtitle="Unique visual balance with right alignment"
245
+ backgroundColor="secondary"
246
+ textAlign="right"
247
+ blockHeight="medium"
248
+ actions={[{ label: 'Learn More', variant: 'primary' }]}
249
+ />
250
+
251
+ </Box>
252
+ </QwickApp>
253
+ ),
254
+ parameters: {
255
+ docs: {
256
+ description: {
257
+ story: 'Text alignment options: left (content-heavy), center (traditional), right (unique balance).',
258
+ },
259
+ },
260
+ },
259
261
  };
260
262
 
261
263
  // Data Binding Examples
262
264
  export const DataBindingBasic: Story = {
263
- render: () => (
264
- <QwickApp appId="heroblock-data-binding" appName='HeroBlock Data Binding'>
265
- <DataProvider dataSource={{ dataProvider }}>
266
- <Box>
267
-
268
- <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
269
- <Typography variant="h5" gutterBottom>📊 Data-Driven HeroBlock</Typography>
270
- <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
271
- HeroBlock components can be driven entirely by CMS data using the dataSource prop.
272
- </Typography>
273
-
274
- <Code title="Usage" language="tsx">{`<HeroBlock dataSource="heroes.home" />`}</Code>
275
-
276
- <Code title="Data Structure" language="json">{JSON.stringify(sampleCmsData.heroes.home, null, 2)}</Code>
277
- </Box>
265
+ render: () => (
266
+ <QwickApp appId="heroblock-data-binding" appName='HeroBlock Data Binding'>
267
+ <DataProvider dataSource={{ dataProvider }}>
268
+ <Box>
269
+
270
+ <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
271
+ <Typography variant="h5" gutterBottom> Data-Driven HeroBlock</Typography>
272
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
273
+ HeroBlock components can be driven entirely by CMS data using the dataSource prop.
274
+ </Typography>
275
+
276
+ <Code title="Usage" language="tsx">{`<HeroBlock dataSource="heroes.home" />`}</Code>
277
+
278
+ <Code title="Data Structure" language="json">{JSON.stringify(sampleCmsData.heroes.home, null, 2)}</Code>
279
+ </Box>
278
280
 
279
- <HeroBlock dataSource="heroes.home" />
280
-
281
- </Box>
282
- </DataProvider>
283
- </QwickApp>
284
- ),
285
- parameters: {
286
- docs: {
287
- description: {
288
- story: 'HeroBlock with data binding - all props resolved from CMS data through dataSource.',
289
- },
290
- },
291
- },
281
+ <HeroBlock dataSource="heroes.home" />
282
+
283
+ </Box>
284
+ </DataProvider>
285
+ </QwickApp>
286
+ ),
287
+ parameters: {
288
+ docs: {
289
+ description: {
290
+ story: 'HeroBlock with data binding - all props resolved from CMS data through dataSource.',
291
+ },
292
+ },
293
+ },
292
294
  };
293
295
 
294
296
  export const DataBindingAdvanced: Story = {
295
- render: () => (
296
- <QwickApp appId="heroblock-data-advanced" appName='Advanced HeroBlock Data Binding'>
297
- <DataProvider dataSource={{ dataProvider }}>
298
- <Box>
299
-
300
- <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
301
- <Typography variant="h5" gutterBottom>🎯 Multiple Data Sources</Typography>
302
- <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
303
- Different HeroBlock components can pull from different data sources with varying configurations.
304
- </Typography>
305
- </Box>
297
+ render: () => (
298
+ <QwickApp appId="heroblock-data-advanced" appName='Advanced HeroBlock Data Binding'>
299
+ <DataProvider dataSource={{ dataProvider }}>
300
+ <Box>
301
+
302
+ <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
303
+ <Typography variant="h5" gutterBottom> Multiple Data Sources</Typography>
304
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
305
+ Different HeroBlock components can pull from different data sources with varying configurations.
306
+ </Typography>
307
+ </Box>
306
308
 
307
- {/* Product Launch Hero */}
308
- <HeroBlock dataSource="heroes.product-launch" />
309
-
310
- {/* About Hero */}
311
- <HeroBlock dataSource="heroes.about" />
312
-
313
- {/* Minimal Hero */}
314
- <HeroBlock dataSource="heroes.minimal" />
315
-
316
- </Box>
317
- </DataProvider>
318
- </QwickApp>
319
- ),
320
- parameters: {
321
- docs: {
322
- description: {
323
- story: 'Advanced data binding with multiple data sources showcasing different hero styles and configurations.',
324
- },
325
- },
326
- },
309
+ {/* Product Launch Hero */}
310
+ <HeroBlock dataSource="heroes.product-launch" />
311
+
312
+ {/* About Hero */}
313
+ <HeroBlock dataSource="heroes.about" />
314
+
315
+ {/* Minimal Hero */}
316
+ <HeroBlock dataSource="heroes.minimal" />
317
+
318
+ </Box>
319
+ </DataProvider>
320
+ </QwickApp>
321
+ ),
322
+ parameters: {
323
+ docs: {
324
+ description: {
325
+ story: 'Advanced data binding with multiple data sources showcasing different hero styles and configurations.',
326
+ },
327
+ },
328
+ },
327
329
  };
328
330
 
329
331
  export const DataBindingWithFallback: Story = {
330
- render: () => (
331
- <QwickApp appId="heroblock-fallback" appName='HeroBlock Data Binding with Fallback'>
332
- <DataProvider dataSource={{ dataProvider }}>
333
- <Box>
334
-
335
- <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
336
- <Typography variant="h5" gutterBottom>🛡️ Fallback Support</Typography>
337
- <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
338
- HeroBlock components gracefully handle missing data sources with fallback props.
339
- </Typography>
340
-
341
- <Code title="Fallback Usage" language="tsx">{`<HeroBlock
342
- dataSource="nonexistent.hero"
343
- title="Fallback Hero Title"
344
- subtitle="Shows when data source is missing"
345
- backgroundColor="default"
332
+ render: () => (
333
+ <QwickApp appId="heroblock-fallback" appName='HeroBlock Data Binding with Fallback'>
334
+ <DataProvider dataSource={{ dataProvider }}>
335
+ <Box>
336
+
337
+ <Box sx={{ p: 4, backgroundColor: 'background.paper' }}>
338
+ <Typography variant="h5" gutterBottom> Fallback Support</Typography>
339
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
340
+ HeroBlock components gracefully handle missing data sources with fallback props.
341
+ </Typography>
342
+
343
+ <Code title="Fallback Usage" language="tsx">{`<HeroBlock
344
+ dataSource="nonexistent.hero"
345
+ title="Fallback Hero Title"
346
+ subtitle="Shows when data source is missing"
347
+ backgroundColor="default"
346
348
  />`}</Code>
347
- </Box>
349
+ </Box>
348
350
 
349
- <HeroBlock
350
- dataSource="nonexistent.hero"
351
- title="Fallback Hero Content"
352
- subtitle="This hero appears when the dataSource doesn't exist, ensuring your page never breaks"
353
- backgroundColor="default"
354
- blockHeight="medium"
355
- textAlign="center"
356
- actions={[
357
- { label: 'Fallback Action', variant: 'primary' }
358
- ]}
359
- />
360
-
361
- </Box>
362
- </DataProvider>
363
- </QwickApp>
364
- ),
365
- parameters: {
366
- docs: {
367
- description: {
368
- story: 'HeroBlock with fallback props when dataSource is missing or unavailable.',
369
- },
370
- },
371
- },
351
+ <HeroBlock
352
+ dataSource="nonexistent.hero"
353
+ title="Fallback Hero Content"
354
+ subtitle="This hero appears when the dataSource doesn't exist, ensuring your page never breaks"
355
+ backgroundColor="default"
356
+ blockHeight="medium"
357
+ textAlign="center"
358
+ actions={[
359
+ { label: 'Fallback Action', variant: 'primary' }
360
+ ]}
361
+ />
362
+
363
+ </Box>
364
+ </DataProvider>
365
+ </QwickApp>
366
+ ),
367
+ parameters: {
368
+ docs: {
369
+ description: {
370
+ story: 'HeroBlock with fallback props when dataSource is missing or unavailable.',
371
+ },
372
+ },
373
+ },
372
374
  };
373
375
 
374
376
  export const RealWorldExample: Story = {
375
- render: () => (
376
- <QwickApp appId="heroblock-real-world" appName='Real World HeroBlock Example'>
377
- <DataProvider dataSource={{ dataProvider }}>
378
- <Box>
379
-
380
- {/* Main Hero - Data Driven */}
381
- <HeroBlock dataSource="heroes.home" />
382
-
383
- {/* Product Launch Hero - Data Driven */}
384
- <HeroBlock dataSource="heroes.product-launch">
385
- <Typography sx={{
386
- mt: 3,
387
- fontSize: '1.1rem',
388
- maxWidth: '600px',
389
- opacity: 0.9,
390
- fontWeight: 500
391
- }}>
392
- Join thousands of developers who have already transformed their workflow
393
- </Typography>
394
- </HeroBlock>
395
-
396
- {/* About Hero - Traditional Props with Custom Content */}
397
- <HeroBlock
398
- title="Ready to Get Started?"
399
- subtitle="Join our community and start building amazing applications today"
400
- backgroundColor="primary"
401
- blockHeight="medium"
402
- textAlign="center"
403
- actions={[
404
- { label: 'Create Account', variant: 'primary', buttonSize: 'large' },
405
- { label: 'Browse Examples', variant: 'text', buttonSize: 'large' }
406
- ]}
407
- >
408
- <Box sx={{
409
- mt: 4,
410
- display: 'flex',
411
- justifyContent: 'center',
412
- gap: 4,
413
- flexWrap: 'wrap',
414
- opacity: 0.9
415
- }}>
416
- <Box sx={{ textAlign: 'center' }}>
417
- <Typography variant="h4" sx={{ fontWeight: 'bold' }}>10k+</Typography>
418
- <Typography>Developers</Typography>
419
- </Box>
420
- <Box sx={{ textAlign: 'center' }}>
421
- <Typography variant="h4" sx={{ fontWeight: 'bold' }}>500+</Typography>
422
- <Typography>Companies</Typography>
423
- </Box>
424
- <Box sx={{ textAlign: 'center' }}>
425
- <Typography variant="h4" sx={{ fontWeight: 'bold' }}>99.9%</Typography>
426
- <Typography>Uptime</Typography>
427
- </Box>
428
- </Box>
429
- </HeroBlock>
430
-
431
- </Box>
432
- </DataProvider>
433
- </QwickApp>
434
- ),
435
- parameters: {
436
- docs: {
437
- description: {
438
- story: 'Real-world example combining data-driven HeroBlocks with traditional usage and custom child content.',
439
- },
440
- },
441
- },
377
+ render: () => (
378
+ <QwickApp appId="heroblock-real-world" appName='Real World HeroBlock Example'>
379
+ <DataProvider dataSource={{ dataProvider }}>
380
+ <Box>
381
+
382
+ {/* Main Hero - Data Driven */}
383
+ <HeroBlock dataSource="heroes.home" />
384
+
385
+ {/* Product Launch Hero - Data Driven */}
386
+ <HeroBlock dataSource="heroes.product-launch">
387
+ <Typography sx={{
388
+ mt: 3,
389
+ fontSize: '1.1rem',
390
+ maxWidth: '600px',
391
+ opacity: 0.9,
392
+ fontWeight: 500
393
+ }}>
394
+ Join thousands of developers who have already transformed their workflow
395
+ </Typography>
396
+ </HeroBlock>
397
+
398
+ {/* About Hero - Traditional Props with Custom Content */}
399
+ <HeroBlock
400
+ title="Ready to Get Started?"
401
+ subtitle="Join our community and start building amazing applications today"
402
+ backgroundColor="primary"
403
+ blockHeight="medium"
404
+ textAlign="center"
405
+ actions={[
406
+ { label: 'Create Account', variant: 'primary', buttonSize: 'large' },
407
+ { label: 'Browse Examples', variant: 'text', buttonSize: 'large' }
408
+ ]}
409
+ >
410
+ <Box sx={{
411
+ mt: 4,
412
+ display: 'flex',
413
+ justifyContent: 'center',
414
+ gap: 4,
415
+ flexWrap: 'wrap',
416
+ opacity: 0.9
417
+ }}>
418
+ <Box sx={{ textAlign: 'center' }}>
419
+ <Typography variant="h4" sx={{ fontWeight: 'bold' }}>10k+</Typography>
420
+ <Typography>Developers</Typography>
421
+ </Box>
422
+ <Box sx={{ textAlign: 'center' }}>
423
+ <Typography variant="h4" sx={{ fontWeight: 'bold' }}>500+</Typography>
424
+ <Typography>Companies</Typography>
425
+ </Box>
426
+ <Box sx={{ textAlign: 'center' }}>
427
+ <Typography variant="h4" sx={{ fontWeight: 'bold' }}>99.9%</Typography>
428
+ <Typography>Uptime</Typography>
429
+ </Box>
430
+ </Box>
431
+ </HeroBlock>
432
+
433
+ </Box>
434
+ </DataProvider>
435
+ </QwickApp>
436
+ ),
437
+ parameters: {
438
+ docs: {
439
+ description: {
440
+ story: 'Real-world example combining data-driven HeroBlocks with traditional usage and custom child content.',
441
+ },
442
+ },
443
+ },
444
+ };
445
+
446
+ // ModelView Serialization Examples - Demonstrating the new ModelView base class
447
+ export const ModelViewBasic: Story = {
448
+ render: () => {
449
+ // Demonstrate that HeroBlock extends ModelView
450
+ const heroInstance = new HeroBlock({
451
+ title: 'ModelView HeroBlock',
452
+ subtitle: 'Extends ModelView for standardized serialization',
453
+ backgroundColor: 'primary',
454
+ textAlign: 'center',
455
+ blockHeight: 'medium',
456
+ actions: [
457
+ { label: 'Test Action', variant: 'primary', buttonSize: 'large' }
458
+ ]
459
+ });
460
+
461
+ // Convert to JSON and back
462
+ const serializedData = heroInstance.toJson();
463
+
464
+ return (
465
+ <QwickApp appId="heroblock-modelview" appName='HeroBlock ModelView Pattern'>
466
+ <Box>
467
+
468
+ <Box sx={{ mb: 6, textAlign: 'center' }}>
469
+ <Typography variant="h3" gutterBottom>HeroBlock ModelView Pattern</Typography>
470
+ <Typography variant="h6" sx={{ mb: 4, opacity: 0.7 }}>
471
+ HeroBlock extends ModelView for standardized serialization and component lifecycle
472
+ </Typography>
473
+
474
+ <Alert severity="info" sx={{ mb: 4, textAlign: 'left' }}>
475
+ The HeroBlock component now extends ModelView base class, which implements the Serializable interface
476
+ and provides standardized serialization patterns. This enables "WebView for React" functionality with
477
+ support for nested Button components and complex hero structures.
478
+ </Alert>
479
+ </Box>
480
+
481
+ {/* Rendered HeroBlock */}
482
+ <Box sx={{ mb: 6 }}>
483
+ <Typography variant="h4" gutterBottom>Rendered HeroBlock</Typography>
484
+ <HeroBlock
485
+ title="ModelView Demonstration"
486
+ subtitle="This HeroBlock extends ModelView and supports full serialization"
487
+ backgroundColor="primary"
488
+ textAlign="center"
489
+ blockHeight="medium"
490
+ actions={[
491
+ { label: 'Learn More', variant: 'primary', buttonSize: 'large' },
492
+ { label: 'View Docs', variant: 'outlined', buttonSize: 'large' }
493
+ ]}
494
+ />
495
+ </Box>
496
+
497
+ {/* Serialized Data */}
498
+ <Box sx={{ mb: 6 }}>
499
+ <Typography variant="h4" gutterBottom>Serialized JSON Data</Typography>
500
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
501
+ The HeroBlock instance serialized to JSON using the toJson() method:
502
+ </Typography>
503
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
504
+ <Code language="json" showLineNumbers={true} title="heroblock-serialized.json">
505
+ {JSON.stringify(serializedData, null, 2)}
506
+ </Code>
507
+ </Paper>
508
+ </Box>
509
+
510
+ </Box>
511
+ </QwickApp>
512
+ );
513
+ },
514
+ parameters: {
515
+ docs: {
516
+ description: {
517
+ story: 'Basic ModelView pattern demonstration showing HeroBlock serialization capabilities.',
518
+ },
519
+ },
520
+ },
521
+ };
522
+
523
+ // Enhanced Serialization Examples - "WebView for React" functionality
524
+ export const SerializationBasic: Story = {
525
+ render: () => {
526
+ // Create a HeroBlock component instance (now extends ModelView)
527
+ const originalHeroComponent = (
528
+ <HeroBlock
529
+ title="Serializable HeroBlock"
530
+ subtitle="Full serialization support with nested Button components"
531
+ backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
532
+ textAlign="center"
533
+ blockHeight="large"
534
+ overlayOpacity={0.6}
535
+ actions={[
536
+ { label: 'Primary Action', variant: 'primary', buttonSize: 'large' },
537
+ { label: 'Secondary Action', variant: 'outlined', buttonSize: 'large' }
538
+ ]}
539
+ />
540
+ );
541
+
542
+ // Serialize using ComponentTransformer
543
+ const serializedData = ComponentTransformer.serialize(originalHeroComponent);
544
+
545
+ // Deserialize back to component
546
+ const deserializedComponent = ComponentTransformer.deserialize(serializedData);
547
+
548
+ // Parse the JSON for display
549
+ const parsedData = JSON.parse(serializedData);
550
+
551
+ return (
552
+ <QwickApp appId="heroblock-serialization-basic" appName='HeroBlock Serialization Demo'>
553
+ <Box>
554
+
555
+ <Box sx={{ mb: 6, textAlign: 'center' }}>
556
+ <Typography variant="h3" gutterBottom>HeroBlock Serialization Pattern</Typography>
557
+ <Typography variant="h6" sx={{ mb: 4, opacity: 0.7 }}>
558
+ "WebView for React" - HeroBlock extends ModelView for standardized serialization
559
+ </Typography>
560
+
561
+ <Alert severity="success" sx={{ mb: 4, textAlign: 'left' }}>
562
+ The HeroBlock component supports full round-trip serialization including nested Button components
563
+ in the actions array, background styles, layout configurations, and all hero-specific properties.
564
+ </Alert>
565
+ </Box>
566
+
567
+ {/* Original Component */}
568
+ <Box sx={{ mb: 6 }}>
569
+ <Typography variant="h4" gutterBottom> Original HeroBlock</Typography>
570
+ {originalHeroComponent}
571
+ </Box>
572
+
573
+ {/* Serialized Data */}
574
+ <Box sx={{ mb: 6 }}>
575
+ <Typography variant="h4" gutterBottom> Serialized JSON</Typography>
576
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
577
+ Complete component serialization including actions array and hero properties:
578
+ </Typography>
579
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
580
+ <Code language="json" showLineNumbers={true} title="heroblock-serialized.json">
581
+ {JSON.stringify(parsedData, null, 2)}
582
+ </Code>
583
+ </Paper>
584
+ </Box>
585
+
586
+ {/* Deserialized Component */}
587
+ <Box sx={{ mb: 6 }}>
588
+ <Typography variant="h4" gutterBottom>♻ Deserialized HeroBlock</Typography>
589
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
590
+ Component reconstructed from JSON data - identical to original:
591
+ </Typography>
592
+ {deserializedComponent as React.ReactElement}
593
+ </Box>
594
+
595
+ </Box>
596
+ </QwickApp>
597
+ );
598
+ },
599
+ parameters: {
600
+ docs: {
601
+ description: {
602
+ story: 'Basic serialization round-trip demonstrating HeroBlock "WebView for React" functionality.',
603
+ },
604
+ },
605
+ },
606
+ };
607
+
608
+ export const SerializationAdvanced: Story = {
609
+ render: () => {
610
+ // Create multiple HeroBlock components with different configurations
611
+ const heroComponents = [
612
+ <HeroBlock
613
+ key="gradient"
614
+ title="Gradient Background Hero"
615
+ subtitle="Beautiful gradients with multiple actions"
616
+ backgroundGradient="linear-gradient(45deg, #2196F3, #21CBF3)"
617
+ textAlign="center"
618
+ blockHeight="medium"
619
+ actions={[
620
+ { label: 'Primary', variant: 'primary', buttonSize: 'large' },
621
+ { label: 'Secondary', variant: 'secondary', buttonSize: 'medium' }
622
+ ]}
623
+ />,
624
+ <HeroBlock
625
+ key="image"
626
+ title="Image Background Hero"
627
+ subtitle="High-quality image with customizable overlay"
628
+ backgroundImage="https://images.unsplash.com/photo-1558618666-fcd25c85cd64?ixlib=rb-4.0.3"
629
+ overlayOpacity={0.7}
630
+ textAlign="left"
631
+ blockHeight="large"
632
+ actions={[
633
+ { label: 'Explore', variant: 'primary', buttonSize: 'large' }
634
+ ]}
635
+ />,
636
+ <HeroBlock
637
+ key="minimal"
638
+ title="Minimal Theme Hero"
639
+ subtitle="Clean design with theme colors"
640
+ backgroundColor="secondary"
641
+ textAlign="right"
642
+ blockHeight="small"
643
+ actions={[
644
+ { label: 'Learn More', variant: 'outlined', buttonSize: 'medium' }
645
+ ]}
646
+ />
647
+ ];
648
+
649
+ // Serialize and deserialize each component
650
+ const serializedComponents = heroComponents.map((component, index) => {
651
+ const serializedData = ComponentTransformer.serialize(component);
652
+ const deserializedComponent = ComponentTransformer.deserialize(serializedData);
653
+ return {
654
+ original: component,
655
+ serialized: serializedData,
656
+ deserialized: deserializedComponent,
657
+ name: ['Gradient', 'Image', 'Minimal'][index]
658
+ };
659
+ });
660
+
661
+ return (
662
+ <QwickApp appId="heroblock-serialization-advanced" appName='Advanced HeroBlock Serialization'>
663
+ <Box>
664
+
665
+ <Box sx={{ mb: 6, textAlign: 'center' }}>
666
+ <Typography variant="h3" gutterBottom>Advanced HeroBlock Serialization</Typography>
667
+ <Typography variant="h6" sx={{ mb: 4, opacity: 0.7 }}>
668
+ Complex serialization scenarios with different HeroBlock configurations
669
+ </Typography>
670
+ </Box>
671
+
672
+ {serializedComponents.map((item, index) => (
673
+ <Box key={index} sx={{ mb: 8 }}>
674
+ <Typography variant="h4" gutterBottom>
675
+ {item.name} HeroBlock Serialization Round-Trip
676
+ </Typography>
677
+
678
+ <Box sx={{ display: 'grid', gridTemplateColumns: '1fr', gap: 4, mb: 4 }}>
679
+ <Box>
680
+ <Typography variant="h6" gutterBottom>Original Component</Typography>
681
+ {item.original}
682
+ </Box>
683
+ <Box>
684
+ <Typography variant="h6" gutterBottom>Deserialized Component</Typography>
685
+ {item.deserialized as React.ReactElement}
686
+ </Box>
687
+ </Box>
688
+
689
+ <Box>
690
+ <Typography variant="h6" gutterBottom>Serialized JSON Structure</Typography>
691
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
692
+ <Code language="json" showLineNumbers={false}>
693
+ {JSON.stringify(JSON.parse(item.serialized), null, 2)}
694
+ </Code>
695
+ </Paper>
696
+ </Box>
697
+
698
+ {index < serializedComponents.length - 1 && <Box sx={{ my: 4, borderBottom: '1px solid', borderColor: 'divider' }} />}
699
+ </Box>
700
+ ))}
701
+
702
+ </Box>
703
+ </QwickApp>
704
+ );
705
+ },
706
+ parameters: {
707
+ docs: {
708
+ description: {
709
+ story: 'Advanced serialization patterns with multiple HeroBlock configurations and background types.',
710
+ },
711
+ },
712
+ },
713
+ };
714
+
715
+ export const SerializationWithDataBinding: Story = {
716
+ render: () => {
717
+ // Create a HeroBlock component with data binding
718
+ const dataBindingComponent = (
719
+ <HeroBlock
720
+ dataSource="heroes.home"
721
+ bindingOptions={{ cache: true, strict: false }}
722
+ />
723
+ );
724
+
725
+ // Serialize and deserialize
726
+ const serializedData = ComponentTransformer.serialize(dataBindingComponent);
727
+ const deserializedComponent = ComponentTransformer.deserialize(serializedData);
728
+ const parsedData = JSON.parse(serializedData);
729
+
730
+ return (
731
+ <QwickApp appId="heroblock-serialization-databinding" appName='HeroBlock Serialization with Data Binding' dataSource={{ dataProvider }}>
732
+ <Box>
733
+
734
+ <Box sx={{ mb: 6, textAlign: 'center' }}>
735
+ <Typography variant="h3" gutterBottom>🔗 HeroBlock Serialization with Data Binding</Typography>
736
+ <Typography variant="h6" sx={{ mb: 4, opacity: 0.7 }}>
737
+ Preserving CMS data connections through serialization
738
+ </Typography>
739
+
740
+ <Alert severity="success" sx={{ mb: 4, textAlign: 'left' }}>
741
+ Data binding configurations (dataSource, bindingOptions) are preserved during serialization,
742
+ ensuring that deserialized HeroBlock components maintain their CMS connections and dynamic content capabilities.
743
+ </Alert>
744
+ </Box>
745
+
746
+ {/* Data Source Configuration */}
747
+ <Box sx={{ mb: 6 }}>
748
+ <Typography variant="h4" gutterBottom> CMS Data Source</Typography>
749
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
750
+ HeroBlock configured to pull content from "heroes.home" data source:
751
+ </Typography>
752
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
753
+ <Code language="tsx" showLineNumbers={true} title="data-binding-usage.tsx">
754
+ {`<HeroBlock
755
+ dataSource="heroes.home"
756
+ bindingOptions={{ cache: true, strict: false }}
757
+ />`}
758
+ </Code>
759
+ </Paper>
760
+ {dataBindingComponent}
761
+ </Box>
762
+
763
+ {/* Serialization Preserves Data Binding */}
764
+ <Box sx={{ mb: 6 }}>
765
+ <Typography variant="h4" gutterBottom> Serialized JSON (Data Binding Preserved)</Typography>
766
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
767
+ <Code language="json" showLineNumbers={true} title="serialized-with-databinding.json">
768
+ {JSON.stringify(parsedData, null, 2)}
769
+ </Code>
770
+ </Paper>
771
+ </Box>
772
+
773
+ {/* Deserialized Component with Data Binding */}
774
+ <Box sx={{ mb: 6 }}>
775
+ <Typography variant="h4" gutterBottom>♻ Deserialized with Active Data Binding</Typography>
776
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
777
+ Deserialized component maintains CMS connection and loads dynamic content:
778
+ </Typography>
779
+ {deserializedComponent as React.ReactElement}
780
+ </Box>
781
+
782
+ </Box>
783
+ </QwickApp>
784
+ );
785
+ },
786
+ parameters: {
787
+ docs: {
788
+ description: {
789
+ story: 'HeroBlock serialization example preserving data binding configuration for CMS-driven content.',
790
+ },
791
+ },
792
+ },
793
+ };
794
+
795
+ export const SerializationNestedActions: Story = {
796
+ render: () => {
797
+ // Create a HeroBlock with complex nested actions (Button components)
798
+ const complexHeroComponent = (
799
+ <HeroBlock
800
+ title="Complex Action HeroBlock"
801
+ subtitle="HeroBlock with multiple nested Button components and complex configurations"
802
+ backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
803
+ textAlign="center"
804
+ blockHeight="large"
805
+ overlayOpacity={0.5}
806
+ actions={[
807
+ {
808
+ label: 'Primary Action',
809
+ variant: 'primary',
810
+ buttonSize: 'large',
811
+ action: { type: 'navigate', url: '/primary', target: '_self' }
812
+ },
813
+ {
814
+ label: 'Secondary Action',
815
+ variant: 'secondary',
816
+ buttonSize: 'medium',
817
+ action: { type: 'navigate', url: '/secondary', target: '_blank' }
818
+ },
819
+ {
820
+ label: 'External Link',
821
+ variant: 'outlined',
822
+ buttonSize: 'medium',
823
+ action: { type: 'external', url: 'https://example.com', target: '_blank' }
824
+ },
825
+ {
826
+ label: 'Custom Action',
827
+ variant: 'text',
828
+ buttonSize: 'small',
829
+ action: { type: 'custom', customHandler: 'handleCustomAction' }
830
+ }
831
+ ]}
832
+ >
833
+ <Typography sx={{ mt: 3, fontSize: '1.1rem', opacity: 0.9 }}>
834
+ Additional nested content within the HeroBlock component
835
+ </Typography>
836
+ </HeroBlock>
837
+ );
838
+
839
+ // Serialize and deserialize the complex structure
840
+ const serializedStructure = ComponentTransformer.serialize(complexHeroComponent);
841
+ const deserializedStructure = ComponentTransformer.deserialize(serializedStructure);
842
+ const parsedData = JSON.parse(serializedStructure);
843
+
844
+ return (
845
+ <QwickApp appId="heroblock-serialization-nested" appName='HeroBlock Nested Actions Serialization'>
846
+ <Box>
847
+
848
+ <Box sx={{ mb: 6, textAlign: 'center' }}>
849
+ <Typography variant="h3" gutterBottom> HeroBlock with Nested Actions</Typography>
850
+ <Typography variant="h6" sx={{ mb: 4, opacity: 0.7 }}>
851
+ Complex nested Button components within HeroBlock actions
852
+ </Typography>
853
+
854
+ <Alert severity="info" sx={{ mb: 4, textAlign: 'left' }}>
855
+ HeroBlock components can contain complex Button configurations in the actions array.
856
+ Each action can include custom properties, event handlers, and action patterns that are
857
+ preserved through the serialization process.
858
+ </Alert>
859
+ </Box>
860
+
861
+ {/* Original Complex HeroBlock */}
862
+ <Box sx={{ mb: 6 }}>
863
+ <Typography variant="h4" gutterBottom> Original Complex HeroBlock</Typography>
864
+ {complexHeroComponent}
865
+ </Box>
866
+
867
+ {/* Serialized Data Preview */}
868
+ <Box sx={{ mb: 6 }}>
869
+ <Typography variant="h4" gutterBottom> Actions Array Serialization</Typography>
870
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
871
+ The complex actions array with Button configurations (showing actions section):
872
+ </Typography>
873
+ <Paper sx={{ p: 2, backgroundColor: 'grey.100' }}>
874
+ <Code language="json" showLineNumbers={true}>
875
+ {JSON.stringify(parsedData.data.actions, null, 2)}
876
+ </Code>
877
+ </Paper>
878
+ </Box>
879
+
880
+ {/* Deserialized Structure */}
881
+ <Box sx={{ mb: 6 }}>
882
+ <Typography variant="h4" gutterBottom>♻ Deserialized HeroBlock</Typography>
883
+ <Typography variant="body1" sx={{ mb: 3, opacity: 0.8 }}>
884
+ Complex HeroBlock reconstructed with all nested Button components:
885
+ </Typography>
886
+ {deserializedStructure as React.ReactElement}
887
+ </Box>
888
+
889
+ {/* Benefits Summary */}
890
+ <Box sx={{ mt: 8, p: 4, backgroundColor: 'success.light', color: 'success.contrastText', borderRadius: 2 }}>
891
+ <Typography variant="h4" gutterBottom>✅ HeroBlock Serialization Benefits</Typography>
892
+ <Box sx={{ display: 'grid', gridTemplateColumns: { xs: '1fr', md: '1fr 1fr' }, gap: 3, mt: 3 }}>
893
+ <Box>
894
+ <Typography variant="h6" gutterBottom> Complete Hero Preservation</Typography>
895
+ <Typography variant="body2" sx={{ opacity: 0.9 }}>
896
+ All hero properties including backgrounds, layout, actions, and content are preserved.
897
+ </Typography>
898
+ </Box>
899
+ <Box>
900
+ <Typography variant="h6" gutterBottom>🔘 Nested Button Serialization</Typography>
901
+ <Typography variant="body2" sx={{ opacity: 0.9 }}>
902
+ Action buttons with complex configurations and event patterns are fully serialized.
903
+ </Typography>
904
+ </Box>
905
+ <Box>
906
+ <Typography variant="h6" gutterBottom> Responsive Layout Support</Typography>
907
+ <Typography variant="body2" sx={{ opacity: 0.9 }}>
908
+ Responsive design, alignment, and height configurations are maintained.
909
+ </Typography>
910
+ </Box>
911
+ <Box>
912
+ <Typography variant="h6" gutterBottom>🔗 Data Binding Integration</Typography>
913
+ <Typography variant="body2" sx={{ opacity: 0.9 }}>
914
+ CMS data connections and dynamic content loading are preserved through serialization.
915
+ </Typography>
916
+ </Box>
917
+ </Box>
918
+ </Box>
919
+
920
+ </Box>
921
+ </QwickApp>
922
+ );
923
+ },
924
+ parameters: {
925
+ docs: {
926
+ description: {
927
+ story: 'Complex nested structure serialization with multiple Button components in HeroBlock actions array.',
928
+ },
929
+ },
930
+ },
442
931
  };