@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
@@ -19,62 +19,62 @@ import PaletteSwitcher from '../components/buttons/PaletteSwitcher';
19
19
 
20
20
  // Advanced CMS data with complex scenarios - using dotted notation for testing JsonDataProvider conversion
21
21
  const advancedCmsData = {
22
- // Multi-language content
23
- 'content.en.welcome': {
24
- html: '<h2>Welcome to QwickApps</h2><p>The future of app development is here.</p>',
25
- placeholder: 'Loading welcome message...'
26
- },
27
- 'content.es.welcome': {
28
- html: '<h2>Bienvenidos a QwickApps</h2><p>El futuro del desarrollo de aplicaciones está aquí.</p>',
29
- placeholder: 'Cargando mensaje de bienvenida...'
30
- },
31
-
32
- // Dynamic content with variables
33
- 'user.greeting': {
34
- html: '<p>Hello <strong>{{userName}}</strong>, welcome back!</p>',
35
- placeholder: 'Loading personalized greeting...'
36
- },
37
-
38
- // Time-sensitive content
39
- 'announcements.current': {
40
- html: '<div class="announcement"><p><strong>🎉 New Feature Alert:</strong> Dynamic data binding with schema validation is now available!</p></div>',
41
- placeholder: 'Loading current announcements...'
42
- },
43
-
44
- // A/B testing variants
45
- 'cta.variant-a': {
46
- html: '<p class="cta-primary"><strong>Start Building Today!</strong> - Try our free plan.</p>',
47
- placeholder: 'Loading call-to-action...'
48
- },
49
- 'cta.variant-b': {
50
- html: '<p class="cta-secondary"><strong>Join 10,000+ Developers</strong> - Get started now.</p>',
51
- placeholder: 'Loading call-to-action...'
52
- },
53
-
54
- // Rich media content
55
- 'blog.featured-post': {
56
- html: `
57
- <article>
58
- <h3>Building Scalable Apps with QwickApps React Framework</h3>
59
- <p class="meta">Published on January 15, 2025 • 8 min read</p>
60
- <p>Learn how our <strong>data-binding system</strong> enables dynamic, scalable applications with type-safe CMS integration and validation...</p>
61
- <a href="/blog/scalable-apps" class="read-more">Continue reading →</a>
62
- </article>
63
- `,
64
- placeholder: 'Loading featured blog post...'
65
- },
66
-
67
- // Malicious content for sanitization testing
68
- 'security.malicious': {
69
- html: '<script>alert("XSS attempt")</script><p>This content includes <strong>malicious scripts</strong> that should be automatically sanitized.</p><img src="x" onerror="alert(\'XSS\')" />',
70
- placeholder: 'Loading content...'
71
- },
72
-
73
- // Performance testing - Large content
74
- 'performance.large-content': {
75
- html: '<div>' + 'Very long content paragraph. '.repeat(100) + '</div>',
76
- placeholder: 'Loading large content...'
77
- }
22
+ // Multi-language content
23
+ 'content.en.welcome': {
24
+ html: '<h2>Welcome to QwickApps</h2><p>The future of app development is here.</p>',
25
+ placeholder: 'Loading welcome message...'
26
+ },
27
+ 'content.es.welcome': {
28
+ html: '<h2>Bienvenidos a QwickApps</h2><p>El futuro del desarrollo de aplicaciones está aquí.</p>',
29
+ placeholder: 'Cargando mensaje de bienvenida...'
30
+ },
31
+
32
+ // Dynamic content with variables
33
+ 'user.greeting': {
34
+ html: '<p>Hello <strong>{{userName}}</strong>, welcome back!</p>',
35
+ placeholder: 'Loading personalized greeting...'
36
+ },
37
+
38
+ // Time-sensitive content
39
+ 'announcements.current': {
40
+ html: '<div class="announcement"><p><strong> New Feature Alert:</strong> Dynamic data binding with schema validation is now available!</p></div>',
41
+ placeholder: 'Loading current announcements...'
42
+ },
43
+
44
+ // A/B testing variants
45
+ 'cta.variant-a': {
46
+ html: '<p class="cta-primary"><strong>Start Building Today!</strong> - Try our free plan.</p>',
47
+ placeholder: 'Loading call-to-action...'
48
+ },
49
+ 'cta.variant-b': {
50
+ html: '<p class="cta-secondary"><strong>Join 10,000+ Developers</strong> - Get started now.</p>',
51
+ placeholder: 'Loading call-to-action...'
52
+ },
53
+
54
+ // Rich media content
55
+ 'blog.featured-post': {
56
+ html: `
57
+ <article>
58
+ <h3>Building Scalable Apps with QwickApps React Framework</h3>
59
+ <p class="meta">Published on January 15, 2025 • 8 min read</p>
60
+ <p>Learn how our <strong>data-binding system</strong> enables dynamic, scalable applications with type-safe CMS integration and validation...</p>
61
+ <a href="/blog/scalable-apps" class="read-more">Continue reading →</a>
62
+ </article>
63
+ `,
64
+ placeholder: 'Loading featured blog post...'
65
+ },
66
+
67
+ // Malicious content for sanitization testing
68
+ 'security.malicious': {
69
+ html: '<script>alert("XSS attempt")</script><p>This content includes <strong>malicious scripts</strong> that should be automatically sanitized.</p><img src="x" onerror="alert(\'XSS\')" />',
70
+ placeholder: 'Loading content...'
71
+ },
72
+
73
+ // Performance testing - Large content
74
+ 'performance.large-content': {
75
+ html: '<div>' + 'Very long content paragraph. '.repeat(100) + '</div>',
76
+ placeholder: 'Loading large content...'
77
+ }
78
78
  };
