@qwickapps/react-framework 1.3.4 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (325) hide show
  1. package/README.md +1688 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/Content.d.ts.map +1 -1
  28. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  30. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  31. package/dist/components/blocks/Footer.d.ts.map +1 -1
  32. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  33. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  34. package/dist/components/blocks/Image.d.ts +41 -0
  35. package/dist/components/blocks/Image.d.ts.map +1 -0
  36. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  37. package/dist/components/blocks/ProductCard.d.ts.map +1 -1
  38. package/dist/components/blocks/Section.d.ts +16 -2
  39. package/dist/components/blocks/Section.d.ts.map +1 -1
  40. package/dist/components/blocks/Text.d.ts +41 -0
  41. package/dist/components/blocks/Text.d.ts.map +1 -0
  42. package/dist/components/blocks/index.d.ts +4 -0
  43. package/dist/components/blocks/index.d.ts.map +1 -1
  44. package/dist/components/buttons/Button.d.ts +23 -7
  45. package/dist/components/buttons/Button.d.ts.map +1 -1
  46. package/dist/components/forms/FormBlock.d.ts +19 -13
  47. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  48. package/dist/components/index.d.ts +4 -0
  49. package/dist/components/index.d.ts.map +1 -1
  50. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  51. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  52. package/dist/components/input/HtmlInputField.d.ts +17 -11
  53. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  54. package/dist/components/input/SelectInputField.d.ts +16 -10
  55. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  56. package/dist/components/input/SwitchInputField.d.ts +16 -10
  57. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  58. package/dist/components/input/TextField.d.ts.map +1 -1
  59. package/dist/components/input/TextInputField.d.ts +16 -11
  60. package/dist/components/input/TextInputField.d.ts.map +1 -1
  61. package/dist/components/layout/GridCell.d.ts +23 -6
  62. package/dist/components/layout/GridCell.d.ts.map +1 -1
  63. package/dist/components/layout/GridLayout.d.ts +24 -23
  64. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  65. package/dist/components/pages/FormPage.d.ts.map +1 -1
  66. package/dist/components/pages/Page.d.ts +49 -87
  67. package/dist/components/pages/Page.d.ts.map +1 -1
  68. package/dist/components/pages/index.d.ts +2 -2
  69. package/dist/components/pages/index.d.ts.map +1 -1
  70. package/dist/config/AppConfig.d.ts +49 -0
  71. package/dist/config/AppConfig.d.ts.map +1 -0
  72. package/dist/config/AppConfigBuilder.d.ts +75 -0
  73. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  74. package/dist/config/index.d.ts +13 -0
  75. package/dist/config/index.d.ts.map +1 -0
  76. package/dist/config/types.d.ts +130 -0
  77. package/dist/config/types.d.ts.map +1 -0
  78. package/dist/config.d.ts +15 -0
  79. package/dist/config.d.ts.map +1 -0
  80. package/dist/config.esm.js +451 -0
  81. package/dist/config.js +455 -0
  82. package/dist/contexts/PrintModeContext.d.ts +27 -0
  83. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  84. package/dist/contexts/QwickAppContext.d.ts +2 -2
  85. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  86. package/dist/contexts/ThemeContext.d.ts.map +1 -1
  87. package/dist/contexts/index.d.ts +2 -0
  88. package/dist/contexts/index.d.ts.map +1 -1
  89. package/dist/hooks/index.d.ts +2 -0
  90. package/dist/hooks/index.d.ts.map +1 -1
  91. package/dist/hooks/usePrintMode.d.ts +39 -0
  92. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  93. package/dist/index.css +1 -1
  94. package/dist/index.d.ts +1 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.esm.css +1 -1
  97. package/dist/index.esm.js +20722 -16021
  98. package/dist/index.js +20725 -16010
  99. package/dist/schemas/CodeSchema.d.ts +2 -1
  100. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  101. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  102. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  103. package/dist/schemas/ContentSchema.d.ts +2 -1
  104. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  105. package/dist/schemas/GridCellSchema.d.ts +25 -0
  106. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  107. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  108. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  109. package/dist/schemas/HtmlSchema.d.ts +14 -0
  110. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  111. package/dist/schemas/ImageSchema.d.ts +32 -0
  112. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  113. package/dist/schemas/LogoSchema.d.ts +35 -0
  114. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  115. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  116. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  117. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  118. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  119. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  120. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  121. package/dist/schemas/SectionSchema.d.ts +2 -1
  122. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  123. package/dist/schemas/TextSchema.d.ts +37 -0
  124. package/dist/schemas/TextSchema.d.ts.map +1 -0
  125. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  126. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  127. package/dist/schemas/index.d.ts +15 -1
  128. package/dist/schemas/index.d.ts.map +1 -1
  129. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  130. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  131. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  132. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  133. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  134. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  135. package/dist/schemas/transformers/registry.d.ts +15 -0
  136. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  137. package/dist/schemas/types/Serializable.d.ts +46 -0
  138. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  139. package/dist/utils/htmlTransform.d.ts.map +1 -1
  140. package/dist/utils/reactUtils.d.ts +12 -3
  141. package/dist/utils/reactUtils.d.ts.map +1 -1
  142. package/package.json +17 -3
  143. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  145. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  148. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  150. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  152. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  154. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  155. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  156. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  158. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  159. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  160. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  161. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  162. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  163. package/src/__tests__/components/Logo.test.js +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  165. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  166. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  167. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  168. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  169. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  172. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  173. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  174. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  175. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  176. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  177. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  178. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  179. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  180. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  181. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  182. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  183. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  184. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  185. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  186. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  187. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  188. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  189. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  190. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  191. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  192. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  193. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  194. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  195. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  196. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  197. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  198. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  199. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  200. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  201. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  202. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  203. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  204. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  205. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  206. package/src/components/ErrorBoundary.tsx +8 -8
  207. package/src/components/Html.tsx +147 -44
  208. package/src/components/Logo.tsx +198 -100
  209. package/src/components/Markdown.tsx +125 -16
  210. package/src/components/QwickApp.tsx +64 -31
  211. package/src/components/QwickIcon.tsx +59 -0
  212. package/src/components/SafeSpan.tsx +65 -10
  213. package/src/components/Scaffold.tsx +2 -8
  214. package/src/components/base/ModelView.tsx +199 -0
  215. package/src/components/base/index.ts +11 -0
  216. package/src/components/blocks/Article.tsx +57 -18
  217. package/src/components/blocks/Code.md +529 -0
  218. package/src/components/blocks/Code.tsx +102 -15
  219. package/src/components/blocks/Content.tsx +25 -77
  220. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  221. package/src/components/blocks/FeatureCard.tsx +1 -2
  222. package/src/components/blocks/FeatureGrid.tsx +19 -1
  223. package/src/components/blocks/Footer.tsx +13 -1
  224. package/src/components/blocks/HeroBlock.tsx +87 -20
  225. package/src/components/blocks/Image.tsx +395 -0
  226. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  227. package/src/components/blocks/ProductCard.tsx +51 -52
  228. package/src/components/blocks/Section.tsx +113 -8
  229. package/src/components/blocks/Text.tsx +285 -0
  230. package/src/components/blocks/index.ts +4 -0
  231. package/src/components/buttons/Button.tsx +184 -15
  232. package/src/components/forms/FormBlock.tsx +70 -17
  233. package/src/components/index.ts +5 -0
  234. package/src/components/input/ChoiceInputField.tsx +48 -18
  235. package/src/components/input/HtmlInputField.tsx +48 -18
  236. package/src/components/input/SelectInputField.tsx +48 -16
  237. package/src/components/input/SwitchInputField.tsx +48 -17
  238. package/src/components/input/TextField.tsx +41 -1
  239. package/src/components/input/TextInputField.tsx +52 -18
  240. package/src/components/layout/GridCell.tsx +118 -9
  241. package/src/components/layout/GridLayout.tsx +125 -24
  242. package/src/components/pages/FormPage.tsx +0 -1
  243. package/src/components/pages/Page.css +304 -332
  244. package/src/components/pages/Page.tsx +307 -255
  245. package/src/components/pages/index.ts +2 -2
  246. package/src/config/AppConfig.ts +133 -0
  247. package/src/config/AppConfigBuilder.ts +421 -0
  248. package/src/config/__tests__/AppConfig.test.ts +385 -0
  249. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  250. package/src/config/index.ts +24 -0
  251. package/src/config/types.ts +170 -0
  252. package/src/config.ts +25 -0
  253. package/src/contexts/PrintModeContext.tsx +332 -0
  254. package/src/contexts/QwickAppContext.tsx +2 -2
  255. package/src/contexts/ThemeContext.tsx +1 -2
  256. package/src/contexts/index.ts +2 -0
  257. package/src/hooks/index.ts +5 -1
  258. package/src/hooks/usePrintMode.ts +73 -0
  259. package/src/index.ts +3 -0
  260. package/src/schemas/CodeSchema.ts +3 -3
  261. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  262. package/src/schemas/ContentSchema.ts +2 -1
  263. package/src/schemas/GridCellSchema.ts +164 -0
  264. package/src/schemas/GridLayoutSchema.ts +133 -0
  265. package/src/schemas/HtmlSchema.ts +47 -0
  266. package/src/schemas/ImageSchema.ts +235 -0
  267. package/src/schemas/LogoSchema.ts +241 -0
  268. package/src/schemas/MarkdownSchema.ts +47 -0
  269. package/src/schemas/PageTemplateSchema.ts +186 -0
  270. package/src/schemas/PrintConfigSchema.ts +207 -0
  271. package/src/schemas/README.md +661 -0
  272. package/src/schemas/SectionSchema.ts +2 -1
  273. package/src/schemas/TextSchema.ts +329 -0
  274. package/src/schemas/ViewModelSchema.ts +115 -0
  275. package/src/schemas/index.ts +21 -2
  276. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  277. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  278. package/src/schemas/transformers/registry.ts +72 -0
  279. package/src/schemas/types/Serializable.ts +51 -0
  280. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  281. package/src/stories/Article.stories.tsx +433 -433
  282. package/src/stories/Button.stories.tsx +1 -1
  283. package/src/stories/CardListGrid.stories.tsx +451 -451
  284. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  285. package/src/stories/Code.stories.tsx +1 -1
  286. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  287. package/src/stories/Content.stories.tsx +393 -393
  288. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  289. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  290. package/src/stories/DataProvider.stories.tsx +1192 -1192
  291. package/src/stories/FeatureCard.stories.tsx +557 -557
  292. package/src/stories/FeatureGrid.stories.tsx +594 -594
  293. package/src/stories/Footer.stories.tsx +640 -640
  294. package/src/stories/FormBlock.stories.tsx +760 -760
  295. package/src/stories/FormComponents.stories.tsx +349 -541
  296. package/src/stories/GridCell.stories.tsx +417 -0
  297. package/src/stories/GridLayout.stories.tsx +353 -0
  298. package/src/stories/HeroBlock.stories.tsx +862 -373
  299. package/src/stories/HtmlInputField.stories.tsx +474 -474
  300. package/src/stories/Image.stories.tsx +819 -0
  301. package/src/stories/Introduction.stories.tsx +667 -667
  302. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  303. package/src/stories/Logo.stories.tsx +165 -6
  304. package/src/stories/Markdown.stories.tsx +137 -137
  305. package/src/stories/ModelView.stories.tsx +477 -0
  306. package/src/stories/Page.stories.tsx +688 -688
  307. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  308. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  309. package/src/stories/ProductCard.stories.tsx +424 -424
  310. package/src/stories/QwickApp.stories.tsx +368 -368
  311. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  312. package/src/stories/SafeSpan.stories.tsx +531 -531
  313. package/src/stories/Section.stories.tsx +90 -2
  314. package/src/stories/SelectInputField.stories.tsx +524 -524
  315. package/src/stories/Text.stories.tsx +560 -0
  316. package/src/stories/TextInputField.stories.tsx +443 -443
  317. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  318. package/src/utils/htmlTransform.tsx +74 -53
  319. package/src/utils/reactUtils.tsx +57 -6
  320. package/dist/index.bundled.css +0 -12
  321. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  322. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  323. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  324. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  325. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -18,9 +18,11 @@
