@qwickapps/react-framework 1.3.4 → 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 (325) hide show
  1. package/README.md +1688 -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/Content.d.ts.map +1 -1
  28. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  30. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  31. package/dist/components/blocks/Footer.d.ts.map +1 -1
  32. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  33. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  34. package/dist/components/blocks/Image.d.ts +41 -0
  35. package/dist/components/blocks/Image.d.ts.map +1 -0
  36. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  37. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  38. package/dist/components/blocks/Section.d.ts +16 -2
  39. package/dist/components/blocks/Section.d.ts.map +1 -1
  40. package/dist/components/blocks/Text.d.ts +41 -0
  41. package/dist/components/blocks/Text.d.ts.map +1 -0
  42. package/dist/components/blocks/index.d.ts +4 -0
  43. package/dist/components/blocks/index.d.ts.map +1 -1
  44. package/dist/components/buttons/Button.d.ts +23 -7
  45. package/dist/components/buttons/Button.d.ts.map +1 -1
  46. package/dist/components/forms/FormBlock.d.ts +19 -13
  47. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  48. package/dist/components/index.d.ts +4 -0
  49. package/dist/components/index.d.ts.map +1 -1
  50. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  51. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  52. package/dist/components/input/HtmlInputField.d.ts +17 -11
  53. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  54. package/dist/components/input/SelectInputField.d.ts +16 -10
  55. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  56. package/dist/components/input/SwitchInputField.d.ts +16 -10
  57. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  58. package/dist/components/input/TextField.d.ts.map +1 -1
  59. package/dist/components/input/TextInputField.d.ts +16 -11
  60. package/dist/components/input/TextInputField.d.ts.map +1 -1
  61. package/dist/components/layout/GridCell.d.ts +23 -6
  62. package/dist/components/layout/GridCell.d.ts.map +1 -1
  63. package/dist/components/layout/GridLayout.d.ts +24 -23
  64. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  65. package/dist/components/pages/FormPage.d.ts.map +1 -1
  66. package/dist/components/pages/Page.d.ts +49 -87
  67. package/dist/components/pages/Page.d.ts.map +1 -1
  68. package/dist/components/pages/index.d.ts +2 -2
  69. package/dist/components/pages/index.d.ts.map +1 -1
  70. package/dist/config/AppConfig.d.ts +49 -0
  71. package/dist/config/AppConfig.d.ts.map +1 -0
  72. package/dist/config/AppConfigBuilder.d.ts +75 -0
  73. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  74. package/dist/config/index.d.ts +13 -0
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/config/types.d.ts +130 -0
  77. package/dist/config/types.d.ts.map +1 -0
  78. package/dist/config.d.ts +15 -0
  79. package/dist/config.d.ts.map +1 -0
  80. package/dist/config.esm.js +451 -0
  81. package/dist/config.js +455 -0
  82. package/dist/contexts/PrintModeContext.d.ts +27 -0
  83. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  84. package/dist/contexts/QwickAppContext.d.ts +2 -2
  85. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  86. package/dist/contexts/ThemeContext.d.ts.map +1 -1
  87. package/dist/contexts/index.d.ts +2 -0
  88. package/dist/contexts/index.d.ts.map +1 -1
  89. package/dist/hooks/index.d.ts +2 -0
  90. package/dist/hooks/index.d.ts.map +1 -1
  91. package/dist/hooks/usePrintMode.d.ts +39 -0
  92. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  93. package/dist/index.css +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.esm.css +1 -1
  97. package/dist/index.esm.js +20722 -16021
  98. package/dist/index.js +20725 -16010
  99. package/dist/schemas/CodeSchema.d.ts +2 -1
  100. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  101. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  102. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  103. package/dist/schemas/ContentSchema.d.ts +2 -1
  104. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  105. package/dist/schemas/GridCellSchema.d.ts +25 -0
  106. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  107. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  108. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  109. package/dist/schemas/HtmlSchema.d.ts +14 -0
  110. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  111. package/dist/schemas/ImageSchema.d.ts +32 -0
  112. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  113. package/dist/schemas/LogoSchema.d.ts +35 -0
  114. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  115. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  116. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  117. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  118. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  119. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  120. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  121. package/dist/schemas/SectionSchema.d.ts +2 -1
  122. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  123. package/dist/schemas/TextSchema.d.ts +37 -0
  124. package/dist/schemas/TextSchema.d.ts.map +1 -0
  125. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  126. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  127. package/dist/schemas/index.d.ts +15 -1
  128. package/dist/schemas/index.d.ts.map +1 -1
  129. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  130. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  131. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  132. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  133. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  134. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  135. package/dist/schemas/transformers/registry.d.ts +15 -0
  136. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  137. package/dist/schemas/types/Serializable.d.ts +46 -0
  138. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  139. package/dist/utils/htmlTransform.d.ts.map +1 -1
  140. package/dist/utils/reactUtils.d.ts +12 -3
  141. package/dist/utils/reactUtils.d.ts.map +1 -1
  142. package/package.json +17 -3
  143. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  145. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  148. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  150. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  152. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  154. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  155. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  156. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  158. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  159. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  160. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  161. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  162. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  163. package/src/__tests__/components/Logo.test.js +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  165. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  166. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  167. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  168. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  169. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  172. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  173. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  174. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  175. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  176. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  177. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  178. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  179. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  180. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  181. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  182. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  183. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  184. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  185. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  186. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  187. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  188. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  189. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  190. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  191. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  192. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  193. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  194. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  195. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  196. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  197. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  198. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  199. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  200. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  201. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  202. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  203. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  204. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  205. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  206. package/src/components/ErrorBoundary.tsx +8 -8
  207. package/src/components/Html.tsx +147 -44
  208. package/src/components/Logo.tsx +198 -100
  209. package/src/components/Markdown.tsx +125 -16
  210. package/src/components/QwickApp.tsx +64 -31
  211. package/src/components/QwickIcon.tsx +59 -0
  212. package/src/components/SafeSpan.tsx +65 -10
  213. package/src/components/Scaffold.tsx +2 -8
  214. package/src/components/base/ModelView.tsx +199 -0
  215. package/src/components/base/index.ts +11 -0
  216. package/src/components/blocks/Article.tsx +57 -18
  217. package/src/components/blocks/Code.md +529 -0
  218. package/src/components/blocks/Code.tsx +102 -15
  219. package/src/components/blocks/Content.tsx +25 -77
  220. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  221. package/src/components/blocks/FeatureCard.tsx +1 -2
  222. package/src/components/blocks/FeatureGrid.tsx +19 -1
  223. package/src/components/blocks/Footer.tsx +13 -1
  224. package/src/components/blocks/HeroBlock.tsx +87 -20
  225. package/src/components/blocks/Image.tsx +395 -0
  226. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  227. package/src/components/blocks/ProductCard.tsx +51 -52
  228. package/src/components/blocks/Section.tsx +113 -8
  229. package/src/components/blocks/Text.tsx +285 -0
  230. package/src/components/blocks/index.ts +4 -0
  231. package/src/components/buttons/Button.tsx +184 -15
  232. package/src/components/forms/FormBlock.tsx +70 -17
  233. package/src/components/index.ts +5 -0
  234. package/src/components/input/ChoiceInputField.tsx +48 -18
  235. package/src/components/input/HtmlInputField.tsx +48 -18
  236. package/src/components/input/SelectInputField.tsx +48 -16
  237. package/src/components/input/SwitchInputField.tsx +48 -17
  238. package/src/components/input/TextField.tsx +41 -1
  239. package/src/components/input/TextInputField.tsx +52 -18
  240. package/src/components/layout/GridCell.tsx +118 -9
  241. package/src/components/layout/GridLayout.tsx +125 -24
  242. package/src/components/pages/FormPage.tsx +0 -1
  243. package/src/components/pages/Page.css +304 -332
  244. package/src/components/pages/Page.tsx +307 -255
  245. package/src/components/pages/index.ts +2 -2
  246. package/src/config/AppConfig.ts +133 -0
  247. package/src/config/AppConfigBuilder.ts +421 -0
  248. package/src/config/__tests__/AppConfig.test.ts +385 -0
  249. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  250. package/src/config/index.ts +24 -0
  251. package/src/config/types.ts +170 -0
  252. package/src/config.ts +25 -0
  253. package/src/contexts/PrintModeContext.tsx +332 -0
  254. package/src/contexts/QwickAppContext.tsx +2 -2
  255. package/src/contexts/ThemeContext.tsx +1 -2
  256. package/src/contexts/index.ts +2 -0
  257. package/src/hooks/index.ts +5 -1
  258. package/src/hooks/usePrintMode.ts +73 -0
  259. package/src/index.ts +3 -0
  260. package/src/schemas/CodeSchema.ts +3 -3
  261. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  262. package/src/schemas/ContentSchema.ts +2 -1
  263. package/src/schemas/GridCellSchema.ts +164 -0
  264. package/src/schemas/GridLayoutSchema.ts +133 -0
  265. package/src/schemas/HtmlSchema.ts +47 -0
  266. package/src/schemas/ImageSchema.ts +235 -0
  267. package/src/schemas/LogoSchema.ts +241 -0
  268. package/src/schemas/MarkdownSchema.ts +47 -0
  269. package/src/schemas/PageTemplateSchema.ts +186 -0
  270. package/src/schemas/PrintConfigSchema.ts +207 -0
  271. package/src/schemas/README.md +661 -0
  272. package/src/schemas/SectionSchema.ts +2 -1
  273. package/src/schemas/TextSchema.ts +329 -0
  274. package/src/schemas/ViewModelSchema.ts +115 -0
  275. package/src/schemas/index.ts +21 -2
  276. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  277. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  278. package/src/schemas/transformers/registry.ts +72 -0
  279. package/src/schemas/types/Serializable.ts +51 -0
  280. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  281. package/src/stories/Article.stories.tsx +433 -433
  282. package/src/stories/Button.stories.tsx +1 -1
  283. package/src/stories/CardListGrid.stories.tsx +451 -451
  284. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  285. package/src/stories/Code.stories.tsx +1 -1
  286. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  287. package/src/stories/Content.stories.tsx +393 -393
  288. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  289. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  290. package/src/stories/DataProvider.stories.tsx +1192 -1192
  291. package/src/stories/FeatureCard.stories.tsx +557 -557
  292. package/src/stories/FeatureGrid.stories.tsx +594 -594
  293. package/src/stories/Footer.stories.tsx +640 -640
  294. package/src/stories/FormBlock.stories.tsx +760 -760
  295. package/src/stories/FormComponents.stories.tsx +349 -541
  296. package/src/stories/GridCell.stories.tsx +417 -0
  297. package/src/stories/GridLayout.stories.tsx +353 -0
  298. package/src/stories/HeroBlock.stories.tsx +862 -373
  299. package/src/stories/HtmlInputField.stories.tsx +474 -474
  300. package/src/stories/Image.stories.tsx +819 -0
  301. package/src/stories/Introduction.stories.tsx +667 -667
  302. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  303. package/src/stories/Logo.stories.tsx +165 -6
  304. package/src/stories/Markdown.stories.tsx +137 -137
  305. package/src/stories/ModelView.stories.tsx +477 -0
  306. package/src/stories/Page.stories.tsx +688 -688
  307. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  308. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  309. package/src/stories/ProductCard.stories.tsx +424 -424
  310. package/src/stories/QwickApp.stories.tsx +368 -368
  311. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  312. package/src/stories/SafeSpan.stories.tsx +531 -531
  313. package/src/stories/Section.stories.tsx +90 -2
  314. package/src/stories/SelectInputField.stories.tsx +524 -524
  315. package/src/stories/Text.stories.tsx +560 -0
  316. package/src/stories/TextInputField.stories.tsx +443 -443
  317. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  318. package/src/utils/htmlTransform.tsx +74 -53
  319. package/src/utils/reactUtils.tsx +57 -6
  320. package/dist/index.bundled.css +0 -12
  321. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  322. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  323. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  324. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  325. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -61,85 +61,33 @@ function ContentView({
61
61
  }
62
62
  };
