@qwickapps/react-framework 1.4.0 → 1.4.2

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 (486) hide show
  1. package/QUICK_START_GUIDE.md +82 -0
  2. package/README.md +231 -21
  3. package/dist/components/Html.d.ts.map +1 -1
  4. package/dist/components/Markdown.d.ts +1 -2
  5. package/dist/components/Markdown.d.ts.map +1 -1
  6. package/dist/components/SafeSpan.d.ts +1 -2
  7. package/dist/components/SafeSpan.d.ts.map +1 -1
  8. package/dist/components/base/Container.d.ts +32 -0
  9. package/dist/components/base/Container.d.ts.map +1 -0
  10. package/dist/components/base/ContainerView.d.ts +65 -0
  11. package/dist/components/base/ContainerView.d.ts.map +1 -0
  12. package/dist/components/base/ModelView.d.ts +37 -46
  13. package/dist/components/base/ModelView.d.ts.map +1 -1
  14. package/dist/components/base/index.d.ts +3 -2
  15. package/dist/components/base/index.d.ts.map +1 -1
  16. package/dist/components/blocks/Article.d.ts +1 -2
  17. package/dist/components/blocks/Article.d.ts.map +1 -1
  18. package/dist/components/blocks/Code-factory.d.ts +22 -0
  19. package/dist/components/blocks/Code-factory.d.ts.map +1 -0
  20. package/dist/components/blocks/Code-old.d.ts +31 -0
  21. package/dist/components/blocks/Code-old.d.ts.map +1 -0
  22. package/dist/components/blocks/Code.d.ts +30 -18
  23. package/dist/components/blocks/Code.d.ts.map +1 -1
  24. package/dist/components/blocks/HeroBlock.d.ts +1 -2
  25. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  26. package/dist/components/blocks/Image.d.ts +1 -2
  27. package/dist/components/blocks/Image.d.ts.map +1 -1
  28. package/dist/components/blocks/Section.d.ts +1 -2
  29. package/dist/components/blocks/Section.d.ts.map +1 -1
  30. package/dist/components/blocks/Text.d.ts +35 -27
  31. package/dist/components/blocks/Text.d.ts.map +1 -1
  32. package/dist/components/buttons/Button.d.ts +1 -2
  33. package/dist/components/buttons/Button.d.ts.map +1 -1
  34. package/dist/components/index.d.ts +2 -0
  35. package/dist/components/index.d.ts.map +1 -1
  36. package/dist/components/input/ChoiceInputField.d.ts +1 -2
  37. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  38. package/dist/components/input/HtmlInputField.d.ts +1 -2
  39. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  40. package/dist/components/input/SelectInputField.d.ts +1 -2
  41. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  42. package/dist/components/pages/Page.d.ts +29 -47
  43. package/dist/components/pages/Page.d.ts.map +1 -1
  44. package/dist/components/pages/index.d.ts +2 -3
  45. package/dist/components/pages/index.d.ts.map +1 -1
  46. package/dist/components/shared/createSerializableView.d.ts +68 -0
  47. package/dist/components/shared/createSerializableView.d.ts.map +1 -0
  48. package/dist/components/shared/viewProps.d.ts +37 -0
  49. package/dist/components/shared/viewProps.d.ts.map +1 -0
  50. package/dist/index.esm.js +21782 -22580
  51. package/dist/index.js +21782 -22579
  52. package/dist/qa/ConsoleWarningTest.d.ts +5 -0
  53. package/dist/qa/ConsoleWarningTest.d.ts.map +1 -0
  54. package/dist/qa/StorageKeyTest.d.ts +6 -0
  55. package/dist/qa/StorageKeyTest.d.ts.map +1 -0
  56. package/dist/qa/ThemeStorageKeyTest.d.ts +6 -0
  57. package/dist/qa/ThemeStorageKeyTest.d.ts.map +1 -0
  58. package/dist/schemas/CodeSchema.d.ts +2 -2
  59. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  60. package/dist/schemas/ContainerSchema.d.ts +12 -0
  61. package/dist/schemas/ContainerSchema.d.ts.map +1 -0
  62. package/dist/schemas/PageTemplateSchema.d.ts +3 -3
  63. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -1
  64. package/dist/schemas/ViewModelSchema.d.ts +46 -6
  65. package/dist/schemas/ViewModelSchema.d.ts.map +1 -1
  66. package/dist/schemas/ViewSchema.d.ts +65 -0
  67. package/dist/schemas/ViewSchema.d.ts.map +1 -0
  68. package/dist/schemas/index.d.ts +1 -1
  69. package/dist/schemas/index.d.ts.map +1 -1
  70. package/dist/schemas/transformers/ComponentTransformer.d.ts +27 -15
  71. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -1
  72. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -1
  73. package/dist/schemas/transformers/registry.d.ts +3 -0
  74. package/dist/schemas/transformers/registry.d.ts.map +1 -1
  75. package/dist/src/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  76. package/dist/src/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  77. package/dist/src/components/AccessibilityChecker.d.ts +12 -0
  78. package/dist/src/components/AccessibilityChecker.d.ts.map +1 -0
  79. package/dist/src/components/AccessibilityProvider.d.ts +64 -0
  80. package/dist/src/components/AccessibilityProvider.d.ts.map +1 -0
  81. package/dist/src/components/Breadcrumbs.d.ts +39 -0
  82. package/dist/src/components/Breadcrumbs.d.ts.map +1 -0
  83. package/dist/src/components/ErrorBoundary.d.ts +46 -0
  84. package/dist/src/components/ErrorBoundary.d.ts.map +1 -0
  85. package/dist/src/components/Html.d.ts +58 -0
  86. package/dist/src/components/Html.d.ts.map +1 -0
  87. package/dist/src/components/Logo.d.ts +56 -0
  88. package/dist/src/components/Logo.d.ts.map +1 -0
  89. package/dist/src/components/Markdown.d.ts +51 -0
  90. package/dist/src/components/Markdown.d.ts.map +1 -0
  91. package/dist/src/components/QwickApp.d.ts +69 -0
  92. package/dist/src/components/QwickApp.d.ts.map +1 -0
  93. package/dist/src/components/QwickAppsLogo.d.ts +25 -0
  94. package/dist/src/components/QwickAppsLogo.d.ts.map +1 -0
  95. package/dist/src/components/QwickIcon.d.ts +23 -0
  96. package/dist/src/components/QwickIcon.d.ts.map +1 -0
  97. package/dist/src/components/ResponsiveMenu.d.ts +38 -0
  98. package/dist/src/components/ResponsiveMenu.d.ts.map +1 -0
  99. package/dist/src/components/SafeSpan.d.ts +29 -0
  100. package/dist/src/components/SafeSpan.d.ts.map +1 -0
  101. package/dist/src/components/Scaffold.d.ts +57 -0
  102. package/dist/src/components/Scaffold.d.ts.map +1 -0
  103. package/dist/src/components/base/Container.d.ts +33 -0
  104. package/dist/src/components/base/Container.d.ts.map +1 -0
  105. package/dist/src/components/base/ModelView.d.ts +92 -0
  106. package/dist/src/components/base/ModelView.d.ts.map +1 -0
  107. package/dist/src/components/base/index.d.ts +12 -0
  108. package/dist/src/components/base/index.d.ts.map +1 -0
  109. package/dist/src/components/blocks/Article.d.ts +32 -0
  110. package/dist/src/components/blocks/Article.d.ts.map +1 -0
  111. package/dist/src/components/blocks/CardListGrid.d.ts +23 -0
  112. package/dist/src/components/blocks/CardListGrid.d.ts.map +1 -0
  113. package/dist/src/components/blocks/Code.d.ts +37 -0
  114. package/dist/src/components/blocks/Code.d.ts.map +1 -0
  115. package/dist/src/components/blocks/Content.d.ts +24 -0
  116. package/dist/src/components/blocks/Content.d.ts.map +1 -0
  117. package/dist/src/components/blocks/CoverImageHeader.d.ts +44 -0
  118. package/dist/src/components/blocks/CoverImageHeader.d.ts.map +1 -0
  119. package/dist/src/components/blocks/FeatureCard.d.ts +66 -0
  120. package/dist/src/components/blocks/FeatureCard.d.ts.map +1 -0
  121. package/dist/src/components/blocks/FeatureGrid.d.ts +48 -0
  122. package/dist/src/components/blocks/FeatureGrid.d.ts.map +1 -0
  123. package/dist/src/components/blocks/Footer.d.ts +56 -0
  124. package/dist/src/components/blocks/Footer.d.ts.map +1 -0
  125. package/dist/src/components/blocks/HeroBlock.d.ts +55 -0
  126. package/dist/src/components/blocks/HeroBlock.d.ts.map +1 -0
  127. package/dist/src/components/blocks/Image.d.ts +40 -0
  128. package/dist/src/components/blocks/Image.d.ts.map +1 -0
  129. package/dist/src/components/blocks/PageBannerHeader.d.ts +30 -0
  130. package/dist/src/components/blocks/PageBannerHeader.d.ts.map +1 -0
  131. package/dist/src/components/blocks/ProductCard.d.ts +57 -0
  132. package/dist/src/components/blocks/ProductCard.d.ts.map +1 -0
  133. package/dist/src/components/blocks/Section.d.ts +45 -0
  134. package/dist/src/components/blocks/Section.d.ts.map +1 -0
  135. package/dist/src/components/blocks/Text.d.ts +34 -0
  136. package/dist/src/components/blocks/Text.d.ts.map +1 -0
  137. package/dist/src/components/blocks/index.d.ts +41 -0
  138. package/dist/src/components/blocks/index.d.ts.map +1 -0
  139. package/dist/src/components/buttons/Button.d.ts +41 -0
  140. package/dist/src/components/buttons/Button.d.ts.map +1 -0
  141. package/dist/src/components/buttons/PaletteSwitcher.d.ts +24 -0
  142. package/dist/src/components/buttons/PaletteSwitcher.d.ts.map +1 -0
  143. package/dist/src/components/buttons/ThemeSwitcher.d.ts +24 -0
  144. package/dist/src/components/buttons/ThemeSwitcher.d.ts.map +1 -0
  145. package/dist/src/components/buttons/index.d.ts +11 -0
  146. package/dist/src/components/buttons/index.d.ts.map +1 -0
  147. package/dist/src/components/forms/FormBlock.d.ts +51 -0
  148. package/dist/src/components/forms/FormBlock.d.ts.map +1 -0
  149. package/dist/src/components/forms/index.d.ts +8 -0
  150. package/dist/src/components/forms/index.d.ts.map +1 -0
  151. package/dist/src/components/index.d.ts +41 -0
  152. package/dist/src/components/index.d.ts.map +1 -0
  153. package/dist/src/components/input/ChoiceInputField.d.ts +29 -0
  154. package/dist/src/components/input/ChoiceInputField.d.ts.map +1 -0
  155. package/dist/src/components/input/HtmlInputField.d.ts +33 -0
  156. package/dist/src/components/input/HtmlInputField.d.ts.map +1 -0
  157. package/dist/src/components/input/SelectInputField.d.ts +31 -0
  158. package/dist/src/components/input/SelectInputField.d.ts.map +1 -0
  159. package/dist/src/components/input/SwitchInputField.d.ts +27 -0
  160. package/dist/src/components/input/SwitchInputField.d.ts.map +1 -0
  161. package/dist/src/components/input/TextField.d.ts +18 -0
  162. package/dist/src/components/input/TextField.d.ts.map +1 -0
  163. package/dist/src/components/input/TextInputField.d.ts +34 -0
  164. package/dist/src/components/input/TextInputField.d.ts.map +1 -0
  165. package/dist/src/components/input/index.d.ts +19 -0
  166. package/dist/src/components/input/index.d.ts.map +1 -0
  167. package/dist/src/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts +34 -0
  168. package/dist/src/components/layout/CollapsibleLayout/CollapsibleLayout.d.ts.map +1 -0
  169. package/dist/src/components/layout/CollapsibleLayout/index.d.ts +9 -0
  170. package/dist/src/components/layout/CollapsibleLayout/index.d.ts.map +1 -0
  171. package/dist/src/components/layout/GridCell.d.ts +32 -0
  172. package/dist/src/components/layout/GridCell.d.ts.map +1 -0
  173. package/dist/src/components/layout/GridCellWrapper.d.ts +46 -0
  174. package/dist/src/components/layout/GridCellWrapper.d.ts.map +1 -0
  175. package/dist/src/components/layout/GridLayout.d.ts +50 -0
  176. package/dist/src/components/layout/GridLayout.d.ts.map +1 -0
  177. package/dist/src/components/layout/index.d.ts +14 -0
  178. package/dist/src/components/layout/index.d.ts.map +1 -0
  179. package/dist/src/components/menu/Menu.d.ts +1 -0
  180. package/dist/src/components/menu/Menu.d.ts.map +1 -0
  181. package/dist/src/components/menu/MenuItem.d.ts +31 -0
  182. package/dist/src/components/menu/MenuItem.d.ts.map +1 -0
  183. package/dist/src/components/menu/index.d.ts +7 -0
  184. package/dist/src/components/menu/index.d.ts.map +1 -0
  185. package/dist/src/components/pages/FormPage.d.ts +66 -0
  186. package/dist/src/components/pages/FormPage.d.ts.map +1 -0
  187. package/dist/src/components/pages/Page.d.ts +68 -0
  188. package/dist/src/components/pages/Page.d.ts.map +1 -0
  189. package/dist/src/components/pages/index.d.ts +10 -0
  190. package/dist/src/components/pages/index.d.ts.map +1 -0
  191. package/dist/src/components/shared/createSerializableView.d.ts +81 -0
  192. package/dist/src/components/shared/createSerializableView.d.ts.map +1 -0
  193. package/dist/src/components/shared/viewProps.d.ts +37 -0
  194. package/dist/src/components/shared/viewProps.d.ts.map +1 -0
  195. package/dist/src/config/AppConfig.d.ts +49 -0
  196. package/dist/src/config/AppConfig.d.ts.map +1 -0
  197. package/dist/src/config/AppConfigBuilder.d.ts +75 -0
  198. package/dist/src/config/AppConfigBuilder.d.ts.map +1 -0
  199. package/dist/src/config/index.d.ts +13 -0
  200. package/dist/src/config/index.d.ts.map +1 -0
  201. package/dist/src/config/types.d.ts +130 -0
  202. package/dist/src/config/types.d.ts.map +1 -0
  203. package/dist/src/config.d.ts +15 -0
  204. package/dist/src/config.d.ts.map +1 -0
  205. package/dist/src/contexts/DataContext.d.ts +139 -0
  206. package/dist/src/contexts/DataContext.d.ts.map +1 -0
  207. package/dist/src/contexts/DimensionsContext.d.ts +42 -0
  208. package/dist/src/contexts/DimensionsContext.d.ts.map +1 -0
  209. package/dist/src/contexts/PaletteContext.d.ts +53 -0
  210. package/dist/src/contexts/PaletteContext.d.ts.map +1 -0
  211. package/dist/src/contexts/PrintModeContext.d.ts +27 -0
  212. package/dist/src/contexts/PrintModeContext.d.ts.map +1 -0
  213. package/dist/src/contexts/QwickAppContext.d.ts +71 -0
  214. package/dist/src/contexts/QwickAppContext.d.ts.map +1 -0
  215. package/dist/src/contexts/ThemeContext.d.ts +65 -0
  216. package/dist/src/contexts/ThemeContext.d.ts.map +1 -0
  217. package/dist/src/contexts/index.d.ts +11 -0
  218. package/dist/src/contexts/index.d.ts.map +1 -0
  219. package/dist/src/hooks/index.d.ts +12 -0
  220. package/dist/src/hooks/index.d.ts.map +1 -0
  221. package/dist/src/hooks/useBaseProps.d.ts +101 -0
  222. package/dist/src/hooks/useBaseProps.d.ts.map +1 -0
  223. package/dist/src/hooks/useDataBinding.d.ts +22 -0
  224. package/dist/src/hooks/useDataBinding.d.ts.map +1 -0
  225. package/dist/src/hooks/usePrintMode.d.ts +39 -0
  226. package/dist/src/hooks/usePrintMode.d.ts.map +1 -0
  227. package/dist/src/index.d.ts +9 -0
  228. package/dist/src/index.d.ts.map +1 -0
  229. package/dist/src/palettes/PaletteAutumn.d.ts +10 -0
  230. package/dist/src/palettes/PaletteAutumn.d.ts.map +1 -0
  231. package/dist/src/palettes/PaletteCosmic.d.ts +10 -0
  232. package/dist/src/palettes/PaletteCosmic.d.ts.map +1 -0
  233. package/dist/src/palettes/PaletteDefault.d.ts +10 -0
  234. package/dist/src/palettes/PaletteDefault.d.ts.map +1 -0
  235. package/dist/src/palettes/PaletteOcean.d.ts +10 -0
  236. package/dist/src/palettes/PaletteOcean.d.ts.map +1 -0
  237. package/dist/src/palettes/PaletteSpring.d.ts +10 -0
  238. package/dist/src/palettes/PaletteSpring.d.ts.map +1 -0
  239. package/dist/src/palettes/PaletteWinter.d.ts +10 -0
  240. package/dist/src/palettes/PaletteWinter.d.ts.map +1 -0
  241. package/dist/src/palettes/index.d.ts +13 -0
  242. package/dist/src/palettes/index.d.ts.map +1 -0
  243. package/dist/src/schemas/ActionSchema.d.ts +21 -0
  244. package/dist/src/schemas/ActionSchema.d.ts.map +1 -0
  245. package/dist/src/schemas/ArticleSchema.d.ts +13 -0
  246. package/dist/src/schemas/ArticleSchema.d.ts.map +1 -0
  247. package/dist/src/schemas/ButtonSchema.d.ts +19 -0
  248. package/dist/src/schemas/ButtonSchema.d.ts.map +1 -0
  249. package/dist/src/schemas/CardListGridSchema.d.ts +17 -0
  250. package/dist/src/schemas/CardListGridSchema.d.ts.map +1 -0
  251. package/dist/src/schemas/ChoiceInputFieldSchema.d.ts +18 -0
  252. package/dist/src/schemas/ChoiceInputFieldSchema.d.ts.map +1 -0
  253. package/dist/src/schemas/CodeSchema.d.ts +18 -0
  254. package/dist/src/schemas/CodeSchema.d.ts.map +1 -0
  255. package/dist/src/schemas/CollapsibleLayoutSchema.d.ts +32 -0
  256. package/dist/src/schemas/CollapsibleLayoutSchema.d.ts.map +1 -0
  257. package/dist/src/schemas/ContainerSchema.d.ts +12 -0
  258. package/dist/src/schemas/ContainerSchema.d.ts.map +1 -0
  259. package/dist/src/schemas/ContentSchema.d.ts +21 -0
  260. package/dist/src/schemas/ContentSchema.d.ts.map +1 -0
  261. package/dist/src/schemas/CoverImageHeaderSchema.d.ts +28 -0
  262. package/dist/src/schemas/CoverImageHeaderSchema.d.ts.map +1 -0
  263. package/dist/src/schemas/FeatureCardSchema.d.ts +28 -0
  264. package/dist/src/schemas/FeatureCardSchema.d.ts.map +1 -0
  265. package/dist/src/schemas/FeatureGridSchema.d.ts +17 -0
  266. package/dist/src/schemas/FeatureGridSchema.d.ts.map +1 -0
  267. package/dist/src/schemas/FeatureItemSchema.d.ts +16 -0
  268. package/dist/src/schemas/FeatureItemSchema.d.ts.map +1 -0
  269. package/dist/src/schemas/FooterItemSchema.d.ts +15 -0
  270. package/dist/src/schemas/FooterItemSchema.d.ts.map +1 -0
  271. package/dist/src/schemas/FooterSchema.d.ts +20 -0
  272. package/dist/src/schemas/FooterSchema.d.ts.map +1 -0
  273. package/dist/src/schemas/FooterSectionSchema.d.ts +15 -0
  274. package/dist/src/schemas/FooterSectionSchema.d.ts.map +1 -0
  275. package/dist/src/schemas/FormBlockSchema.d.ts +19 -0
  276. package/dist/src/schemas/FormBlockSchema.d.ts.map +1 -0
  277. package/dist/src/schemas/GridCellSchema.d.ts +23 -0
  278. package/dist/src/schemas/GridCellSchema.d.ts.map +1 -0
  279. package/dist/src/schemas/GridLayoutSchema.d.ts +21 -0
  280. package/dist/src/schemas/GridLayoutSchema.d.ts.map +1 -0
  281. package/dist/src/schemas/HeaderActionSchema.d.ts +17 -0
  282. package/dist/src/schemas/HeaderActionSchema.d.ts.map +1 -0
  283. package/dist/src/schemas/HeroBlockSchema.d.ts +22 -0
  284. package/dist/src/schemas/HeroBlockSchema.d.ts.map +1 -0
  285. package/dist/src/schemas/HtmlInputFieldSchema.d.ts +18 -0
  286. package/dist/src/schemas/HtmlInputFieldSchema.d.ts.map +1 -0
  287. package/dist/src/schemas/HtmlSchema.d.ts +14 -0
  288. package/dist/src/schemas/HtmlSchema.d.ts.map +1 -0
  289. package/dist/src/schemas/ImageSchema.d.ts +32 -0
  290. package/dist/src/schemas/ImageSchema.d.ts.map +1 -0
  291. package/dist/src/schemas/LogoSchema.d.ts +35 -0
  292. package/dist/src/schemas/LogoSchema.d.ts.map +1 -0
  293. package/dist/src/schemas/MarkdownSchema.d.ts +14 -0
  294. package/dist/src/schemas/MarkdownSchema.d.ts.map +1 -0
  295. package/dist/src/schemas/MetadataItemSchema.d.ts +13 -0
  296. package/dist/src/schemas/MetadataItemSchema.d.ts.map +1 -0
  297. package/dist/src/schemas/PageBannerHeaderSchema.d.ts +28 -0
  298. package/dist/src/schemas/PageBannerHeaderSchema.d.ts.map +1 -0
  299. package/dist/src/schemas/PageTemplateSchema.d.ts +31 -0
  300. package/dist/src/schemas/PageTemplateSchema.d.ts.map +1 -0
  301. package/dist/src/schemas/PaletteSwitcherSchema.d.ts +16 -0
  302. package/dist/src/schemas/PaletteSwitcherSchema.d.ts.map +1 -0
  303. package/dist/src/schemas/PrintConfigSchema.d.ts +31 -0
  304. package/dist/src/schemas/PrintConfigSchema.d.ts.map +1 -0
  305. package/dist/src/schemas/ProductCardSchema.d.ts +39 -0
  306. package/dist/src/schemas/ProductCardSchema.d.ts.map +1 -0
  307. package/dist/src/schemas/SafeSpanSchema.d.ts +13 -0
  308. package/dist/src/schemas/SafeSpanSchema.d.ts.map +1 -0
  309. package/dist/src/schemas/SectionSchema.d.ts +16 -0
  310. package/dist/src/schemas/SectionSchema.d.ts.map +1 -0
  311. package/dist/src/schemas/SelectInputFieldSchema.d.ts +27 -0
  312. package/dist/src/schemas/SelectInputFieldSchema.d.ts.map +1 -0
  313. package/dist/src/schemas/SwitchInputFieldSchema.d.ts +18 -0
  314. package/dist/src/schemas/SwitchInputFieldSchema.d.ts.map +1 -0
  315. package/dist/src/schemas/TextInputFieldSchema.d.ts +22 -0
  316. package/dist/src/schemas/TextInputFieldSchema.d.ts.map +1 -0
  317. package/dist/src/schemas/TextSchema.d.ts +37 -0
  318. package/dist/src/schemas/TextSchema.d.ts.map +1 -0
  319. package/dist/src/schemas/ThemeSwitcherSchema.d.ts +19 -0
  320. package/dist/src/schemas/ThemeSwitcherSchema.d.ts.map +1 -0
  321. package/dist/src/schemas/ViewSchema.d.ts +66 -0
  322. package/dist/src/schemas/ViewSchema.d.ts.map +1 -0
  323. package/dist/src/schemas/index.d.ts +47 -0
  324. package/dist/src/schemas/index.d.ts.map +1 -0
  325. package/dist/src/schemas/transformers/ComponentTransformer.d.ts +128 -0
  326. package/dist/src/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  327. package/dist/src/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  328. package/dist/src/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  329. package/dist/src/schemas/transformers/registry.d.ts +18 -0
  330. package/dist/src/schemas/transformers/registry.d.ts.map +1 -0
  331. package/dist/src/schemas/types/Serializable.d.ts +46 -0
  332. package/dist/src/schemas/types/Serializable.d.ts.map +1 -0
  333. package/dist/src/stories/_templates/SerializationTemplate.d.ts +44 -0
  334. package/dist/src/stories/_templates/SerializationTemplate.d.ts.map +1 -0
  335. package/dist/src/templates/TemplateResolver.d.ts +52 -0
  336. package/dist/src/templates/TemplateResolver.d.ts.map +1 -0
  337. package/dist/src/templates/index.d.ts +7 -0
  338. package/dist/src/templates/index.d.ts.map +1 -0
  339. package/dist/src/types/CacheProvider.d.ts +18 -0
  340. package/dist/src/types/CacheProvider.d.ts.map +1 -0
  341. package/dist/src/types/CollapsibleLayout.d.ts +142 -0
  342. package/dist/src/types/CollapsibleLayout.d.ts.map +1 -0
  343. package/dist/src/types/ContentProxy.d.ts +47 -0
  344. package/dist/src/types/ContentProxy.d.ts.map +1 -0
  345. package/dist/src/types/DataTypes.d.ts +185 -0
  346. package/dist/src/types/DataTypes.d.ts.map +1 -0
  347. package/dist/src/types/TemplateProvider.d.ts +10 -0
  348. package/dist/src/types/TemplateProvider.d.ts.map +1 -0
  349. package/dist/src/types/TemplateResolver.d.ts +23 -0
  350. package/dist/src/types/TemplateResolver.d.ts.map +1 -0
  351. package/dist/src/types/index.d.ts +82 -0
  352. package/dist/src/types/index.d.ts.map +1 -0
  353. package/dist/src/utils/breakpoints.d.ts +35 -0
  354. package/dist/src/utils/breakpoints.d.ts.map +1 -0
  355. package/dist/src/utils/cssUtils.d.ts +17 -0
  356. package/dist/src/utils/cssUtils.d.ts.map +1 -0
  357. package/dist/src/utils/customPaletteManager.d.ts +8 -0
  358. package/dist/src/utils/customPaletteManager.d.ts.map +1 -0
  359. package/dist/src/utils/dimensions.d.ts +34 -0
  360. package/dist/src/utils/dimensions.d.ts.map +1 -0
  361. package/dist/src/utils/htmlTransform.d.ts +44 -0
  362. package/dist/src/utils/htmlTransform.d.ts.map +1 -0
  363. package/dist/src/utils/index.d.ts +16 -0
  364. package/dist/src/utils/index.d.ts.map +1 -0
  365. package/dist/src/utils/logger.d.ts +26 -0
  366. package/dist/src/utils/logger.d.ts.map +1 -0
  367. package/dist/src/utils/paletteUtils.d.ts +38 -0
  368. package/dist/src/utils/paletteUtils.d.ts.map +1 -0
  369. package/dist/src/utils/persistenceUtils.d.ts +31 -0
  370. package/dist/src/utils/persistenceUtils.d.ts.map +1 -0
  371. package/dist/src/utils/reactUtils.d.ts +33 -0
  372. package/dist/src/utils/reactUtils.d.ts.map +1 -0
  373. package/dist/src/utils/spacing.d.ts +34 -0
  374. package/dist/src/utils/spacing.d.ts.map +1 -0
  375. package/dist/src/utils/themePerformanceMonitor.d.ts +32 -0
  376. package/dist/src/utils/themePerformanceMonitor.d.ts.map +1 -0
  377. package/dist/src/utils/themeUtils.d.ts +27 -0
  378. package/dist/src/utils/themeUtils.d.ts.map +1 -0
  379. package/dist/utils/cssUtils.d.ts +17 -0
  380. package/dist/utils/cssUtils.d.ts.map +1 -0
  381. package/dist/utils/index.d.ts +1 -0
  382. package/dist/utils/index.d.ts.map +1 -1
  383. package/package.json +5 -2
  384. package/scripts/bundle-css.cjs +27 -0
  385. package/scripts/create-project.sh +28 -0
  386. package/scripts/create-qwickapps-project.js +284 -0
  387. package/src/__tests__/components/base/Container.test.tsx +966 -0
  388. package/src/__tests__/schemas/PageTemplateSchema.test.ts +1 -1
  389. package/src/__tests__/schemas/ViewSchema.test.ts +805 -0
  390. package/src/__tests__/schemas/builders.test.ts +2 -2
  391. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +19 -19
  392. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +13 -13
  393. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +39 -39
  394. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +14 -14
  395. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +8 -8
  396. package/src/__tests__/schemas/transformers/nested-serialization.test.tsx +181 -0
  397. package/src/__tests__/schemas/transformers/round-trip-component-serialization.test.tsx +458 -0
  398. package/src/__tests__/test_image_accessibility.test.tsx +226 -0
  399. package/src/__tests__/utils/optional-logging.test.ts +3 -3
  400. package/src/components/Html.tsx +24 -15
  401. package/src/components/Logo.tsx +2 -2
  402. package/src/components/Markdown.tsx +2 -7
  403. package/src/components/SafeSpan.tsx +2 -7
  404. package/src/components/base/Container.tsx +61 -0
  405. package/src/components/base/ModelView.tsx +225 -91
  406. package/src/components/base/index.ts +3 -2
  407. package/src/components/blocks/Article.tsx +2 -7
  408. package/src/components/blocks/CardListGrid.tsx +2 -2
  409. package/src/components/blocks/Code.tsx +91 -179
  410. package/src/components/blocks/Content.tsx +2 -2
  411. package/src/components/blocks/CoverImageHeader.tsx +2 -2
  412. package/src/components/blocks/HeroBlock.tsx +54 -146
  413. package/src/components/blocks/Image.tsx +82 -196
  414. package/src/components/blocks/PageBannerHeader.tsx +2 -2
  415. package/src/components/blocks/Section.tsx +79 -181
  416. package/src/components/blocks/Text.tsx +100 -198
  417. package/src/components/buttons/Button.tsx +85 -183
  418. package/src/components/buttons/PaletteSwitcher.tsx +2 -2
  419. package/src/components/buttons/ThemeSwitcher.tsx +2 -2
  420. package/src/components/forms/FormBlock.tsx +2 -2
  421. package/src/components/index.ts +5 -0
  422. package/src/components/input/ChoiceInputField.tsx +76 -160
  423. package/src/components/input/HtmlInputField.tsx +141 -264
  424. package/src/components/input/SelectInputField.tsx +48 -153
  425. package/src/components/input/SwitchInputField.tsx +41 -139
  426. package/src/components/input/TextInputField.tsx +39 -116
  427. package/src/components/layout/GridCell.tsx +36 -122
  428. package/src/components/layout/GridLayout.tsx +55 -127
  429. package/src/components/pages/Page.tsx +268 -276
  430. package/src/components/pages/index.ts +2 -3
  431. package/src/components/shared/createSerializableView.tsx +280 -0
  432. package/src/components/shared/viewProps.ts +207 -0
  433. package/src/config/__tests__/AppConfigBuilder.test.ts +2 -2
  434. package/src/contexts/DataContext.tsx +1 -1
  435. package/src/schemas/ButtonSchema.ts +3 -2
  436. package/src/schemas/CardListGridSchema.ts +3 -2
  437. package/src/schemas/ChoiceInputFieldSchema.ts +3 -2
  438. package/src/schemas/CodeSchema.ts +8 -6
  439. package/src/schemas/ContainerSchema.ts +25 -0
  440. package/src/schemas/FeatureCardSchema.ts +1 -1
  441. package/src/schemas/FormBlockSchema.ts +3 -2
  442. package/src/schemas/GridCellSchema.ts +4 -10
  443. package/src/schemas/GridLayoutSchema.ts +8 -14
  444. package/src/schemas/HeroBlockSchema.ts +3 -2
  445. package/src/schemas/HtmlInputFieldSchema.ts +3 -2
  446. package/src/schemas/ImageSchema.ts +3 -2
  447. package/src/schemas/PageTemplateSchema.ts +5 -5
  448. package/src/schemas/SectionSchema.ts +4 -12
  449. package/src/schemas/SelectInputFieldSchema.ts +3 -2
  450. package/src/schemas/SwitchInputFieldSchema.ts +2 -2
  451. package/src/schemas/TextInputFieldSchema.ts +3 -2
  452. package/src/schemas/ViewSchema.ts +570 -0
  453. package/src/schemas/index.ts +1 -1
  454. package/src/schemas/transformers/ComponentTransformer.ts +185 -163
  455. package/src/schemas/transformers/ReactNodeTransformer.ts +31 -28
  456. package/src/schemas/transformers/registry.ts +17 -10
  457. package/src/stories/Button.stories.tsx +24 -0
  458. package/src/stories/ChoiceInputField.stories.tsx +28 -1
  459. package/src/stories/Code.stories.tsx +61 -1
  460. package/src/stories/Container.stories.tsx +954 -0
  461. package/src/stories/FormBlock.stories.tsx +54 -0
  462. package/src/stories/FormComponents.stories.tsx +8 -13
  463. package/src/stories/GridCell.stories.tsx +23 -64
  464. package/src/stories/GridLayout.stories.tsx +22 -47
  465. package/src/stories/HeroBlock.stories.tsx +28 -0
  466. package/src/stories/HtmlInputField.stories.tsx +23 -1
  467. package/src/stories/Image.stories.tsx +45 -233
  468. package/src/stories/Markdown.stories.tsx +1 -1
  469. package/src/stories/Section.stories.tsx +38 -4
  470. package/src/stories/SelectInputField.stories.tsx +26 -1
  471. package/src/stories/Text.stories.tsx +22 -54
  472. package/src/stories/TextInputField.stories.tsx +24 -1
  473. package/src/stories/_templates/SerializationTemplate.tsx +165 -0
  474. package/src/templates/TemplateResolver.ts +2 -2
  475. package/src/types/CollapsibleLayout.ts +2 -2
  476. package/src/utils/cssUtils.ts +49 -0
  477. package/src/utils/index.ts +1 -0
  478. package/src/utils/logger.ts +13 -13
  479. package/src/__tests__/components/base/ModelView.test.tsx +0 -220
  480. package/src/__tests__/schemas/ViewModelSchema.test.ts +0 -80
  481. package/src/components/blocks/Code.md +0 -529
  482. package/src/schemas/README.md +0 -661
  483. package/src/schemas/ViewModelSchema.ts +0 -115
  484. package/src/tests/ConsoleWarningTest.tsx +0 -30
  485. package/src/tests/StorageKeyTest.tsx +0 -110
  486. package/src/tests/ThemeStorageKeyTest.tsx +0 -114
