@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,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
+ });