@qwickapps/react-framework 1.3.5 → 1.4.1

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 +1691 -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
@@ -0,0 +1,403 @@
1
+ /**
2
+ * GridCell Component Serialization Tests
3
+ *
4
+ * Tests for the GridCell component's ModelView implementation and
5
+ * serialization capabilities using ComponentTransformer.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { render, screen } from '@testing-library/react';
12
+ import '@testing-library/jest-dom';
13
+ import { ComponentTransformer } from '../../../schemas/transformers/ComponentTransformer';
14
+ import { GridCell } from '../../../components/layout/GridCell';
15
+ import { Text } from '../../../components/layout/../blocks/Text';
16
+ import { Button } from '../../../components/layout/../buttons/Button';
17
+ import { Code } from '../../../components/layout/../blocks/Code';
18
+
19
+ describe('GridCell Serialization', () => {
20
+ beforeEach(() => {
21
+ // Clear component registry for clean tests
22
+ ComponentTransformer.clearRegistry();
23
+
24
+ // Register all necessary components
25
+ ComponentTransformer.registerComponent(GridCell as any);
26
+ ComponentTransformer.registerComponent(Text as any);
27
+ ComponentTransformer.registerComponent(Button as any);
28
+ ComponentTransformer.registerComponent(Code as any);
29
+ });
30
+
31
+ afterEach(() => {
32
+ ComponentTransformer.clearRegistry();
33
+ });
34
+
35
+ describe('Basic Serialization', () => {
36
+ it('should serialize and deserialize basic grid cell', () => {
37
+ // Create original component
38
+ const originalComponent = (
39
+ <GridCell
40
+ span={6}
41
+ background="primary.main"
42
+ padding="medium"
43
+ >
44
+ <div>Cell content</div>
45
+ </GridCell>
46
+ );
47
+
48
+ // Serialize
49
+ const serialized = ComponentTransformer.serialize(originalComponent);
50
+ expect(serialized).toBeTruthy();
51
+ expect(typeof serialized).toBe('string');
52
+
53
+ // Parse to check structure
54
+ const parsed = JSON.parse(serialized);
55
+ expect(parsed.tag).toBe('GridCell');
56
+ expect(parsed.version).toBe('1.0.0');
57
+ expect(parsed.data.span).toBe(6);
58
+ expect(parsed.data.background).toBe('primary.main');
59
+ expect(parsed.data.padding).toBe('medium');
60
+ // Children should be serialized as JSON string
61
+ expect(typeof parsed.data.children).toBe('string');
62
+ const children = JSON.parse(parsed.data.children);
63
+ expect(children.data.props.children.value).toBe('Cell content');
64
+ });
65
+
66
+ it('should serialize empty grid cell', () => {
67
+ const originalComponent = (
68
+ <GridCell span={12} />
69
+ );
70
+
71
+ const serialized = ComponentTransformer.serialize(originalComponent);
72
+ const parsed = JSON.parse(serialized);
73
+
74
+ expect(parsed.tag).toBe('GridCell');
75
+ expect(parsed.data.span).toBe(12);
76
+ expect(parsed.data.children).toBeUndefined();
77
+ });
78
+
79
+ it('should serialize grid cell with responsive properties', () => {
80
+ const originalComponent = (
81
+ <GridCell
82
+ xs={12}
83
+ sm={6}
84
+ md={4}
85
+ lg={3}
86
+ xl={2}
87
+ height="200px"
88
+ className="responsive-cell"
89
+ >
90
+ <div>Responsive content</div>
91
+ </GridCell>
92
+ );
93
+
94
+ const serialized = ComponentTransformer.serialize(originalComponent);
95
+ const parsed = JSON.parse(serialized);
96
+
97
+ expect(parsed.data.xs).toBe(12);
98
+ expect(parsed.data.sm).toBe(6);
99
+ expect(parsed.data.md).toBe(4);
100
+ expect(parsed.data.lg).toBe(3);
101
+ expect(parsed.data.xl).toBe(2);
102
+ expect(parsed.data.height).toBe('200px');
103
+ expect(parsed.data.className).toBe('responsive-cell');
104
+ });
105
+
106
+ it('should serialize grid cell with styling properties', () => {
107
+ const originalComponent = (
108
+ <GridCell
109
+ background="secondary.light"
110
+ padding="large"
111
+ margin="small"
112
+ width="100%"
113
+ >
114
+ <span>Styled content</span>
115
+ </GridCell>
116
+ );
117
+
118
+ const serialized = ComponentTransformer.serialize(originalComponent);
119
+ const parsed = JSON.parse(serialized);
120
+
121
+ expect(parsed.data.background).toBe('secondary.light');
122
+ expect(parsed.data.padding).toBe('large');
123
+ expect(parsed.data.margin).toBe('small');
124
+ expect(parsed.data.width).toBe('100%');
125
+ });
126
+ });
127
+
128
+ describe('Nested Component Serialization', () => {
129
+ it('should serialize grid cell with nested Text component', () => {
130
+ const originalComponent = (
131
+ <GridCell span={8}>
132
+ <Text
133
+ content="Hello, World!"
134
+ variant="h2"
135
+ color="primary"
136
+ />
137
+ </GridCell>
138
+ );
139
+
140
+ const serialized = ComponentTransformer.serialize(originalComponent);
141
+ const parsed = JSON.parse(serialized);
142
+
143
+ expect(parsed.tag).toBe('GridCell');
144
+
145
+ // Children should be serialized as JSON string
146
+ expect(typeof parsed.data.children).toBe('string');
147
+ const nestedText = JSON.parse(parsed.data.children);
148
+ expect(nestedText.tag).toBe('Text');
149
+ expect(nestedText.data.content).toBe('Hello, World!');
150
+ expect(nestedText.data.variant).toBe('h2');
151
+ expect(nestedText.data.color).toBe('primary');
152
+ // Note: textAlign is not a property in TextSchema
153
+ });
154
+
155
+ it('should serialize grid cell with nested Button component', () => {
156
+ const originalComponent = (
157
+ <GridCell xs={12} sm={6}>
158
+ <Button
159
+ label="Click Me"
160
+ variant="primary"
161
+ buttonSize="large"
162
+ disabled={false}
163
+ />
164
+ </GridCell>
165
+ );
166
+
167
+ const serialized = ComponentTransformer.serialize(originalComponent);
168
+ const parsed = JSON.parse(serialized);
169
+
170
+ // Children should be serialized as JSON string
171
+ expect(typeof parsed.data.children).toBe('string');
172
+ const nestedButton = JSON.parse(parsed.data.children);
173
+ expect(nestedButton.tag).toBe('Button');
174
+ expect(nestedButton.data.label).toBe('Click Me');
175
+ expect(nestedButton.data.variant).toBe('primary');
176
+ expect(nestedButton.data.buttonSize).toBe('large'); // Button schema uses buttonSize, not size
177
+ expect(nestedButton.data.disabled).toBe(false);
178
+ });
179
+
180
+ it('should serialize grid cell with multiple nested components', () => {
181
+ const originalComponent = (
182
+ <GridCell md={6}>
183
+ <Text content="Title" variant="h3" />
184
+ <Text content="Description text here" variant="body1" />
185
+ <Button label="Action" variant="outlined" />
186
+ </GridCell>
187
+ );
188
+
189
+ const serialized = ComponentTransformer.serialize(originalComponent);
190
+ const parsed = JSON.parse(serialized);
191
+
192
+ // Children should be serialized as JSON string
193
+ expect(typeof parsed.data.children).toBe('string');
194
+ const children = JSON.parse(parsed.data.children);
195
+ expect(Array.isArray(children)).toBe(true);
196
+ expect(children).toHaveLength(3);
197
+
198
+ expect(children[0].tag).toBe('Text');
199
+ expect(children[0].data.content).toBe('Title');
200
+
201
+ expect(children[1].tag).toBe('Text');
202
+ expect(children[1].data.content).toBe('Description text here');
203
+
204
+ expect(children[2].tag).toBe('Button');
205
+ expect(children[2].data.label).toBe('Action');
206
+ });
207
+
208
+ it('should serialize grid cell with mixed content', () => {
209
+ const originalComponent = (
210
+ <GridCell span={12}>
211
+ <Text content="Header" variant="h4" />
212
+ <div>Regular div content</div>
213
+ <Code language="javascript">
214
+ console.log("Hello, World!");
215
+ </Code>
216
+ <span>More text</span>
217
+ </GridCell>
218
+ );
219
+
220
+ const serialized = ComponentTransformer.serialize(originalComponent);
221
+ const parsed = JSON.parse(serialized);
222
+
223
+ // Children should be serialized as JSON string
224
+ expect(typeof parsed.data.children).toBe('string');
225
+ const children = JSON.parse(parsed.data.children);
226
+ expect(Array.isArray(children)).toBe(true);
227
+ expect(children).toHaveLength(4);
228
+
229
+ // First child is Text component
230
+ expect(children[0].tag).toBe('Text');
231
+ expect(children[0].data.content).toBe('Header');
232
+
233
+ // Second child is regular div (serialized as react node)
234
+ expect(typeof children[1]).toBe('object');
235
+ expect(children[1].tag).toBe('__react_node__');
236
+
237
+ // Third child is Code component
238
+ expect(children[2].tag).toBe('Code');
239
+ expect(children[2].data.language).toBe('javascript');
240
+
241
+ // Fourth child is span (serialized as react node)
242
+ expect(typeof children[3]).toBe('object');
243
+ expect(children[3].tag).toBe('__react_node__');
244
+ });
245
+ });
246
+
247
+ describe('Deserialization', () => {
248
+ it('should deserialize back to working component', () => {
249
+ const originalComponent = (
250
+ <GridCell
251
+ xs={12}
252
+ md={6}
253
+ background="background.paper"
254
+ padding="large"
255
+ >
256
+ <Text content="Test Content" variant="body1" />
257
+ </GridCell>
258
+ );
259
+
260
+ // Serialize and deserialize
261
+ const serialized = ComponentTransformer.serialize(originalComponent);
262
+ const deserialized = ComponentTransformer.deserialize(serialized);
263
+
264
+ // Render both to compare
265
+ const { container: originalContainer } = render(originalComponent);
266
+ const { container: deserializedContainer } = render(deserialized);
267
+
268
+ // Check that both render successfully
269
+ expect(originalContainer.firstChild).toBeTruthy();
270
+ expect(deserializedContainer.firstChild).toBeTruthy();
271
+
272
+ // Both should have proper data attributes for grid props
273
+ const originalCell = originalContainer.firstChild as HTMLElement;
274
+ const deserializedCell = deserializedContainer.firstChild as HTMLElement;
275
+
276
+ expect(originalCell.getAttribute('data-grid-xs')).toBe('12');
277
+ expect(deserializedCell.getAttribute('data-grid-xs')).toBe('12');
278
+ expect(originalCell.getAttribute('data-grid-md')).toBe('6');
279
+ expect(deserializedCell.getAttribute('data-grid-md')).toBe('6');
280
+ });
281
+
282
+ it('should preserve all cell properties after round-trip serialization', () => {
283
+ const originalComponent = (
284
+ <GridCell
285
+ span={8}
286
+ xs={12}
287
+ sm={8}
288
+ md={6}
289
+ lg={4}
290
+ xl={3}
291
+ background="error.light"
292
+ padding="huge"
293
+ margin="medium"
294
+ height="300px"
295
+ width="100%"
296
+ className="test-cell"
297
+ >
298
+ <Text content="Round trip test" />
299
+ </GridCell>
300
+ );
301
+
302
+ // Double serialization to test round-trip
303
+ const serialized1 = ComponentTransformer.serialize(originalComponent);
304
+ const deserialized1 = ComponentTransformer.deserialize(serialized1);
305
+ const serialized2 = ComponentTransformer.serialize(deserialized1);
306
+ const parsed2 = JSON.parse(serialized2);
307
+
308
+ // All properties should be preserved
309
+ expect(parsed2.data.span).toBe(8);
310
+ expect(parsed2.data.xs).toBe(12);
311
+ expect(parsed2.data.sm).toBe(8);
312
+ expect(parsed2.data.md).toBe(6);
313
+ expect(parsed2.data.lg).toBe(4);
314
+ expect(parsed2.data.xl).toBe(3);
315
+ expect(parsed2.data.background).toBe('error.light');
316
+ expect(parsed2.data.padding).toBe('huge');
317
+ expect(parsed2.data.margin).toBe('medium');
318
+ expect(parsed2.data.height).toBe('300px');
319
+ expect(parsed2.data.width).toBe('100%');
320
+ expect(parsed2.data.className).toBe('test-cell');
321
+ });
322
+ });
323
+
324
+ describe('Performance', () => {
325
+ it('should serialize complex cell efficiently', () => {
326
+ const complexContent = Array.from({ length: 20 }, (_, i) => (
327
+ <Text key={i} content={`Text item ${i + 1}`} variant="body2" />
328
+ ));
329
+
330
+ const complexCell = (
331
+ <GridCell md={6}>
332
+ {complexContent}
333
+ </GridCell>
334
+ );
335
+
336
+ const startTime = performance.now();
337
+ const serialized = ComponentTransformer.serialize(complexCell);
338
+ const endTime = performance.now();
339
+
340
+ expect(serialized).toBeTruthy();
341
+ expect(endTime - startTime).toBeLessThan(50); // Should complete within 50ms
342
+
343
+ const parsed = JSON.parse(serialized);
344
+ const children = JSON.parse(parsed.data.children);
345
+ expect(children).toHaveLength(20);
346
+ });
347
+ });
348
+
349
+ describe('Error Handling', () => {
350
+ it('should handle cell with null children gracefully', () => {
351
+ const cellWithNullChild = (
352
+ <GridCell span={6}>
353
+ <Text content="Valid text" />
354
+ {null}
355
+ <Text content="Another valid text" />
356
+ </GridCell>
357
+ );
358
+
359
+ expect(() => {
360
+ const serialized = ComponentTransformer.serialize(cellWithNullChild);
361
+ const parsed = JSON.parse(serialized);
362
+ const children = JSON.parse(parsed.data.children);
363
+ expect(children).toHaveLength(3); // null becomes a child
364
+ }).not.toThrow();
365
+ });
366
+
367
+ it('should handle cell with deeply nested structures', () => {
368
+ const deeplyNestedCell = (
369
+ <GridCell>
370
+ <div>
371
+ <div>
372
+ <div>
373
+ <Text content="Deep nested text" />
374
+ </div>
375
+ </div>
376
+ </div>
377
+ </GridCell>
378
+ );
379
+
380
+ expect(() => {
381
+ const serialized = ComponentTransformer.serialize(deeplyNestedCell);
382
+ const deserialized = ComponentTransformer.deserialize(serialized);
383
+ render(deserialized);
384
+ }).not.toThrow();
385
+ });
386
+
387
+ it('should handle cell with invalid responsive values gracefully', () => {
388
+ // This tests runtime handling, schema validation would catch invalid values at development time
389
+ const cellWithValidValues = (
390
+ <GridCell xs={12} sm={6} md={4}>
391
+ <Text content="Valid cell" />
392
+ </GridCell>
393
+ );
394
+
395
+ const serialized = ComponentTransformer.serialize(cellWithValidValues);
396
+ const parsed = JSON.parse(serialized);
397
+
398
+ expect(parsed.data.xs).toBe(12);
399
+ expect(parsed.data.sm).toBe(6);
400
+ expect(parsed.data.md).toBe(4);
401
+ });
402
+ });
403
+ });