63
63
 
64
- // Content wrapper based on variant
65
- const ContentWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
66
- const paddingValue = getPadding();
67
- const mappedMaxWidth = mapToMUIBreakpoint(contentMaxWidth === 'false' ? false : contentMaxWidth as BreakpointValue);
68
- const commonSx: SxProps<Theme> = {
69
- textAlign: centered ? 'center' : 'left',
70
- maxWidth: mappedMaxWidth !== false
71
- ? theme.breakpoints.values[mappedMaxWidth]
72
- : '100%',
73
- width: '100%',
74
- ...(centered && contentMaxWidth && {
75
- mx: 'auto',
76
- }),
77
- p: paddingValue,
78
- ...styleProps.sx,
79
- };
80
-
81
- switch (variant) {
82
- case 'elevated':
83
- return (
84
- <Paper
85
- elevation={4}
86
- {...htmlProps}
87
- {...otherProps}
88
- sx={{
89
- ...commonSx,
90
- backgroundColor: theme.palette.background.paper,
91
- }}
92
- >
93
- {children}
94
- </Paper>
95
- );
96
- case 'outlined':
97
- return (
98
- <Paper
99
- variant="outlined"
100
- elevation={0}
101
- {...htmlProps}
102
- {...otherProps}
103
- sx={{
104
- ...commonSx,
105
- backgroundColor: 'var(--theme-surface)',
106
- borderColor: 'var(--theme-border-main)', // Use theme border color
107
- borderWidth: 1,
108
- borderStyle: 'solid',
109
- }}
110
- >
111
- {children}
112
- </Paper>
113
- );
114
- case 'filled':
115
- return (
116
- <Box
117
- {...htmlProps}
118
- {...otherProps}
119
- sx={{
120
- ...commonSx,
121
- backgroundColor: 'var(--theme-surface-variant)', // Use theme surface variant
122
- borderRadius: 1,
123
- }}
124
- >
125
- {children}
126
- </Box>
127
- );
128
- default:
129
- return (
130
- <Box
131
- {...htmlProps}
132
- {...otherProps}
133
- sx={commonSx}
134
- >
135
- {children}
136
- </Box>
137
- );
138
- }
64
+ // Compute stable wrapper element (avoid recreating component type each render which caused remount & focus loss)
65
+ const paddingValue = getPadding();
66
+ const mappedMaxWidth = mapToMUIBreakpoint(contentMaxWidth === 'false' ? false : contentMaxWidth as BreakpointValue);
67
+ const commonSx: SxProps<Theme> = {
68
+ textAlign: centered ? 'center' : 'left',
69
+ maxWidth: mappedMaxWidth !== false ? theme.breakpoints.values[mappedMaxWidth] : '100%',
70
+ width: '100%',
71
+ ...(centered && contentMaxWidth && { mx: 'auto' }),
72
+ p: paddingValue,
73
+ ...styleProps.sx,
139
74
  };