79
79
 
80
80
  // Create cached data provider for performance
@@ -82,13 +82,13 @@ const jsonProvider = new JsonDataProvider({ data: advancedCmsData });
82
82
  const cachedDataProvider = new CachedDataProvider(jsonProvider, { maxSize: 100, defaultTTL: 60000 });
83
83
 
84
84
  const meta: Meta<typeof SafeSpan> = {
85
- title: 'Framework/Advanced Data Binding',
86
- component: SafeSpan,
87
- parameters: {
88
- layout: 'padded',
89
- docs: {
90
- description: {
91
- component: `
85
+ title: 'Framework/Advanced Data Binding',
86
+ component: SafeSpan,
87
+ parameters: {
88
+ layout: 'padded',
89
+ docs: {
90
+ description: {
91
+ component: `
92
92
  # Advanced Data Binding Examples
93
93
 
94
94
  This section demonstrates advanced use cases for the data binding system including:
@@ -116,17 +116,17 @@ All HTML content is automatically sanitized:
116
116
  - Dangerous attributes are filtered
117
117
  - Only safe HTML elements are allowed
118
118
  - XSS protection is built-in
119
- `
120
- }
121
- }
122
- },
123
- decorators: [
124
- (Story) => (
125
- <DataProvider dataSource={{ dataProvider: cachedDataProvider }}>
126
- <Story />
127
- </DataProvider>
128
- )
129
- ]
119
+ `
120
+ }
121
+ }
122
+ },
123
+ decorators: [
124
+ (Story) => (
125
+ <DataProvider dataSource={{ dataProvider: cachedDataProvider }}>
126
+ <Story />
127
+ </DataProvider>
128
+ )
129
+ ]
130
130
  };
131
131
 
132
132
  export default meta;
@@ -134,415 +134,415 @@ type Story = StoryObj<typeof meta>;
134
134
 
135
135
  // Multi-language Support
