@qwickapps/react-framework 1.4.1 → 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 +221 -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
@@ -28,11 +28,39 @@ const patternRegistry = new Map<string, PatternHandler>();
28
28
  */
29
29
  export type PatternHandler = (element: Element) => any;
30
30
 
31
+ /**
32
+ * Strict mode: throw on unregistered components
33
+ * When true, the transformer will throw errors instead of using fallback
34
+ */
35
+ let strictMode = true;
36
+
37
+ /**
38
+ * Fallback tag for unregistered components / html / text (legacy mode only)
39
+ */
40
+ const FALLBACK_TAG = '__react_node__';
41
+ const FALLBACK_VERSION = '1.0.0';
42
+
31
43
  /**
32
44
  * Core transformer for React component serialization
33
45
  * Provides static methods for component registration and transformation
34
46
  */
35
47
  export class ComponentTransformer {
48
+ /**
49
+ * Enable or disable strict mode
50
+ * @param enabled - Whether to enable strict mode (throws on unregistered components)
51
+ */
52
+ static setStrictMode(enabled: boolean): void {
53
+ strictMode = enabled;
54
+ }
55
+
56
+ /**
57
+ * Check if strict mode is enabled
58
+ * @returns True if strict mode is enabled
59
+ */
60
+ static isStrictMode(): boolean {
61
+ return strictMode;
62
+ }
63
+
36
64
  /**
37
65
  * Register a component class for serialization
38
66
  * Component must declare its own tagName and version via static properties
@@ -40,21 +68,26 @@ export class ComponentTransformer {
40
68
  */
41
69
  static registerComponent(componentClass: SerializableConstructor): void {
42
70
  const { tagName, version } = componentClass;
43
-
71
+
44
72
  if (!tagName || typeof tagName !== 'string') {
45
73
  throw new Error(`Component class must have a static 'tagName' property`);
46
74
  }
47
-
75
+
48
76
  if (!version || typeof version !== 'string') {
49
- throw new Error(`Component class must have a static 'version' property`);
77
+ throw new Error(`Component class '${tagName}' must have a static 'version' property`);
50
78
  }
51
-
79
+
80
+ if (typeof (componentClass as any).fromJson !== 'function') {
81
+ throw new Error(`Component class '${tagName}' must implement static 'fromJson' method`);
82
+ }
83
+
52
84
  if (componentRegistry.has(tagName)) {
53
85
  console.warn(`Component '${tagName}' is already registered. Overwriting existing registration.`);
54
86
  }
55
-
87
+
88
+ console.log(`TEST: Registering component: ${tagName} (version ${version})`);
56
89
  componentRegistry.set(tagName, componentClass);
57
-
90
+
58
91
  // Register HTML patterns if component supports them
59
92
  if (typeof (componentClass as any).registerPatternHandlers === 'function') {
60
93
  (componentClass as any).registerPatternHandlers(ComponentTransformer);
@@ -63,185 +96,169 @@ export class ComponentTransformer {
63
96
 
64
97
  /**
65
98
  * Serialize React node(s) to JSON string
66
- * @param node - React node or array of nodes to serialize
67
- * @returns JSON string representation
99
+ * In strict mode: throws on unregistered components
100
+ * In legacy mode: uses fallback tag for unregistered components/html/text
68
101
  */
69
102
  static serialize(node: ReactNode | ReactNode[]): string {
70
- const serializedData = ComponentTransformer.serializeNode(node);
103
+ const serializedData = ComponentTransformer.serializeNode(node as any);
71
104
  return JSON.stringify(serializedData);
72
105
  }
73
106
 
74
107
  /**
75
108
  * Deserialize JSON input to React node(s)
76
- * @param input - JSON string or parsed object/array to deserialize
77
- * @returns React node or array of nodes
109
+ * In strict mode: throws on unregistered components
110
+ * In legacy mode: never throws; always returns a valid ReactNode (or array) or null
111
+ * - Strings: try JSON.parse; if fails, return the string as a text node
112
+ * - Objects/arrays: only schema objects are transformed; non-schema become text via JSON.stringify
78
113
  */
79
114
  static deserialize(input: string | object | object[]): ReactNode | ReactNode[] {
80
- let parsedData: any;
81
-
82
- // Handle string input - parse JSON only if it looks like JSON
83
115
  if (typeof input === 'string') {
84
- // Check if string looks like JSON (starts with { [ or " or is a boolean/number/null)
85
- const trimmed = input.trim();
86
- if (trimmed.startsWith('{') || trimmed.startsWith('[') || trimmed.startsWith('"') ||
87
- trimmed === 'null' || trimmed === 'true' || trimmed === 'false' ||
88
- (!isNaN(Number(trimmed)) && trimmed !== '')) {
89
- try {
90
- parsedData = JSON.parse(input);
91
- } catch (error) {
92
- throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
93
- }
94
- } else {
95
- // For strings that contain JSON-like characters but aren't valid JSON, try to parse anyway
96
- if (trimmed.includes('{') || trimmed.includes('[')) {
97
- try {
98
- parsedData = JSON.parse(input);
99
- } catch (error) {
100
- throw new Error(`Invalid JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
101
- }
102
- } else {
103
- // Treat as plain string
104
- parsedData = input;
105
- }
116
+ try {
117
+ const parsed = JSON.parse(input);
118
+ return ComponentTransformer.deserializeData(parsed);
119
+ } catch {
120
+ // Not JSON; plain string is a valid ReactNode
121
+ return input;
106
122
  }
107
- } else {
108
- parsedData = input;
109
123
  }
110
124
 
111
- return ComponentTransformer.deserializeData(parsedData);
125
+ if (input == null) return null;
126
+ return ComponentTransformer.deserializeData(input as any);
112
127
  }
113
128
 
114
129
  /**
115
- * Internal method to serialize a single React node
116
- * @param node - React node to serialize
117
- * @returns Serializable data structure
130
+ * Type guard for serialized component schema objects
131
+ * Requires: { tagName: string; version: string; data: any }
132
+ * Optional: key?: string
133
+ */
134
+ private static isSerializedComponent(obj: any): obj is { tagName: string; version: string; data: any; key?: string } {
135
+ return !!obj
136
+ && typeof obj === 'object'
137
+ && typeof (obj as any).tagName === 'string'
138
+ && typeof (obj as any).version === 'string'
139
+ && 'data' in (obj as any);
140
+ }
141
+
142
+ /**
143
+ * Internal method to deserialize data back to React nodes
144
+ * @param data - Data to deserialize
145
+ * @returns React node(s)
118
146
  */
119
- private static serializeNode(node: ReactNode): any {
120
- if (node === null || node === undefined) {
121
- return null;
122
- }
147
+ private static deserializeData(data: any): ReactNode | ReactNode[] {
148
+ if (data == null) return null;
123
149
 
124
- // Handle arrays of nodes
125
- if (Array.isArray(node)) {
126
- return node.map(child => ComponentTransformer.serializeNode(child));
150
+ // Arrays: map recursively
151
+ if (Array.isArray(data)) {
152
+ return data.map(item => ComponentTransformer.deserializeData(item));
127
153
  }
128
154
 
129
- // Handle primitive values
130
- if (typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {
131
- return node;
132
- }
155
+ if (ComponentTransformer.isSerializedComponent(data)) {
156
+ const { key, tagName, data: componentData } = data;
133
157
 
134
- // Handle plain objects (non-React elements)
135
- if (typeof node === 'object' && node !== null && !('type' in node)) {
136
- // For plain objects, try to serialize recursively or convert to string
137
158
  try {
138
- const serialized: any = {};
139
- for (const [key, value] of Object.entries(node)) {
140
- serialized[key] = ComponentTransformer.serializeNode(value);
159
+ const componentClass = componentRegistry.get(tagName);
160
+
161
+ if (!componentClass) {
162
+ if (strictMode) {
163
+ throw new Error(`Component '${tagName}' is not registered in strict mode`);
164
+ }
165
+ // Legacy fallback
166
+ const node = ComponentTransformer.deserializeUnregisteredComponent(componentData);
167
+ return key ? React.cloneElement(node as ReactElement, { key }) : node;
141
168
  }
142
- return serialized;
143
- } catch {
144
- return String(node);
145
- }
146
- }
147
169
 
148
- // Handle React elements
149
- if (typeof node === 'object' && node !== null && 'type' in node) {
150
- const element = node as ReactElement;
151
-
152
- // Check if this is a registered component
153
- const componentType = element.type;
154
- if (typeof componentType === 'function') {
155
- // Find the tag name for this component
156
- const tagName = ComponentTransformer.findTagNameForComponent(componentType);
157
- if (tagName) {
158
- const componentClass = componentRegistry.get(tagName)!;
159
- // Create a temporary instance to call toJson
160
- const instance = new (componentClass as any)(element.props);
161
- const serializedData = instance.toJson();
162
-
163
- return {
164
- tag: tagName,
165
- version: componentClass.version,
166
- data: serializedData
167
- };
170
+ const node = componentClass.fromJson(data);
171
+ // Apply key if provided
172
+ return key ? React.cloneElement(node as ReactElement, { key }) : node;
173
+ } catch (error) {
174
+ if (strictMode) {
175
+ throw error; // Re-throw in strict mode
168
176
  }
177
+ console.error(`TEST: Error deserializing component '${tagName}':`, error);
169
178
  }
170
-
171
- // For unregistered components, use ReactNodeTransformer fallback
172
- return ComponentTransformer.serializeUnregisteredComponent(element);
173
179
  }
174
180
 
175
- // Fallback for other node types
176
- return String(node);
181
+ console.warn(`TEST: Unrecognized data:`, data);
182
+ return String(data);
177
183
  }
178
184
 
179
185
  /**
180
- * Internal method to deserialize data back to React nodes
181
- * @param data - Data to deserialize
182
- * @returns React node(s)
186
+ * Internal method to serialize a single React node
187
+ * @param node - React node to serialize
188
+ * @returns Serializable data structure { tagName, version, data }
183
189
  */
184
- private static deserializeData(data: any): ReactNode | ReactNode[] {
185
- if (data === null || data === undefined) {
186
- return null;
187
- }
190
+ private static serializeNode(node: any): any {
191
+ if (node == null) return null;
188
192
 
189
- // Handle arrays
190
- if (Array.isArray(data)) {
191
- return data.map(item => ComponentTransformer.deserializeData(item));
193
+ // Handle arrays of nodes (produce array of schema objects/null)
194
+ if (Array.isArray(node)) {
195
+ return node.map(child => ComponentTransformer.serializeNode(child));
192
196
  }
193
197
 
194
- // Handle primitive values
195
- if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean') {
196
- return data;
198
+ // Handle primitive values (strings, numbers, booleans) - these are valid React children
199
+ if (typeof node === 'string' || typeof node === 'number' || typeof node === 'boolean') {
200
+ return node;
197
201
  }
198
202
 
199
- // Handle serialized component data
200
- if (typeof data === 'object' && data.tag) {
201
- const { tag, data: componentData } = data;
202
-
203
- // Handle unregistered components using ReactNodeTransformer
204
- if (tag === '__react_node__') {
205
- return ComponentTransformer.deserializeUnregisteredComponent(componentData);
206
- }
207
-
208
- const componentClass = componentRegistry.get(tag);
209
- if (!componentClass) {
210
- // Fallback to ReactNodeTransformer for unknown registered components
211
- console.warn(`Unknown component: ${tag}. Using ReactNodeTransformer fallback.`);
212
- return ComponentTransformer.deserializeUnregisteredComponent(componentData);
213
- }
203
+ // React elements
204
+ if (typeof node === 'object' && 'type' in node) {
205
+ const element = node as ReactElement;
206
+ const key = element.key ? { key: String(element.key) } : {};
214
207
 
215
- // Validate that componentData exists
216
- if (componentData === undefined) {
217
- throw new Error(`Malformed component data: missing 'data' property for component '${tag}'`);
218
- }
208
+ // Registered component?
209
+ const componentType = element.type;
210
+ if (typeof componentType === 'function') {
211
+ const tagName = ComponentTransformer.findTagNameForComponent(componentType);
212
+ if (tagName) {
213
+ console.log(`TEST: Serializing component instance of ${tagName}:`, element.props);
214
+ const componentClass = componentRegistry.get(tagName)!;
219
215
 
220
- // Call static fromJson method to recreate the component
221
- return componentClass.fromJson(componentData);
222
- }
216
+ let serializedData: any = null;
217
+ console.log(`TEST: Element type:`, typeof (element as any).toJson);
218
+ console.log(`TEST: Component type:`, typeof (componentClass as any).toJson);
219
+ if (typeof (componentClass as any).toJson === 'function') {
220
+ console.log(`TEST: Serializing via component toJson method ${tagName}:`, element.props);
221
+ serializedData = (componentClass as any).toJson(element.props);
222
+ }
223
223
 
224
- // Fallback - return as-is
225
- return data;
226
- }
224
+ if (serializedData !== null) {
225
+ // Process children recursively if they exist in the data
226
+ if (serializedData.data && serializedData.data.children !== undefined) {
227
+ serializedData.data.children = ComponentTransformer.serializeNode(serializedData.data.children);
228
+ }
229
+
230
+ const result = {
231
+ ...key,
232
+ ...serializedData
233
+ };
234
+ console.log(`TEST: Serialized component ${tagName}:`, result);
235
+ return result;
236
+ }
237
+ } else if (strictMode) {
238
+ // In strict mode, throw if we can't find a tag name for the component
239
+ const componentName = (componentType as any).displayName || (componentType as any).name || 'Unknown';
240
+ throw new Error(`Unregistered component '${componentName}' cannot be serialized in strict mode`);
241
+ }
242
+ }
243
+ }
227
244
 
245
+ if (strictMode) {
246
+ throw new Error(`Cannot serialize unregistered node in strict mode: ${typeof node === 'object' && node && 'type' in node ? node.type : typeof node}`);
247
+ }
228
248
 
229
- /**
230
- * Serialize unregistered React components using ReactNodeTransformer
231
- * @param element - React element to serialize
232
- * @returns Serializable data structure
233
- */
234
- private static serializeUnregisteredComponent(element: ReactElement): any {
235
- return {
236
- tag: '__react_node__',
237
- version: '1.0.0',
238
- data: ReactNodeTransformer.serialize(element)
249
+ const result = {
250
+ tagName: FALLBACK_TAG,
251
+ version: FALLBACK_VERSION,
252
+ data: ReactNodeTransformer.serialize(node)
239
253
  };
254
+ console.log(`TEST: Serialized unregistered node as ${FALLBACK_TAG}:`, result, node);
255
+ console.log(`TEST: Component Registry:`, componentRegistry);
256
+ return result;
240
257
  }
241
258
 
242
259
  /**
243
- * Deserialize unregistered components using ReactNodeTransformer
244
- * @param data - Serialized data
260
+ * Deserialize unregistered nodes using ReactNodeTransformer
261
+ * @param data - Serialized data from ReactNodeTransformer
245
262
  * @returns React node
246
263
  */
247
264
  private static deserializeUnregisteredComponent(data: any): ReactNode {
@@ -254,14 +271,30 @@ export class ComponentTransformer {
254
271
  * @returns Tag name or null if not found
255
272
  */
256
273
  private static findTagNameForComponent(componentType: any): string | null {
257
- const entries = Array.from(componentRegistry.entries());
258
- for (const [tagName, registeredClass] of entries) {
259
- // This is a simplified check - in a real implementation you might need
260
- // more sophisticated matching based on the component's static methods
261
- if (registeredClass === componentType) {
262
- return tagName;
263
- }
274
+ // Direct constructor match
275
+ for (const [tagName, registeredClass] of componentRegistry.entries()) {
276
+ if (registeredClass === componentType) return tagName;
277
+ }
278
+
279
+ // If the component exposes a tagName, prefer it
280
+ const explicitTag = componentType?.tagName;
281
+ if (typeof explicitTag === 'string' && componentRegistry.has(explicitTag)) {
282
+ return explicitTag;
283
+ }
284
+
285
+ // Unwrap common HOC/wrapper names
286
+ const name: string | undefined = componentType?.displayName || componentType?.name;
287
+ if (name) {
288
+ // ForwardRef(Typography) -> Typography, Styled(Typography) -> Typography
289
+ // WithDataBinding(Text) -> Text, TextWithDataBinding -> Text
290
+ const unwrapped =
291
+ name.replace(/^[A-Za-z]+?\(([^)]+)\)$/, '$1')
292
+ .replace(/WithDataBinding$/, '');
293
+
294
+ if (componentRegistry.has(unwrapped)) return unwrapped;
295
+ if (componentRegistry.has(name)) return name;
264
296
  }
297
+
265
298
  return null;
266
299
  }
267
300
 
@@ -310,7 +343,6 @@ export class ComponentTransformer {
310
343
  * @returns React node if pattern matches, null otherwise
311
344
  */
312
345
  static transformHTMLElement(element: Element): ReactNode | null {
313
- // Find matching pattern handler
314
346
  for (const [pattern, handler] of patternRegistry) {
315
347
  if (element.matches(pattern)) {
316
348
  try {
@@ -322,7 +354,7 @@ export class ComponentTransformer {
322
354
  }
323
355
  }
324
356
  }
325
- return null; // No pattern matched
357
+ return null;
326
358
  }
327
359
 
328
360
  /**
@@ -331,13 +363,9 @@ export class ComponentTransformer {
331
363
  * @returns Array of React nodes
332
364
  */
333
365
  static transformHTML(html: string): ReactNode[] {
334
- if (!html.trim()) {
335
- return [];
336
- }
337
-
366
+ if (!html.trim()) return [];
338
367
  const parser = new DOMParser();
339
368
  const doc = parser.parseFromString(html, 'text/html');
340
-
341
369
  return Array.from(doc.body.children).map((element, index) =>
342
370
  ComponentTransformer.transformElement(element, `element-${index}`)
343
371
  );
@@ -350,28 +378,22 @@ export class ComponentTransformer {
350
378
  * @returns React node
351
379
  */
352
380
  private static transformElement(element: Element, key: string): ReactNode {
353
- // Try to find a registered pattern handler
354
381
  const transformedNode = ComponentTransformer.transformHTMLElement(element);
355
- if (transformedNode) {
356
- return transformedNode;
357
- }
382
+ if (transformedNode) return transformedNode;
358
383
 
359
- // No pattern matched - check for nested transformable content
360
384
  const children = Array.from(element.children);
361
- const hasTransformableChildren = children.some(child =>
385
+ const hasTransformableChildren = children.some(child =>
362
386
  Array.from(patternRegistry.keys()).some(pattern => child.matches(pattern))
363
387
  );
364
388
 
365
389
  if (hasTransformableChildren) {
366
- // Transform children recursively
367
390
  const transformedChildren = children.map((child, index) =>
368
391
  ComponentTransformer.transformElement(child, `${key}-${index}`)
369
392
  );
370
-
371
- // Create element with transformed children
393
+
372
394
  return React.createElement(
373
395
  element.tagName.toLowerCase(),
374
- {
396
+ {
375
397
  key,
376
398
  className: element.className || undefined,
377
399
  id: element.id || undefined
@@ -8,8 +8,8 @@
8
8
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
9
9
  */
10
10
 
11
- import { ReactNode, ReactElement, isValidElement, createElement } from 'react';
12
- import SafeSpan from '../../components/SafeSpan';
11
+ import { ReactElement, ReactNode, createElement, isValidElement } from 'react';
12
+ import { Html } from '../../components/Html';
13
13
 
14
14
  /**
15
15
  * Transformer for standard React content and HTML elements
@@ -45,12 +45,23 @@ export class ReactNodeTransformer {
45
45
  // Handle React elements
46
46
  if (isValidElement(node)) {
47
47
  const element = node as ReactElement;
48
-
48
+ console.log(`TEST: isValidElement:`, element);
49
+
50
+ const comp: any = element.type;
51
+ const rawName =
52
+ typeof comp === 'string'
53
+ ? comp
54
+ : comp?.render?.name || comp?.name || comp?.muiName || comp?.displayName || 'Anonymous';
55
+
56
+ // Normalize wrapper names like ForwardRef(Typography), Styled(Typography)
57
+ const displayName =
58
+ typeof rawName === 'string'
59
+ ? (rawName.match(/^[A-Za-z]+?\(([^)]+)\)$/)?.[1] || rawName)
60
+ : 'Anonymous';
61
+
49
62
  return {
50
63
  type: 'react-element',
51
- elementType: typeof element.type === 'string'
52
- ? element.type
53
- : (element.type as any).name || 'Anonymous',
64
+ elementType: displayName,
54
65
  props: ReactNodeTransformer.serializeProps(element.props),
55
66
  key: element.key
56
67
  };
@@ -94,16 +105,16 @@ export class ReactNodeTransformer {
94
105
  switch (data.type) {
95
106
  case 'primitive':
96
107
  return data.value;
97
-
108
+
98
109
  case 'string':
99
110
  return data.value;
100
-
111
+
101
112
  case 'array':
102
113
  return data.children?.map((child: any) => ReactNodeTransformer.deserialize(child)) || [];
103
-
114
+
104
115
  case 'react-element':
105
116
  return ReactNodeTransformer.deserializeReactElement(data);
106
-
117
+
107
118
  case 'object':
108
119
  const result: any = {};
109
120
  if (data.data && typeof data.data === 'object') {
@@ -112,7 +123,7 @@ export class ReactNodeTransformer {
112
123
  }
113
124
  }
114
125
  return result;
115
-
126
+
116
127
  default:
117
128
  return String(data.value || data);
118
129
  }
@@ -165,23 +176,15 @@ export class ReactNodeTransformer {
165
176
  // Handle HTML elements
166
177
  if (typeof elementType === 'string') {
167
178
  const deserializedProps = ReactNodeTransformer.deserializeProps(props);
179
+ console.log(`TEST: Create Element:`, elementType, deserializedProps);
168
180
  return createElement(elementType, { key, ...deserializedProps });
169
181
  }
170
-
171
- // For unknown component types, check if we have HTML content
172
- if (props && typeof props.children === 'string' && props.children.includes('<')) {
173
- // Use SafeSpan component to render HTML content safely
174
- return createElement(SafeSpan, { key, html: props.children });
175
- }
176
-
177
- // Fallback to div with text content
178
- const textContent = ReactNodeTransformer.extractTextContent(props);
179
- return createElement('div', { key }, textContent || `Unknown component: ${elementType}`);
180
-
181
182
  } catch (error) {
182
183
  console.warn('Error deserializing React element:', error);
183
- return createElement('div', { key }, `Error rendering component: ${elementType}`);
184
184
  }
185
+
186
+ // Use Html component to render HTML content safely
187
+ return createElement(Html, { key, children: props.children });
185
188
  }
186
189
 
187
190
  /**
@@ -214,23 +217,23 @@ export class ReactNodeTransformer {
214
217
  */
215
218
  private static extractTextContent(props: any): string | null {
216
219
  if (!props) return null;
217
-
220
+
218
221
  if (typeof props.children === 'string') {
219
222
  return props.children;
220
223
  }
221
-
224
+
222
225
  if (props.title && typeof props.title === 'string') {
223
226
  return props.title;
224
227
  }
225
-
228
+
226
229
  if (props.label && typeof props.label === 'string') {
227
230
  return props.label;
228
231
  }
229
-
232
+
230
233
  if (props.text && typeof props.text === 'string') {
231
234
  return props.text;
232
235
  }
233
-
236
+
234
237
  return null;
235
238
  }
236
239
  }
@@ -8,27 +8,34 @@
8
8
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
9
9
  */
10
10
 
11
- import { ComponentTransformer } from './ComponentTransformer';
11
+ import { Container } from '../../components/base/Container';
12
12
  import { Code } from '../../components/blocks/Code';
13
- import { Section } from '../../components/blocks/Section';
13
+ import { HeroBlock } from '../../components/blocks/HeroBlock';
14
14
  import { Image } from '../../components/blocks/Image';
15
+ import { Section } from '../../components/blocks/Section';
15
16
  import { Text } from '../../components/blocks/Text';
16
- import { HeroBlock } from '../../components/blocks/HeroBlock';
17
- import Button from '../../components/buttons/Button';
18
- import { GridLayout } from '../../components/layout/GridLayout';
19
- import { GridCell } from '../../components/layout/GridCell';
20
- import { TextInputField } from '../../components/input/TextInputField';
21
- import { SelectInputField } from '../../components/input/SelectInputField';
22
- import { HtmlInputField } from '../../components/input/HtmlInputField';
17
+ import { Button } from '../../components/buttons/Button';
18
+ import { FormBlock } from '../../components/forms/FormBlock';
23
19
  import { ChoiceInputField } from '../../components/input/ChoiceInputField';
20
+ import { HtmlInputField } from '../../components/input/HtmlInputField';
21
+ import { SelectInputField } from '../../components/input/SelectInputField';
24
22
  import { SwitchInputField } from '../../components/input/SwitchInputField';
25
- import { FormBlock } from '../../components/forms/FormBlock';
23
+ import { TextInputField } from '../../components/input/TextInputField';
24
+ import { GridCell } from '../../components/layout/GridCell';
25
+ import { GridLayout } from '../../components/layout/GridLayout';
26
+ import { ComponentTransformer } from './ComponentTransformer';
26
27
 
27
28
  /**
28
29
  * Register all serializable components with the ComponentTransformer
29
30
  * This function should be called once during application initialization
31
+ *
32
+ * Phase 0: Foundation in place - ready for component migration
33
+ * Phase 1+: Components will be migrated to createSerializableView factory
30
34
  */
31
35
  export function registerSerializableComponents(): void {
36
+ // Register Container component - Base layout component with child serialization support
37
+ ComponentTransformer.registerComponent(Container as any);
38
+
32
39
  // Register Code component - First production component with serialization support
33
40
  ComponentTransformer.registerComponent(Code as any);
34
41