140
75
 
76
+ let Wrapper: React.ElementType = Box;
77
+ let wrapperProps: Record<string, any> = { ...htmlProps, ...otherProps, sx: commonSx };
78
+ if (variant === 'elevated') {
79
+ Wrapper = Paper;
80
+ wrapperProps = { ...wrapperProps, elevation: 4, sx: { ...commonSx, backgroundColor: theme.palette.background.paper } };
81
+ } else if (variant === 'outlined') {
82
+ Wrapper = Paper;
83
+ wrapperProps = { ...wrapperProps, variant: 'outlined', elevation: 0, sx: { ...commonSx, backgroundColor: 'var(--theme-surface)', borderColor: 'var(--theme-border-main)', borderWidth: 1, borderStyle: 'solid' } };
84
+ } else if (variant === 'filled') {
85
+ Wrapper = Box;
86
+ wrapperProps = { ...wrapperProps, sx: { ...commonSx, backgroundColor: 'var(--theme-surface-variant)', borderRadius: 1 } };
87
+ }
88
+
141
89
  return (
142
- <ContentWrapper>
90
+ <Wrapper {...wrapperProps}>
143
91
  <Stack spacing={2}>
144
92
  {/* Header */}
145
93
  {(title || subtitle) && (
@@ -210,7 +158,7 @@ function ContentView({
210
158
  </Stack>
211
159
  )}
212
160
  </Stack>
213
- </ContentWrapper>
161
+ </Wrapper>
214
162
  );
215
163
  }
216
164
 
@@ -424,10 +424,15 @@ function CoverImageHeader(props: CoverImageHeaderProps) {
424
424
 
425
425
  // Convert HeaderActionModel[] to HeaderAction[] if actions exist
426
426
  const { actions: modelActions, ...viewProps } = coverImageHeaderProps;
427
- const convertedActions: HeaderAction[] = modelActions ? modelActions.map(action => ({
428
- ...action,
429
- onClick: () => console.log(`Action clicked: ${action.id}`) // Default handler for data-driven actions
430
- })) : [];
427
+ const convertedActions: HeaderAction[] = modelActions
428
+ ? modelActions
429
+ .filter(action => typeof action.id === 'string' && !!action.id)
430
+ .map(action => ({
431
+ ...action,
432
+ id: action.id as string,
433
+ onClick: () => console.log(`Action clicked: ${action.id}`) // Default handler for data-driven actions
434
+ }))
435
+ : [];
431
436
 
432
437
  return <CoverImageHeaderView {...viewProps} actions={convertedActions} />;
433
438
  }
@@ -237,10 +237,9 @@ function FeatureCardView({
237
237
  <Button
238
238
  key={action.id}
239
239
  variant={action.variant || 'contained'}
240
- color={action.color || 'primary'}
240
+ // color={action.color || 'primary'}
241
241
  disabled={action.disabled}
242
242
  onClick={action.onClick}
243
- size="small"
244
243
  >
245
244
  {action.label}
246
245
  </Button>
@@ -140,7 +140,25 @@ function FeatureGrid(props: FeatureGridProps) {
140
140
  return null;
141
141
  }
142
142
 
143
- return <FeatureGridView {...featureGridProps} />;
143
+ // Ensure features have a non-optional 'id'
144
+ const safeFeatures =
145
+ Array.isArray(featureGridProps.features)
146
+ ? featureGridProps.features.map((f, idx) => ({
147
+ ...f,
148
+ id: f.id ?? `feature-${idx}`,
149
+ title: f.title ?? '',
150
+ description: f.description ?? '',
151
+ }))
152
+ : featureGridProps.features;
153
+
154
+ // Ensure columns is one of the allowed values
155
+ const allowedColumns = [1, 2, 3, 4, 5, 6];
156
+ const columns =
157
+ allowedColumns.includes(featureGridProps.columns as number)
158
+ ? (featureGridProps.columns as 1 | 2 | 3 | 4 | 5 | 6)
159
+ : undefined;
160
+
161
+ return <FeatureGridView {...featureGridProps} features={safeFeatures} columns={columns} />;
144
162
  }
145
163
 
146
164
  export default FeatureGrid;
@@ -337,7 +337,19 @@ function Footer(props: FooterProps) {
337
337
  return null;
338
338
  }
339
339
 
340
- return <FooterView {...footerProps} />;
340
+ // Map FooterSectionModel[] to FooterSection[] and ensure id is a string
341
+ const mappedSections =
342
+ footerProps.sections?.map(section => ({
343
+ ...section,
344
+ id: section.id ?? '', // fallback to empty string if id is undefined
345
+ items: section.items?.map(item => ({
346
+ ...item,
347
+ id: item.id ?? '', // fallback to empty string if id is undefined
348
+ label: item.label ?? '', // ensure label is always a string
349
+ })) ?? [],
350
+ })) ?? [];
351
+
352
+ return <FooterView {...footerProps} sections={mappedSections} />;
341
353
  }
342
354
 
343
355
  export default Footer;
@@ -1,40 +1,44 @@
1
1
  /**
2
- * HeroBlock Component - Full-width hero section with data binding support
3
- *
4
- * Enhanced with data binding support through dataSource prop.
5
- *
6
- * Usage:
7
- * - Traditional: <HeroBlock title="Welcome" subtitle="Get started" actions={[...]} />
8
- * - Data-driven: <HeroBlock dataSource="pages.home.hero" />
2
+ * HeroBlock Component - Full-width hero section with serialization support
9
3
  *
10
4
  * Features:
11
5
  * - Responsive headline, subtitle, and actions
12
6
  * - Supports background images, gradients, and theme colors
13
7
  * - Overlay for image backgrounds
14
8
  * - Customizable height, alignment, and overlay opacity
9
+ * - Full serialization support via ModelView
10
+ * - Nested Button component serialization support
11
+ *
12
+ * Usage:
13
+ * - Traditional: <HeroBlock title="Welcome" subtitle="Get started" actions={[...]} />
14
+ * - Data-driven: <HeroBlock dataSource="pages.home.hero" />
15
+ * - Serializable: ComponentTransformer.serialize(<HeroBlock ... />)
15
16
  *
16
17
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
17
18
  */
18
19
 
19
20
  import { Box, Container, Stack, Typography, useTheme } from '@mui/material';
20
- import { WithDataBinding, ModelProps } from '@qwickapps/schema';
21
- import React from 'react';
22
- import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
21
+ import type { ModelProps, WithDataBinding } from '@qwickapps/schema';
22
+ import React, { ReactElement, ReactNode } from 'react';
23
+ import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding } from '../../hooks';
23
24
  import HeroBlockModel from '../../schemas/HeroBlockSchema';
