@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,819 @@
1
+ /**
2
+ * Image Component Stories - Comprehensive image display with data binding support
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+
7
+ import { Box, Divider, Typography, Alert, Paper, Grid } from '@mui/material';
8
+ import { JsonDataProvider } from '@qwickapps/schema';
9
+ import type { Meta, StoryObj } from '@storybook/react';
10
+ import { Image } from '../components/blocks';
11
+ import { ComponentTransformer } from '../schemas/transformers/ComponentTransformer';
12
+ import { ModelView } from '../components/base/ModelView';
13
+ import QwickApp from '../components/QwickApp';
14
+ import React from 'react';
15
+
16
+ // Sample image URLs for different use cases
17
+ const sampleImages = {
18
+ landscape: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2340&q=80',
19
+ portrait: 'https://images.unsplash.com/photo-1494790108755-2616c57b8a14?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=987&q=80',
20
+ square: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2340&q=80',
21
+ technology: 'https://images.unsplash.com/photo-1518709268805-4e9042af2176?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2225&q=80',
22
+ product: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80',
23
+ fallback: 'https://via.placeholder.com/400x300/e0e0e0/666666?text=Fallback+Image'
24
+ };
25
+
26
+ // Sample CMS data for data binding examples
27
+ const sampleCmsData = {
28
+ gallery: {
29
+ heroImage: {
30
+ src: sampleImages.landscape,
31
+ alt: 'Beautiful mountain landscape at sunset',
32
+ width: 800,
33
+ height: 600,
34
+ objectFit: 'cover',
35
+ objectPosition: 'center',
36
+ title: 'Mountain Sunset - Professional Photography',
37
+ showLoading: true,
38
+ borderRadius: '12px'
39
+ },
40
+ profileImage: {
41
+ src: sampleImages.portrait,
42
+ alt: 'Professional headshot of a smiling woman',
43
+ width: 200,
44
+ height: 200,
45
+ objectFit: 'cover',
46
+ objectPosition: 'center',
47
+ borderRadius: '50%',
48
+ showLoading: true,
49
+ draggable: false
50
+ },
51
+ productImage: {
52
+ src: sampleImages.product,
53
+ alt: 'Premium headphones on white background',
54
+ width: 400,
55
+ height: 300,
56
+ objectFit: 'contain',
57
+ objectPosition: 'center',
58
+ showLoading: true,
59
+ showError: true,
60
+ fallbackSrc: sampleImages.fallback,
61
+ borderRadius: '8px'
62
+ },
63
+ responsiveImage: {
64
+ src: sampleImages.technology,
65
+ alt: 'Modern laptop setup with code on screen',
66
+ objectFit: 'cover',
67
+ objectPosition: 'center',
68
+ sizes: '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw',
69
+ srcSet: `${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`,
70
+ showLoading: true,
71
+ borderRadius: '16px'
72
+ }
73
+ }
74
+ };
75
+
76
+ const dataProvider = new JsonDataProvider({ data: sampleCmsData });
77
+
78
+ const meta = {
79
+ title: 'Components/Image',
80
+ component: Image,
81
+ parameters: {
82
+ layout: 'padded',
83
+ docs: {
84
+ description: {
85
+ component: `Image is a comprehensive image display component with advanced features for responsive design, loading states, and accessibility.
86
+
87
+ **Key Features:**
88
+ - **Responsive Images**: Support for srcSet and sizes for optimized loading
89
+ - **Object Fit Control**: Full control over how images fit their containers
90
+ - **Loading States**: Visual feedback during image loading with customizable placeholders
91
+ - **Error Handling**: Graceful fallback for failed image loads
92
+ - **Accessibility**: Proper alt text and title support for screen readers
93
+ - **Lazy Loading**: Built-in support for performance optimization
94
+ - **Data Binding**: Full CMS integration through dataSource prop
95
+ - **Customization**: Border radius, positioning, and styling options
96
+ - **Fallback Support**: Automatic fallback to alternative image sources
97
+ - **Touch Friendly**: Configurable draggable behavior for touch interfaces
98
+
99
+ **Perfect For:**
100
+ - Hero sections and banners
101
+ - Product galleries and catalogs
102
+ - Profile pictures and avatars
103
+ - Content illustrations and media
104
+ - Responsive image grids
105
+ - Progressive web app imagery`,
106
+ },
107
+ },
108
+ },
109
+ tags: ['autodocs'],
110
+ } satisfies Meta<typeof Image>;
111
+
112
+ export default meta;
113
+ type Story = StoryObj<typeof Image>;
114
+
115
+ // Traditional Usage Examples
116
+ export const BasicImage: Story = {
117
+ render: () => (
118
+ <QwickApp appId="image-basic" appName='Basic Image Example'>
119
+ <Image
120
+ src={sampleImages.landscape}
121
+ alt="Beautiful mountain landscape at sunset"
122
+ width={600}
123
+ height={400}
124
+ showLoading={true}
125
+ />
126
+ </QwickApp>
127
+ ),
128
+ parameters: {
129
+ docs: {
130
+ description: {
131
+ story: 'Basic image display with loading state and proper alt text for accessibility.',
132
+ },
133
+ },
134
+ },
135
+ };
136
+
137
+ export const ResponsiveImage: Story = {
138
+ render: () => (
139
+ <QwickApp appId="image-responsive" appName='Responsive Image Example'>
140
+ <Image
141
+ src={sampleImages.technology}
142
+ alt="Modern laptop setup with code on screen"
143
+ objectFit="cover"
144
+ objectPosition="center"
145
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
146
+ srcSet={`${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`}
147
+ showLoading={true}
148
+ borderRadius="16px"
149
+ style={{ width: '100%', maxWidth: '800px', height: '400px' }}
150
+ />
151
+ </QwickApp>
152
+ ),
153
+ parameters: {
154
+ docs: {
155
+ description: {
156
+ story: 'Responsive image with srcSet for different screen sizes and optimized loading.',
157
+ },
158
+ },
159
+ },
160
+ };
161
+
162
+ export const ObjectFitModes: Story = {
163
+ render: () => (
164
+ <QwickApp appId="image-object-fit" appName='Object Fit Examples'>
165
+ <Grid container spacing={3}>
166
+ <Grid item xs={12} sm={6} md={4}>
167
+ <Typography variant="h6" gutterBottom>Cover (default)</Typography>
168
+ <Image
169
+ src={sampleImages.landscape}
170
+ alt="Landscape with cover fit"
171
+ width={300}
172
+ height={200}
173
+ objectFit="cover"
174
+ borderRadius="8px"
175
+ showLoading={true}
176
+ />
177
+ </Grid>
178
+
179
+ <Grid item xs={12} sm={6} md={4}>
180
+ <Typography variant="h6" gutterBottom>Contain</Typography>
181
+ <Image
182
+ src={sampleImages.landscape}
183
+ alt="Landscape with contain fit"
184
+ width={300}
185
+ height={200}
186
+ objectFit="contain"
187
+ borderRadius="8px"
188
+ showLoading={true}
189
+ style={{ backgroundColor: '#f5f5f5' }}
190
+ />
191
+ </Grid>
192
+
193
+ <Grid item xs={12} sm={6} md={4}>
194
+ <Typography variant="h6" gutterBottom>Fill</Typography>
195
+ <Image
196
+ src={sampleImages.landscape}
197
+ alt="Landscape with fill fit"
198
+ width={300}
199
+ height={200}
200
+ objectFit="fill"
201
+ borderRadius="8px"
202
+ showLoading={true}
203
+ />
204
+ </Grid>
205
+
206
+ <Grid item xs={12} sm={6} md={4}>
207
+ <Typography variant="h6" gutterBottom>Scale Down</Typography>
208
+ <Image
209
+ src={sampleImages.square}
210
+ alt="Small image with scale-down fit"
211
+ width={300}
212
+ height={200}
213
+ objectFit="scale-down"
214
+ borderRadius="8px"
215
+ showLoading={true}
216
+ style={{ backgroundColor: '#f5f5f5' }}
217
+ />
218
+ </Grid>
219
+
220
+ <Grid item xs={12} sm={6} md={4}>
221
+ <Typography variant="h6" gutterBottom>None</Typography>
222
+ <Image
223
+ src={sampleImages.square}
224
+ alt="Image with no fitting"
225
+ width={300}
226
+ height={200}
227
+ objectFit="none"
228
+ borderRadius="8px"
229
+ showLoading={true}
230
+ style={{ backgroundColor: '#f5f5f5' }}
231
+ />
232
+ </Grid>
233
+ </Grid>
234
+ </QwickApp>
235
+ ),
236
+ parameters: {
237
+ docs: {
238
+ description: {
239
+ story: 'Different object-fit modes showing how images resize within their containers.',
240
+ },
241
+ },
242
+ },
243
+ };
244
+
245
+ export const LoadingAndErrorStates: Story = {
246
+ render: () => (
247
+ <QwickApp appId="image-states" appName='Loading and Error States'>
248
+ <Grid container spacing={3}>
249
+ <Grid item xs={12} md={4}>
250
+ <Typography variant="h6" gutterBottom>With Loading State</Typography>
251
+ <Image
252
+ src={sampleImages.portrait}
253
+ alt="Portrait with loading state"
254
+ width={300}
255
+ height={300}
256
+ objectFit="cover"
257
+ borderRadius="8px"
258
+ showLoading={true}
259
+ />
260
+ </Grid>
261
+
262
+ <Grid item xs={12} md={4}>
263
+ <Typography variant="h6" gutterBottom>Error with Fallback</Typography>
264
+ <Image
265
+ src="https://invalid-url-that-will-fail.jpg"
266
+ alt="Image that will fail to load"
267
+ width={300}
268
+ height={300}
269
+ objectFit="cover"
270
+ borderRadius="8px"
271
+ showError={true}
272
+ fallbackSrc={sampleImages.fallback}
273
+ />
274
+ </Grid>
275
+
276
+ <Grid item xs={12} md={4}>
277
+ <Typography variant="h6" gutterBottom>Error State Only</Typography>
278
+ <Image
279
+ src="https://another-invalid-url.jpg"
280
+ alt="Image that will show error"
281
+ width={300}
282
+ height={300}
283
+ objectFit="cover"
284
+ borderRadius="8px"
285
+ showError={true}
286
+ />
287
+ </Grid>
288
+ </Grid>
289
+ </QwickApp>
290
+ ),
291
+ parameters: {
292
+ docs: {
293
+ description: {
294
+ story: 'Loading states and error handling including fallback image support.',
295
+ },
296
+ },
297
+ },
298
+ };
299
+
300
+ export const ShapeVariations: Story = {
301
+ render: () => (
302
+ <QwickApp appId="image-shapes" appName='Image Shape Variations'>
303
+ <Grid container spacing={3} alignItems="center">
304
+ <Grid item xs={12} sm={6} md={3}>
305
+ <Typography variant="h6" gutterBottom>Circular Avatar</Typography>
306
+ <Image
307
+ src={sampleImages.portrait}
308
+ alt="Circular profile picture"
309
+ width={150}
310
+ height={150}
311
+ objectFit="cover"
312
+ objectPosition="center"
313
+ borderRadius="50%"
314
+ draggable={false}
315
+ showLoading={true}
316
+ />
317
+ </Grid>
318
+
319
+ <Grid item xs={12} sm={6} md={3}>
320
+ <Typography variant="h6" gutterBottom>Rounded Rectangle</Typography>
321
+ <Image
322
+ src={sampleImages.product}
323
+ alt="Product image with rounded corners"
324
+ width={200}
325
+ height={150}
326
+ objectFit="cover"
327
+ borderRadius="16px"
328
+ showLoading={true}
329
+ />
330
+ </Grid>
331
+
332
+ <Grid item xs={12} sm={6} md={3}>
333
+ <Typography variant="h6" gutterBottom>Sharp Rectangle</Typography>
334
+ <Image
335
+ src={sampleImages.technology}
336
+ alt="Technology image with sharp corners"
337
+ width={200}
338
+ height={150}
339
+ objectFit="cover"
340
+ borderRadius="0px"
341
+ showLoading={true}
342
+ />
343
+ </Grid>
344
+
345
+ <Grid item xs={12} sm={6} md={3}>
346
+ <Typography variant="h6" gutterBottom>Custom Radius</Typography>
347
+ <Image
348
+ src={sampleImages.square}
349
+ alt="Image with custom border radius"
350
+ width={150}
351
+ height={150}
352
+ objectFit="cover"
353
+ borderRadius="24px"
354
+ showLoading={true}
355
+ />
356
+ </Grid>
357
+ </Grid>
358
+ </QwickApp>
359
+ ),
360
+ parameters: {
361
+ docs: {
362
+ description: {
363
+ story: 'Various border radius options for different image shapes and use cases.',
364
+ },
365
+ },
366
+ },
367
+ };
368
+
369
+ export const InteractiveFeatures: Story = {
370
+ render: () => (
371
+ <QwickApp appId="image-interactive" appName='Interactive Image Features'>
372
+ <Grid container spacing={3}>
373
+ <Grid item xs={12} md={6}>
374
+ <Typography variant="h6" gutterBottom>Clickable Image</Typography>
375
+ <Image
376
+ src={sampleImages.landscape}
377
+ alt="Clickable landscape image"
378
+ width={400}
379
+ height={300}
380
+ objectFit="cover"
381
+ borderRadius="12px"
382
+ showLoading={true}
383
+ onClick={(e) => alert('Image clicked!')}
384
+ style={{ cursor: 'pointer', transition: 'transform 0.2s', '&:hover': { transform: 'scale(1.02)' } }}
385
+ title="Click me!"
386
+ />
387
+ </Grid>
388
+
389
+ <Grid item xs={12} md={6}>
390
+ <Typography variant="h6" gutterBottom>Non-draggable Image</Typography>
391
+ <Image
392
+ src={sampleImages.portrait}
393
+ alt="Non-draggable portrait"
394
+ width={300}
395
+ height={400}
396
+ objectFit="cover"
397
+ borderRadius="12px"
398
+ draggable={false}
399
+ showLoading={true}
400
+ title="This image cannot be dragged"
401
+ />
402
+ </Grid>
403
+ </Grid>
404
+ </QwickApp>
405
+ ),
406
+ parameters: {
407
+ docs: {
408
+ description: {
409
+ story: 'Interactive features including click handlers and drag control.',
410
+ },
411
+ },
412
+ },
413
+ };
414
+
415
+ // Data Binding Examples
416
+ export const DataBoundHeroImage: Story = {
417
+ render: () => (
418
+ <QwickApp appId="image-hero-data" appName='Data-Bound Hero Image'>
419
+ <Image
420
+ dataSource={dataProvider.createDataSource('gallery.heroImage')}
421
+ bindingOptions={{
422
+ cache: true,
423
+ cacheTTL: 300000,
424
+ strict: false
425
+ }}
426
+ />
427
+ </QwickApp>
428
+ ),
429
+ parameters: {
430
+ docs: {
431
+ description: {
432
+ story: 'Hero image loaded from CMS data with caching enabled for performance.',
433
+ },
434
+ },
435
+ },
436
+ };
437
+
438
+ export const DataBoundProfileAvatar: Story = {
439
+ render: () => (
440
+ <QwickApp appId="image-avatar-data" appName='Data-Bound Profile Avatar'>
441
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
442
+ <Image
443
+ dataSource={dataProvider.createDataSource('gallery.profileImage')}
444
+ bindingOptions={{
445
+ cache: true,
446
+ strict: false
447
+ }}
448
+ />
449
+ <Box>
450
+ <Typography variant="h6">Sarah Johnson</Typography>
451
+ <Typography variant="body2" color="text.secondary">Senior Developer</Typography>
452
+ </Box>
453
+ </Box>
454
+ </QwickApp>
455
+ ),
456
+ parameters: {
457
+ docs: {
458
+ description: {
459
+ story: 'Profile avatar loaded from CMS with circular styling and non-draggable setting.',
460
+ },
461
+ },
462
+ },
463
+ };
464
+
465
+ export const DataBoundProductImage: Story = {
466
+ render: () => (
467
+ <QwickApp appId="image-product-data" appName='Data-Bound Product Image'>
468
+ <Image
469
+ dataSource={dataProvider.createDataSource('gallery.productImage')}
470
+ bindingOptions={{
471
+ cache: true,
472
+ strict: false
473
+ }}
474
+ />
475
+ </QwickApp>
476
+ ),
477
+ parameters: {
478
+ docs: {
479
+ description: {
480
+ story: 'Product image with fallback support and error handling from CMS data.',
481
+ },
482
+ },
483
+ },
484
+ };
485
+
486
+ export const DataBoundResponsiveImage: Story = {
487
+ render: () => (
488
+ <QwickApp appId="image-responsive-data" appName='Data-Bound Responsive Image'>
489
+ <Box sx={{ width: '100%', maxWidth: '800px' }}>
490
+ <Image
491
+ dataSource={dataProvider.createDataSource('gallery.responsiveImage')}
492
+ bindingOptions={{
493
+ cache: true,
494
+ strict: false
495
+ }}
496
+ style={{ width: '100%', height: '400px' }}
497
+ />
498
+ </Box>
499
+ </QwickApp>
500
+ ),
501
+ parameters: {
502
+ docs: {
503
+ description: {
504
+ story: 'Responsive image with srcSet and sizes loaded from CMS for optimal performance.',
505
+ },
506
+ },
507
+ },
508
+ };
509
+
510
+ // ModelView Serialization Examples - Demonstrating the new ModelView base class
511
+ export const ModelViewBasic: Story = {
512
+ render: () => {
513
+ // Demonstrate that Image extends ModelView
514
+ const imageInstance = new Image({
515
+ src: sampleImages.landscape,
516
+ alt: 'Mountain landscape',
517
+ width: 400,
518
+ height: 300,
519
+ objectFit: 'cover',
520
+ borderRadius: '12px',
521
+ showLoading: true
522
+ });
523
+
524
+ // Show that it has ModelView properties
525
+ const hasToJson = typeof imageInstance.toJson === 'function';
526
+ const hasFromJson = typeof (imageInstance.constructor as any).fromJson === 'function';
527
+ const tagName = (imageInstance.constructor as any).tagName;
528
+ const version = (imageInstance.constructor as any).version;
529
+
530
+ return (
531
+ <QwickApp appId="image-modelview" appName='Image ModelView Demonstration'>
532
+ <Box sx={{ mb: 4 }}>
533
+ <Alert severity="info" sx={{ mb: 2 }}>
534
+ <Typography variant="body2" component="div">
535
+ <strong>Image Component extends ModelView:</strong><br />
536
+ • Has toJson method: {hasToJson ? '✅ Yes' : '❌ No'}<br />
537
+ • Has fromJson method: {hasFromJson ? '✅ Yes' : '❌ No'}<br />
538
+ • Component tag name: <code>{tagName}</code><br />
539
+ • Component version: <code>{version}</code>
540
+ </Typography>
541
+ </Alert>
542
+
543
+ {imageInstance.render()}
544
+ </Box>
545
+ </QwickApp>
546
+ );
547
+ },
548
+ parameters: {
549
+ docs: {
550
+ description: {
551
+ story: 'Demonstrates that Image extends ModelView and has serialization capabilities.',
552
+ },
553
+ },
554
+ },
555
+ };
556
+
557
+ // Enhanced Serialization Examples - "WebView for React" functionality
558
+ export const SerializationBasic: Story = {
559
+ render: () => {
560
+ // Create an Image component instance (now extends ModelView)
561
+ const originalImageComponent = (
562
+ <Image
563
+ src={sampleImages.landscape}
564
+ alt="Serializable mountain landscape"
565
+ width={600}
566
+ height={400}
567
+ objectFit="cover"
568
+ objectPosition="center"
569
+ borderRadius="16px"
570
+ showLoading={true}
571
+ title="Beautiful mountain vista"
572
+ />
573
+ );
574
+
575
+ // Serialize the component to JSON
576
+ const serialized = ComponentTransformer.serialize(originalImageComponent);
577
+
578
+ // Deserialize back to a React component
579
+ const deserializedComponent = ComponentTransformer.deserialize(serialized);
580
+
581
+ return (
582
+ <QwickApp appId="image-serialization-basic" appName='Basic Image Serialization'>
583
+ <Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
584
+
585
+ <Box>
586
+ <Typography variant="h6" gutterBottom>Original Image Component</Typography>
587
+ {originalImageComponent}
588
+ </Box>
589
+
590
+ <Divider />
591
+
592
+ <Box>
593
+ <Typography variant="h6" gutterBottom>Serialized JSON Data</Typography>
594
+ <Paper elevation={1} sx={{ p: 2, backgroundColor: 'grey.50' }}>
595
+ <Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.75rem' }}>
596
+ {JSON.stringify(JSON.parse(serialized), null, 2)}
597
+ </Typography>
598
+ </Paper>
599
+ </Box>
600
+
601
+ <Divider />
602
+
603
+ <Box>
604
+ <Typography variant="h6" gutterBottom>Deserialized Component (Recreated from JSON)</Typography>
605
+ {deserializedComponent}
606
+ </Box>
607
+
608
+ <Alert severity="success">
609
+ <Typography variant="body2">
610
+ <strong>Serialization Success!</strong> The Image component was successfully serialized to JSON and deserialized back to a functional React component with all properties preserved.
611
+ </Typography>
612
+ </Alert>
613
+
614
+ </Box>
615
+ </QwickApp>
616
+ );
617
+ },
618
+ parameters: {
619
+ docs: {
620
+ description: {
621
+ story: 'Demonstrates basic Image component serialization and deserialization using ComponentTransformer.',
622
+ },
623
+ },
624
+ },
625
+ };
626
+
627
+ export const SerializationComplex: Story = {
628
+ render: () => {
629
+ // Create a complex Image with multiple features
630
+ const complexImageComponent = (
631
+ <Image
632
+ src={sampleImages.technology}
633
+ alt="Complex responsive technology image"
634
+ width={800}
635
+ height={500}
636
+ objectFit="cover"
637
+ objectPosition="center"
638
+ loading="lazy"
639
+ borderRadius="20px"
640
+ showLoading={true}
641
+ showError={true}
642
+ fallbackSrc={sampleImages.fallback}
643
+ sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
644
+ srcSet={`${sampleImages.technology}&w=400 400w, ${sampleImages.technology}&w=800 800w, ${sampleImages.technology}&w=1200 1200w`}
645
+ title="Advanced technology setup with multiple monitors"
646
+ draggable={false}
647
+ />
648
+ );
649
+
650
+ // Serialize with all the complex properties
651
+ const serialized = ComponentTransformer.serialize(complexImageComponent);
652
+ const deserializedComponent = ComponentTransformer.deserialize(serialized);
653
+
654
+ // Parse for display
655
+ const parsedData = JSON.parse(serialized);
656
+
657
+ return (
658
+ <QwickApp appId="image-serialization-complex" appName='Complex Image Serialization'>
659
+ <Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
660
+
661
+ <Box>
662
+ <Typography variant="h6" gutterBottom>Original Complex Image</Typography>
663
+ <Typography variant="body2" color="text.secondary" gutterBottom>
664
+ Includes responsive srcSet, fallback image, loading states, and custom styling
665
+ </Typography>
666
+ {complexImageComponent}
667
+ </Box>
668
+
669
+ <Divider />
670
+
671
+ <Box>
672
+ <Typography variant="h6" gutterBottom>Serialized Properties</Typography>
673
+ <Grid container spacing={2}>
674
+ <Grid item xs={12} md={6}>
675
+ <Paper elevation={1} sx={{ p: 2, height: '300px', overflow: 'auto' }}>
676
+ <Typography variant="subtitle2" gutterBottom>JSON Structure:</Typography>
677
+ <Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.7rem' }}>
678
+ {JSON.stringify(parsedData, null, 2)}
679
+ </Typography>
680
+ </Paper>
681
+ </Grid>
682
+ <Grid item xs={12} md={6}>
683
+ <Paper elevation={1} sx={{ p: 2 }}>
684
+ <Typography variant="subtitle2" gutterBottom>Key Properties:</Typography>
685
+ <Typography variant="body2" component="div">
686
+ • Component: <code>{parsedData.tag}</code><br />
687
+ • Version: <code>{parsedData.version}</code><br />
688
+ • Source: <code>{parsedData.data?.src ? 'Present' : 'Missing'}</code><br />
689
+ • Alt text: <code>{parsedData.data?.alt ? 'Present' : 'Missing'}</code><br />
690
+ • Dimensions: <code>{parsedData.data?.width}x{parsedData.data?.height}</code><br />
691
+ • Object fit: <code>{parsedData.data?.objectFit}</code><br />
692
+ • Border radius: <code>{parsedData.data?.borderRadius}</code><br />
693
+ • Loading behavior: <code>{parsedData.data?.loading}</code><br />
694
+ • Fallback: <code>{parsedData.data?.fallbackSrc ? 'Present' : 'None'}</code><br />
695
+ • Responsive: <code>{parsedData.data?.srcSet ? 'Yes' : 'No'}</code>
696
+ </Typography>
697
+ </Paper>
698
+ </Grid>
699
+ </Grid>
700
+ </Box>
701
+
702
+ <Divider />
703
+
704
+ <Box>
705
+ <Typography variant="h6" gutterBottom>Deserialized Component</Typography>
706
+ <Typography variant="body2" color="text.secondary" gutterBottom>
707
+ Recreated from JSON with all properties and functionality intact
708
+ </Typography>
709
+ {deserializedComponent}
710
+ </Box>
711
+
712
+ <Alert severity="info">
713
+ <Typography variant="body2">
714
+ <strong>Advanced Serialization Success!</strong> All Image properties including responsive configuration,
715
+ fallback handling, loading states, and styling were perfectly preserved through the serialization process.
716
+ </Typography>
717
+ </Alert>
718
+
719
+ </Box>
720
+ </QwickApp>
721
+ );
722
+ },
723
+ parameters: {
724
+ docs: {
725
+ description: {
726
+ story: 'Demonstrates complex Image serialization with responsive images, fallbacks, and all advanced features.',
727
+ },
728
+ },
729
+ },
730
+ };
731
+
732
+ export const SerializationWithDataBinding: Story = {
733
+ render: () => {
734
+ // Create a data-bound Image component
735
+ const dataBoundImageComponent = (
736
+ <Image
737
+ dataSource={dataProvider.createDataSource('gallery.heroImage')}
738
+ bindingOptions={{
739
+ cache: true,
740
+ cacheTTL: 300000,
741
+ strict: false
742
+ }}
743
+ />
744
+ );
745
+
746
+ // Serialize the data-bound component
747
+ const serialized = ComponentTransformer.serialize(dataBoundImageComponent);
748
+ const deserializedComponent = ComponentTransformer.deserialize(serialized);
749
+ const parsedData = JSON.parse(serialized);
750
+
751
+ return (
752
+ <QwickApp appId="image-serialization-databound" appName='Data-Bound Image Serialization'>
753
+ <Box sx={{ '& > *:not(:last-child)': { mb: 4 } }}>
754
+
755
+ <Box>
756
+ <Typography variant="h6" gutterBottom>Original Data-Bound Image</Typography>
757
+ <Typography variant="body2" color="text.secondary" gutterBottom>
758
+ Image loaded from CMS data source with caching enabled
759
+ </Typography>
760
+ {dataBoundImageComponent}
761
+ </Box>
762
+
763
+ <Divider />
764
+
765
+ <Box>
766
+ <Typography variant="h6" gutterBottom>Serialized Data Binding</Typography>
767
+ <Grid container spacing={2}>
768
+ <Grid item xs={12} md={8}>
769
+ <Paper elevation={1} sx={{ p: 2 }}>
770
+ <Typography variant="subtitle2" gutterBottom>Serialized JSON:</Typography>
771
+ <Typography variant="body2" component="pre" sx={{ whiteSpace: 'pre-wrap', fontSize: '0.7rem', maxHeight: '200px', overflow: 'auto' }}>
772
+ {JSON.stringify(parsedData, null, 2)}
773
+ </Typography>
774
+ </Paper>
775
+ </Grid>
776
+ <Grid item xs={12} md={4}>
777
+ <Paper elevation={1} sx={{ p: 2 }}>
778
+ <Typography variant="subtitle2" gutterBottom>Data Binding Info:</Typography>
779
+ <Typography variant="body2" component="div">
780
+ • Data source: <code>{parsedData.data?.dataSource ? 'Preserved' : 'Missing'}</code><br />
781
+ • Binding options: <code>{parsedData.data?.bindingOptions ? 'Present' : 'None'}</code><br />
782
+ • Cache enabled: <code>{parsedData.data?.bindingOptions?.cache ? 'Yes' : 'No'}</code><br />
783
+ • Cache TTL: <code>{parsedData.data?.bindingOptions?.cacheTTL || 'Default'}</code><br />
784
+ • Strict mode: <code>{parsedData.data?.bindingOptions?.strict ? 'Yes' : 'No'}</code>
785
+ </Typography>
786
+ </Paper>
787
+ </Grid>
788
+ </Grid>
789
+ </Box>
790
+
791
+ <Divider />
792
+
793
+ <Box>
794
+ <Typography variant="h6" gutterBottom>Deserialized Data-Bound Component</Typography>
795
+ <Typography variant="body2" color="text.secondary" gutterBottom>
796
+ Recreated with full data binding functionality preserved
797
+ </Typography>
798
+ {deserializedComponent}
799
+ </Box>
800
+
801
+ <Alert severity="success">
802
+ <Typography variant="body2">
803
+ <strong>Data Binding Serialization Success!</strong> The Image component with CMS data binding,
804
+ caching configuration, and all binding options was successfully serialized and recreated.
805
+ </Typography>
806
+ </Alert>
807
+
808
+ </Box>
809
+ </QwickApp>
810
+ );
811
+ },
812
+ parameters: {
813
+ docs: {
814
+ description: {
815
+ story: 'Demonstrates serialization of data-bound Image components with CMS integration preserved.',
816
+ },
817
+ },
818
+ },
819
+ };