@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
package/README.md CHANGED
@@ -4,6 +4,24 @@ A complete React framework for building modern, responsive applications with int
4
4
 
5
5
  ## What's New
6
6
 
7
+ ### January 5, 2025 - Component Serialization System ("WebView for React")
8
+
9
+ - **Complete Component Serialization**: Full "WebView for React" functionality enabling components to be serialized to JSON and reconstructed while preserving functionality
10
+ - **Data Binding Preservation**: Serialization system seamlessly preserves data binding configuration across serialize/deserialize cycles
11
+ - **Code Component Reference Implementation**: Code component serves as the canonical example with <1ms serialization performance and comprehensive ReactNode handling
12
+ - **Image Component ModelView Integration**: Image component successfully converted to ModelView architecture with 300-500x performance targets exceeded and 100% backward compatibility
13
+ - **Text Component ModelView Integration**: Text component successfully converted to ModelView architecture with 125-500x performance targets exceeded, comprehensive typography serialization, and 96.3% test coverage
14
+ - **HeroBlock Component Complex Serialization**: **First component with nested component serialization** - HeroBlock successfully converted with Button actions array support and 500x performance targets exceeded (0.0009ms basic, 0.0058ms complex serialization)
15
+ - **GridLayout & GridCell Components**: **First responsive grid system with complete serialization** - GridLayout and GridCell components successfully converted to ModelView with 3-169x performance targets exceeded and complete responsive breakpoint preservation
16
+ - **Responsive Grid Breakthrough**: GridLayout and GridCell establish patterns for responsive layout serialization with all breakpoint configurations (xs,sm,md,lg,xl) preserved through serialization cycles
17
+ - **Complex Layout Support**: GridLayout handles 1-6 column responsive layouts with nested GridCell components, maintaining complete functionality after reconstruction
18
+ - **Nested Component Breakthrough**: HeroBlock establishes architectural patterns for complex components with nested React elements, demonstrating serialization system capability for sophisticated component hierarchies
19
+ - **Production-Ready Components**: Code, Image, Text, HeroBlock, GridLayout, and GridCell components approved for production deployment with comprehensive QA validation
20
+ - **Typography Serialization**: Complete Material-UI Typography integration with all variants (h1-h6, body1/2, subtitle, button, caption, overline), color support, and text formatting preserved
21
+ - **Performance Excellence**: QA validation with enhanced test coverage, handles 1000+ components in <50ms, memory usage <50MB for large component trees
22
+ - **Production Ready**: Cross-browser compatibility, comprehensive error handling, and graceful fallback for unknown components
23
+ - **CMS Integration**: Components can be stored in CMS systems as JSON and reconstructed maintaining full React functionality
24
+
7
25
  ### September 4, 2025 - Stability & Inline Wrapper Guard
8
26
 
9
27
  - **ProductCard Stability Fix**: Removed inline wrapper React components that caused subtree remounts and potential focus/state loss; replaced with stable JSX fragments.
@@ -55,18 +73,47 @@ A complete React framework for building modern, responsive applications with int
55
73
  ### 🧩 **Component Library**
56
74
  - **Logo Component**: Dynamic, customizable logos with badges and animations
57
75
  - **Theme Controls**: Built-in theme and palette switchers
58
- - **Form Components**: Accessible, themed form inputs
76
+ - **Form Components**: Accessible, themed form inputs with complete serialization support
77
+ - **Advanced Form Fields**: TextInputField, SelectInputField, HtmlInputField, ChoiceInputField, SwitchInputField with controlled state preservation
78
+ - **Form Containers**: FormBlock component with nested form component support and status messaging
59
79
  - **Safe Components**: XSS-protected content rendering
60
80
  - **Html Component**: Transform HTML strings to React components with configurable rules
61
81
  - **Markdown Component**: Convert Markdown to React components with syntax highlighting
62
82
  - **Transform System**: Extensible HTML element transformation with fallback handling
63
83
 
84
+ ### 🔄 **Component Serialization System**
85
+ - **"WebView for React" Functionality**: Serialize React components to JSON and reconstruct with full functionality preserved
86
+ - **Complete Form Serialization**: **First form state management serialization system** - All form components preserve controlled component state, validation rules, and error handling
87
+ - **Production-Ready Components**: 11 components with complete ModelView architecture and comprehensive QA validation (Code, Image, Text, HeroBlock, GridLayout, GridCell, TextInputField, SelectInputField, HtmlInputField, ChoiceInputField, SwitchInputField, FormBlock)
88
+ - **Form Components Innovation**: TextInputField, SelectInputField, HtmlInputField, ChoiceInputField, SwitchInputField, and FormBlock with 97.5% test pass rate and 0.4ms average serialization
89
+ - **Complex Form Data Handling**: Options arrays, HTML content, validation configurations, choice fields, and boolean controls fully supported through serialization
90
+ - **Production Form Workflows**: Complete form creation, editing, validation, and submission workflows preserved through serialize/deserialize cycles
91
+ - **Nested Component Serialization**: HeroBlock component pioneered nested component serialization with Button actions array support
92
+ - **Responsive Grid Serialization**: GridLayout and GridCell components provide first responsive grid system with complete serialization and breakpoint preservation
93
+ - **Complex Component Architecture**: Components handle sophisticated hierarchical structures with background images, gradients, responsive layouts, and interactive elements
94
+ - **Breakpoint Preservation**: All responsive breakpoint configurations (xs,sm,md,lg,xl) fully preserved through serialization cycles
95
+ - **Data Binding Integration**: Components maintain data source connections through serialization cycles
96
+ - **Performance Optimized**: <1ms serialization/deserialization, handles 1000+ components efficiently, 2.5-500x performance targets exceeded
97
+ - **CMS Ready**: Store components in databases/CMS systems and reconstruct as living React components
98
+ - **Graceful Fallbacks**: Unknown components automatically use HTML fallback rendering
99
+ - **Cross-Platform**: Consistent serialization across all major browsers and environments
100
+
64
101
  ### 🛡️ **Built-in Error Handling & Accessibility**
65
102
  - **ErrorBoundary**: Automatic error catching with user-friendly fallback UI and retry functionality
66
103
  - **AccessibilityProvider**: WCAG 2.1 AA compliance with system preference detection and ARIA announcements
67
104
  - **Breadcrumbs**: Accessible navigation hierarchy with keyboard support and customization
68
105
  - **Automatic Integration**: All features automatically enabled in QwickApp without configuration
69
106
 
107
+ ### 📄 **Serializable Page System with Advanced Print Support**
108
+ - **Schema-Driven Architecture**: Complete page templates with ViewModelSchema, PrintConfigSchema, and PageTemplateSchema for full serialization
109
+ - **Intelligent Print Detection**: Automatic print mode activation via browser events (Ctrl+P/Cmd+P) with comprehensive state management
110
+ - **Advanced Print Configuration**: Complete print theming system with headers, footers, backgrounds, page margins (0mm-25mm), and CSS variable-driven positioning
111
+ - **Dynamic Print Layout**: Edge-to-edge printing capabilities with configurable page margins, automatic height measurement, and proper page break handling
112
+ - **Print Content Control**: ReactNode | string support for headers/footers, background image/color support, and interactive element hiding
113
+ - **Template-Driven Development**: JSON-serializable page configurations with metadata, SEO optimization, and complete customization
114
+ - **CMS-Ready Integration**: Dynamic page content through dataSource with seamless database and headless CMS connectivity
115
+ - **Page Context System**: Automatic QwickApp scaffolding integration with print-aware navigation and routing
116
+
70
117
  ### 🚀 **Developer Experience**
71
118
  - **TypeScript First**: Full TypeScript support with comprehensive types
72
119
  - **Storybook**: Interactive component documentation
@@ -99,7 +146,8 @@ import {
99
146
  ResponsiveMenu,
100
147
  HeroBlock,
101
148
  Section,
102
- Content
149
+ Content,
150
+ ComponentTransformer
103
151
  } from '@qwickapps/react-framework';
104
152
 
