@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,301 @@
1
+ /**
2
+ * ComponentTransformer HTML Pattern Tests
3
+ *
4
+ * Tests the HTML pattern registration and transformation functionality
5
+ * of the ComponentTransformer system.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { ComponentTransformer, PatternHandler } from '../ComponentTransformer';
12
+ import { Code } from '../../../../schemas/transformers/components/blocks/Code';
13
+
14
+ // Mock DOM environment for Node.js testing
15
+ Object.defineProperty(global, 'DOMParser', {
16
+ writable: true,
17
+ value: class DOMParser {
18
+ parseFromString(htmlString: string, contentType: string) {
19
+ // Simple mock that creates elements for our tests
20
+ const mockDoc = {
21
+ body: {
22
+ children: []
23
+ }
24
+ };
25
+
26
+ // Simple parsing for basic elements
27
+ if (htmlString.includes('<code>')) {
28
+ const codeElement = {
29
+ tagName: 'CODE',
30
+ textContent: 'console.log("test");',
31
+ className: '',
32
+ classList: [],
33
+ matches: (selector: string) => selector === 'code',
34
+ querySelector: () => null,
35
+ children: []
36
+ };
37
+ mockDoc.body.children = [codeElement];
38
+ }
39
+
40
+ return mockDoc;
41
+ }
42
+ }
43
+ });
44
+
45
+ // Mock document.createElement
46
+ Object.defineProperty(global, 'document', {
47
+ writable: true,
48
+ value: {
49
+ createElement: (tagName: string) => ({
50
+ tagName: tagName.toUpperCase(),
51
+ className: '',
52
+ classList: [],
53
+ textContent: '',
54
+ innerHTML: '',
55
+ id: '',
56
+ appendChild: jest.fn(),
57
+ querySelector: jest.fn(),
58
+ matches: jest.fn(),
59
+ children: []
60
+ })
61
+ }
62
+ });
63
+
64
+ describe('ComponentTransformer HTML Patterns', () => {
65
+ beforeEach(() => {
66
+ // Clear registries before each test
67
+ ComponentTransformer.clearRegistry();
68
+ });
69
+
70
+ describe('Pattern Registration', () => {
71
+ test('should register HTML patterns', () => {
72
+ const mockHandler: PatternHandler = (element: Element) => ({
73
+ tagName: 'TestComponent',
74
+ props: { content: element.textContent }
75
+ });
76
+
77
+ ComponentTransformer.registerPattern('div.test', mockHandler);
78
+
79
+ expect(ComponentTransformer.hasPattern('div.test')).toBe(true);
80
+ expect(ComponentTransformer.getRegisteredPatterns()).toContain('div.test');
81
+ });
82
+
83
+ test('should warn when overriding existing patterns', () => {
84
+ const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
85
+
86
+ const handler1: PatternHandler = () => ({ tagName: 'Component1' });
87
+ const handler2: PatternHandler = () => ({ tagName: 'Component2' });
88
+
89
+ ComponentTransformer.registerPattern('div.test', handler1);
90
+ ComponentTransformer.registerPattern('div.test', handler2);
91
+
92
+ expect(consoleSpy).toHaveBeenCalledWith(
93
+ "Pattern 'div.test' is already registered. Overwriting existing handler."
94
+ );
95
+
96
+ consoleSpy.mockRestore();
97
+ });
98
+
99
+ test('should register patterns when component is registered', () => {
100
+ // Mock the Code component's registerPatternHandlers method
101
+ const originalRegisterPatterns = Code.registerPatternHandlers;
102
+ const mockRegisterPatterns = jest.fn();
103
+ Code.registerPatternHandlers = mockRegisterPatterns;
104
+
105
+ ComponentTransformer.registerComponent(Code as any);
106
+
107
+ expect(mockRegisterPatterns).toHaveBeenCalledWith(ComponentTransformer);
108
+
109
+ // Restore original method
110
+ Code.registerPatternHandlers = originalRegisterPatterns;
111
+ });
112
+ });
113
+
114
+ describe('HTML Element Transformation', () => {
115
+ test('should transform matching HTML elements', () => {
116
+ // Register a test pattern
117
+ const testHandler: PatternHandler = (element: Element) => ({
118
+ tagName: 'TestComponent',
119
+ props: {
120
+ content: element.textContent,
121
+ className: element.className
122
+ }
123
+ });
124
+
125
+ ComponentTransformer.registerPattern('div.highlight', testHandler);
126
+
127
+ // Create test element
128
+ const div = document.createElement('div');
129
+ div.className = 'highlight';
130
+ div.textContent = 'Test content';
131
+
132
+ // Mock ComponentTransformer.deserialize to return a simple result
133
+ const originalDeserialize = ComponentTransformer.deserialize;
134
+ ComponentTransformer.deserialize = jest.fn().mockReturnValue(
135
+ React.createElement('div', { 'data-testid': 'transformed' }, 'Test content')
136
+ );
137
+
138
+ const result = ComponentTransformer.transformHTMLElement(div);
139
+
140
+ expect(ComponentTransformer.deserialize).toHaveBeenCalledWith({
141
+ tagName: 'TestComponent',
142
+ props: {
143
+ content: 'Test content',
144
+ className: 'highlight'
145
+ }
146
+ });
147
+
148
+ expect(result).toBeTruthy();
149
+
150
+ // Restore original method
151
+ ComponentTransformer.deserialize = originalDeserialize;
152
+ });
153
+
154
+ test('should return null for non-matching elements', () => {
155
+ ComponentTransformer.registerPattern('div.highlight', () => ({ tagName: 'Test' }));
156
+
157
+ const div = document.createElement('div');
158
+ div.className = 'normal';
159
+
160
+ const result = ComponentTransformer.transformHTMLElement(div);
161
+ expect(result).toBeNull();
162
+ });
163
+
164
+ test('should handle transformation errors gracefully', () => {
165
+ const consoleSpy = jest.spyOn(console, 'warn').mockImplementation();
166
+
167
+ const errorHandler: PatternHandler = () => {
168
+ throw new Error('Transformation error');
169
+ };
170
+
171
+ ComponentTransformer.registerPattern('div.error', errorHandler);
172
+
173
+ const div = document.createElement('div');
174
+ div.className = 'error';
175
+
176
+ const result = ComponentTransformer.transformHTMLElement(div);
177
+
178
+ expect(result).toBeNull();
179
+ expect(consoleSpy).toHaveBeenCalledWith(
180
+ "Error transforming element with pattern 'div.error':",
181
+ expect.any(Error)
182
+ );
183
+
184
+ consoleSpy.mockRestore();
185
+ });
186
+ });
187
+
188
+ describe('HTML String Transformation', () => {
189
+ test('should transform HTML string to React nodes', () => {
190
+ // Register test pattern
191
+ ComponentTransformer.registerPattern('code', (element: Element) => ({
192
+ tagName: 'Code',
193
+ props: {
194
+ children: element.textContent,
195
+ language: 'javascript'
196
+ }
197
+ }));
198
+
199
+ // Mock deserialize to return test elements
200
+ const originalDeserialize = ComponentTransformer.deserialize;
201
+ ComponentTransformer.deserialize = jest.fn().mockReturnValue(
202
+ React.createElement('pre', { 'data-testid': 'code-block' })
203
+ );
204
+
205
+ const html = '<code>console.log("hello");</code>';
206
+ const results = ComponentTransformer.transformHTML(html);
207
+
208
+ expect(results).toHaveLength(1);
209
+ expect(ComponentTransformer.deserialize).toHaveBeenCalled();
210
+
211
+ ComponentTransformer.deserialize = originalDeserialize;
212
+ });
213
+
214
+ test('should return empty array for empty HTML', () => {
215
+ const results = ComponentTransformer.transformHTML('');
216
+ expect(results).toEqual([]);
217
+ });
218
+
219
+ test('should return empty array for whitespace-only HTML', () => {
220
+ const results = ComponentTransformer.transformHTML(' \n \t ');
221
+ expect(results).toEqual([]);
222
+ });
223
+ });
224
+
225
+ describe('Code Component Integration', () => {
226
+ test('should register Code component patterns', () => {
227
+ // Register Code component
228
+ ComponentTransformer.registerComponent(Code as any);
229
+
230
+ // Check that patterns were registered
231
+ expect(ComponentTransformer.hasPattern('pre code')).toBe(true);
232
+ expect(ComponentTransformer.hasPattern('code.highlight')).toBe(true);
233
+ });
234
+
235
+ test('should transform pre+code elements', () => {
236
+ ComponentTransformer.registerComponent(Code as any);
237
+
238
+ // Create pre+code element
239
+ const pre = document.createElement('pre');
240
+ const code = document.createElement('code');
241
+ code.className = 'language-javascript';
242
+ code.textContent = 'console.log("test");';
243
+ pre.appendChild(code);
244
+
245
+ // Mock deserialize
246
+ const originalDeserialize = ComponentTransformer.deserialize;
247
+ ComponentTransformer.deserialize = jest.fn().mockReturnValue(
248
+ React.createElement('div', { 'data-testid': 'code-component' })
249
+ );
250
+
251
+ const result = ComponentTransformer.transformHTMLElement(pre);
252
+
253
+ expect(ComponentTransformer.deserialize).toHaveBeenCalledWith({
254
+ tagName: 'Code',
255
+ props: {
256
+ language: 'javascript',
257
+ showCopy: true,
258
+ showLineNumbers: false,
259
+ children: 'console.log("test");'
260
+ }
261
+ });
262
+
263
+ expect(result).toBeTruthy();
264
+
265
+ ComponentTransformer.deserialize = originalDeserialize;
266
+ });
267
+
268
+ test('should handle missing code child in pre element', () => {
269
+ ComponentTransformer.registerComponent(Code as any);
270
+
271
+ const pre = document.createElement('pre');
272
+ pre.textContent = 'Just text, no code element';
273
+
274
+ // Since the transformPreCode handler returns null for elements without code child,
275
+ // the element should not match and return null
276
+ const result = ComponentTransformer.transformHTMLElement(pre);
277
+ expect(result).toBeNull();
278
+ });
279
+ });
280
+
281
+ describe('Registry Management', () => {
282
+ test('should clear pattern registry', () => {
283
+ ComponentTransformer.registerPattern('div.test', () => ({ tagName: 'Test' }));
284
+ expect(ComponentTransformer.hasPattern('div.test')).toBe(true);
285
+
286
+ ComponentTransformer.clearRegistry();
287
+ expect(ComponentTransformer.hasPattern('div.test')).toBe(false);
288
+ expect(ComponentTransformer.getRegisteredPatterns()).toHaveLength(0);
289
+ });
290
+
291
+ test('should get list of registered patterns', () => {
292
+ ComponentTransformer.registerPattern('div.test1', () => ({ tagName: 'Test1' }));
293
+ ComponentTransformer.registerPattern('span.test2', () => ({ tagName: 'Test2' }));
294
+
295
+ const patterns = ComponentTransformer.getRegisteredPatterns();
296
+ expect(patterns).toContain('div.test1');
297
+ expect(patterns).toContain('span.test2');
298
+ expect(patterns).toHaveLength(2);
299
+ });
300
+ });
301
+ });