@qwickapps/react-framework 1.3.5 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/README.md +1681 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  28. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  30. package/dist/components/blocks/Footer.d.ts.map +1 -1
  31. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  32. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  33. package/dist/components/blocks/Image.d.ts +41 -0
  34. package/dist/components/blocks/Image.d.ts.map +1 -0
  35. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  36. package/dist/components/blocks/Section.d.ts +16 -2
  37. package/dist/components/blocks/Section.d.ts.map +1 -1
  38. package/dist/components/blocks/Text.d.ts +41 -0
  39. package/dist/components/blocks/Text.d.ts.map +1 -0
  40. package/dist/components/blocks/index.d.ts +4 -0
  41. package/dist/components/blocks/index.d.ts.map +1 -1
  42. package/dist/components/buttons/Button.d.ts +23 -7
  43. package/dist/components/buttons/Button.d.ts.map +1 -1
  44. package/dist/components/forms/FormBlock.d.ts +19 -13
  45. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  46. package/dist/components/index.d.ts +4 -0
  47. package/dist/components/index.d.ts.map +1 -1
  48. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  49. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  50. package/dist/components/input/HtmlInputField.d.ts +17 -11
  51. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  52. package/dist/components/input/SelectInputField.d.ts +16 -10
  53. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  54. package/dist/components/input/SwitchInputField.d.ts +16 -10
  55. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  56. package/dist/components/input/TextField.d.ts.map +1 -1
  57. package/dist/components/input/TextInputField.d.ts +16 -11
  58. package/dist/components/input/TextInputField.d.ts.map +1 -1
  59. package/dist/components/layout/GridCell.d.ts +23 -6
  60. package/dist/components/layout/GridCell.d.ts.map +1 -1
  61. package/dist/components/layout/GridLayout.d.ts +24 -23
  62. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  63. package/dist/components/pages/FormPage.d.ts.map +1 -1
  64. package/dist/components/pages/Page.d.ts +49 -87
  65. package/dist/components/pages/Page.d.ts.map +1 -1
  66. package/dist/components/pages/index.d.ts +2 -2
  67. package/dist/components/pages/index.d.ts.map +1 -1
  68. package/dist/config/AppConfig.d.ts +49 -0
  69. package/dist/config/AppConfig.d.ts.map +1 -0
  70. package/dist/config/AppConfigBuilder.d.ts +75 -0
  71. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  72. package/dist/config/index.d.ts +13 -0
  73. package/dist/config/index.d.ts.map +1 -0
  74. package/dist/config/types.d.ts +130 -0
  75. package/dist/config/types.d.ts.map +1 -0
  76. package/dist/config.d.ts +15 -0
  77. package/dist/config.d.ts.map +1 -0
  78. package/dist/config.esm.js +451 -0
  79. package/dist/config.js +455 -0
  80. package/dist/contexts/PrintModeContext.d.ts +27 -0
  81. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  82. package/dist/contexts/QwickAppContext.d.ts +2 -2
  83. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  84. package/dist/contexts/index.d.ts +2 -0
  85. package/dist/contexts/index.d.ts.map +1 -1
  86. package/dist/hooks/index.d.ts +2 -0
  87. package/dist/hooks/index.d.ts.map +1 -1
  88. package/dist/hooks/usePrintMode.d.ts +39 -0
  89. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  90. package/dist/index.css +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.esm.css +1 -1
  94. package/dist/index.esm.js +10951 -6238
  95. package/dist/index.js +11014 -6287
  96. package/dist/schemas/CodeSchema.d.ts +2 -1
  97. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  98. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  99. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  100. package/dist/schemas/ContentSchema.d.ts +2 -1
  101. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  102. package/dist/schemas/GridCellSchema.d.ts +25 -0
  103. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  104. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  105. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  106. package/dist/schemas/HtmlSchema.d.ts +14 -0
  107. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  108. package/dist/schemas/ImageSchema.d.ts +32 -0
  109. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  110. package/dist/schemas/LogoSchema.d.ts +35 -0
  111. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  112. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  113. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  114. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  115. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  116. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  117. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  118. package/dist/schemas/SectionSchema.d.ts +2 -1
  119. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  120. package/dist/schemas/TextSchema.d.ts +37 -0
  121. package/dist/schemas/TextSchema.d.ts.map +1 -0
  122. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  123. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  124. package/dist/schemas/index.d.ts +15 -1
  125. package/dist/schemas/index.d.ts.map +1 -1
  126. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  127. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  128. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  129. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  130. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  131. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  132. package/dist/schemas/transformers/registry.d.ts +15 -0
  133. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  134. package/dist/schemas/types/Serializable.d.ts +46 -0
  135. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  136. package/dist/utils/htmlTransform.d.ts.map +1 -1
  137. package/dist/utils/reactUtils.d.ts +12 -3
  138. package/dist/utils/reactUtils.d.ts.map +1 -1
  139. package/package.json +17 -3
  140. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  141. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  142. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  143. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  145. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  148. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  150. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  152. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  154. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  155. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  156. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  158. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  159. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  160. package/src/__tests__/components/Logo.test.js +3 -3
  161. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  162. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  163. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  165. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  166. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  167. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  168. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  169. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  172. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  173. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  174. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  175. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  176. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  177. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  178. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  179. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  180. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  181. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  182. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  183. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  184. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  185. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  186. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  187. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  188. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  189. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  190. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  191. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  192. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  193. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  194. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  195. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  196. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  197. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  198. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  199. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  200. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  201. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  202. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  203. package/src/components/ErrorBoundary.tsx +8 -8
  204. package/src/components/Html.tsx +147 -44
  205. package/src/components/Logo.tsx +198 -100
  206. package/src/components/Markdown.tsx +125 -16
  207. package/src/components/QwickApp.tsx +64 -31
  208. package/src/components/QwickIcon.tsx +59 -0
  209. package/src/components/SafeSpan.tsx +65 -10
  210. package/src/components/Scaffold.tsx +2 -8
  211. package/src/components/base/ModelView.tsx +199 -0
  212. package/src/components/base/index.ts +11 -0
  213. package/src/components/blocks/Article.tsx +57 -18
  214. package/src/components/blocks/Code.md +529 -0
  215. package/src/components/blocks/Code.tsx +102 -15
  216. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  217. package/src/components/blocks/FeatureCard.tsx +1 -2
  218. package/src/components/blocks/FeatureGrid.tsx +19 -1
  219. package/src/components/blocks/Footer.tsx +13 -1
  220. package/src/components/blocks/HeroBlock.tsx +87 -20
  221. package/src/components/blocks/Image.tsx +395 -0
  222. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  223. package/src/components/blocks/ProductCard.tsx +1 -1
  224. package/src/components/blocks/Section.tsx +113 -8
  225. package/src/components/blocks/Text.tsx +285 -0
  226. package/src/components/blocks/index.ts +4 -0
  227. package/src/components/buttons/Button.tsx +184 -15
  228. package/src/components/forms/FormBlock.tsx +70 -17
  229. package/src/components/index.ts +5 -0
  230. package/src/components/input/ChoiceInputField.tsx +48 -18
  231. package/src/components/input/HtmlInputField.tsx +48 -18
  232. package/src/components/input/SelectInputField.tsx +48 -16
  233. package/src/components/input/SwitchInputField.tsx +48 -17
  234. package/src/components/input/TextField.tsx +41 -1
  235. package/src/components/input/TextInputField.tsx +52 -18
  236. package/src/components/layout/GridCell.tsx +118 -9
  237. package/src/components/layout/GridLayout.tsx +125 -24
  238. package/src/components/pages/FormPage.tsx +0 -1
  239. package/src/components/pages/Page.css +304 -332
  240. package/src/components/pages/Page.tsx +307 -255
  241. package/src/components/pages/index.ts +2 -2
  242. package/src/config/AppConfig.ts +133 -0
  243. package/src/config/AppConfigBuilder.ts +421 -0
  244. package/src/config/__tests__/AppConfig.test.ts +385 -0
  245. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  246. package/src/config/index.ts +24 -0
  247. package/src/config/types.ts +170 -0
  248. package/src/config.ts +25 -0
  249. package/src/contexts/PrintModeContext.tsx +332 -0
  250. package/src/contexts/QwickAppContext.tsx +2 -2
  251. package/src/contexts/index.ts +2 -0
  252. package/src/hooks/index.ts +5 -1
  253. package/src/hooks/usePrintMode.ts +73 -0
  254. package/src/index.ts +3 -0
  255. package/src/schemas/CodeSchema.ts +3 -3
  256. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  257. package/src/schemas/ContentSchema.ts +2 -1
  258. package/src/schemas/GridCellSchema.ts +164 -0
  259. package/src/schemas/GridLayoutSchema.ts +133 -0
  260. package/src/schemas/HtmlSchema.ts +47 -0
  261. package/src/schemas/ImageSchema.ts +235 -0
  262. package/src/schemas/LogoSchema.ts +241 -0
  263. package/src/schemas/MarkdownSchema.ts +47 -0
  264. package/src/schemas/PageTemplateSchema.ts +186 -0
  265. package/src/schemas/PrintConfigSchema.ts +207 -0
  266. package/src/schemas/README.md +661 -0
  267. package/src/schemas/SectionSchema.ts +2 -1
  268. package/src/schemas/TextSchema.ts +329 -0
  269. package/src/schemas/ViewModelSchema.ts +115 -0
  270. package/src/schemas/index.ts +21 -2
  271. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  272. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  273. package/src/schemas/transformers/registry.ts +72 -0
  274. package/src/schemas/types/Serializable.ts +51 -0
  275. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  276. package/src/stories/Article.stories.tsx +433 -433
  277. package/src/stories/Button.stories.tsx +1 -1
  278. package/src/stories/CardListGrid.stories.tsx +451 -451
  279. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  280. package/src/stories/Code.stories.tsx +1 -1
  281. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  282. package/src/stories/Content.stories.tsx +393 -393
  283. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  284. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  285. package/src/stories/DataProvider.stories.tsx +1192 -1192
  286. package/src/stories/FeatureCard.stories.tsx +557 -557
  287. package/src/stories/FeatureGrid.stories.tsx +594 -594
  288. package/src/stories/Footer.stories.tsx +640 -640
  289. package/src/stories/FormBlock.stories.tsx +760 -760
  290. package/src/stories/FormComponents.stories.tsx +349 -541
  291. package/src/stories/GridCell.stories.tsx +417 -0
  292. package/src/stories/GridLayout.stories.tsx +353 -0
  293. package/src/stories/HeroBlock.stories.tsx +862 -373
  294. package/src/stories/HtmlInputField.stories.tsx +474 -474
  295. package/src/stories/Image.stories.tsx +819 -0
  296. package/src/stories/Introduction.stories.tsx +667 -667
  297. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  298. package/src/stories/Logo.stories.tsx +165 -6
  299. package/src/stories/Markdown.stories.tsx +137 -137
  300. package/src/stories/ModelView.stories.tsx +477 -0
  301. package/src/stories/Page.stories.tsx +688 -688
  302. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  303. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  304. package/src/stories/ProductCard.stories.tsx +424 -424
  305. package/src/stories/QwickApp.stories.tsx +368 -368
  306. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  307. package/src/stories/SafeSpan.stories.tsx +531 -531
  308. package/src/stories/Section.stories.tsx +90 -2
  309. package/src/stories/SelectInputField.stories.tsx +524 -524
  310. package/src/stories/Text.stories.tsx +560 -0
  311. package/src/stories/TextInputField.stories.tsx +443 -443
  312. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  313. package/src/utils/htmlTransform.tsx +74 -53
  314. package/src/utils/reactUtils.tsx +57 -6
  315. package/dist/index.bundled.css +0 -12
  316. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  317. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  318. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  319. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  320. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -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';