@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
@@ -0,0 +1,491 @@
1
+ /**
2
+ * Text Component Serialization Tests
3
+ *
4
+ * Tests for the Text 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 { Text } from '../../../components/blocks/Text';
15
+
16
+ describe('Text Serialization', () => {
17
+ beforeEach(() => {
18
+ // Clear component registry for clean tests
19
+ ComponentTransformer.clearRegistry();
20
+
21
+ // Register Text component
22
+ ComponentTransformer.registerComponent(Text as any);
23
+ });
24
+
25
+ afterEach(() => {
26
+ ComponentTransformer.clearRegistry();
27
+ });
28
+
29
+ describe('Basic Serialization', () => {
30
+ it('should serialize and deserialize basic text component', () => {
31
+ // Create original component
32
+ const originalComponent = (
33
+ <Text
34
+ content="Hello, World!"
35
+ variant="body1"
36
+ />
37
+ );
38
+
39
+ // Serialize
40
+ const serialized = ComponentTransformer.serialize(originalComponent);
41
+ expect(serialized).toBeTruthy();
42
+ expect(typeof serialized).toBe('string');
43
+
44
+ // Parse to check structure
45
+ const parsed = JSON.parse(serialized);
46
+ expect(parsed.tag).toBe('Text');
47
+ expect(parsed.version).toBe('1.0.0');
48
+ expect(parsed.data.content).toBe('Hello, World!');
49
+ expect(parsed.data.variant).toBe('body1');
50
+
51
+ // Deserialize
52
+ const deserialized = ComponentTransformer.deserialize(serialized);
53
+ expect(React.isValidElement(deserialized)).toBe(true);
54
+ });
55
+
56
+ it('should preserve all typography properties through serialization', () => {
57
+ const originalComponent = (
58
+ <Text
59
+ content="Comprehensive Typography Test"
60
+ variant="h2"
61
+ color="primary"
62
+ align="center"
63
+ component="h1"
64
+ fontWeight="bold"
65
+ textDecoration="underline"
66
+ textTransform="uppercase"
67
+ noWrap={true}
68
+ paragraph={false}
69
+ gutterBottom={true}
70
+ fontSize="2.5rem"
71
+ lineHeight="1.2"
72
+ letterSpacing="0.1em"
73
+ fontFamily="Arial, sans-serif"
74
+ customColor="#1976d2"
75
+ maxWidth="600px"
76
+ />
77
+ );
78
+
79
+ const serialized = ComponentTransformer.serialize(originalComponent);
80
+ const parsed = JSON.parse(serialized);
81
+ const data = parsed.data;
82
+
83
+ expect(data.content).toBe('Comprehensive Typography Test');
84
+ expect(data.variant).toBe('h2');
85
+ expect(data.color).toBe('primary');
86
+ expect(data.align).toBe('center');
87
+ expect(data.component).toBe('h1');
88
+ expect(data.fontWeight).toBe('bold');
89
+ expect(data.textDecoration).toBe('underline');
90
+ expect(data.textTransform).toBe('uppercase');
91
+ expect(data.noWrap).toBe(true);
92
+ expect(data.paragraph).toBe(false);
93
+ expect(data.gutterBottom).toBe(true);
94
+ expect(data.fontSize).toBe('2.5rem');
95
+ expect(data.lineHeight).toBe('1.2');
96
+ expect(data.letterSpacing).toBe('0.1em');
97
+ expect(data.fontFamily).toBe('Arial, sans-serif');
98
+ expect(data.customColor).toBe('#1976d2');
99
+ expect(data.maxWidth).toBe('600px');
100
+
101
+ const deserialized = ComponentTransformer.deserialize(serialized);
102
+ expect(React.isValidElement(deserialized)).toBe(true);
103
+ });
104
+
105
+ it('should handle all typography variants', () => {
106
+ const variants = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'subtitle1', 'subtitle2', 'body1', 'body2', 'button', 'caption', 'overline'];
107
+
108
+ variants.forEach(variant => {
109
+ const originalComponent = (
110
+ <Text
111
+ content={`This is ${variant} variant`}
112
+ variant={variant as any}
113
+ />
114
+ );
115
+
116
+ const serialized = ComponentTransformer.serialize(originalComponent);
117
+ const parsed = JSON.parse(serialized);
118
+
119
+ expect(parsed.data.variant).toBe(variant);
120
+ expect(parsed.data.content).toBe(`This is ${variant} variant`);
121
+
122
+ const deserialized = ComponentTransformer.deserialize(serialized);
123
+ expect(React.isValidElement(deserialized)).toBe(true);
124
+ });
125
+ });
126
+
127
+ it('should handle all color variants', () => {
128
+ const colors = ['primary', 'secondary', 'textPrimary', 'textSecondary', 'error', 'warning', 'info', 'success', 'inherit'];
129
+
130
+ colors.forEach(color => {
131
+ const originalComponent = (
132
+ <Text
133
+ content={`This is ${color} colored text`}
134
+ color={color as any}
135
+ />
136
+ );
137
+
138
+ const serialized = ComponentTransformer.serialize(originalComponent);
139
+ const parsed = JSON.parse(serialized);
140
+
141
+ expect(parsed.data.color).toBe(color);
142
+
143
+ const deserialized = ComponentTransformer.deserialize(serialized);
144
+ expect(React.isValidElement(deserialized)).toBe(true);
145
+ });
146
+ });
147
+
148
+ it('should handle all alignment options', () => {
149
+ const alignments = ['left', 'center', 'right', 'justify', 'inherit'];
150
+
151
+ alignments.forEach(align => {
152
+ const originalComponent = (
153
+ <Text
154
+ content={`This text is ${align} aligned`}
155
+ align={align as any}
156
+ />
157
+ );
158
+
159
+ const serialized = ComponentTransformer.serialize(originalComponent);
160
+ const parsed = JSON.parse(serialized);
161
+
162
+ expect(parsed.data.align).toBe(align);
163
+
164
+ const deserialized = ComponentTransformer.deserialize(serialized);
165
+ expect(React.isValidElement(deserialized)).toBe(true);
166
+ });
167
+ });
168
+
169
+ it('should handle semantic HTML elements', () => {
170
+ const elements = ['p', 'span', 'div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'label', 'legend'];
171
+
172
+ elements.forEach(element => {
173
+ const originalComponent = (
174
+ <Text
175
+ content={`This is rendered as ${element} element`}
176
+ component={element as any}
177
+ />
178
+ );
179
+
180
+ const serialized = ComponentTransformer.serialize(originalComponent);
181
+ const parsed = JSON.parse(serialized);
182
+
183
+ expect(parsed.data.component).toBe(element);
184
+
185
+ const deserialized = ComponentTransformer.deserialize(serialized);
186
+ expect(React.isValidElement(deserialized)).toBe(true);
187
+ });
188
+ });
189
+ });
190
+
191
+ describe('Performance Tests', () => {
192
+ it('should serialize text component in under 1ms', () => {
193
+ const component = (
194
+ <Text
195
+ content="Performance test content"
196
+ variant="h1"
197
+ color="primary"
198
+ />
199
+ );
200
+
201
+ const startTime = performance.now();
202
+ const serialized = ComponentTransformer.serialize(component);
203
+ const endTime = performance.now();
204
+
205
+ expect(serialized).toBeTruthy();
206
+ expect(endTime - startTime).toBeLessThan(1); // Less than 1ms
207
+ });
208
+
209
+ it('should deserialize text component in under 1ms', () => {
210
+ const component = (
211
+ <Text
212
+ content="Performance test content"
213
+ variant="h1"
214
+ color="primary"
215
+ />
216
+ );
217
+
218
+ const serialized = ComponentTransformer.serialize(component);
219
+
220
+ const startTime = performance.now();
221
+ const deserialized = ComponentTransformer.deserialize(serialized);
222
+ const endTime = performance.now();
223
+
224
+ expect(React.isValidElement(deserialized)).toBe(true);
225
+ expect(endTime - startTime).toBeLessThan(1); // Less than 1ms
226
+ });
227
+
228
+ it('should handle large text content efficiently', () => {
229
+ const largeContent = 'Lorem ipsum '.repeat(1000); // ~11KB of text
230
+
231
+ const component = (
232
+ <Text
233
+ content={largeContent}
234
+ variant="body1"
235
+ paragraph={true}
236
+ />
237
+ );
238
+
239
+ const startTime = performance.now();
240
+ const serialized = ComponentTransformer.serialize(component);
241
+ const deserialized = ComponentTransformer.deserialize(serialized);
242
+ const endTime = performance.now();
243
+
244
+ expect(React.isValidElement(deserialized)).toBe(true);
245
+ expect(endTime - startTime).toBeLessThan(5); // Less than 5ms for large content
246
+ });
247
+ });
248
+
249
+ describe('Edge Cases', () => {
250
+ it('should handle empty content', () => {
251
+ const component = (
252
+ <Text content="" variant="body1" />
253
+ );
254
+
255
+ const serialized = ComponentTransformer.serialize(component);
256
+ const parsed = JSON.parse(serialized);
257
+
258
+ expect(parsed.data.content).toBe('');
259
+
260
+ const deserialized = ComponentTransformer.deserialize(serialized);
261
+ expect(React.isValidElement(deserialized)).toBe(true);
262
+ });
263
+
264
+ it('should handle undefined content', () => {
265
+ const component = (
266
+ <Text variant="body1" />
267
+ );
268
+
269
+ const serialized = ComponentTransformer.serialize(component);
270
+ const parsed = JSON.parse(serialized);
271
+
272
+ expect(parsed.data.content).toBeUndefined();
273
+
274
+ const deserialized = ComponentTransformer.deserialize(serialized);
275
+ expect(React.isValidElement(deserialized)).toBe(true);
276
+ });
277
+
278
+ it('should handle special characters in content', () => {
279
+ const specialContent = 'Special chars: !@#$%^&*()[]{}|;:,.<>?~`"\'\n\t\r';
280
+
281
+ const component = (
282
+ <Text content={specialContent} variant="body1" />
283
+ );
284
+
285
+ const serialized = ComponentTransformer.serialize(component);
286
+ const parsed = JSON.parse(serialized);
287
+
288
+ expect(parsed.data.content).toBe(specialContent);
289
+
290
+ const deserialized = ComponentTransformer.deserialize(serialized);
291
+ expect(React.isValidElement(deserialized)).toBe(true);
292
+ });
293
+
294
+ it('should handle unicode characters', () => {
295
+ const unicodeContent = 'Unicode: 🚀 🌟 📱 💡 🎯 🔥 ⭐ 🎉 🎨 🌈 中文 العربية 한국어 日本語 русский';
296
+
297
+ const component = (
298
+ <Text content={unicodeContent} variant="body1" />
299
+ );
300
+
301
+ const serialized = ComponentTransformer.serialize(component);
302
+ const parsed = JSON.parse(serialized);
303
+
304
+ expect(parsed.data.content).toBe(unicodeContent);
305
+
306
+ const deserialized = ComponentTransformer.deserialize(serialized);
307
+ expect(React.isValidElement(deserialized)).toBe(true);
308
+ });
309
+
310
+ it('should handle numeric content (zero)', () => {
311
+ const component = (
312
+ <Text content="0" variant="body1" />
313
+ );
314
+
315
+ const serialized = ComponentTransformer.serialize(component);
316
+ const parsed = JSON.parse(serialized);
317
+
318
+ expect(parsed.data.content).toBe('0');
319
+
320
+ const deserialized = ComponentTransformer.deserialize(serialized);
321
+ expect(React.isValidElement(deserialized)).toBe(true);
322
+ });
323
+
324
+ it('should handle default property values', () => {
325
+ const component = (
326
+ <Text content="Default properties test" />
327
+ );
328
+
329
+ const serialized = ComponentTransformer.serialize(component);
330
+ const parsed = JSON.parse(serialized);
331
+ const data = parsed.data;
332
+
333
+ // Should include explicit undefined for default values that weren't set
334
+ expect(data.content).toBe('Default properties test');
335
+ expect(data.variant).toBeUndefined(); // Will default to 'body1' in component
336
+ expect(data.color).toBeUndefined(); // Will default to 'inherit' in component
337
+ expect(data.align).toBeUndefined(); // Will default to 'inherit' in component
338
+
339
+ const deserialized = ComponentTransformer.deserialize(serialized);
340
+ expect(React.isValidElement(deserialized)).toBe(true);
341
+ });
342
+ });
343
+
344
+ describe('Render Consistency', () => {
345
+ it('should render serialized and original components identically', () => {
346
+ const originalComponent = (
347
+ <Text
348
+ content="Render consistency test"
349
+ variant="h3"
350
+ color="secondary"
351
+ align="center"
352
+ fontWeight="bold"
353
+ />
354
+ );
355
+
356
+ // Render original
357
+ const { container: originalContainer } = render(originalComponent);
358
+ const originalHTML = originalContainer.innerHTML;
359
+
360
+ // Serialize and deserialize
361
+ const serialized = ComponentTransformer.serialize(originalComponent);
362
+ const deserialized = ComponentTransformer.deserialize(serialized);
363
+
364
+ // Render deserialized
365
+ const { container: deserializedContainer } = render(deserialized as React.ReactElement);
366
+ const deserializedHTML = deserializedContainer.innerHTML;
367
+
368
+ // Should produce identical HTML output
369
+ expect(deserializedHTML).toBe(originalHTML);
370
+ });
371
+
372
+ it('should maintain text content after serialization round-trip', () => {
373
+ const testContent = 'This content should remain exactly the same after serialization';
374
+
375
+ const originalComponent = (
376
+ <Text content={testContent} variant="body1" />
377
+ );
378
+
379
+ const serialized = ComponentTransformer.serialize(originalComponent);
380
+ const deserialized = ComponentTransformer.deserialize(serialized);
381
+
382
+ render(deserialized as React.ReactElement);
383
+
384
+ // Check if the text content is preserved
385
+ expect(screen.getByText(testContent)).toBeInTheDocument();
386
+ });
387
+ });
388
+
389
+ describe('Data Structure Validation', () => {
390
+ it('should create valid JSON structure', () => {
391
+ const component = (
392
+ <Text
393
+ content="JSON validation test"
394
+ variant="h4"
395
+ color="primary"
396
+ gutterBottom={true}
397
+ />
398
+ );
399
+
400
+ const serialized = ComponentTransformer.serialize(component);
401
+ const parsed = JSON.parse(serialized);
402
+
403
+ // Validate top-level structure
404
+ expect(parsed).toHaveProperty('tag');
405
+ expect(parsed).toHaveProperty('version');
406
+ expect(parsed).toHaveProperty('data');
407
+
408
+ // Validate component identification
409
+ expect(parsed.tag).toBe('Text');
410
+ expect(parsed.version).toBe('1.0.0');
411
+
412
+ // Validate data structure
413
+ expect(typeof parsed.data).toBe('object');
414
+ expect(parsed.data.content).toBe('JSON validation test');
415
+ expect(parsed.data.variant).toBe('h4');
416
+ expect(parsed.data.color).toBe('primary');
417
+ expect(parsed.data.gutterBottom).toBe(true);
418
+ });
419
+
420
+ it('should maintain type integrity for all properties', () => {
421
+ const component = (
422
+ <Text
423
+ content="Type integrity test"
424
+ variant="h2"
425
+ color="error"
426
+ align="right"
427
+ component="h3"
428
+ fontWeight="600"
429
+ textDecoration="underline"
430
+ textTransform="capitalize"
431
+ noWrap={false}
432
+ paragraph={true}
433
+ gutterBottom={false}
434
+ fontSize="1.8rem"
435
+ lineHeight="1.4"
436
+ letterSpacing="0.05em"
437
+ fontFamily="Helvetica, sans-serif"
438
+ customColor="#ff5722"
439
+ maxWidth="500px"
440
+ />
441
+ );
442
+
443
+ const serialized = ComponentTransformer.serialize(component);
444
+ const parsed = JSON.parse(serialized);
445
+ const data = parsed.data;
446
+
447
+ // Validate string properties
448
+ expect(typeof data.content).toBe('string');
449
+ expect(typeof data.variant).toBe('string');
450
+ expect(typeof data.color).toBe('string');
451
+ expect(typeof data.align).toBe('string');
452
+ expect(typeof data.component).toBe('string');
453
+ expect(typeof data.fontWeight).toBe('string');
454
+ expect(typeof data.textDecoration).toBe('string');
455
+ expect(typeof data.textTransform).toBe('string');
456
+ expect(typeof data.fontSize).toBe('string');
457
+ expect(typeof data.lineHeight).toBe('string');
458
+ expect(typeof data.letterSpacing).toBe('string');
459
+ expect(typeof data.fontFamily).toBe('string');
460
+ expect(typeof data.customColor).toBe('string');
461
+ expect(typeof data.maxWidth).toBe('string');
462
+
463
+ // Validate boolean properties
464
+ expect(typeof data.noWrap).toBe('boolean');
465
+ expect(typeof data.paragraph).toBe('boolean');
466
+ expect(typeof data.gutterBottom).toBe('boolean');
467
+ });
468
+ });
469
+
470
+ describe('Component Identity', () => {
471
+ it('should preserve static component properties', () => {
472
+ expect(Text.tagName).toBe('Text');
473
+ expect(Text.version).toBe('1.0.0');
474
+ expect(typeof Text.fromJson).toBe('function');
475
+ });
476
+
477
+ it('should support fromJson static method', () => {
478
+ const jsonData = {
479
+ content: 'Static method test',
480
+ variant: 'h5',
481
+ color: 'success'
482
+ };
483
+
484
+ const component = Text.fromJson(jsonData);
485
+ expect(React.isValidElement(component)).toBe(true);
486
+
487
+ render(component);
488
+ expect(screen.getByText('Static method test')).toBeInTheDocument();
489
+ });
490
+ });
491
+ });