18
18
 
19
19
  import { Box, Container } from '@mui/material';
20
20
  import type { WithDataBinding } from '@qwickapps/schema';
21
- import React from 'react';
21
+ import React, { ReactElement, ReactNode } from 'react';
22
22
  import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
23
23
  import SectionModel from '../../schemas/SectionSchema';
24
+ import { ModelView } from '../base/ModelView';
25
+ import { ComponentTransformer } from '../../schemas/transformers/ComponentTransformer';
24
26
  import type { BreakpointValue } from '../../types';
25
27
  import { mapToMUIBreakpoint } from '../../utils/breakpoints';
26
28
 
@@ -146,18 +148,111 @@ function SectionView({
146
148
  );
147
149
  }
148
150
 
149
- // Main component with data binding support
150
- function Section(props: SectionProps) {
151
- const { dataSource, bindingOptions, ...restProps } = props;
151
+ // Main component with data binding support and serialization capability
152
+ export class Section extends ModelView<SectionProps, SectionModel> {
153
+ // Component self-declaration for serialization
154
+ static readonly tagName = 'Section';
155
+ static readonly version = '1.0.0';
156
+
157
+ // Deserialization: JSON data → React element
158
+ static fromJson(jsonData: any): ReactElement {
159
+ return <Section {...jsonData} />;
160
+ }
161
+
162
+ // Section supports nested components
163
+ protected hasNestedComponents(children: ReactNode): boolean {
164
+ return true;
165
+ }
166
+
167
+ // Override serializeChildren to handle nested components properly
168
+ protected serializeChildren(children: ReactNode): any {
169
+ if (typeof children === 'string') {
170
+ return children;
171
+ }
172
+
173
+ if (children !== undefined) {
174
+ return ComponentTransformer.serialize(children);
175
+ }
176
+
177
+ return undefined;
178
+ }
179
+
180
+ // Component-specific serialization properties
181
+ protected getComponentSpecificProps(): any {
182
+ return {
183
+ background: this.props.background,
184
+ color: this.props.color,
185
+ padding: this.props.padding,
186
+ contentMaxWidth: this.props.contentMaxWidth,
187
+ component: this.props.component
188
+ };
189
+ }
152
190
 
153
- // If no dataSource, use traditional props
154
- if (!dataSource) {
191
+ // Section component renders traditional props view
192
+ protected renderView(): React.ReactElement {
193
+ const { dataSource, bindingOptions, ...restProps } = this.props;
155
194
  return <SectionView {...restProps} />;
156
195
  }
157
196
 
197
+ // Section component renders data-bound view
198
+ protected renderWithDataBinding(): React.ReactElement {
199
+ return <SectionWithDataBinding {...this.props} />;
200
+ }
201
+
202
+ // Register HTML patterns that Section component can handle
203
+ static registerPatternHandlers(registry: any): void {
204
+ // Register section element pattern
205
+ if (!registry.hasPattern('section')) {
206
+ registry.registerPattern('section', Section.transformSection);
207
+ }
208
+
209
+ // Register section with specific classes
210
+ if (!registry.hasPattern('section.blog-section')) {
211
+ registry.registerPattern('section.blog-section', Section.transformBlogSection);
212
+ }
213
+ }
214
+
215
+ // Transform generic section elements to Section component
216
+ private static transformSection(element: Element): any {
217
+ const padding = element.getAttribute('data-padding') || 'medium';
218
+ const background = element.getAttribute('data-background');
219
+ const contentMaxWidth = element.getAttribute('data-max-width') || 'lg';
220
+
221
+ return {
222
+ tagName: 'Section',
223
+ props: {
224
+ padding,
225
+ background,
226
+ contentMaxWidth,
227
+ children: element.innerHTML
228
+ }
229
+ };
230
+ }
231
+
232
+ // Transform blog section elements to Section component with specific styling
233
+ private static transformBlogSection(element: Element): any {
234
+ const padding = element.getAttribute('data-padding') || 'large';
235
+ const background = element.getAttribute('data-background') || 'var(--theme-surface)';
236
+
237
+ return {
238
+ tagName: 'Section',
239
+ props: {
240
+ padding,
241
+ background,
242
+ contentMaxWidth: 'md',
243
+ children: element.innerHTML
244
+ }
245
+ };
246
+ }
247
+ }
248
+
249
+ // Helper component to handle data binding with hooks (since we can't use hooks in class components)
250
+ function SectionWithDataBinding(props: SectionProps) {
251
+ const { dataSource, bindingOptions, ...restProps } = props;
252
+
158
253
  // Use data binding
159
254
  const { dataSource: _source, loading, error, cached, ...sectionProps } = useDataBinding<SectionModel>(
160
- dataSource,
255
+ dataSource!,
161
256
  restProps as Partial<SectionModel>,
162
257
  SectionModel.getSchema(),
163
258
  { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
@@ -203,7 +298,17 @@ function Section(props: SectionProps) {
203
298
  return null;
204
299
  }
205
300
 
206
- return <SectionView {...sectionProps} />;
301
+ console.log('Resolved props for Section:', sectionProps);
302
+
303
+ // Handle type conversion for contentMaxWidth - convert "false" string to boolean false
304
+ const typedSectionProps: SectionViewProps = {
305
+ ...sectionProps,
306
+ contentMaxWidth: sectionProps.contentMaxWidth === "false"
307
+ ? false
308
+ : sectionProps.contentMaxWidth as BreakpointValue
309
+ };
310
+
311
+ return <SectionView {...typedSectionProps} />;
207
312
  }
208
313
 
209
314
  export default Section;
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Text - Comprehensive typography display component with serialization support
3
+ *
4
+ * Features:
5
+ * - Complete typography variant support (h1-h6, body1/2, subtitle, etc.)
6
+ * - Rich styling options (color, alignment, font properties)
7
+ * - Custom typography overrides (fontSize, fontFamily, etc.)
8
+ * - Semantic HTML element rendering
9
+ * - Text formatting and decoration options
10
+ * - Full serialization support via ModelView
11
+ *
12
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
13
+ */
14
+
15
+ import React, { ReactElement, ReactNode } from 'react';
16
+ import { Typography } from '@mui/material';
17
+ import type { WithDataBinding, ModelProps } from '@qwickapps/schema';
18
+ import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding } from '../../hooks';
19
+ import TextModel from '../../schemas/TextSchema';
20
+ import { ModelView } from '../base/ModelView';
21
+
22
+ type TextViewProps = ModelProps<TextModel> & {
23
+ /** Click handler for the text */
24
+ onClick?: (event: React.MouseEvent<HTMLElement>) => void;
25
+ /** Additional inline styles */
26
+ style?: React.CSSProperties;
27
+ /** Additional CSS class names */
28
+ className?: string;
29
+ };
30
+
31
+ export interface TextProps extends TextViewProps, WithDataBinding {}
32
+
33
+ // View component - handles the actual rendering
34
+ function TextView({
35
+ content,
36
+ variant = 'body1',
37
+ color = 'inherit',
38
+ align = 'inherit',
39
+ component = 'p',
40
+ fontWeight = 'inherit',
41
+ textDecoration = 'none',
42
+ textTransform = 'none',
43
+ noWrap = false,
44
+ paragraph = false,
45
+ gutterBottom = false,
46
+ fontSize,
47
+ lineHeight,
48
+ letterSpacing,
49
+ fontFamily,
50
+ customColor,
51
+ maxWidth,
52
+ children,
53
+ onClick,
54
+ style,
55
+ className,
56
+ ...restProps
57
+ }: TextViewProps) {
58
+ const { styleProps, htmlProps, restProps: otherProps } = useBaseProps(restProps);
59
+
60
+ // Mark as QwickApp component
61
+ (TextView as any)[QWICKAPP_COMPONENT] = true;
62
+
63
+ // Determine the text content to display
64
+ const textContent = children || content;
65
+
66
+ // Early return if no content provided
67
+ if (!textContent && textContent !== 0) {
68
+ return null;
69
+ }
70
+
71
+ // Build custom styles
72
+ const customStyles: React.CSSProperties = {
73
+ ...style
74
+ };
75
+
76
+ // Apply custom typography overrides
77
+ if (fontSize) customStyles.fontSize = fontSize;
78
+ if (lineHeight) customStyles.lineHeight = lineHeight;
79
+ if (letterSpacing) customStyles.letterSpacing = letterSpacing;
80
+ if (fontFamily) customStyles.fontFamily = fontFamily;
81
+ if (customColor) customStyles.color = customColor;
82
+ if (maxWidth) customStyles.maxWidth = maxWidth;
83
+
84
+ // Apply text formatting
85
+ if (fontWeight !== 'inherit') customStyles.fontWeight = fontWeight;
86
+ if (textDecoration !== 'none') customStyles.textDecoration = textDecoration;
87
+ if (textTransform !== 'none') customStyles.textTransform = textTransform;
88
+
89
+ // Handle onClick cursor
90
+ if (onClick) customStyles.cursor = 'pointer';
91
+
92
+ return (
93
+ <Typography
94
+ {...htmlProps}
95
+ {...styleProps}
96
+ {...otherProps}
97
+ variant={variant}
98
+ color={color as any}
99
+ align={align}
100
+ component={component}
101
+ noWrap={noWrap}
102
+ paragraph={paragraph}
103
+ gutterBottom={gutterBottom}
104
+ className={`text ${className || ''}`.trim()}
105
+ style={customStyles}
106
+ onClick={onClick}
107
+ >
108
+ {textContent}
109
+ </Typography>
110
+ );
111
+ }
112
+
113
+ // Main component with data binding support and serialization capability
114
+ export class Text extends ModelView<TextProps, TextModel> {
115
+ // Component self-declaration for serialization
116
+ static readonly tagName = 'Text';
117
+ static readonly version = '1.0.0';
118
+
119
+ // Deserialization: JSON data → React element
120
+ static fromJson(jsonData: any): ReactElement {
121
+ return <Text {...jsonData} />;
122
+ }
123
+
124
+ // Component-specific serialization properties
125
+ protected getComponentSpecificProps(): any {
126
+ return {
127
+ content: this.props.content,
128
+ variant: this.props.variant,
129
+ color: this.props.color,
130
+ align: this.props.align,
131
+ component: this.props.component,
132
+ fontWeight: this.props.fontWeight,
133
+ textDecoration: this.props.textDecoration,
134
+ textTransform: this.props.textTransform,
135
+ noWrap: this.props.noWrap,
136
+ paragraph: this.props.paragraph,
137
+ gutterBottom: this.props.gutterBottom,
138
+ fontSize: this.props.fontSize,
139
+ lineHeight: this.props.lineHeight,
140
+ letterSpacing: this.props.letterSpacing,
141
+ fontFamily: this.props.fontFamily,
142
+ customColor: this.props.customColor,
143
+ maxWidth: this.props.maxWidth,
144
+ // Note: children ReactNode will be handled by base serialization if needed
145
+ };
146
+ }
147
+
148
+ // Text component renders traditional props view
149
+ protected renderView(): React.ReactElement {
150
+ const { dataSource, bindingOptions, ...restProps } = this.props;
151
+ return <TextView {...restProps} />;
152
+ }
153
+
154
+ // Text component renders data-bound view
155
+ protected renderWithDataBinding(): React.ReactElement {
156
+ return <TextWithDataBinding {...this.props} />;
157
+ }
158
+
159
+ // Register HTML patterns that Text component can handle
160
+ static registerPatternHandlers(registry: any): void {
161
+ // Register paragraph elements
162
+ if (!registry.hasPattern('p')) {
163
+ registry.registerPattern('p', Text.transformParagraph);
164
+ }
165
+
166
+ // Register heading elements
167
+ const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
168
+ headings.forEach(heading => {
169
+ if (!registry.hasPattern(heading)) {
170
+ registry.registerPattern(heading, (element: Element) => Text.transformHeading(element, heading));
171
+ }
172
+ });
173
+
174
+ // Register span elements
175
+ if (!registry.hasPattern('span')) {
176
+ registry.registerPattern('span', Text.transformSpan);
177
+ }
178
+ }
179
+
180
+ // Transform paragraph elements to Text component
181
+ private static transformParagraph(element: Element): any {
182
+ return {
183
+ tagName: 'Text',
184
+ props: {
185
+ variant: 'body1',
186
+ component: 'p',
187
+ children: element.textContent || ''
188
+ }
189
+ };
190
+ }
191
+
192
+ // Transform heading elements to Text component
193
+ private static transformHeading(element: Element, tagName: string): any {
194
+ const variantMap: { [key: string]: string } = {
195
+ 'h1': 'h1',
196
+ 'h2': 'h2',
197
+ 'h3': 'h3',
198
+ 'h4': 'h4',
199
+ 'h5': 'h5',
200
+ 'h6': 'h6'
201
+ };
202
+
203
+ return {
204
+ tagName: 'Text',
205
+ props: {
206
+ variant: variantMap[tagName] || 'h4',
207
+ component: tagName,
208
+ children: element.textContent || ''
209
+ }
210
+ };
211
+ }
212
+
213
+ // Transform span elements to Text component
214
+ private static transformSpan(element: Element): any {
215
+ return {
216
+ tagName: 'Text',
217
+ props: {
218
+ variant: 'body2',
219
+ component: 'span',
220
+ children: element.textContent || ''
221
+ }
222
+ };
223
+ }
224
+ }
225
+
226
+ // Helper component to handle data binding with hooks (since we can't use hooks in class components)
227
+ function TextWithDataBinding(props: TextProps) {
228
+ const { dataSource, bindingOptions, ...restProps } = props;
229
+
230
+ // Use data binding
231
+ const { dataSource: _source, loading, error, cached, ...rawTextProps } = useDataBinding<TextModel>(
232
+ dataSource!,
233
+ restProps as Partial<TextModel>,
234
+ TextModel.getSchema(),
235
+ { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
236
+ );
237
+
238
+ // Use props directly since new serialization system handles component-level transformation
239
+ const textProps = rawTextProps;
240
+
241
+ // Show loading state
242
+ if (loading) {
243
+ return (
244
+ <Typography
245
+ variant={textProps.variant || 'body1'}
246
+ color="text.secondary"
247
+ sx={{
248
+ backgroundColor: 'grey.100',
249
+ borderRadius: '4px',
250
+ padding: '0.5rem',
251
+ maxWidth: textProps.maxWidth
252
+ }}
253
+ >
254
+ Loading text...
255
+ </Typography>
256
+ );
257
+ }
258
+
259
+ if (error) {
260
+ console.error('Error loading text:', error);
261
+ if (process.env.NODE_ENV !== 'production') {
262
+ return (
263
+ <Typography
264
+ variant={textProps.variant || 'body1'}
265
+ color="error"
266
+ sx={{
267
+ backgroundColor: 'error.light',
268
+ color: 'error.contrastText',
269
+ borderRadius: '4px',
270
+ padding: '0.5rem',
271
+ maxWidth: textProps.maxWidth
272
+ }}
273
+ >
274
+ Error Loading Text: {error.message}
275
+ </Typography>
276
+ );
277
+ }
278
+ return null;
279
+ }
280
+
281
+ console.log('Resolved props for Text:', textProps);
282
+ return <TextView {...textProps} />;
283
+ }
284
+
285
+ export default Text;
@@ -19,6 +19,8 @@ export { default as CoverImageHeader } from './CoverImageHeader';
19
19
  export { default as FeatureGrid } from './FeatureGrid';
20
20
  export { default as Footer } from './Footer';
21
21
  export { default as Section } from './Section';
22
+ export { default as Image } from './Image';
23
+ export { default as Text } from './Text';
22
24
  export { default as ProductCard } from './ProductCard';
23
25
  export { default as FeatureCard } from './FeatureCard';
24
26
  export { default as CardListGrid } from './CardListGrid';
@@ -32,6 +34,8 @@ export type { CoverImageHeaderProps, HeaderAction } from './CoverImageHeader';
32
34
  export type { FeatureGridProps, FeatureItem as FeatureGridItem } from './FeatureGrid';
33
35
  export type { FooterProps } from './Footer';
34
36
  export type { SectionProps } from './Section';
37
+ export type { ImageProps } from './Image';
38
+ export type { TextProps } from './Text';
35
39
  export type { ProductCardProps, Product, ProductCardAction } from './ProductCard';
36
40
  export type { FeatureCardProps, FeatureItem, FeatureCardAction } from './FeatureCard';
37
41
  export type { CardListGridProps } from './CardListGrid';