@@ -0,0 +1,280 @@
1
+ /**
2
+ * createSerializableView - Factory for schema-driven components
3
+ *
4
+ * Creates functional components that:
5
+ * - Normalize schema props using normalizeViewProps
6
+ * - Apply useBaseProps exactly once for style/html/grid processing
7
+ * - Optionally integrate data binding (gated by enabled flag)
8
+ * - Attach static tagName/version/fromJson/toJson for serialization
9
+ *
10
+ * Works seamlessly with existing BaseComponentProps system and provides
11
+ * the foundation for the new schema-driven architecture.
12
+ *
13
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
14
+ */
15
+
16
+ import React, { ComponentType, ReactElement, ReactNode } from 'react';
17
+ // SerializableConstructor type is defined inline below
18
+ import { useBaseProps, useDataBinding, QWICKAPP_COMPONENT } from '../../hooks';
19
+ import { normalizeViewProps, ViewProps } from './viewProps';
20
+
21
+ /**
22
+ * Helper function to convert React children to text content
23
+ * Used for content-prop strategy to map JSX children to content strings
24
+ */
25
+ function toText(node: ReactNode): string | undefined {
26
+ if (node == null || typeof node === 'boolean') return undefined;
27
+ if (typeof node === 'string' || typeof node === 'number') return String(node);
28
+ if (Array.isArray(node)) return node.map(toText).filter(Boolean).join('');
29
+ return undefined;
30
+ }
31
+
32
+ /**
33
+ * Children handling strategy for serialization
34
+ */
35
+ type ChildrenStrategy =
36
+ | { mode: 'react-children' }
37
+ | { mode: 'content-prop'; propName?: string };
38
+
39
+ /**
40
+ * Component factory configuration
41
+ */
42
+ interface CreateSerializableViewConfig<P extends ViewProps> {
43
+ /** Component tag name for serialization */
44
+ tagName: string;
45
+ /** Component version for serialization */
46
+ version: string;
47
+ /** Component role: 'view' for display components, 'container' for layout components */
48
+ role: 'view' | 'container';
49
+ /** View function that renders the component */
50
+ View: ComponentType<P>;
51
+ /** Children handling strategy - defaults to 'react-children' */
52
+ childrenStrategy?: ChildrenStrategy;
53
+ /** Optional prop finalizer function */
54
+ finalize?: (props: P) => P;
55
+ }
56
+
57
+ /**
58
+ * Serializable component interface with all required static properties
59
+ */
60
+ export interface SerializableComponent<P extends ViewProps> {
61
+ (props: P): ReactElement;
62
+ tagName: string;
63
+ version: string;
64
+ fromJson: (data: any) => ReactElement;
65
+ toJson: (props: P) => any;
66
+ displayName?: string;
67
+ [QWICKAPP_COMPONENT]: symbol;
68
+ }
69
+
70
+ /**
71
+ * Create a serializable view component using the factory pattern
72
+ *
73
+ * @param config - Factory configuration
74
+ * @returns Serializable component with attached static methods
75
+ */
76
+ export function createSerializableView<P extends ViewProps>(
77
+ config: CreateSerializableViewConfig<P>
78
+ ): SerializableComponent<P> {
79
+ const { tagName, version, role, View, childrenStrategy = { mode: 'react-children' }, finalize } = config;
80
+
81
+ // Create the main component function
82
+ function SerializableViewComponent(props: P): ReactElement {
83
+ const { dataSource, bindingOptions, children, ...schemaProps } = props as any;
84
+
85
+ // Step 1: Handle content-prop strategy (map JSX children → content)
86
+ let propsForProcessing = schemaProps;
87
+ if (childrenStrategy.mode === 'content-prop') {
88
+ const propName = childrenStrategy.propName || 'content';
89
+ if (propsForProcessing[propName] == null) {
90
+ const textContent = toText(children);
91
+ if (typeof textContent === 'string') {
92
+ propsForProcessing = { ...propsForProcessing, [propName]: textContent };
93
+ }
94
+ }
95
+ }
96
+
97
+ // Step 2: Normalize schema props to runtime-friendly format
98
+ const normalizedProps = normalizeViewProps(propsForProcessing);
99
+
100
+ // Step 2: ALWAYS call all hooks first (Rules of Hooks)
101
+ const { loading, error, ...resolvedProps } = useDataBinding(
102
+ dataSource || undefined, // Pass undefined if no dataSource
103
+ normalizedProps,
104
+ undefined, // Schema - let the hook infer it
105
+ dataSource ? { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions } : { enabled: false }
106
+ );
107
+
108
+ // Determine which props to use based on data binding state
109
+ let boundProps = normalizedProps;
110
+ if (dataSource && !error) {
111
+ boundProps = { ...normalizedProps, ...resolvedProps };
112
+ }
113
+
114
+ // Step 3: Apply useBaseProps for style/html/grid processing (ALWAYS call this hook)
115
+ const { gridProps, styleProps, htmlProps, restProps } = useBaseProps(boundProps);
116
+
117
+ // Step 4: Handle special states AFTER all hooks have been called
118
+ if (dataSource && loading) {
119
+ return <div>Loading...</div> as ReactElement;
120
+ }
121
+
122
+ if (dataSource && error) {
123
+ console.error('Data binding error:', error);
124
+ if (process.env.NODE_ENV !== 'production') {
125
+ return <div style={{ color: 'red', padding: '1rem', border: '1px solid red' }}>
126
+ Error loading data: {error.message}
127
+ </div> as ReactElement;
128
+ }
129
+ // In production, continue with fallback props (already set above)
130
+ }
131
+
132
+ // Step 5: Prepare final props and apply optional finalize function
133
+ let viewProps = {
134
+ ...restProps,
135
+ ...styleProps,
136
+ ...htmlProps,
137
+ // Grid props are passed separately if needed by container components
138
+ ...(role === 'container' && gridProps ? { gridProps } : {}),
139
+ } as P;
140
+
141
+ // Apply finalize function if provided
142
+ if (finalize) {
143
+ viewProps = finalize(viewProps);
144
+ }
145
+
146
+ // Step 6: Render with appropriate children strategy
147
+ if (childrenStrategy.mode === 'content-prop') {
148
+ // For content-prop components, don't pass children to the view
149
+ return <View {...viewProps} />;
150
+ } else {
151
+ // For react-children components, pass children through
152
+ return <View {...viewProps}>{children}</View>;
153
+ }
154
+ }
155
+
156
+ // Attach static properties for serialization
157
+ const component = SerializableViewComponent as unknown as SerializableComponent<P>;
158
+
159
+ // Component identification
160
+ component.tagName = tagName;
161
+ component.version = version;
162
+ component[QWICKAPP_COMPONENT] = QWICKAPP_COMPONENT;
163
+
164
+ // Serialization methods
165
+ component.fromJson = function fromJson(data: any): ReactElement {
166
+ const { tagName: dataTagName, version: dataVersion, data: componentData } = data;
167
+
168
+ // Validate deserialization data
169
+ if (dataTagName !== tagName) {
170
+ throw new Error(`Tag name mismatch: expected ${tagName}, got ${dataTagName}`);
171
+ }
172
+
173
+ if (dataVersion !== version) {
174
+ console.warn(`Version mismatch for ${tagName}: expected ${version}, got ${dataVersion}`);
175
+ }
176
+
177
+ // Handle deserialization based on children strategy
178
+ if (childrenStrategy.mode === 'content-prop') {
179
+ const propName = childrenStrategy.propName || 'content';
180
+ const { children: _ignored, ...rest } = componentData || {};
181
+ const contentData = { ...rest, [propName]: componentData?.[propName] || '' };
182
+ return React.createElement(component as ComponentType<P>, contentData as P);
183
+ } else {
184
+ // For react-children strategy, recursively deserialize children
185
+ const deserializedData = { ...componentData };
186
+ if (componentData.children !== undefined) {
187
+ // Import ComponentTransformer here to avoid circular dependency
188
+ const { ComponentTransformer } = require('../../schemas/transformers/ComponentTransformer');
189
+ deserializedData.children = ComponentTransformer.deserialize(componentData.children);
190
+ }
191
+ return React.createElement(component as ComponentType<P>, deserializedData as P);
192
+ }
193
+ };
194
+
195
+ component.toJson = function toJson(props: P): any {
196
+ // Handle serialization based on children strategy
197
+ if (childrenStrategy.mode === 'content-prop') {
198
+ const propName = childrenStrategy.propName || 'content';
199
+ const { children: _ignored, ...rest } = props || {};
200
+ const contentValue = (props as any)?.[propName] ?? toText((props as any)?.children);
201
+
202
+ // Clean props for content-prop serialization
203
+ const cleanProps: any = {};
204
+ for (const [key, value] of Object.entries(rest)) {
205
+ if (typeof value === 'function' && key.startsWith('on')) {
206
+ cleanProps[key] = value.toString();
207
+ } else if (typeof value !== 'function' && value !== undefined && value !== null) {
208
+ cleanProps[key] = value;
209
+ }
210
+ }
211
+
212
+ return {
213
+ tagName,
214
+ version,
215
+ data: { ...cleanProps, [propName]: contentValue || '' },
216
+ };
217
+ } else {
218
+ // Handle react-children strategy (existing logic)
219
+ const cleanProps: any = {};
220
+
221
+ for (const [key, value] of Object.entries(props)) {
222
+ if (typeof value === 'function' && key.startsWith('on')) {
223
+ // Convert event handlers to string representation
224
+ cleanProps[key] = value.toString();
225
+ } else if (typeof value === 'function') {
226
+ // Skip non-event handler functions
227
+ continue;
228
+ } else if (key === 'children') {
229
+ // IMPORTANT: Include children as-is for recursive serialization by ComponentTransformer
230
+ // The ComponentTransformer.serializeNode() will handle the recursive serialization
231
+ cleanProps[key] = value;
232
+ } else if (value !== undefined && value !== null) {
233
+ // Include all other serializable props
234
+ cleanProps[key] = value;
235
+ }
236
+ }
237
+
238
+ return {
239
+ tagName,
240
+ version,
241
+ data: cleanProps,
242
+ };
243
+ }
244
+ };
245
+
246
+ // Set display name for debugging
247
+ component.displayName = `SerializableView(${tagName})`;
248
+
249
+ return component;
250
+ }
251
+
252
+ /**
253
+ * Type helper for components created with createSerializableView
254
+ */
255
+ export type SerializableViewComponent<P extends ViewProps> = SerializableComponent<P>;
256
+
257
+ /**
258
+ * Type guard to check if a component is serializable
259
+ */
260
+ export function isSerializableComponent(component: any): component is SerializableComponent<any> {
261
+ return component &&
262
+ typeof component === 'function' &&
263
+ typeof component.tagName === 'string' &&
264
+ typeof component.version === 'string' &&
265
+ typeof component.fromJson === 'function' &&
266
+ typeof component.toJson === 'function' &&
267
+ component[QWICKAPP_COMPONENT] === QWICKAPP_COMPONENT;
268
+ }
269
+
270
+ /**
271
+ * Extract component metadata for registration
272
+ */
273
+ export function getComponentMetadata(component: SerializableComponent<any>) {
274
+ return {
275
+ tagName: component.tagName,
276
+ version: component.version,
277
+ fromJson: component.fromJson,
278
+ toJson: component.toJson,
279
+ };
280
+ }
@@ -0,0 +1,207 @@
1
+ /**
2
+ * ViewProps - Runtime-friendly props derived from ViewSchema
3
+ *
4
+ * Provides normalized view props that integrate seamlessly with the existing
5
+ * BaseComponentProps system and useBaseProps hook. Handles type conversion
6
+ * from schema strings to proper React prop types including event handlers,
7
+ * styling props, and grid values.
8
+ *
9
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
10
+ */
11
+
12
+ import type { SxProps, Theme } from '@mui/material/styles';
13
+ import type { SchemaProps, WithDataBinding } from '@qwickapps/schema';
14
+ import { BaseComponentProps } from '../../hooks/useBaseProps';
15
+ import { ViewSchema } from '../../schemas/ViewSchema';
16
+
17
+ /**
18
+ * ViewProps - Single source of truth for all base component props
19
+ *
20
+ * Extends SchemaProps<ViewSchema> to get all base properties with proper types
21
+ * and adds WithDataBinding for CMS integration. ViewSchema is the authoritative
22
+ * source for all base props including styling, grid, events, accessibility, etc.
23
+ */
24
+ export interface ViewProps extends SchemaProps<ViewSchema>, WithDataBinding {
25
+ // Add children prop for components that need it
26
+ children?: React.ReactNode;
27
+ }
28
+
29
+ /**
30
+ * Type for string event handlers in schema
31
+ */
32
+ type EventHandlerValue = string | React.MouseEventHandler<any> | React.FocusEventHandler<any> | undefined;
33
+
34
+ /**
35
+ * Runtime event handler conversion map
36
+ */
37
+ interface EventHandlers {
38
+ onClick?: React.MouseEventHandler<any>;
39
+ onMouseEnter?: React.MouseEventHandler<any>;
40
+ onMouseLeave?: React.MouseEventHandler<any>;
41
+ onFocus?: React.FocusEventHandler<any>;
42
+ onBlur?: React.FocusEventHandler<any>;
43
+ }
44
+
45
+ /**
46
+ * Convert string event handlers to React function handlers
47
+ * @param eventHandlers - Object containing string or function event handlers
48
+ * @returns Object with converted function handlers
49
+ */
50
+ function parseEventHandlers(eventHandlers: Record<string, EventHandlerValue>): EventHandlers {
51
+ const result: EventHandlers = {};
52
+
53
+ for (const [key, value] of Object.entries(eventHandlers)) {
54
+ if (typeof value === 'string' && value.trim()) {
55
+ try {
56
+ // Convert string to function - safe eval for event handlers
57
+ // This creates a function that executes the string as code
58
+ const func = new Function('event', value);
59
+ result[key as keyof EventHandlers] = func as any;
60
+ } catch (error) {
61
+ console.warn(`Invalid event handler string for ${key}:`, value, error);
62
+ // Keep as undefined for invalid handlers
63
+ }
64
+ } else if (typeof value === 'function') {
65
+ // Already a function, use as-is
66
+ result[key as keyof EventHandlers] = value as any;
67
+ }
68
+ }
69
+
70
+ return result;
71
+ }
72
+
73
+ /**
74
+ * Parse SX props from string or object
75
+ * @param sx - SX prop as string or object
76
+ * @returns Parsed SX props
77
+ */
78
+ function parseSxProps(sx: string | SxProps<Theme> | undefined): SxProps<Theme> | undefined {
79
+ if (!sx) return undefined;
80
+
81
+ if (typeof sx === 'string') {
82
+ try {
83
+ return JSON.parse(sx);
84
+ } catch (error) {
85
+ console.warn('Invalid sx JSON string:', sx, error);
86
+ return undefined;
87
+ }
88
+ }
89
+
90
+ return sx;
91
+ }
92
+
93
+ /**
94
+ * Parse style props from string or object
95
+ * @param style - Style prop as string or object
96
+ * @returns Parsed style props
97
+ */
98
+ function parseStyleProps(style: string | React.CSSProperties | undefined): React.CSSProperties | undefined {
99
+ if (!style) return undefined;
100
+
101
+ if (typeof style === 'string') {
102
+ try {
103
+ return JSON.parse(style);
104
+ } catch (error) {
105
+ console.warn('Invalid style JSON string:', style, error);
106
+ return undefined;
107
+ }
108
+ }
109
+
110
+ return style;
111
+ }
112
+
113
+ /**
114
+ * Coerce grid values from strings to numbers/keywords
115
+ * @param value - Grid value as string or number
116
+ * @returns Coerced value
117
+ */
118
+ function coerceGridValue(value: string | number | undefined): number | 'auto' | 'grow' | undefined {
119
+ if (value === undefined || value === null) return undefined;
120
+
121
+ if (typeof value === 'number') return value;
122
+
123
+ if (typeof value === 'string') {
124
+ // Handle keyword values
125
+ if (value === 'auto' || value === 'grow') return value;
126
+
127
+ // Try to parse as number
128
+ const parsed = parseInt(value, 10);
129
+ if (!isNaN(parsed) && parsed > 0) return parsed;
130
+ }
131
+
132
+ return undefined;
133
+ }
134
+
135
+ /**
136
+ * Normalize ViewProps for runtime use
137
+ *
138
+ * Converts schema-friendly string props to runtime-friendly React props:
139
+ * - Parses sx/style JSON strings
140
+ * - Converts string event handlers to functions
141
+ * - Coerces grid span/breakpoint values from strings to numbers/keywords
142
+ * - Maintains compatibility with BaseComponentProps system
143
+ *
144
+ * @param props - Raw ViewProps from schema
145
+ * @returns Normalized props compatible with useBaseProps
146
+ */
147
+ export function normalizeViewProps<T extends ViewProps>(props: T): T & BaseComponentProps {
148
+ const {
149
+ sx,
150
+ style,
151
+ onClick,
152
+ onMouseEnter,
153
+ onMouseLeave,
154
+ onFocus,
155
+ onBlur,
156
+ span,
157
+ xs,
158
+ sm,
159
+ md,
160
+ lg,
161
+ xl,
162
+ backgroundColor,
163
+ ...restProps
164
+ } = props;
165
+
166
+ // Parse style and sx props
167
+ const normalizedSx = parseSxProps(sx);
168
+ const normalizedStyle = parseStyleProps(style);
169
+
170
+ // Parse event handlers
171
+ const eventHandlers = parseEventHandlers({
172
+ onClick,
173
+ onMouseEnter,
174
+ onMouseLeave,
175
+ onFocus,
176
+ onBlur,
177
+ });
178
+
179
+ // Coerce grid values
180
+ const normalizedGridProps = {
181
+ span: coerceGridValue(span),
182
+ xs: coerceGridValue(xs),
183
+ sm: coerceGridValue(sm),
184
+ md: coerceGridValue(md),
185
+ lg: coerceGridValue(lg),
186
+ xl: coerceGridValue(xl),
187
+ };
188
+
189
+ // Canonicalize background prop (backgroundColor → background)
190
+ const canonicalBackground = (restProps as any).background ?? backgroundColor;
191
+
192
+ // Return normalized props with proper typing
193
+ const normalized = {
194
+ ...restProps,
195
+ ...normalizedGridProps,
196
+ sx: normalizedSx,
197
+ style: normalizedStyle,
198
+ ...eventHandlers,
199
+ // Set canonical background prop
200
+ background: canonicalBackground,
201
+ } as T & BaseComponentProps;
202
+
203
+ // Remove backgroundColor to avoid duplication
204
+ delete (normalized as any).backgroundColor;
205
+
206
+ return normalized;
207
+ }
@@ -107,7 +107,7 @@ describe('AppConfigBuilder', () => {
107
107
  .withId('custom-app')
108
108
  .withShortName('Custom')
109
109
  .withDescription('A custom application')
110
- .withVersion('2.0.0')
110
+ .withVersion('1.0.0')
111
111
  .withLogo('./custom-logo.svg')
112
112
  .withPort(4000)
113
113
  .withPreviewPort(5000)
@@ -118,7 +118,7 @@ describe('AppConfigBuilder', () => {
118
118
 
119
119
  expect(config.app.shortName).toBe('Custom');
120
120
  expect(config.app.description).toBe('A custom application');
121
- expect(config.app.version).toBe('2.0.0');
121
+ expect(config.app.version).toBe('1.0.0');
122
122
  expect(config.app.logo).toBe('./custom-logo.svg');
123
123
  expect(config.build.port).toBe(4000);
124
124
  expect(config.build.previewPort).toBe(5000);
@@ -202,7 +202,7 @@ export function useResolveTemplate(template: string) {
202
202
  let isMounted = true;
203
203
 
204
204
  async function resolve() {
205
- if (!template || !template.includes('{{')) {
205
+ if (!template) {
206
206
  setResolved(template);
207
207
  return;
208
208
  }
@@ -6,10 +6,11 @@
6
6
 
7
7
  import { IsBoolean, IsOptional, IsString, IsIn } from 'class-validator';
8
8
  import 'reflect-metadata';
9
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
9
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
10
+ import { ViewSchema } from './ViewSchema';
10
11
 
11
12
  @Schema('Button', '1.0.0')
12
- export class ButtonModel extends Model {
13
+ export class ButtonModel extends ViewSchema {
13
14
  @Field()
14
15
  @Editor({
15
16
  field_type: FieldType.TEXT,
@@ -6,10 +6,11 @@
6
6
 
7
7
  import { IsArray, IsOptional, IsNumber, IsIn, IsBoolean, IsObject, IsString } from 'class-validator';
8
8
  import 'reflect-metadata';
9
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
9
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
10
+ import { ContainerSchema } from './ContainerSchema';
10
11
 
11
12
  @Schema('CardListGrid', '1.0.0')
12
- export class CardListGridModel extends Model {
13
+ export class CardListGridModel extends ContainerSchema {
13
14
  @Field()
14
15
  @Editor({
15
16
  field_type: FieldType.REPEATER,
@@ -6,10 +6,11 @@
6
6
 
7
7
  import { IsArray, IsBoolean, IsNumber, IsOptional, IsString } from 'class-validator';
8
8
  import 'reflect-metadata';
9
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
9
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
10
+ import { ViewSchema } from './ViewSchema';
10
11
 
11
12
  @Schema('ChoiceInputField', '1.0.0')
12
- export class ChoiceInputFieldModel extends Model {
13
+ export class ChoiceInputFieldModel extends ViewSchema {
13
14
  @Field()
14
15
  @Editor({
15
16
  field_type: FieldType.TEXT,
@@ -7,19 +7,21 @@
7
7
  import type { ReactNode } from 'react';
8
8
  import { IsBoolean, IsOptional, IsString } from 'class-validator';
9
9
  import 'reflect-metadata';
10
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
10
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
11
+ import ViewSchema from './ViewSchema';
11
12
 
12
13
  @Schema('Code', '1.0.0')
13
- export class CodeModel extends Model {
14
+ export class CodeModel extends ViewSchema {
14
15
  @Field()
15
16
  @Editor({
16
17
  field_type: FieldType.TEXTAREA,
17
- label: 'Code Content',
18
- description: 'The code content to display with syntax highlighting',
18
+ label: 'Content',
19
+ description: 'Raw code text. If provided, React children are ignored in serialization.',
19
20
  placeholder: 'Enter code content...'
20
21
  })
21
- @IsString() // Schema validation: must be string for serialization
22
- children?: ReactNode; // Runtime type: supports natural React usage
22
+ @IsOptional()
23
+ @IsString()
24
+ content?: string;
23
25
 
24
26
  @Field()
25
27
  @Editor({
@@ -0,0 +1,25 @@
1
+ /**
2
+ * ContainerSchema - Comprehensive base class for all container components
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+
7
+ import { Editor, Field, FieldType, Schema } from '@qwickapps/schema';
8
+ import { IsOptional, IsString } from 'class-validator';
9
+ import type { ReactNode } from 'react';
10
+ import 'reflect-metadata';
11
+ import ViewSchema from './ViewSchema';
12
+
13
+ @Schema('ContainerSchema', '1.0.0')
14
+ export class ContainerSchema extends ViewSchema {
15
+ @Field()
16
+ @Editor({
17
+ field_type: FieldType.TEXTAREA,
18
+ label: 'Content',
19
+ description: 'Main content shown when expanded (HTML supported)',
20
+ placeholder: 'Enter main content...'
21
+ })
22
+ @IsOptional()
23
+ @IsString()
24
+ children?: ReactNode;
25
+ }
@@ -80,7 +80,7 @@ export class FeatureCardActionModel extends Model {
80
80
  disabled?: boolean;
81
81
  }
82
82
 
83
- @Schema('FeatureCard', '2.0.0')
83
+ @Schema('FeatureCard', '1.0.0')
84
84
  export class FeatureCardModel extends Model {
85
85
  @Field({ type: DataType.OBJECT })
86
86
  @Editor({
@@ -6,10 +6,11 @@
6
6
 
7
7
  import { IsBoolean, IsIn, IsOptional, IsString } from 'class-validator';
8
8
  import 'reflect-metadata';
9
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
9
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
10
+ import { ContainerSchema } from './ContainerSchema';
10
11
 
11
12
  @Schema('FormBlock', '1.0.0')
12
- export class FormBlockModel extends Model {
13
+ export class FormBlockModel extends ContainerSchema {
13
14
  @Field()
14
15
  @Editor({
15
16
  field_type: FieldType.TEXT,
@@ -7,18 +7,12 @@
7
7
  import type { ReactNode } from 'react';
8
8
  import { IsOptional, IsString, IsNumber, IsIn } from 'class-validator';
9
9
  import 'reflect-metadata';
10
- import { Editor, Field, Schema, Model, FieldType } from '@qwickapps/schema';
10
+ import { Editor, Field, Schema, FieldType } from '@qwickapps/schema';
11
+ import { ContainerSchema } from './ContainerSchema';
11
12
 
12
13
  @Schema('GridCell', '1.0.0')
13
- export class GridCellModel extends Model {
14
- @Field()
15
- @Editor({
16
- field_type: FieldType.TEXTAREA,
17
- label: 'Children',
18
- description: 'Content to display inside the grid cell',
19
- placeholder: 'Nested components will be serialized automatically'
20
- })
21
- children?: ReactNode; // Runtime type: supports natural React usage
14
+ export class GridCellModel extends ContainerSchema {
15
+ // children field inherited from ContainerSchema
22
16
 
23
17
  // Grid responsive properties
24
18
  @Field()