105
153
  const menuItems = [
@@ -567,6 +615,1633 @@ Both components provide comprehensive error handling:
567
615
  </Html>
568
616
  ```
569
617
 
618
+ ## Serializable Page System
619
+
620
+ The QwickApps React Framework includes a sophisticated Page System that enables serializable page templates with comprehensive print support, intelligent print detection, and seamless CMS integration through a schema-driven architecture.
621
+
622
+ ### Core Page System Features
623
+
624
+ #### 🎯 **Schema-Driven Architecture**
625
+ - **ViewModelSchema**: Base schema with common UI attributes (styling, accessibility, layout)
626
+ - **PrintConfigSchema**: Complete print mode configuration with theming and optimization
627
+ - **PageTemplateSchema**: Full page models extending ViewModel with metadata, SEO, and print settings
628
+ - **JSON Serialization**: Complete page configurations stored and transmitted as JSON
629
+
630
+ #### 🖨️ **Intelligent Print Detection**
631
+ - **Automatic URL Detection**: `?print=true` parameter triggers print mode instantly
632
+ - **Browser Event Integration**: Captures Ctrl+P and print menu events automatically
633
+ - **Manual Control**: Programmatic print mode activation with custom configurations
634
+ - **Scaffolding Awareness**: Automatically hides navigation and headers in print mode
635
+
636
+ #### 📊 **CMS Integration Ready**
637
+ - **Database Storage**: Store complete page templates as JSON in any database
638
+ - **Headless CMS**: Direct integration with Strapi, Contentful, Sanity, and custom APIs
639
+ - **Dynamic Loading**: Fetch page templates at runtime with fallback handling
640
+ - **Version Control**: Schema versioning for backward compatibility and migrations
641
+
642
+ ### Page Component Usage
643
+
644
+ #### Basic Page Implementation
645
+ ```tsx
646
+ import { Page, usePrintMode, PageTemplateSchema } from '@qwickapps/react-framework';
647
+
648
+ // Simple page with props
649
+ function HomePage() {
650
+ return (
651
+ <Page
652
+ title="Welcome to Our App"
653
+ description="Experience the best of our platform"
654
+ variant="default"
655
+ padding="large"
656
+ printConfig={{
657
+ theme: 'light',
658
+ hideScaffolding: true,
659
+ showPrintDate: true
660
+ }}
661
+ >
662
+ <h1>Welcome!</h1>
663
+ <p>Your page content here...</p>
664
+ </Page>
665
+ );
666
+ }
667
+
668
+ // Schema-driven page with complete serialization
669
+ const pageTemplate: PageTemplateSchema = {
670
+ slug: "about-us",
671
+ name: "About Us",
672
+ title: "About Our Company | MyApp",
673
+ description: "Learn more about our company history and values",
674
+ metaKeywords: "company, about, history, values, team",
675
+ metaAuthor: "Company Team",
676
+ children: `
677
+ <h1>About Our Company</h1>
678
+ <p>Founded in 2020, we are dedicated to creating amazing experiences...</p>
679
+ <section class="team">
680
+ <h2>Our Team</h2>
681
+ <p>Meet the people behind our success...</p>
682
+ </section>
683
+ `,
684
+ printConfig: {
685
+ theme: "light",
686
+ hideScaffolding: true,
687
+ hideInteractiveElements: true,
688
+ optimizeForMonochrome: true,
689
+ printTitle: "Company Overview - About Us",
690
+ printHeader: "Company Information",
691
+ printFooter: "© 2025 Our Company • Confidential",
692
+ showPrintDate: true
693
+ },
694
+ showInNavigation: true,
695
+ navigationPriority: 2,
696
+ indexable: true
697
+ };
698
+
699
+ function AboutPage() {
700
+ return <Page template={pageTemplate} />;
701
+ }
702
+ ```
703
+
704
+ ### Schema Architecture
705
+
706
+ #### ViewModelSchema - Base UI Schema
707
+ ```tsx
708
+ import { ViewModelSchema } from '@qwickapps/react-framework';
709
+
710
+ // Base schema for all UI components - provides consistent styling and accessibility
711
+ interface ViewModelSchema {
712
+ // Styling Properties
713
+ className?: string; // CSS class name for custom styling
714
+ style?: string; // Inline styles as JSON string
715
+ id?: string; // Unique HTML element ID
716
+ hidden?: boolean; // Component visibility control
717
+
718
+ // Accessibility Properties
719
+ 'aria-label'?: string; // Accessibility label for screen readers
720
+ 'aria-describedby'?: string; // IDs of elements describing this component
721
+ 'aria-labelledby'?: string; // IDs of elements labeling this component
722
+ role?: string; // ARIA role (button, navigation, main, etc.)
723
+
724
+ // Testing Properties
725
+ 'data-testid'?: string; // Test automation identifier
726
+ }
727
+
728
+ // Example: Custom component extending ViewModelSchema
729
+ class CustomCard extends ViewModelSchema {
730
+ @Field()
731
+ title?: string;
732
+
733
+ @Field()
734
+ content?: string;
735
+
736
+ // Inherits all styling and accessibility properties from ViewModelSchema
737
+ }
738
+ ```
739
+
740
+ #### PrintConfigSchema - Print Configuration
741
+ ```tsx
742
+ import { PrintConfigSchema } from '@qwickapps/react-framework';
743
+
744
+ interface PrintConfigSchema {
745
+ // Theme & Appearance
746
+ theme?: 'light' | 'dark'; // Print theme mode
747
+ palette?: string; // Color palette (default, autumn, cosmic, etc.)
748
+ optimizeForMonochrome?: boolean; // Black & white print optimization
749
+
750
+ // Layout Control
751
+ hideScaffolding?: boolean; // Hide navigation, headers, footers
752
+ hideInteractiveElements?: boolean; // Hide buttons, forms, interactive content
753
+
754
+ // Print Metadata
755
+ printTitle?: string; // Custom title for print header
756
+ printHeader?: string; // Custom header text
757
+ printFooter?: string; // Custom footer text
758
+ showPrintDate?: boolean; // Include print timestamp
759
+ }
760
+
761
+ // Advanced print configuration examples
762
+ const reportPrintConfig: PrintConfigSchema = {
763
+ theme: 'light',
764
+ palette: 'default',
765
+ hideScaffolding: true,
766
+ hideInteractiveElements: true,
767
+ optimizeForMonochrome: true,
768
+ printTitle: 'Quarterly Sales Report - Q4 2024',
769
+ printHeader: 'CONFIDENTIAL - Internal Use Only',
770
+ printFooter: 'Page [page] of [total] • Generated on [date] • QwickApps.com',
771
+ showPrintDate: true
772
+ };
773
+
774
+ const invoicePrintConfig: PrintConfigSchema = {
775
+ theme: 'light',
776
+ hideScaffolding: true,
777
+ hideInteractiveElements: true,
778
+ printTitle: 'Invoice #INV-2024-001',
779
+ printFooter: 'Thank you for your business!',
780
+ showPrintDate: false // Don't show print date on invoices
781
+ };
782
+ ```
783
+
784
+ #### PageTemplateSchema - Complete Page Model
785
+ ```tsx
786
+ import { PageTemplateSchema, PrintConfigSchema } from '@qwickapps/react-framework';
787
+
788
+ interface PageTemplateSchema extends ViewModelSchema {
789
+ // Page Identity & Navigation
790
+ slug?: string; // URL-friendly identifier (e.g., "about-us")
791
+ name?: string; // Human-readable page name
792
+ icon?: string; // Page icon for navigation
793
+
794
+ // SEO & Metadata
795
+ title?: string; // HTML title tag content
796
+ description?: string; // Meta description for search engines
797
+ metaKeywords?: string; // SEO keywords (comma-separated)
798
+ metaAuthor?: string; // Page author information
799
+ canonicalUrl?: string; // Canonical URL for SEO
800
+ indexable?: boolean; // Allow search engine indexing
801
+
802
+ // Content & Layout
803
+ children?: React.ReactNode | string; // Page content (JSX or HTML string)
804
+ layout?: string; // Layout template identifier
805
+
806
+ // Print Configuration
807
+ printConfig?: PrintConfigSchema; // Print mode settings
808
+
809
+ // Access Control
810
+ requiresAuth?: boolean; // Authentication required
811
+ requiredRoles?: string; // Required user roles (comma-separated)
812
+
813
+ // Navigation Control
814
+ showInNavigation?: boolean; // Include in navigation menus
815
+ navigationPriority?: number; // Menu ordering (lower = higher priority)
816
+ }
817
+
818
+ // Complete page template examples
819
+ const productPageTemplate: PageTemplateSchema = {
820
+ // Identity
821
+ slug: "premium-widgets",
822
+ name: "Premium Widgets",
823
+ icon: "widgets",
824
+
825
+ // SEO
826
+ title: "Premium Widgets - Best Quality Widgets | Our Store",
827
+ description: "Discover our premium widget collection with superior quality and innovative designs.",
828
+ metaKeywords: "widgets, premium, quality, innovative, store",
829
+ metaAuthor: "Product Team",
830
+ canonicalUrl: "https://ourstore.com/products/premium-widgets",
831
+ indexable: true,
832
+
833
+ // Content (can be HTML string or React components)
834
+ children: `
835
+ <div class="product-page">
836
+ <h1>Premium Widgets</h1>
837
+ <div class="product-gallery">
838
+ <!-- Product images would go here -->
839
+ </div>
840
+ <div class="product-details">
841
+ <h2>Product Features</h2>
842
+ <ul>
843
+ <li>Superior build quality</li>
844
+ <li>Innovative design</li>
845
+ <li>5-year warranty</li>
846
+ </ul>
847
+ </div>
848
+ <div class="product-actions">
849
+ <button class="btn-primary">Add to Cart</button>
850
+ <button class="btn-secondary">Add to Wishlist</button>
851
+ </div>
852
+ </div>
853
+ `,
854
+
855
+ // Print configuration for product pages
856
+ printConfig: {
857
+ theme: 'light',
858
+ hideScaffolding: true,
859
+ hideInteractiveElements: true, // Hide Add to Cart buttons when printing
860
+ printTitle: 'Premium Widgets - Product Information',
861
+ printFooter: 'Visit ourstore.com for latest pricing and availability',
862
+ showPrintDate: true
863
+ },
864
+
865
+ // Navigation
866
+ showInNavigation: true,
867
+ navigationPriority: 5,
868
+
869
+ // Access (no authentication required for product pages)
870
+ requiresAuth: false
871
+ };
872
+
873
+ const adminDashboardTemplate: PageTemplateSchema = {
874
+ slug: "admin-dashboard",
875
+ name: "Admin Dashboard",
876
+ title: "Administrator Dashboard | Our App",
877
+ description: "Administrative dashboard with user management and analytics",
878
+
879
+ // Restricted content
880
+ requiresAuth: true,
881
+ requiredRoles: "admin,superuser",
882
+ showInNavigation: true,
883
+ navigationPriority: 1,
884
+ indexable: false, // Don't index admin pages
885
+
886
+ // Admin-specific print configuration
887
+ printConfig: {
888
+ theme: 'light',
889
+ hideScaffolding: true,
890
+ printTitle: 'Administrator Dashboard Report',
891
+ printHeader: 'CONFIDENTIAL - Administrative Data',
892
+ showPrintDate: true,
893
+ optimizeForMonochrome: true
894
+ }
895
+ };
896
+ ```
897
+
898
+ ### Print Mode Integration
899
+
900
+ #### usePrintMode Hook - Comprehensive Print Control
901
+ ```tsx
902
+ import { usePrintMode } from '@qwickapps/react-framework';
903
+
904
+ function DocumentPage() {
905
+ const {
906
+ isPrintMode,
907
+ printConfig,
908
+ enterPrintMode,
909
+ exitPrintMode,
910
+ togglePrintMode
911
+ } = usePrintMode({
912
+ theme: 'light',
913
+ hideScaffolding: true,
914
+ showPrintDate: true,
915
+ printTitle: 'Important Document',
916
+ optimizeForMonochrome: false
917
+ });
918
+
919
+ // Print mode is automatically detected from:
920
+ // 1. URL parameter: ?print=true
921
+ // 2. Browser print events (Ctrl+P, File > Print)
922
+ // 3. Manual activation via the functions below
923
+
924
+ const handleCustomPrint = () => {
925
+ // Enter print mode with custom configuration
926
+ enterPrintMode({
927
+ theme: 'light',
928
+ hideInteractiveElements: true,
929
+ printTitle: 'Custom Print Title',
930
+ printHeader: 'CONFIDENTIAL',
931
+ optimizeForMonochrome: true
932
+ });
933
+
934
+ // Trigger browser print dialog
935
+ setTimeout(() => window.print(), 100);
936
+ };
937
+
938
+ return (
939
+ <div>
940
+ {/* Print mode indicator */}
941
+ {isPrintMode && (
942
+ <div className="print-mode-banner">
943
+ <span>📄 Print Mode Active</span>
944
+ <span>Theme: {printConfig.theme}</span>
945
+ <span>Monochrome: {printConfig.optimizeForMonochrome ? 'Yes' : 'No'}</span>
946
+ </div>
947
+ )}
948
+
949
+ {/* Print controls (hidden in print mode) */}
950
+ {!isPrintMode && (
951
+ <div className="print-controls">
952
+ <button onClick={() => togglePrintMode()}>
953
+ Toggle Print Mode
954
+ </button>
955
+ <button onClick={handleCustomPrint}>
956
+ Print Document
957
+ </button>
958
+ <button onClick={() => {
959
+ enterPrintMode({ optimizeForMonochrome: true });
960
+ }}>
961
+ Print in B&W
962
+ </button>
963
+ </div>
964
+ )}
965
+
966
+ {/* Page content */}
967
+ <main>
968
+ <h1>Document Title</h1>
969
+ <p>Your document content here...</p>
970
+ </main>
971
+ </div>
972
+ );
973
+ }
974
+ ```
975
+
976
+ #### Print URL Integration
977
+ ```tsx
978
+ // Automatic print mode via URL
979
+ // Navigate to: https://yourapp.com/document?print=true
980
+
981
+ function App() {
982
+ return (
983
+ <Router>
984
+ <Routes>
985
+ <Route path="/document" element={
986
+ <Page
987
+ title="Document"
988
+ printConfig={{
989
+ hideScaffolding: true,
990
+ showPrintDate: true,
991
+ printTitle: 'Important Document'
992
+ }}
993
+ >
994
+ <DocumentContent />
995
+ </Page>
996
+ } />
997
+ </Routes>
998
+ </Router>
999
+ );
1000
+ }
1001
+
1002
+ // The Page component automatically detects ?print=true and activates print mode
1003
+ ```
1004
+
1005
+ ### CMS and Database Integration
1006
+
1007
+ #### Dynamic Page Loading from CMS
1008
+ ```tsx
1009
+ import { Page, PageTemplateSchema } from '@qwickapps/react-framework';
1010
+
1011
+ // Headless CMS integration example
1012
+ function CMSPage({ pageSlug }: { pageSlug: string }) {
1013
+ const [pageTemplate, setPageTemplate] = useState<PageTemplateSchema | null>(null);
1014
+ const [loading, setLoading] = useState(true);
1015
+ const [error, setError] = useState<string | null>(null);
1016
+
1017
+ useEffect(() => {
1018
+ // Fetch page template from CMS
1019
+ fetchPageFromCMS(pageSlug)
1020
+ .then(template => {
1021
+ setPageTemplate(template);
1022
+ setLoading(false);
1023
+ })
1024
+ .catch(err => {
1025
+ setError(err.message);
1026
+ setLoading(false);
1027
+ });
1028
+ }, [pageSlug]);
1029
+
1030
+ // Loading state
1031
+ if (loading) {
1032
+ return (
1033
+ <Page title="Loading..." loading={{ type: 'spinner', message: 'Loading page...' }}>
1034
+ <div>Loading page content...</div>
1035
+ </Page>
1036
+ );
1037
+ }
1038
+
1039
+ // Error state
1040
+ if (error) {
1041
+ return (
1042
+ <Page
1043
+ title="Error"
1044
+ message={{ type: 'error', content: `Failed to load page: ${error}` }}
1045
+ >
1046
+ <div>Page could not be loaded</div>
1047
+ </Page>
1048
+ );
1049
+ }
1050
+
1051
+ // Render page from CMS template
1052
+ return pageTemplate ? (
1053
+ <Page template={pageTemplate} />
1054
+ ) : (
1055
+ <Page title="Not Found" message={{ type: 'warning', content: 'Page not found' }}>
1056
+ <h1>Page Not Found</h1>
1057
+ <p>The requested page could not be found.</p>
1058
+ </Page>
1059
+ );
1060
+ }
1061
+
1062
+ // CMS API integration function
1063
+ async function fetchPageFromCMS(slug: string): Promise<PageTemplateSchema> {
1064
+ // Example: Strapi CMS integration
1065
+ const response = await fetch(`/api/pages?filters[slug][$eq]=${slug}&populate=*`);
1066
+ if (!response.ok) {
1067
+ throw new Error('Page not found');
1068
+ }
1069
+
1070
+ const { data } = await response.json();
1071
+ if (!data.length) {
1072
+ throw new Error('Page not found');
1073
+ }
1074
+
1075
+ const cmsPage = data[0].attributes;
1076
+
1077
+ // Transform CMS data to PageTemplateSchema
1078
+ const pageTemplate: PageTemplateSchema = {
1079
+ slug: cmsPage.slug,
1080
+ name: cmsPage.name,
1081
+ title: cmsPage.seoTitle || cmsPage.name,
1082
+ description: cmsPage.seoDescription,
1083
+ metaKeywords: cmsPage.metaKeywords,
1084
+ metaAuthor: cmsPage.author?.name,
1085
+ children: cmsPage.content,
1086
+ printConfig: {
1087
+ theme: cmsPage.printTheme || 'light',
1088
+ hideScaffolding: cmsPage.printHideNavigation ?? true,
1089
+ showPrintDate: cmsPage.printShowDate ?? true,
1090
+ printTitle: cmsPage.printTitle || cmsPage.name
1091
+ },
1092
+ showInNavigation: cmsPage.showInMenu ?? true,
1093
+ navigationPriority: cmsPage.menuOrder || 0,
1094
+ requiresAuth: cmsPage.requiresAuthentication ?? false,
1095
+ indexable: cmsPage.seoIndexable ?? true
1096
+ };
1097
+
1098
+ return pageTemplate;
1099
+ }
1100
+ ```
1101
+
1102
+ #### Database Storage Example
1103
+ ```tsx
1104
+ // Example: Storing page templates in database
1105
+ const pageTemplates = [
1106
+ {
1107
+ id: 1,
1108
+ template: JSON.stringify({
1109
+ slug: "home",
1110
+ name: "Home",
1111
+ title: "Welcome to Our App | Home",
1112
+ description: "Experience the best of our platform",
1113
+ children: "<h1>Welcome!</h1><p>Get started with our amazing features...</p>",
1114
+ printConfig: {
1115
+ theme: "light",
1116
+ hideScaffolding: true,
1117
+ showPrintDate: true
1118
+ }
1119
+ } as PageTemplateSchema)
1120
+ },
1121
+ // More templates...
1122
+ ];
1123
+
1124
+ // Loading page from database
1125
+ function DatabasePage({ pageId }: { pageId: number }) {
1126
+ const [template, setTemplate] = useState<PageTemplateSchema | null>(null);
1127
+
1128
+ useEffect(() => {
1129
+ // Simulate database fetch
1130
+ const dbPage = pageTemplates.find(p => p.id === pageId);
1131
+ if (dbPage) {
1132
+ setTemplate(JSON.parse(dbPage.template));
1133
+ }
1134
+ }, [pageId]);
1135
+
1136
+ return template ? <Page template={template} /> : <div>Loading...</div>;
1137
+ }
1138
+ ```
1139
+
1140
+ ### Page Context and Lifecycle
1141
+
1142
+ #### Advanced Page Context Usage
1143
+ ```tsx
1144
+ import { usePageContext, usePage } from '@qwickapps/react-framework';
1145
+
1146
+ function PageAwareComponent() {
1147
+ const { route, isPrintMode, printConfig } = usePageContext();
1148
+ const { setTitle, setDescription } = usePage();
1149
+
1150
+ useEffect(() => {
1151
+ // Dynamic page metadata updates
1152
+ setTitle(`Dynamic Title - ${Date.now()}`);
1153
+ setDescription('Dynamically updated description');
1154
+ }, []);
1155
+
1156
+ // Render differently based on print mode
1157
+ if (isPrintMode) {
1158
+ return (
1159
+ <div className="print-optimized">
1160
+ <h2>Print-Optimized View</h2>
1161
+ <p>Current route: {route}</p>
1162
+ <p>Print theme: {printConfig.theme}</p>
1163
+ <p>Print date shown: {printConfig.showPrintDate ? 'Yes' : 'No'}</p>
1164
+ {/* Simplified content for printing */}
1165
+ </div>
1166
+ );
1167
+ }
1168
+
1169
+ return (
1170
+ <div className="interactive-view">
1171
+ <h2>Interactive View</h2>
1172
+ <p>Route: {route}</p>
1173
+ <button onClick={() => alert('Interactive element')}>
1174
+ Click me
1175
+ </button>
1176
+ {/* Full interactive content */}
1177
+ </div>
1178
+ );
1179
+ }
1180
+ ```
1181
+
1182
+ ### Page Variants and Layout Options
1183
+
1184
+ #### Advanced Page Styling
1185
+ ```tsx
1186
+ // Different page layout variants for different use cases
1187
+ function LayoutExamples() {
1188
+ return (
1189
+ <>
1190
+ {/* Centered layout for landing pages */}
1191
+ <Page
1192
+ variant="centered"
1193
+ padding="large"
1194
+ maxWidth="medium"
1195
+ background="default"
1196
+ title="Landing Page"
1197
+ >
1198
+ <h1>Welcome to Our App</h1>
1199
+ <p>Centered content with medium width</p>
1200
+ </Page>
1201
+
1202
+ {/* Full width for dashboards */}
1203
+ <Page
1204
+ variant="fullwidth"
1205
+ padding="small"
1206
+ background="surface"
1207
+ title="Dashboard"
1208
+ >
1209
+ <div className="dashboard-grid">
1210
+ {/* Dashboard widgets */}
1211
+ </div>
1212
+ </Page>
1213
+
1214
+ {/* Narrow layout for articles/blogs */}
1215
+ <Page
1216
+ variant="narrow"
1217
+ padding="large"
1218
+ background="default"
1219
+ title="Blog Article"
1220
+ printConfig={{
1221
+ hideScaffolding: true,
1222
+ optimizeForMonochrome: true,
1223
+ printTitle: 'Article Title'
1224
+ }}
1225
+ >
1226
+ <article>
1227
+ <h1>Article Title</h1>
1228
+ <p>Narrow layout optimized for reading...</p>
1229
+ </article>
1230
+ </Page>
1231
+
1232
+ {/* Wide layout for data tables */}
1233
+ <Page
1234
+ variant="wide"
1235
+ padding="medium"
1236
+ background="surface"
1237
+ title="Data Tables"
1238
+ >
1239
+ <table className="data-table">
1240
+ {/* Wide table content */}
1241
+ </table>
1242
+ </Page>
1243
+ </>
1244
+ );
1245
+ }
1246
+ ```
1247
+
1248
+ ## Advanced Print System
1249
+
1250
+ The QwickApps React Framework includes a sophisticated print system that enables professional print layouts with intelligent detection, dynamic configuration, and comprehensive theming support.
1251
+
1252
+ ### Print Mode Detection
1253
+
1254
+ The print system automatically detects print mode through multiple channels:
1255
+
1256
+ #### URL Parameter Detection
1257
+ ```tsx
1258
+ // Navigate to URL with print parameter to automatically enter print mode
1259
+ https://yourapp.com/document?print=true
1260
+
1261
+ // Print mode activates immediately with configured settings
1262
+ ```
1263
+
1264
+ #### Browser Print Event Detection
1265
+ ```tsx
1266
+ // Automatic detection of Ctrl+P (Windows/Linux) or Cmd+P (Mac)
1267
+ // Also detects File > Print menu usage
1268
+ // Print mode applies before print dialog opens
1269
+ ```
1270
+
1271
+ #### Manual Print Mode Control
1272
+ ```tsx
1273
+ import { usePrintMode } from '@qwickapps/react-framework';
1274
+
1275
+ function DocumentPage() {
1276
+ const {
1277
+ isPrintMode,
1278
+ printConfig,
1279
+ enterPrintMode,
1280
+ exitPrintMode,
1281
+ togglePrintMode,
1282
+ triggerPrint
1283
+ } = usePrintMode();
1284
+
1285
+ const handlePrint = () => {
1286
+ // Enter print mode with custom configuration
1287
+ triggerPrint({
1288
+ theme: 'light',
1289
+ hideScaffolding: true,
1290
+ showPrintDate: true,
1291
+ printTitle: 'Custom Document Title'
1292
+ });
1293
+
1294
+ // Trigger browser print dialog
1295
+ setTimeout(() => window.print(), 100);
1296
+ };
1297
+
1298
+ return (
1299
+ <div>
1300
+ {isPrintMode ? (
1301
+ <div className="print-mode-banner">
1302
+ Print Mode Active - {printConfig.theme} theme
1303
+ </div>
1304
+ ) : (
1305
+ <button onClick={handlePrint}>Print Document</button>
1306
+ )}
1307
+
1308
+ <main>
1309
+ <h1>Document Content</h1>
1310
+ <p>Your document content here...</p>
1311
+ </main>
1312
+ </div>
1313
+ );
1314
+ }
1315
+ ```
1316
+
1317
+ ### Print Configuration System
1318
+
1319
+ #### Complete Print Configuration Options
1320
+ ```tsx
1321
+ import { PrintConfigSchema } from '@qwickapps/react-framework';
1322
+
1323
+ const advancedPrintConfig: PrintConfigSchema = {
1324
+ // Theme Control
1325
+ theme: 'light' | 'dark', // Print theme mode
1326
+ palette: 'default' | 'autumn' | 'cosmic', // Color palette
1327
+ optimizeForMonochrome: true, // B&W optimization
1328
+
1329
+ // Layout Control
1330
+ hideScaffolding: true, // Hide navigation/headers
1331
+ hideInteractiveElements: true, // Hide buttons/forms
1332
+ pageMargins: '12mm', // 0mm, 6mm, 12mm, 20mm, 25mm
1333
+
1334
+ // Custom Headers & Footers
1335
+ printTitle: 'Quarterly Report - Q4 2024', // Custom document title
1336
+ printHeader: '<div>CONFIDENTIAL</div>', // Custom header content
1337
+ printFooter: 'Page [page] of [total]', // Custom footer content
1338
+ printHeaderFirstPage: '<div>Cover Page</div>', // Different first page header
1339
+ printFooterFirstPage: 'Generated: [date]', // Different first page footer
1340
+
1341
+ // Background & Styling
1342
+ printBackground: 'linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%)',
1343
+ printBackgroundFirstPage: 'url(/logo-watermark.png) center, #ffffff',
1344
+
1345
+ // Header/Footer Sizing
1346
+ printHeaderHeight: '60px', // CSS units (px, mm, etc.)
1347
+ printFooterHeight: '40px', // CSS units (px, mm, etc.)
1348
+
1349
+ // Metadata
1350
+ showPrintDate: true // Include print timestamp
1351
+ };
1352
+ ```
1353
+
1354
+ #### Page Component with Print Configuration
1355
+ ```tsx
1356
+ import { Page, PrintConfigSchema } from '@qwickapps/react-framework';
1357
+
1358
+ // Using Page component with print configuration
1359
+ function ReportPage() {
1360
+ const printConfig: Partial<PrintConfigSchema> = {
1361
+ theme: 'light',
1362
+ hideScaffolding: true,
1363
+ hideInteractiveElements: true,
1364
+ optimizeForMonochrome: true,
1365
+ printTitle: 'Annual Sales Report',
1366
+ printHeader: 'CONFIDENTIAL - Internal Use Only',
1367
+ printFooter: 'Company © 2024 • Generated on [date]',
1368
+ pageMargins: '20mm',
1369
+ showPrintDate: true
1370
+ };
1371
+
1372
+ return (
1373
+ <Page
1374
+ title="Annual Sales Report"
1375
+ description="Comprehensive sales analysis for fiscal year"
1376
+ printConfig={printConfig}
1377
+ >
1378
+ <h1>Annual Sales Report</h1>
1379
+ <div className="report-content">
1380
+ {/* Report content */}
1381
+ </div>
1382
+ </Page>
1383
+ );
1384
+ }
1385
+ ```
1386
+
1387
+ ### Page Margins and Layout Options
1388
+
1389
+ #### Edge-to-Edge Printing (0mm margins)
1390
+ ```tsx
1391
+ const borderlessPrintConfig = {
1392
+ pageMargins: '0mm', // Complete edge-to-edge printing
1393
+ printBackground: '#f0f0f0' // Background covers entire page
1394
+ };
1395
+ ```
1396
+
1397
+ #### Standard Margin Options
1398
+ ```tsx
1399
+ const marginOptions = {
1400
+ compact: { pageMargins: '6mm' }, // Minimal margins
1401
+ standard: { pageMargins: '12mm' }, // Standard business documents
1402
+ large: { pageMargins: '20mm' }, // Formal documents
1403
+ formal: { pageMargins: '25mm' } // Academic/legal documents
1404
+ };
1405
+ ```
1406
+
1407
+ ### Dynamic CSS Variable System
1408
+
1409
+ The print system uses CSS variables for dynamic header/footer positioning:
1410
+
1411
+ ```css
1412
+ /* Automatically generated during print mode */
1413
+ @media print {
1414
+ .page-print-mode {
1415
+ --print-header-height: 60px; /* Measured or configured */
1416
+ --print-footer-height: 40px; /* Measured or configured */
1417
+ --print-background: transparent; /* Configured background */
1418
+ }
1419
+ }
1420
+
1421
+ /* Use in your custom print styles */
1422
+ .custom-print-content {
1423
+ margin-top: var(--print-header-height);
1424
+ margin-bottom: var(--print-footer-height);
1425
+ background: var(--print-background);
1426
+ }
1427
+ ```
1428
+
1429
+ ### Advanced Print Headers and Footers
1430
+
1431
+ #### ReactNode Headers/Footers
1432
+ ```tsx
1433
+ import { SafeSpan } from '@qwickapps/react-framework';
1434
+
1435
+ const customPrintConfig = {
1436
+ // React component header
1437
+ printHeader: (
1438
+ <div style={{ textAlign: 'center', fontWeight: 'bold' }}>
1439
+ <h2>Company Annual Report</h2>
1440
+ <p>Confidential - Internal Use Only</p>
1441
+ </div>
1442
+ ),
1443
+
1444
+ // HTML string footer
1445
+ printFooter: `
1446
+ <div style="display: flex; justify-content: space-between;">
1447
+ <span>© 2024 Company Name</span>
1448
+ <span>Page [page] of [total]</span>
1449
+ <span>Generated: ${new Date().toLocaleDateString()}</span>
1450
+ </div>
1451
+ `,
1452
+
1453
+ // Different first page header
1454
+ printHeaderFirstPage: (
1455
+ <div className="cover-page-header">
1456
+ <img src="/company-logo.png" alt="Company Logo" />
1457
+ <h1>Annual Report 2024</h1>
1458
+ </div>
1459
+ )
1460
+ };
1461
+ ```
1462
+
1463
+ #### Template Variables in Headers/Footers
1464
+ ```tsx
1465
+ const templatePrintConfig = {
1466
+ printFooter: 'Page [page] of [total] • Generated on [date] • company.com',
1467
+ printHeader: 'Document: [title] • Department: [department] • Classification: [level]'
1468
+ };
1469
+
1470
+ // Template variables are automatically replaced:
1471
+ // [page] → Current page number
1472
+ // [total] → Total page count
1473
+ // [date] → Current date/time
1474
+ // [title] → Document title
1475
+ // Custom variables from page context
1476
+ ```
1477
+
1478
+ ### Print-Specific Page Variants
1479
+
1480
+ #### Different Layout Variants for Print
1481
+ ```tsx
1482
+ function DocumentPage() {
1483
+ return (
1484
+ <Page
1485
+ variant="narrow" // Optimized for reading
1486
+ padding="large"
1487
+ background="default"
1488
+ printConfig={{
1489
+ hideScaffolding: true,
1490
+ optimizeForMonochrome: true,
1491
+ printTitle: 'Article Title'
1492
+ }}
1493
+ >
1494
+ <article>
1495
+ <h1>Article Title</h1>
1496
+ <p>Content optimized for print...</p>
1497
+ </article>
1498
+ </Page>
1499
+ );
1500
+ }
1501
+
1502
+ // Wide layout for tables and data
1503
+ function DataTablePage() {
1504
+ return (
1505
+ <Page
1506
+ variant="wide"
1507
+ padding="small"
1508
+ printConfig={{
1509
+ pageMargins: '6mm', // Minimize margins for tables
1510
+ hideScaffolding: true,
1511
+ printTitle: 'Data Report'
1512
+ }}
1513
+ >
1514
+ <table className="data-table">
1515
+ {/* Wide table content */}
1516
+ </table>
1517
+ </Page>
1518
+ );
1519
+ }
1520
+ ```
1521
+
1522
+ ### Integration with Page Templates
1523
+
1524
+ #### Schema-Driven Print Configuration
1525
+ ```tsx
1526
+ import { PageTemplateSchema } from '@qwickapps/react-framework';
1527
+
1528
+ const pageTemplate: PageTemplateSchema = {
1529
+ slug: "financial-report",
1530
+ name: "Financial Report",
1531
+ title: "Q4 Financial Report | Company",
1532
+ description: "Quarterly financial analysis and projections",
1533
+
1534
+ // Complete print configuration in schema
1535
+ printConfig: {
1536
+ theme: "light",
1537
+ hideScaffolding: true,
1538
+ hideInteractiveElements: true,
1539
+ optimizeForMonochrome: true,
1540
+ printTitle: "Q4 2024 Financial Report",
1541
+ printHeader: "CONFIDENTIAL - Financial Department",
1542
+ printFooter: "© 2024 Company • Internal Use Only",
1543
+ pageMargins: "20mm",
1544
+ showPrintDate: true,
1545
+ printBackground: "linear-gradient(to bottom, #f8f9fa, #ffffff)"
1546
+ },
1547
+
1548
+ children: `
1549
+ <div class="financial-report">
1550
+ <h1>Q4 Financial Performance</h1>
1551
+ <section class="metrics">
1552
+ <!-- Financial content -->
1553
+ </section>
1554
+ </div>
1555
+ `
1556
+ };
1557
+
1558
+ // Use template-driven page
1559
+ function FinancialReportPage() {
1560
+ return <Page template={pageTemplate} />;
1561
+ }
1562
+ ```
1563
+
1564
+ ### Print Mode Context and State Management
1565
+
1566
+ #### Accessing Print State Throughout App
1567
+ ```tsx
1568
+ import { usePageContext } from '@qwickapps/react-framework';
1569
+
1570
+ function PrintAwareComponent() {
1571
+ const {
1572
+ isPrintMode,
1573
+ printConfig,
1574
+ triggerPrint
1575
+ } = usePageContext();
1576
+
1577
+ // Conditional rendering based on print mode
1578
+ if (isPrintMode) {
1579
+ return (
1580
+ <div className="print-optimized">
1581
+ <h2>Print-Optimized View</h2>
1582
+ <p>Simplified content for printing</p>
1583
+ <p>Theme: {printConfig.theme}</p>
1584
+ </div>
1585
+ );
1586
+ }
1587
+
1588
+ return (
1589
+ <div className="interactive-view">
1590
+ <h2>Interactive View</h2>
1591
+ <button onClick={() => triggerPrint({
1592
+ optimizeForMonochrome: true,
1593
+ printTitle: 'Custom Print Title'
1594
+ })}>
1595
+ Print This Page
1596
+ </button>
1597
+ </div>
1598
+ );
1599
+ }
1600
+ ```
1601
+
1602
+ ### Print CSS Classes and Styling
1603
+
1604
+ #### Automatic Print Mode Classes
1605
+ ```css
1606
+ /* Page automatically gets print mode classes */
1607
+ .page-print-mode {
1608
+ /* Applied when in print mode */
1609
+ }
1610
+
1611
+ .page-print-borderless {
1612
+ /* Applied when pageMargins: '0mm' */
1613
+ }
1614
+
1615
+ .page-print-compact {
1616
+ /* Applied when pageMargins: '6mm' */
1617
+ }
1618
+
1619
+ .page-print-large {
1620
+ /* Applied when pageMargins: '20mm' */
1621
+ }
1622
+
1623
+ .page-print-formal {
1624
+ /* Applied when pageMargins: '25mm' */
1625
+ }
1626
+
1627
+ .has-background {
1628
+ /* Applied when custom background is specified */
1629
+ }
1630
+ ```
1631
+
1632
+ #### Custom Print Styling
1633
+ ```css
1634
+ /* Print-specific component styling */
1635
+ @media print {
1636
+ .interactive-element {
1637
+ display: none !important; /* Hide interactive elements */
1638
+ }
1639
+
1640
+ .print-only {
1641
+ display: block !important; /* Show print-only content */
1642
+ }
1643
+
1644
+ .page-break-before {
1645
+ page-break-before: always; /* Force page breaks */
1646
+ }
1647
+
1648
+ .no-break {
1649
+ page-break-inside: avoid; /* Prevent breaking */
1650
+ }
1651
+ }
1652
+
1653
+ /* Print header/footer styling */
1654
+ .page-print-header {
1655
+ position: fixed;
1656
+ top: 0;
1657
+ left: 0;
1658
+ right: 0;
1659
+ height: var(--print-header-height);
1660
+ background: white;
1661
+ border-bottom: 1px solid #ddd;
1662
+ padding: 10px;
1663
+ box-sizing: border-box;
1664
+ }
1665
+
1666
+ .page-print-footer {
1667
+ position: fixed;
1668
+ bottom: 0;
1669
+ left: 0;
1670
+ right: 0;
1671
+ height: var(--print-footer-height);
1672
+ background: white;
1673
+ border-top: 1px solid #ddd;
1674
+ padding: 10px;
1675
+ box-sizing: border-box;
1676
+ }
1677
+ ```
1678
+
1679
+ ### Print System Best Practices
1680
+
1681
+ #### Performance Optimization
1682
+ ```tsx
1683
+ // Efficient print mode detection
1684
+ const { isPrintMode } = usePrintMode();
1685
+
1686
+ // Conditional loading of print-specific components
1687
+ const PrintableContent = lazy(() => import('./PrintableContent'));
1688
+
1689
+ // Memoized print configuration
1690
+ const printConfig = useMemo(() => ({
1691
+ theme: 'light',
1692
+ hideScaffolding: true,
1693
+ optimizeForMonochrome: true
1694
+ }), []);
1695
+ ```
1696
+
1697
+ #### Accessibility in Print Mode
1698
+ ```tsx
1699
+ const accessiblePrintConfig = {
1700
+ // High contrast for accessibility
1701
+ optimizeForMonochrome: true,
1702
+ theme: 'light',
1703
+
1704
+ // Clear headers for navigation
1705
+ printHeader: 'Document Title - Section Navigation',
1706
+
1707
+ // Informative footers
1708
+ printFooter: 'Page [page] of [total] - Contact: support@company.com'
1709
+ };
1710
+ ```
1711
+
1712
+ #### Multi-Page Document Handling
1713
+ ```tsx
1714
+ function MultiPageDocument() {
1715
+ return (
1716
+ <Page printConfig={{
1717
+ pageMargins: '20mm',
1718
+ printHeader: 'Multi-Page Report',
1719
+ printFooter: 'Page [page] of [total]',
1720
+ printBackground: 'white'
1721
+ }}>
1722
+ <section className="page-break-before">
1723
+ <h1>Chapter 1</h1>
1724
+ <p>Content that starts on a new page...</p>
1725
+ </section>
1726
+
1727
+ <section className="page-break-before">
1728
+ <h1>Chapter 2</h1>
1729
+ <p>Content that starts on another new page...</p>
1730
+ </section>
1731
+
1732
+ <div className="no-break">
1733
+ <h2>Important Section</h2>
1734
+ <p>Content that should not be split across pages...</p>
1735
+ </div>
1736
+ </Page>
1737
+ );
1738
+ }
1739
+ ```
1740
+
1741
+ ### Migration Guide
1742
+
1743
+ #### Converting Legacy Pages to New System
1744
+ ```tsx
1745
+ // BEFORE: Legacy page implementation
1746
+ function LegacyHomePage() {
1747
+ useEffect(() => {
1748
+ document.title = "Home | My App";
1749
+ }, []);
1750
+
1751
+ return (
1752
+ <div className="page-container">
1753
+ <div className="page-header">
1754
+ <h1>Welcome to My App</h1>
1755
+ </div>
1756
+ <div className="page-content">
1757
+ <p>Some content here...</p>
1758
+ </div>
1759
+ </div>
1760
+ );
1761
+ }
1762
+
1763
+ // AFTER: New Page system (Method 1: Props-based)
1764
+ function NewHomePage() {
1765
+ return (
1766
+ <Page
1767
+ title="Home | My App"
1768
+ description="Welcome to our application"
1769
+ variant="default"
1770
+ padding="medium"
1771
+ printConfig={{
1772
+ hideScaffolding: true,
1773
+ showPrintDate: true
1774
+ }}
1775
+ >
1776
+ <h1>Welcome to My App</h1>
1777
+ <p>Some content here...</p>
1778
+ </Page>
1779
+ );
1780
+ }
1781
+
1782
+ // AFTER: New Page system (Method 2: Template-based)
1783
+ const homePageTemplate: PageTemplateSchema = {
1784
+ slug: "home",
1785
+ name: "Home",
1786
+ title: "Home | My App",
1787
+ description: "Welcome to our application",
1788
+ children: `
1789
+ <h1>Welcome to My App</h1>
1790
+ <p>Some content here...</p>
1791
+ `,
1792
+ printConfig: {
1793
+ theme: 'light',
1794
+ hideScaffolding: true,
1795
+ showPrintDate: true
1796
+ },
1797
+ showInNavigation: true,
1798
+ navigationPriority: 0
1799
+ };
1800
+
1801
+ function TemplateHomePage() {
1802
+ return <Page template={homePageTemplate} />;
1803
+ }
1804
+
1805
+ // AFTER: CMS-integrated page
1806
+ function CMSHomePage() {
1807
+ return (
1808
+ <Page
1809
+ dataSource="api/pages/home"
1810
+ title="Home | My App" // Fallback if CMS data fails
1811
+ description="Welcome to our application"
1812
+ >
1813
+ {/* Fallback content */}
1814
+ <h1>Loading...</h1>
1815
+ </Page>
1816
+ );
1817
+ }
1818
+ ```
1819
+
1820
+ #### Print-Aware Migration
1821
+ ```tsx
1822
+ // BEFORE: Manual print handling
1823
+ function LegacyPrintablePage() {
1824
+ const [isPrinting, setIsPrinting] = useState(false);
1825
+
1826
+ useEffect(() => {
1827
+ const handleBeforePrint = () => setIsPrinting(true);
1828
+ const handleAfterPrint = () => setIsPrinting(false);
1829
+
1830
+ window.addEventListener('beforeprint', handleBeforePrint);
1831
+ window.addEventListener('afterprint', handleAfterPrint);
1832
+
1833
+ return () => {
1834
+ window.removeEventListener('beforeprint', handleBeforePrint);
1835
+ window.removeEventListener('afterprint', handleAfterPrint);
1836
+ };
1837
+ }, []);
1838
+
1839
+ return (
1840
+ <div className={isPrinting ? 'print-mode' : ''}>
1841
+ {!isPrinting && <nav>Navigation</nav>}
1842
+ <main>Content</main>
1843
+ </div>
1844
+ );
1845
+ }
1846
+
1847
+ // AFTER: Automatic print handling with Page system
1848
+ function NewPrintablePage() {
1849
+ return (
1850
+ <Page
1851
+ title="Printable Document"
1852
+ printConfig={{
1853
+ hideScaffolding: true, // Automatically hides navigation
1854
+ hideInteractiveElements: true, // Hides buttons when printing
1855
+ optimizeForMonochrome: true, // Optimizes for B&W printing
1856
+ printTitle: 'Important Document', // Custom print title
1857
+ showPrintDate: true // Shows print date
1858
+ }}
1859
+ >
1860
+ <main>Content</main>
1861
+ <button>Interactive Element</button> {/* Hidden in print mode */}
1862
+ </Page>
1863
+ );
1864
+ }
1865
+ ```
1866
+
1867
+ ### Best Practices
1868
+
1869
+ #### Page System Best Practices
1870
+ 1. **Use Templates for CMS**: Always use `PageTemplateSchema` for CMS-driven content
1871
+ 2. **Print Configuration**: Define print behavior early in development
1872
+ 3. **SEO Optimization**: Always include title, description, and metadata
1873
+ 4. **Accessibility**: Use proper heading hierarchy and ARIA attributes
1874
+ 5. **Performance**: Lazy load heavy content and optimize images for print
1875
+
1876
+ #### Schema Design Patterns
1877
+ ```tsx
1878
+ // Good: Comprehensive page template
1879
+ const wellDesignedTemplate: PageTemplateSchema = {
1880
+ // Clear identity
1881
+ slug: "user-guide",
1882
+ name: "User Guide",
1883
+
1884
+ // Complete SEO
1885
+ title: "User Guide - How to Use Our App | MyApp",
1886
+ description: "Comprehensive guide to using all features of MyApp effectively",
1887
+ metaKeywords: "user guide, tutorial, help, documentation",
1888
+ metaAuthor: "Documentation Team",
1889
+
1890
+ // Print-optimized
1891
+ printConfig: {
1892
+ theme: 'light',
1893
+ hideScaffolding: true,
1894
+ hideInteractiveElements: true,
1895
+ printTitle: 'User Guide v2.1',
1896
+ printFooter: 'For latest updates, visit myapp.com/guide',
1897
+ showPrintDate: true,
1898
+ optimizeForMonochrome: true
1899
+ },
1900
+
1901
+ // Proper navigation
1902
+ showInNavigation: true,
1903
+ navigationPriority: 3,
1904
+
1905
+ // No authentication needed for user guide
1906
+ requiresAuth: false,
1907
+ indexable: true
1908
+ };
1909
+ ```
1910
+
1911
+ ## Component Serialization System
1912
+
1913
+ The QwickApps React Framework includes a powerful Component Serialization System that enables "WebView for React" functionality. Components can be serialized to JSON, transmitted across boundaries, stored in databases or CMS systems, and reconstructed as fully functional React components.
1914
+
1915
+ ### Basic Serialization Usage
1916
+
1917
+ ```tsx
1918
+ import {
1919
+ ComponentTransformer,
1920
+ Code, Image, Text, HeroBlock, GridLayout, GridCell, Button,
1921
+ TextInputField, SelectInputField, HtmlInputField, ChoiceInputField, SwitchInputField, FormBlock
1922
+ } from '@qwickapps/react-framework';
1923
+
1924
+ // Create components
1925
+ const codeComponent = (
1926
+ <Code language="javascript" showCopy={true} title="example.js">
1927
+ const greeting = 'Hello, Serialization!';
1928
+ console.log(greeting);
1929
+ </Code>
1930
+ );
1931
+
1932
+ const imageComponent = (
1933
+ <Image
1934
+ src="/example.jpg"
1935
+ alt="Example image"
1936
+ width={400}
1937
+ height={300}
1938
+ responsive={true}
1939
+ loading="lazy"
1940
+ />
1941
+ );
1942
+
1943
+ const textComponent = (
1944
+ <Text
1945
+ variant="h2"
1946
+ color="primary"
1947
+ align="center"
1948
+ component="h1"
1949
+ gutterBottom={true}
1950
+ >
1951
+ Welcome to Component Serialization!
1952
+ </Text>
1953
+ );
1954
+
1955
+ // Complex component with nested elements
1956
+ const heroBlockComponent = (
1957
+ <HeroBlock
1958
+ title="Serializable Hero Section"
1959
+ subtitle="Full functionality preserved through JSON serialization"
1960
+ backgroundGradient="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
1961
+ height="medium"
1962
+ actions={[
1963
+ <Button key="primary" variant="contained" color="primary">Get Started</Button>,
1964
+ <Button key="secondary" variant="outlined" color="secondary">Learn More</Button>
1965
+ ]}
1966
+ />
1967
+ );
1968
+
1969
+ // Responsive grid layout with nested components
1970
+ const gridLayoutComponent = (
1971
+ <GridLayout columns={3} spacing="large" equalHeight responsive>
1972
+ <GridCell xs={12} sm={6} md={4} padding="medium">
1973
+ <Text variant="h3">Feature One</Text>
1974
+ <Text variant="body1">Description of the first feature</Text>
1975
+ </GridCell>
1976
+ <GridCell xs={12} sm={6} md={4} padding="medium">
1977
+ <Text variant="h3">Feature Two</Text>
1978
+ <Text variant="body1">Description of the second feature</Text>
1979
+ </GridCell>
1980
+ <GridCell xs={12} sm={12} md={4} padding="medium">
1981
+ <Text variant="h3">Feature Three</Text>
1982
+ <Text variant="body1">Description of the third feature</Text>
1983
+ </GridCell>
1984
+ </GridLayout>
1985
+ );
1986
+
1987
+ // Form components with state management
1988
+ const formComponent = (
1989
+ <FormBlock title="User Registration" status="active">
1990
+ <TextInputField
1991
+ value="John Doe"
1992
+ placeholder="Enter your name"
1993
+ required={true}
1994
+ validation={{ minLength: 2 }}
1995
+ />
1996
+ <SelectInputField
1997
+ value="admin"
1998
+ options={[
1999
+ { label: "Administrator", value: "admin" },
2000
+ { label: "User", value: "user" },
2001
+ { label: "Guest", value: "guest" }
2002
+ ]}
2003
+ required={true}
2004
+ />
2005
+ <HtmlInputField
2006
+ value="<p>Rich <strong>text</strong> content</p>"
2007
+ placeholder="Enter description"
2008
+ />
2009
+ <ChoiceInputField
2010
+ value={["option1", "option2"]}
2011
+ options={[
2012
+ { label: "Option 1", value: "option1" },
2013
+ { label: "Option 2", value: "option2" }
2014
+ ]}
2015
+ />
2016
+ <SwitchInputField
2017
+ value={true}
2018
+ label="Enable notifications"
2019
+ validation={{ required: true }}
2020
+ />
2021
+ </FormBlock>
2022
+ );
2023
+
2024
+ // Serialize to JSON string
2025
+ const serializedCode = ComponentTransformer.serialize(codeComponent);
2026
+ const serializedImage = ComponentTransformer.serialize(imageComponent);
2027
+ const serializedText = ComponentTransformer.serialize(textComponent);
2028
+ const serializedHero = ComponentTransformer.serialize(heroBlockComponent);
2029
+ const serializedGrid = ComponentTransformer.serialize(gridLayoutComponent);
2030
+ const serializedForm = ComponentTransformer.serialize(formComponent);
2031
+
2032
+ // Deserialize back to React components
2033
+ const reconstructedCode = ComponentTransformer.deserialize(serializedCode);
2034
+ const reconstructedImage = ComponentTransformer.deserialize(serializedImage);
2035
+ const reconstructedText = ComponentTransformer.deserialize(serializedText);
2036
+ const reconstructedHero = ComponentTransformer.deserialize(serializedHero);
2037
+ const reconstructedGrid = ComponentTransformer.deserialize(serializedGrid);
2038
+ const reconstructedForm = ComponentTransformer.deserialize(serializedForm);
2039
+ // All components are fully functional with all properties preserved, including nested components, responsive breakpoints, and form state
2040
+ ```
2041
+
2042
+ ### Serialized Data Format
2043
+
2044
+ Components are serialized using a standardized format:
2045
+
2046
+ ```json
2047
+ // Code Component
2048
+ {
2049
+ "tag": "Code",
2050
+ "version": "1.0.0",
2051
+ "data": {
2052
+ "children": "const greeting = 'Hello, Serialization!';\nconsole.log(greeting);",
2053
+ "language": "javascript",
2054
+ "showCopy": true,
2055
+ "title": "example.js"
2056
+ }
2057
+ }
2058
+
2059
+ // Image Component
2060
+ {
2061
+ "tag": "Image",
2062
+ "version": "1.0.0",
2063
+ "data": {
2064
+ "src": "/example.jpg",
2065
+ "alt": "Example image",
2066
+ "width": 400,
2067
+ "height": 300,
2068
+ "responsive": true,
2069
+ "loading": "lazy"
2070
+ }
2071
+ }
2072
+
2073
+ // Text Component
2074
+ {
2075
+ "tag": "Text",
2076
+ "version": "1.0.0",
2077
+ "data": {
2078
+ "children": "Welcome to Component Serialization!",
2079
+ "variant": "h2",
2080
+ "color": "primary",
2081
+ "align": "center",
2082
+ "component": "h1",
2083
+ "gutterBottom": true
2084
+ }
2085
+ }
2086
+
2087
+ // HeroBlock Component with Nested Elements
2088
+ {
2089
+ "tag": "HeroBlock",
2090
+ "version": "1.0.0",
2091
+ "data": {
2092
+ "title": "Serializable Hero Section",
2093
+ "subtitle": "Full functionality preserved through JSON serialization",
2094
+ "backgroundGradient": "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
2095
+ "height": "medium",
2096
+ "actions": "[{\"key\":\"primary\",\"type\":\"Button\",\"props\":{\"variant\":\"contained\",\"color\":\"primary\",\"children\":\"Get Started\"}},{\"key\":\"secondary\",\"type\":\"Button\",\"props\":{\"variant\":\"outlined\",\"color\":\"secondary\",\"children\":\"Learn More\"}}]"
2097
+ }
2098
+ }
2099
+
2100
+ // GridLayout Component with Responsive Configuration
2101
+ {
2102
+ "tag": "GridLayout",
2103
+ "version": "1.0.0",
2104
+ "data": {
2105
+ "columns": 3,
2106
+ "spacing": "large",
2107
+ "equalHeight": true,
2108
+ "responsive": true,
2109
+ "children": "[{\"tag\":\"GridCell\",\"version\":\"1.0.0\",\"data\":{\"xs\":12,\"sm\":6,\"md\":4,\"padding\":\"medium\",\"children\":\"Feature content...\"}},{\"tag\":\"GridCell\",\"version\":\"1.0.0\",\"data\":{\"xs\":12,\"sm\":6,\"md\":4,\"padding\":\"medium\",\"children\":\"More content...\"}}]"
2110
+ }
2111
+ }
2112
+
2113
+ // GridCell Component with Responsive Breakpoints
2114
+ {
2115
+ "tag": "GridCell",
2116
+ "version": "1.0.0",
2117
+ "data": {
2118
+ "xs": 12,
2119
+ "sm": 6,
2120
+ "md": 4,
2121
+ "lg": 3,
2122
+ "xl": 2,
2123
+ "padding": "medium",
2124
+ "children": "Cell content with responsive breakpoint configuration"
2125
+ }
2126
+ }
2127
+ ```
2128
+
2129
+ ### CMS and API Integration
2130
+
2131
+ The serialization system is perfect for CMS integration:
2132
+
2133
+ ```tsx
2134
+ // API returns serialized components
2135
+ const response = await fetch('/api/content/components');
2136
+ const { components } = await response.json();
2137
+
2138
+ // Render components from API/CMS data
2139
+ function DynamicContent() {
2140
+ return (
2141
+ <div>
2142
+ {components.map((componentData, index) => (
2143
+ <div key={index}>
2144
+ {ComponentTransformer.deserialize(componentData)}
2145
+ </div>
2146
+ ))}
2147
+ </div>
2148
+ );
2149
+ }
2150
+
2151
+ // CMS provides serialized component data
2152
+ const cmsData = {
2153
+ tag: "Code",
2154
+ version: "1.0.0",
2155
+ data: {
2156
+ children: "// Code from CMS\nconst cms = 'integration';",
2157
+ language: "javascript",
2158
+ showCopy: true,
2159
+ title: "CMS Example"
2160
+ }
2161
+ };
2162
+
2163
+ // Automatic reconstruction from CMS
2164
+ const cmsComponent = ComponentTransformer.deserialize(cmsData);
2165
+ ```
2166
+
2167
+ ### Data Binding with Serialization
2168
+
2169
+ Components with data binding maintain their connections through serialization:
2170
+
2171
+ ```tsx
2172
+ // Component with data binding
2173
+ const dataBoundComponent = (
2174
+ <Code
2175
+ dataSource="api/code-examples/fibonacci"
2176
+ bindingOptions={{ cache: true, cacheTTL: 300000 }}
2177
+ language="javascript"
2178
+ showCopy={true}
2179
+ />
2180
+ );
2181
+
2182
+ // Serialization preserves data binding configuration
2183
+ const serialized = ComponentTransformer.serialize(dataBoundComponent);
2184
+
2185
+ // After deserialization, data binding continues to work
2186
+ const deserialized = ComponentTransformer.deserialize(serialized);
2187
+ // Component will still load data from "api/code-examples/fibonacci"
2188
+ ```
2189
+
2190
+ ### Performance Characteristics
2191
+
2192
+ The serialization system is highly optimized:
2193
+
2194
+ - **Serialization Speed**: <1ms for typical components
2195
+ - **Deserialization Speed**: <1ms for component reconstruction
2196
+ - **Scalability**: Handles 1000+ components in <50ms
2197
+ - **Memory Usage**: <50MB for component trees with 5000+ components
2198
+ - **Cross-Browser**: Consistent performance across all major browsers
2199
+
2200
+ ### Creating Serializable Components
2201
+
2202
+ The Code component serves as the reference implementation. To make your own components serializable:
2203
+
2204
+ ```tsx
2205
+ import React, { ReactElement } from 'react';
2206
+ import { Serializable } from '@qwickapps/react-framework';
2207
+
2208
+ export class MyComponent extends React.Component<MyComponentProps> implements Serializable {
2209
+ // Component self-declaration
2210
+ static readonly tagName = 'MyComponent';
2211
+ static readonly version = '1.0.0';
2212
+
2213
+ // Deserialization: JSON data → React element
2214
+ static fromJson(jsonData: any): ReactElement {
2215
+ return <MyComponent {...jsonData} />;
2216
+ }
2217
+
2218
+ // Serialization: Component instance → JSON data
2219
+ toJson(): any {
2220
+ return {
2221
+ title: this.props.title,
2222
+ content: this.props.content,
2223
+ // Add all serializable props
2224
+ };
2225
+ }
2226
+
2227
+ render() {
2228
+ return <MyComponentView {...this.props} />;
2229
+ }
2230
+ }
2231
+
2232
+ // Components are automatically registered when imported
2233
+ ```
2234
+
2235
+ ### Documentation and Resources
2236
+
2237
+ For complete implementation guidance:
2238
+
2239
+ - **Implementation Guide**: `/docs/COMPONENT_SERIALIZATION_GUIDE.md`
2240
+ - **Component Templates**: `/docs/SERIALIZABLE_COMPONENT_TEMPLATE.md`
2241
+ - **Migration Guide**: `/docs/SERIALIZATION_MIGRATION.md`
2242
+ - **Architecture Details**: `/ARCHITECTURE.md#component-serialization-system-architecture`
2243
+ - **Code Component Example**: `/src/components/blocks/Code.md`
2244
+
570
2245
  ## Theming System
571
2246
 
572
2247
  ### Theme Modes
@@ -955,6 +2630,10 @@ import type {
955
2630
  CollapsibleLayoutProps,
956
2631
  CollapsibleLayoutViewProps,
957
2632
  UseCollapsibleLayoutState,
2633
+ // Component Serialization Types
2634
+ Serializable,
2635
+ SerializableConstructor,
2636
+ ComponentTransformer,
958
2637
  } from '@qwickapps/react-framework';
959
2638
  ```
960
2639