136
136
  export const MultiLanguageContent: Story = {
137
- render: () => {
138
- const [language, setLanguage] = useState<'en' | 'es'>('en');
139
-
140
- return (
141
- <Section>
142
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem' }}>
143
- <Typography variant='h4'>Multilanguage Support</Typography>
144
- <div style={{ display: 'flex', gap: '8px' }}>
145
- <ThemeSwitcher />
146
- <PaletteSwitcher />
147
- </div>
148
- </div>
149
- <Typography variant='body1' gutterBottom>
150
- Switch between English and Spanish content dynamically using the data binding system.
151
- </Typography>
152
- <br/>
153
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
154
- <GridLayout>
155
- <Button variant={language === 'en' ? 'contained' : 'outlined'} onClick={() => setLanguage('en')}>English</Button>
156
- <Button variant={language === 'es' ? 'contained' : 'outlined'} onClick={() => setLanguage('es')}>Español</Button>
157
- <SafeSpan span={12} dataSource={`content.${language}.welcome`} />
158
- </GridLayout>
159
- </Card>
160
- <Code title='Source Code'>{`<GridLayout>
161
- <Button variant={language === 'en' ? 'contained' : 'outlined'} onClick={() => setLanguage('en')}>English</Button>
162
- <Button variant={language === 'es' ? 'contained' : 'outlined'} onClick={() => setLanguage('es')}>Español</Button>
163
- <SafeSpan span={12} dataSource={\`content.\${language}.welcome\`} />
137
+ render: () => {
138
+ const [language, setLanguage] = useState<'en' | 'es'>('en');
139
+
140
+ return (
141
+ <Section>
142
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem' }}>
143
+ <Typography variant='h4'>Multilanguage Support</Typography>
144
+ <div style={{ display: 'flex', gap: '8px' }}>
145
+ <ThemeSwitcher />
146
+ <PaletteSwitcher />
147
+ </div>
148
+ </div>
149
+ <Typography variant='body1' gutterBottom>
150
+ Switch between English and Spanish content dynamically using the data binding system.
151
+ </Typography>
152
+ <br/>
153
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
154
+ <GridLayout>
155
+ <Button variant={language === 'en' ? 'contained' : 'outlined'} onClick={() => setLanguage('en')}>English</Button>
156
+ <Button variant={language === 'es' ? 'contained' : 'outlined'} onClick={() => setLanguage('es')}>Español</Button>
157
+ <SafeSpan span={12} dataSource={`content.${language}.welcome`} />
158
+ </GridLayout>
159
+ </Card>
160
+ <Code title='Source Code'>{`<GridLayout>
161
+ <Button variant={language === 'en' ? 'contained' : 'outlined'} onClick={() => setLanguage('en')}>English</Button>
162
+ <Button variant={language === 'es' ? 'contained' : 'outlined'} onClick={() => setLanguage('es')}>Español</Button>
163
+ <SafeSpan span={12} dataSource={\`content.\${language}.welcome\`} />
164
164
  </GridLayout>`}
165
- </Code>
166
- <Code title='Multi-language Content'>{`'content.en.welcome': [
167
- {
168
- html: '<h2>Welcome to QwickApps</h2><p>The future of app development is here.</p>'
169
- }
165
+ </Code>
166
+ <Code title='Multi-language Content'>{`'content.en.welcome': [
167
+ {
168
+ html: '<h2>Welcome to QwickApps</h2><p>The future of app development is here.</p>'
169
+ }
170
170
  ],
171
171
  'content.es.welcome': [
172
- {
173
- html: '<h2>Bienvenidos a QwickApps</h2><p>El futuro del desarrollo de aplicaciones está aquí.</p>'
174
- }
172
+ {
173
+ html: '<h2>Bienvenidos a QwickApps</h2><p>El futuro del desarrollo de aplicaciones está aquí.</p>'
174
+ }
175
175
  ]`}</Code>
176
- </Section>
177
- );
178
- },
179
- parameters: {
180
- docs: {
181
- description: {
182
- story: 'Demonstrates multi-language content switching using dynamic dataSource paths.'
183
- }
184
- }
185
- }
176
+ </Section>
177
+ );
178
+ },
179
+ parameters: {
180
+ docs: {
181
+ description: {
182
+ story: 'Demonstrates multi-language content switching using dynamic dataSource paths.'
183
+ }
184
+ }
185
+ }
186
186
  };
187
187
 
188
188
  // A/B Testing
189
189
  export const ABTestingVariants: Story = {
190
- render: () => {
191
- const [variant, setVariant] = useState<'a' | 'b'>('a');
192
-
193
- return (
194
- <Section>
195
- <Typography variant="h4">A/B Testing Variants</Typography>
196
- <Typography variant="body1" gutterBottom>
197
- A/B testing implementation using dynamic dataSource selection for conversion optimization.
198
- </Typography>
199
-
200
- <GridLayout>
201
- <Typography variant="h6">Select A/B Test Variant:</Typography>
202
- <GridLayout columns={2} spacing="medium">
203
- <Button variant={variant === 'a' ? 'contained' : 'outlined'} onClick={() => setVariant('a')}>
204
- Variant A (Start Building)
205
- </Button>
206
- <Button variant={variant === 'b' ? 'contained' : 'outlined'} onClick={() => setVariant('b')}>
207
- Variant B (Join Community)
208
- </Button>
209
- </GridLayout>
210
-
211
- <Card variant="outlined" style={{ padding: '1.5rem', backgroundColor: '#e3f2fd' }}>
212
- <SafeSpan dataSource={`cta.variant-${variant}`} />
213
- </Card>
214
- </GridLayout>
215
-
216
- <Code title="A/B Testing Implementation">{`const [variant, setVariant] = useState<'a' | 'b'>('a');
190
+ render: () => {
191
+ const [variant, setVariant] = useState<'a' | 'b'>('a');
192
+
193
+ return (
194
+ <Section>
195
+ <Typography variant="h4">A/B Testing Variants</Typography>
196
+ <Typography variant="body1" gutterBottom>
197
+ A/B testing implementation using dynamic dataSource selection for conversion optimization.
198
+ </Typography>
199
+
200
+ <GridLayout>
201
+ <Typography variant="h6">Select A/B Test Variant:</Typography>
202
+ <GridLayout columns={2} spacing="medium">
203
+ <Button variant={variant === 'a' ? 'contained' : 'outlined'} onClick={() => setVariant('a')}>
204
+ Variant A (Start Building)
205
+ </Button>
206
+ <Button variant={variant === 'b' ? 'contained' : 'outlined'} onClick={() => setVariant('b')}>
207
+ Variant B (Join Community)
208
+ </Button>
209
+ </GridLayout>
210
+
211
+ <Card variant="outlined" style={{ padding: '1.5rem', backgroundColor: '#e3f2fd' }}>
212
+ <SafeSpan dataSource={`cta.variant-${variant}`} />
213
+ </Card>
214
+ </GridLayout>
215
+
216
+ <Code title="A/B Testing Implementation">{`const [variant, setVariant] = useState<'a' | 'b'>('a');
217
217
 
218
218
  return (
219
- <SafeSpan dataSource={\`cta.variant-\${variant}\`} />
219
+ <SafeSpan dataSource={\`cta.variant-\${variant}\`} />
220
220
  );`}</Code>
221
221
 
222
- <Code title="A/B Test Data Structure">{`'cta.variant-a': [
223
- {
224
- html: '<p class="cta-primary"><strong>Start Building Today!</strong> - Try our free plan.</p>'
225
- }
222
+ <Code title="A/B Test Data Structure">{`'cta.variant-a': [
223
+ {
224
+ html: '<p class="cta-primary"><strong>Start Building Today!</strong> - Try our free plan.</p>'
225
+ }
226
226
  ],
227
227
  'cta.variant-b': [
228
- {
229
- html: '<p class="cta-secondary"><strong>Join 10,000+ Developers</strong> - Get started now.</p>'
230
- }
228
+ {
229
+ html: '<p class="cta-secondary"><strong>Join 10,000+ Developers</strong> - Get started now.</p>'
230
+ }
231
231
  ]`}</Code>
232
- </Section>
233
- );
234
- },
235
- parameters: {
236
- docs: {
237
- description: {
238
- story: 'A/B testing implementation using dynamic dataSource selection for conversion optimization.'
239
- }
240
- }
241
- }
232
+ </Section>
233
+ );
234
+ },
235
+ parameters: {
236
+ docs: {
237
+ description: {
238
+ story: 'A/B testing implementation using dynamic dataSource selection for conversion optimization.'
239
+ }
240
+ }
241
+ }
242
242
  };
243
243
 
244
244
  // Rich Media Content
245
245
  export const RichMediaContent: Story = {
246
- render: () => (
247
- <Section>
248
- <Typography variant="h4">Rich Media Content</Typography>
249
- <Typography variant="body1" gutterBottom>
250
- Complex HTML content with multiple elements, perfect for blog posts and articles.
251
- </Typography>
252
-
253
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8f9fa' }}>
254
- <SafeSpan dataSource="blog.featured-post" />
255
- </Card>
256
-
257
- <Code title="Usage">{`<SafeSpan dataSource="blog.featured-post" />`}</Code>
258
-
259
- <Code title="Rich Media Data Structure">{`'blog.featured-post': [
260
- {
261
- html: \`
262
- <article>
263
- <h3>Building Scalable Apps with QwickApps React Framework</h3>
264
- <p class="meta">Published on January 15, 2025 • 8 min read</p>
265
- <p>Learn how our <strong>data-binding system</strong> enables dynamic applications...</p>
266
- <a href="/blog/scalable-apps" class="read-more">Continue reading →</a>
267
- </article>
268
- \`,
269
- placeholder: 'Loading featured blog post...'
270
- }
246
+ render: () => (
247
+ <Section>
248
+ <Typography variant="h4">Rich Media Content</Typography>
249
+ <Typography variant="body1" gutterBottom>
250
+ Complex HTML content with multiple elements, perfect for blog posts and articles.
251
+ </Typography>
252
+
253
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8f9fa' }}>
254
+ <SafeSpan dataSource="blog.featured-post" />
255
+ </Card>
256
+
257
+ <Code title="Usage">{`<SafeSpan dataSource="blog.featured-post" />`}</Code>
258
+
259
+ <Code title="Rich Media Data Structure">{`'blog.featured-post': [
260
+ {
261
+ html: \`
262
+ <article>
263
+ <h3>Building Scalable Apps with QwickApps React Framework</h3>
264
+ <p class="meta">Published on January 15, 2025 • 8 min read</p>
265
+ <p>Learn how our <strong>data-binding system</strong> enables dynamic applications...</p>
266
+ <a href="/blog/scalable-apps" class="read-more">Continue reading →</a>
267
+ </article>
268
+ \`,
269
+ placeholder: 'Loading featured blog post...'
270
+ }
271
271
  ]`}</Code>
272
- </Section>
273
- ),
274
- parameters: {
275
- docs: {
276
- description: {
277
- story: 'Complex HTML content with multiple elements, perfect for blog posts and articles.'
278
- }
279
- }
280
- }
272
+ </Section>
273
+ ),
274
+ parameters: {
275
+ docs: {
276
+ description: {
277
+ story: 'Complex HTML content with multiple elements, perfect for blog posts and articles.'
278
+ }
279
+ }
280
+ }
281
281
  };
282
282
 
283
283
  // Security Testing
284
284
  export const SecurityAndSanitization: Story = {
285
- render: () => (
286
- <Section>
287
- <Typography variant="h4">Security and Sanitization</Typography>
288
- <Typography variant="body1" gutterBottom>
289
- Demonstrates automatic HTML sanitization to prevent XSS attacks and malicious content.
290
- </Typography>
291
-
292
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#fff3cd' }}>
293
- <Typography variant="body2">
294
- <strong>🛡️ Security Test:</strong> The content below contains malicious scripts that are automatically sanitized.
295
- </Typography>
296
- </Card>
297
-
298
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#f8f9fa' }}>
299
- <SafeSpan dataSource="security.malicious" />
300
- </Card>
301
-
302
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#d4edda' }}>
303
- <Typography variant="h6" gutterBottom>What was filtered:</Typography>
304
- <ul>
305
- <li>&lt;script&gt; tags removed</li>
306
- <li>onerror attributes removed</li>
307
- <li>Only safe HTML elements preserved</li>
308
- </ul>
309
- </Card>
310
-
311
- <Code title="Malicious Content (Auto-Sanitized)">{`<SafeSpan dataSource="security.malicious" />`}</Code>
312
-
313
- <Code title="Malicious Data Source">{`'security.malicious': [
314
- {
315
- html: '<script>alert("XSS attempt")</script><p>Safe content with <strong>formatting</strong></p><img src="x" onerror="alert(\\'XSS\\')" />',
316
- placeholder: 'Loading content...'
317
- }
285
+ render: () => (
286
+ <Section>
287
+ <Typography variant="h4">Security and Sanitization</Typography>
288
+ <Typography variant="body1" gutterBottom>
289
+ Demonstrates automatic HTML sanitization to prevent XSS attacks and malicious content.
290
+ </Typography>
291
+
292
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#fff3cd' }}>
293
+ <Typography variant="body2">
294
+ <strong> Security Test:</strong> The content below contains malicious scripts that are automatically sanitized.
295
+ </Typography>
296
+ </Card>
297
+
298
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#f8f9fa' }}>
299
+ <SafeSpan dataSource="security.malicious" />
300
+ </Card>
301
+
302
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem', backgroundColor: '#d4edda' }}>
303
+ <Typography variant="h6" gutterBottom>What was filtered:</Typography>
304
+ <ul>
305
+ <li>&lt;script&gt; tags removed</li>
306
+ <li>onerror attributes removed</li>
307
+ <li>Only safe HTML elements preserved</li>
308
+ </ul>
309
+ </Card>
310
+
311
+ <Code title="Malicious Content (Auto-Sanitized)">{`<SafeSpan dataSource="security.malicious" />`}</Code>
312
+
313
+ <Code title="Malicious Data Source">{`'security.malicious': [
314
+ {
315
+ html: '<script>alert("XSS attempt")</script><p>Safe content with <strong>formatting</strong></p><img src="x" onerror="alert(\\'XSS\\')" />',
316
+ placeholder: 'Loading content...'
317
+ }
318
318
  ]`}</Code>
319
- </Section>
320
- ),
321
- parameters: {
322
- docs: {
323
- description: {
324
- story: 'Demonstrates automatic HTML sanitization to prevent XSS attacks and malicious content.'
325
- }
326
- }
327
- }
319
+ </Section>
320
+ ),
321
+ parameters: {
322
+ docs: {
323
+ description: {
324
+ story: 'Demonstrates automatic HTML sanitization to prevent XSS attacks and malicious content.'
325
+ }
326
+ }
327
+ }
328
328
  };
329
329
 
330
330
  // Performance Testing
331
331
  export const PerformanceOptimization: Story = {
332
- render: () => (
333
- <Section>
334
- <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem' }}>
335
- <Typography variant="h4">Performance Optimization</Typography>
336
- <div style={{ display: 'flex', gap: '8px' }}>
337
- <ThemeSwitcher />
338
- <PaletteSwitcher />
339
- </div>
340
- </div>
341
- <Typography variant="body1" gutterBottom>
342
- Performance optimization with caching for large content blocks.
343
- </Typography>
344
-
345
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
346
- <Typography variant="body2" color="text.primary">
347
- <strong>⚡ Performance Test:</strong> Large content with caching enabled for optimal performance.
348
- </Typography>
349
- </Card>
350
-
351
- <Card variant="outlined" style={{ maxHeight: '200px', overflow: 'auto', padding: '1rem', marginBottom: '1rem' }}>
352
- <SafeSpan dataSource="performance.large-content" />
353
- </Card>
354
-
355
- <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
356
- <Typography variant="h6" gutterBottom>Performance Features:</Typography>
357
- <ul>
358
- <li>Memory caching with 5-minute TTL</li>
359
- <li>Automatic content chunking for large data</li>
360
- <li>Efficient re-rendering on data changes</li>
361
- </ul>
362
- </Card>
363
-
364
- <Code title="Cached Performance">{`<DataProvider dataSource={{ dataProvider: cachedDataProvider }}>
365
- <SafeSpan dataSource="performance.large-content" />
332
+ render: () => (
333
+ <Section>
334
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '1rem' }}>
335
+ <Typography variant="h4">Performance Optimization</Typography>
336
+ <div style={{ display: 'flex', gap: '8px' }}>
337
+ <ThemeSwitcher />
338
+ <PaletteSwitcher />
339
+ </div>
340
+ </div>
341
+ <Typography variant="body1" gutterBottom>
342
+ Performance optimization with caching for large content blocks.
343
+ </Typography>
344
+
345
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
346
+ <Typography variant="body2" color="text.primary">
347
+ <strong> Performance Test:</strong> Large content with caching enabled for optimal performance.
348
+ </Typography>
349
+ </Card>
350
+
351
+ <Card variant="outlined" style={{ maxHeight: '200px', overflow: 'auto', padding: '1rem', marginBottom: '1rem' }}>
352
+ <SafeSpan dataSource="performance.large-content" />
353
+ </Card>
354
+
355
+ <Card variant="outlined" style={{ padding: '1rem', marginBottom: '1rem' }}>
356
+ <Typography variant="h6" gutterBottom>Performance Features:</Typography>
357
+ <ul>
358
+ <li>Memory caching with 5-minute TTL</li>
359
+ <li>Automatic content chunking for large data</li>
360
+ <li>Efficient re-rendering on data changes</li>
361
+ </ul>
362
+ </Card>
363
+
364
+ <Code title="Cached Performance">{`<DataProvider dataSource={{ dataProvider: cachedDataProvider }}>
365
+ <SafeSpan dataSource="performance.large-content" />
366
366
  </DataProvider>`}</Code>
367
367
 
368
- <Code title="Cache Configuration">{`const jsonProvider = new JsonDataProvider({ data: advancedCmsData });
368
+ <Code title="Cache Configuration">{`const jsonProvider = new JsonDataProvider({ data: advancedCmsData });
369
369
  const cacheProvider = new MemoryCacheProvider<any[]>({
370
- maxSize: 100,
371
- defaultTtl: 60000
370
+ maxSize: 100,
371
+ defaultTtl: 60000
372
372
  });
373
373
  const cachedDataProvider = new CachedDataProvider(jsonProvider, cacheProvider);`}</Code>
374
- </Section>
375
- ),
376
- parameters: {
377
- docs: {
378
- description: {
379
- story: 'Performance optimization with caching for large content blocks.'
380
- }
381
- }
382
- }
374
+ </Section>
375
+ ),
376
+ parameters: {
377
+ docs: {
378
+ description: {
379
+ story: 'Performance optimization with caching for large content blocks.'
380
+ }
381
+ }
382
+ }
383
383
  };
384
384
 
385
385
  // Custom Hook Usage
386
386
  export const CustomHookExample: Story = {
387
- render: () => {
388
- const CustomComponent: React.FC<{ dataSource: string }> = ({ dataSource }) => {
389
- const { loading, error } = useDataBinding(
390
- dataSource,
391
- {
392
- html: '<p>Fallback HTML content</p>',
393
- placeholder: 'Fallback placeholder'
394
- },
395
- undefined,
396
- { strict: true, cache: true }
397
- );
398
-
399
- if (loading) {
400
- return (
401
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8f9fa' }}>
402
- <Typography variant="body2">Loading content...</Typography>
403
- </Card>
404
- );
405
- }
406
-
407
- if (error) {
408
- return (
409
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8d7da' }}>
410
- <Typography variant="body2" color="error">
411
- <strong>Error:</strong> {error.message}
412
- </Typography>
413
- </Card>
414
- );
415
- }
416
-
417
- return (
418
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#d4edda' }}>
419
- <SafeSpan dataSource={dataSource} />
420
- <Typography variant="caption" color="textSecondary" style={{ marginTop: '0.5rem', display: 'block' }}>
421
- Loaded via custom useDataBinding hook
422
- </Typography>
423
- </Card>
424
- );
425
- };
426
-
427
- return (
428
- <Section>
429
- <Typography variant="h4">Custom Hook Implementation</Typography>
430
- <Typography variant="body1" gutterBottom>
431
- Custom implementation using the useDataBinding hook directly with advanced options like validation and caching.
432
- </Typography>
433
-
434
- <CustomComponent dataSource="announcements.current" />
435
-
436
- <Code title="Custom Hook Usage">{`const CustomComponent: React.FC<{ dataSource: string }> = ({ dataSource }) => {
437
- const { loading, error } = useDataBinding(
438
- dataSource,
439
- {
440
- html: '<p>Fallback HTML content</p>',
441
- placeholder: 'Fallback placeholder'
442
- },
443
- undefined,
444
- { strict: true, cache: true }
445
- );
446
-
447
- if (loading) return <LoadingComponent />;
448
- if (error) return <ErrorComponent error={error} />;
449
-
450
- return <SafeSpan dataSource={dataSource} />;
387
+ render: () => {
388
+ const CustomComponent: React.FC<{ dataSource: string }> = ({ dataSource }) => {
389
+ const { loading, error } = useDataBinding(
390
+ dataSource,
391
+ {
392
+ html: '<p>Fallback HTML content</p>',
393
+ placeholder: 'Fallback placeholder'
394
+ },
395
+ undefined,
396
+ { strict: true, cache: true }
397
+ );
398
+
399
+ if (loading) {
400
+ return (
401
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8f9fa' }}>
402
+ <Typography variant="body2">Loading content...</Typography>
403
+ </Card>
404
+ );
405
+ }
406
+
407
+ if (error) {
408
+ return (
409
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8d7da' }}>
410
+ <Typography variant="body2" color="error">
411
+ <strong>Error:</strong> {error.message}
412
+ </Typography>
413
+ </Card>
414
+ );
415
+ }
416
+
417
+ return (
418
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#d4edda' }}>
419
+ <SafeSpan dataSource={dataSource} />
420
+ <Typography variant="caption" color="textSecondary" style={{ marginTop: '0.5rem', display: 'block' }}>
421
+ Loaded via custom useDataBinding hook
422
+ </Typography>
423
+ </Card>
424
+ );
425
+ };
426
+
427
+ return (
428
+ <Section>
429
+ <Typography variant="h4">Custom Hook Implementation</Typography>
430
+ <Typography variant="body1" gutterBottom>
431
+ Custom implementation using the useDataBinding hook directly with advanced options like validation and caching.
432
+ </Typography>
433
+
434
+ <CustomComponent dataSource="announcements.current" />
435
+
436
+ <Code title="Custom Hook Usage">{`const CustomComponent: React.FC<{ dataSource: string }> = ({ dataSource }) => {
437
+ const { loading, error } = useDataBinding(
438
+ dataSource,
439
+ {
440
+ html: '<p>Fallback HTML content</p>',
441
+ placeholder: 'Fallback placeholder'
442
+ },
443
+ undefined,
444
+ { strict: true, cache: true }
445
+ );
446
+
447
+ if (loading) return <LoadingComponent />;
448
+ if (error) return <ErrorComponent error={error} />;
449
+
450
+ return <SafeSpan dataSource={dataSource} />;
451
451
  };`}</Code>
452
452
 
453
- <Code title="Hook Options">{`const options = {
454
- strict: true, // Enable strict schema validation
455
- cache: true, // Enable caching for performance
456
- fallback: { // Custom fallback data
457
- html: '<p>Custom fallback content</p>',
458
- placeholder: 'Custom placeholder'
459
- }
453
+ <Code title="Hook Options">{`const options = {
454
+ strict: true, // Enable strict schema validation
455
+ cache: true, // Enable caching for performance
456
+ fallback: { // Custom fallback data
457
+ html: '<p>Custom fallback content</p>',
458
+ placeholder: 'Custom placeholder'
459
+ }
460
460
  };`}</Code>
461
- </Section>
462
- );
463
- },
464
- parameters: {
465
- docs: {
466
- description: {
467
- story: 'Custom implementation using the useDataBinding hook directly with advanced options like validation and caching.'
468
- }
469
- }
470
- }
461
+ </Section>
462
+ );
463
+ },
464
+ parameters: {
465
+ docs: {
466
+ description: {
467
+ story: 'Custom implementation using the useDataBinding hook directly with advanced options like validation and caching.'
468
+ }
469
+ }
470
+ }
471
471
  };
472
472
 
473
473
  // Error Handling
474
474
  export const ErrorHandlingScenarios: Story = {
475
- render: () => (
476
- <Section>
477
- <Typography variant="h4">Error Handling Scenarios</Typography>
478
- <Typography variant="body1" gutterBottom>
479
- Various error handling scenarios showing how the system gracefully degrades when data is missing or invalid.
480
- </Typography>
481
-
482
- <GridLayout spacing="large">
483
- <div>
484
- <Typography variant="h6">Non-existent Data Source</Typography>
485
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#fff3cd' }}>
486
- <SafeSpan
487
- dataSource="does.not.exist"
488
- placeholder="Fallback when data source doesn't exist"
489
- />
490
- </Card>
491
- </div>
492
-
493
- <div>
494
- <Typography variant="h6">Empty Data Source</Typography>
495
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8d7da' }}>
496
- <SafeSpan
497
- dataSource="empty.data"
498
- html="<p>Fallback HTML when data is empty</p>"
499
- />
500
- </Card>
501
- </div>
502
-
503
- <div>
504
- <Typography variant="h6">Graceful Degradation</Typography>
505
- <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#d4edda' }}>
506
- <SafeSpan
507
- dataSource="malformed.data"
508
- bindingOptions={{
509
- fallback: {
510
- html: '<p>Graceful fallback for <strong>malformed data</strong></p>',
511
- placeholder: 'Fallback placeholder'
512
- }
513
- }}
514
- />
515
- </Card>
516
- </div>
517
- </GridLayout>
518
-
519
- <Code title="Non-existent Data Source">{`<SafeSpan
520
- dataSource="does.not.exist"
521
- placeholder="Fallback when data source doesn't exist"
475
+ render: () => (
476
+ <Section>
477
+ <Typography variant="h4">Error Handling Scenarios</Typography>
478
+ <Typography variant="body1" gutterBottom>
479
+ Various error handling scenarios showing how the system gracefully degrades when data is missing or invalid.
480
+ </Typography>
481
+
482
+ <GridLayout spacing="large">
483
+ <div>
484
+ <Typography variant="h6">Non-existent Data Source</Typography>
485
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#fff3cd' }}>
486
+ <SafeSpan
487
+ dataSource="does.not.exist"
488
+ placeholder="Fallback when data source doesn't exist"
489
+ />
490
+ </Card>
491
+ </div>
492
+
493
+ <div>
494
+ <Typography variant="h6">Empty Data Source</Typography>
495
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#f8d7da' }}>
496
+ <SafeSpan
497
+ dataSource="empty.data"
498
+ html="<p>Fallback HTML when data is empty</p>"
499
+ />
500
+ </Card>
501
+ </div>
502
+
503
+ <div>
504
+ <Typography variant="h6">Graceful Degradation</Typography>
505
+ <Card variant="outlined" style={{ padding: '1rem', backgroundColor: '#d4edda' }}>
506
+ <SafeSpan
507
+ dataSource="malformed.data"
508
+ bindingOptions={{
509
+ fallback: {
510
+ html: '<p>Graceful fallback for <strong>malformed data</strong></p>',
511
+ placeholder: 'Fallback placeholder'
512
+ }
513
+ }}
514
+ />
515
+ </Card>
516
+ </div>
517
+ </GridLayout>
518
+
519
+ <Code title="Non-existent Data Source">{`<SafeSpan
520
+ dataSource="does.not.exist"
521
+ placeholder="Fallback when data source doesn't exist"
522
522
  />`}</Code>
523
523
 
524
- <Code title="Custom Fallback Options">{`<SafeSpan
525
- dataSource="malformed.data"
526
- bindingOptions={{
527
- fallback: {
528
- html: '<p>Graceful fallback for <strong>malformed data</strong></p>',
529
- placeholder: 'Fallback placeholder'
530
- }
531
- }}
524
+ <Code title="Custom Fallback Options">{`<SafeSpan
525
+ dataSource="malformed.data"
526
+ bindingOptions={{
527
+ fallback: {
528
+ html: '<p>Graceful fallback for <strong>malformed data</strong></p>',
529
+ placeholder: 'Fallback placeholder'
530
+ }
531
+ }}
532
532
  />`}</Code>
533
533
 
534
- <Code title="Error Handling Strategy">{`// System handles errors gracefully:
534
+ <Code title="Error Handling Strategy">{`// System handles errors gracefully:
535
535
  // 1. Uses fallback props when data source fails
536
536
  // 2. Shows placeholder text when content is empty
537
537
  // 3. Applies custom fallback options when specified
538
538
  // 4. Never breaks the UI - always renders something useful`}</Code>
539
- </Section>
540
- ),
541
- parameters: {
542
- docs: {
543
- description: {
544
- story: 'Various error handling scenarios showing how the system gracefully degrades when data is missing or invalid.'
545
- }
546
- }
547
- }
539
+ </Section>
540
+ ),
541
+ parameters: {
542
+ docs: {
543
+ description: {
544
+ story: 'Various error handling scenarios showing how the system gracefully degrades when data is missing or invalid.'
545
+ }
546
+ }
547
+ }
548
548
  };