25
+ import { ModelView } from '../base/ModelView';
24
26
  import { Button, ButtonProps } from '../buttons/Button';
25
27
 
26
- type HeroBlockViewProps = Partial<ModelProps<HeroBlockModel>> & WithBaseProps & {
28
+ type HeroBlockViewProps = ModelProps<HeroBlockModel> & {
27
29
  /** Action buttons (data-driven) */
28
30
  actions?: ButtonProps[];
29
31
  /** Additional content below the text */
30
- children?: React.ReactNode;
32
+ children?: ReactNode;
33
+ /** Click handler for the hero section */
34
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
35
+ /** Additional inline styles */
36
+ style?: React.CSSProperties;
31
37
  };
32
38
 
33
39
  export interface HeroBlockProps extends HeroBlockViewProps, WithDataBinding {}
34
40
 
35
- /**
36
- * Core HeroBlock View component - handles hero section rendering
37
- */
41
+ // View component - handles the actual rendering
38
42
  function HeroBlockView({
39
43
  title = '',
40
44
  subtitle,
@@ -230,17 +234,77 @@ function HeroBlockView({
230
234
  );
231
235
  }
232
236
 
233
- function HeroBlock(props: HeroBlockProps) {
234
- const { dataSource, bindingOptions, ...restProps } = props;
237
+ // Main component with data binding support and serialization capability
238
+ export class HeroBlock extends ModelView<HeroBlockProps, HeroBlockModel> {
239
+ // Component self-declaration for serialization
240
+ static readonly tagName = 'HeroBlock';
241
+ static readonly version = '1.0.0';
242
+
243
+ // Deserialization: JSON data → React element
244
+ static fromJson(jsonData: any): ReactElement {
245
+ return <HeroBlock {...jsonData} />;
246
+ }
247
+
248
+ // Component-specific serialization properties
249
+ protected getComponentSpecificProps(): any {
250
+ return {
251
+ title: this.props.title,
252
+ subtitle: this.props.subtitle,
253
+ backgroundImage: this.props.backgroundImage,
254
+ backgroundGradient: this.props.backgroundGradient,
255
+ backgroundColor: this.props.backgroundColor,
256
+ textAlign: this.props.textAlign,
257
+ blockHeight: this.props.blockHeight,
258
+ overlayOpacity: this.props.overlayOpacity,
259
+ // Serialize actions array (ButtonProps)
260
+ actions: this.props.actions
261
+ };
262
+ }
263
+
264
+ // Override serializeChildren to handle nested Button components
265
+ protected serializeChildren(children: ReactNode): any {
266
+ if (typeof children === 'string') {
267
+ return children;
268
+ }
269
+
270
+ // HeroBlock can contain complex nested content, but not necessarily other serializable components
271
+ // Handle the children as-is for now, since HeroBlock typically contains MUI Typography and Box elements
272
+ // The actions prop is handled separately in getComponentSpecificProps
273
+ if (children) {
274
+ // For HeroBlock, children are typically additional content (Typography, Box)
275
+ // These don't need component serialization, just text extraction
276
+ const { extractTextFromReactNode } = require('../../utils/reactUtils');
277
+ return extractTextFromReactNode(children);
278
+ }
279
+
280
+ return undefined;
281
+ }
235
282
 
236
- // If no dataSource, use traditional props
237
- if (!dataSource) {
283
+ // Indicate that HeroBlock doesn't contain nested serializable components in children
284
+ // (actions are handled separately via props)
285
+ protected hasNestedComponents(children: ReactNode): boolean {
286
+ return false;
287
+ }
288
+
289
+ // HeroBlock component renders traditional props view
290
+ protected renderView(): React.ReactElement {
291
+ const { dataSource, bindingOptions, ...restProps } = this.props;
238
292
  return <HeroBlockView {...restProps} />;
239
293
  }
240
294
 
295
+ // HeroBlock component renders data-bound view
296
+ protected renderWithDataBinding(): React.ReactElement {
297
+ return <HeroBlockWithDataBinding {...this.props} />;
298
+ }
299
+ }
300
+
301
+ // Helper component to handle data binding with hooks (since we can't use hooks in class components)
302
+ function HeroBlockWithDataBinding(props: HeroBlockProps) {
303
+ const { dataSource, bindingOptions, ...restProps } = props;
304
+
241
305
  // Use data binding
242
306
  const { dataSource: _source, loading, error, cached, ...heroProps } = useDataBinding<HeroBlockModel>(
243
- dataSource,
307
+ dataSource!,
244
308
  restProps as Partial<HeroBlockModel>,
245
309
  HeroBlockModel.getSchema(),
246
310
  { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
@@ -277,4 +341,7 @@ function HeroBlock(props: HeroBlockProps) {
277
341
  return <HeroBlockView {...heroProps} />;
278
342
  }
279
343
 
344
+ // Mark as QwickApp component
345
+ (HeroBlock as any)[QWICKAPP_COMPONENT] = true;
346
+
280
347
  export default HeroBlock;