@qwickapps/react-framework 1.3.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 (441) hide show
  1. package/LICENSE +44 -0
  2. package/README.md +794 -0
  3. package/dist/components/AccessibilityChecker.d.ts +12 -0
  4. package/dist/components/AccessibilityChecker.d.ts.map +1 -0
  5. package/dist/components/Html.d.ts +48 -0
  6. package/dist/components/Html.d.ts.map +1 -0
  7. package/dist/components/Logo.d.ts +79 -0
  8. package/dist/components/Logo.d.ts.map +1 -0
  9. package/dist/components/Markdown.d.ts +47 -0
  10. package/dist/components/Markdown.d.ts.map +1 -0
  11. package/dist/components/QwickApp.d.ts +56 -0
  12. package/dist/components/QwickApp.d.ts.map +1 -0
  13. package/dist/components/QwickAppsLogo.d.ts +25 -0
  14. package/dist/components/QwickAppsLogo.d.ts.map +1 -0
  15. package/dist/components/ResponsiveMenu.d.ts +38 -0
  16. package/dist/components/ResponsiveMenu.d.ts.map +1 -0
  17. package/dist/components/SafeSpan.d.ts +23 -0
  18. package/dist/components/SafeSpan.d.ts.map +1 -0
  19. package/dist/components/Scaffold.d.ts +57 -0
  20. package/dist/components/Scaffold.d.ts.map +1 -0
  21. package/dist/components/blocks/Article.d.ts +23 -0
  22. package/dist/components/blocks/Article.d.ts.map +1 -0
  23. package/dist/components/blocks/CardListGrid.d.ts +23 -0
  24. package/dist/components/blocks/CardListGrid.d.ts.map +1 -0
  25. package/dist/components/blocks/Code.d.ts +21 -0
  26. package/dist/components/blocks/Code.d.ts.map +1 -0
  27. package/dist/components/blocks/Content.d.ts +24 -0
  28. package/dist/components/blocks/Content.d.ts.map +1 -0
  29. package/dist/components/blocks/CoverImageHeader.d.ts +44 -0
  30. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -0
  31. package/dist/components/blocks/FeatureCard.d.ts +66 -0
  32. package/dist/components/blocks/FeatureCard.d.ts.map +1 -0
  33. package/dist/components/blocks/FeatureGrid.d.ts +48 -0
  34. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -0
  35. package/dist/components/blocks/Footer.d.ts +56 -0
  36. package/dist/components/blocks/Footer.d.ts.map +1 -0
  37. package/dist/components/blocks/HeroBlock.d.ts +33 -0
  38. package/dist/components/blocks/HeroBlock.d.ts.map +1 -0
  39. package/dist/components/blocks/PageBannerHeader.d.ts +30 -0
  40. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -0
  41. package/dist/components/blocks/ProductCard.d.ts +57 -0
  42. package/dist/components/blocks/ProductCard.d.ts.map +1 -0
  43. package/dist/components/blocks/Section.d.ts +40 -0
  44. package/dist/components/blocks/Section.d.ts.map +1 -0
  45. package/dist/components/blocks/index.d.ts +37 -0
  46. package/dist/components/blocks/index.d.ts.map +1 -0
  47. package/dist/components/buttons/Button.d.ts +38 -0
  48. package/dist/components/buttons/Button.d.ts.map +1 -0
  49. package/dist/components/buttons/PaletteSwitcher.d.ts +24 -0
  50. package/dist/components/buttons/PaletteSwitcher.d.ts.map +1 -0
  51. package/dist/components/buttons/ThemeSwitcher.d.ts +24 -0
  52. package/dist/components/buttons/ThemeSwitcher.d.ts.map +1 -0
  53. package/dist/components/buttons/index.d.ts +11 -0
  54. package/dist/components/buttons/index.d.ts.map +1 -0
  55. package/dist/components/forms/FormBlock.d.ts +45 -0
  56. package/dist/components/forms/FormBlock.d.ts.map +1 -0
  57. package/dist/components/forms/index.d.ts +8 -0
  58. package/dist/components/forms/index.d.ts.map +1 -0
  59. package/dist/components/index.d.ts +32 -0
  60. package/dist/components/index.d.ts.map +1 -0
  61. package/dist/components/input/ChoiceInputField.d.ts +30 -0
  62. package/dist/components/input/ChoiceInputField.d.ts.map +1 -0
  63. package/dist/components/input/HtmlInputField.d.ts +29 -0
  64. package/dist/components/input/HtmlInputField.d.ts.map +1 -0
  65. package/dist/components/input/SelectInputField.d.ts +29 -0
  66. package/dist/components/input/SelectInputField.d.ts.map +1 -0
  67. package/dist/components/input/TextField.d.ts +18 -0
  68. package/dist/components/input/TextField.d.ts.map +1 -0
  69. package/dist/components/input/TextInputField.d.ts +32 -0
  70. package/dist/components/input/TextInputField.d.ts.map +1 -0
  71. package/dist/components/input/index.d.ts +17 -0
  72. package/dist/components/input/index.d.ts.map +1 -0
  73. package/dist/components/layout/GridCell.d.ts +16 -0
  74. package/dist/components/layout/GridCell.d.ts.map +1 -0
  75. package/dist/components/layout/GridCellWrapper.d.ts +46 -0
  76. package/dist/components/layout/GridCellWrapper.d.ts.map +1 -0
  77. package/dist/components/layout/GridLayout.d.ts +38 -0
  78. package/dist/components/layout/GridLayout.d.ts.map +1 -0
  79. package/dist/components/layout/index.d.ts +12 -0
  80. package/dist/components/layout/index.d.ts.map +1 -0
  81. package/dist/components/menu/Menu.d.ts +1 -0
  82. package/dist/components/menu/Menu.d.ts.map +1 -0
  83. package/dist/components/menu/MenuItem.d.ts +31 -0
  84. package/dist/components/menu/MenuItem.d.ts.map +1 -0
  85. package/dist/components/menu/index.d.ts +7 -0
  86. package/dist/components/menu/index.d.ts.map +1 -0
  87. package/dist/components/pages/FormPage.d.ts +66 -0
  88. package/dist/components/pages/FormPage.d.ts.map +1 -0
  89. package/dist/components/pages/Page.d.ts +124 -0
  90. package/dist/components/pages/Page.d.ts.map +1 -0
  91. package/dist/components/pages/index.d.ts +11 -0
  92. package/dist/components/pages/index.d.ts.map +1 -0
  93. package/dist/contexts/DataContext.d.ts +139 -0
  94. package/dist/contexts/DataContext.d.ts.map +1 -0
  95. package/dist/contexts/DimensionsContext.d.ts +42 -0
  96. package/dist/contexts/DimensionsContext.d.ts.map +1 -0
  97. package/dist/contexts/PaletteContext.d.ts +53 -0
  98. package/dist/contexts/PaletteContext.d.ts.map +1 -0
  99. package/dist/contexts/QwickAppContext.d.ts +71 -0
  100. package/dist/contexts/QwickAppContext.d.ts.map +1 -0
  101. package/dist/contexts/ThemeContext.d.ts +65 -0
  102. package/dist/contexts/ThemeContext.d.ts.map +1 -0
  103. package/dist/contexts/index.d.ts +9 -0
  104. package/dist/contexts/index.d.ts.map +1 -0
  105. package/dist/hooks/index.d.ts +10 -0
  106. package/dist/hooks/index.d.ts.map +1 -0
  107. package/dist/hooks/useBaseProps.d.ts +101 -0
  108. package/dist/hooks/useBaseProps.d.ts.map +1 -0
  109. package/dist/hooks/useDataBinding.d.ts +22 -0
  110. package/dist/hooks/useDataBinding.d.ts.map +1 -0
  111. package/dist/index.css +1 -0
  112. package/dist/index.d.ts +8 -0
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.esm.css +1 -0
  115. package/dist/index.esm.js +24143 -0
  116. package/dist/index.js +24245 -0
  117. package/dist/palettes/PaletteAutumn.d.ts +10 -0
  118. package/dist/palettes/PaletteAutumn.d.ts.map +1 -0
  119. package/dist/palettes/PaletteCosmic.d.ts +10 -0
  120. package/dist/palettes/PaletteCosmic.d.ts.map +1 -0
  121. package/dist/palettes/PaletteDefault.d.ts +10 -0
  122. package/dist/palettes/PaletteDefault.d.ts.map +1 -0
  123. package/dist/palettes/PaletteOcean.d.ts +10 -0
  124. package/dist/palettes/PaletteOcean.d.ts.map +1 -0
  125. package/dist/palettes/PaletteSpring.d.ts +10 -0
  126. package/dist/palettes/PaletteSpring.d.ts.map +1 -0
  127. package/dist/palettes/PaletteWinter.d.ts +10 -0
  128. package/dist/palettes/PaletteWinter.d.ts.map +1 -0
  129. package/dist/palettes/index.d.ts +13 -0
  130. package/dist/palettes/index.d.ts.map +1 -0
  131. package/dist/schemas/ActionSchema.d.ts +21 -0
  132. package/dist/schemas/ActionSchema.d.ts.map +1 -0
  133. package/dist/schemas/ArticleSchema.d.ts +13 -0
  134. package/dist/schemas/ArticleSchema.d.ts.map +1 -0
  135. package/dist/schemas/Builders.d.ts +7 -0
  136. package/dist/schemas/Builders.d.ts.map +1 -0
  137. package/dist/schemas/ButtonSchema.d.ts +19 -0
  138. package/dist/schemas/ButtonSchema.d.ts.map +1 -0
  139. package/dist/schemas/CardListGridSchema.d.ts +17 -0
  140. package/dist/schemas/CardListGridSchema.d.ts.map +1 -0
  141. package/dist/schemas/ChoiceInputFieldSchema.d.ts +18 -0
  142. package/dist/schemas/ChoiceInputFieldSchema.d.ts.map +1 -0
  143. package/dist/schemas/CodeSchema.d.ts +18 -0
  144. package/dist/schemas/CodeSchema.d.ts.map +1 -0
  145. package/dist/schemas/ContentSchema.d.ts +20 -0
  146. package/dist/schemas/ContentSchema.d.ts.map +1 -0
  147. package/dist/schemas/CoverImageHeaderSchema.d.ts +28 -0
  148. package/dist/schemas/CoverImageHeaderSchema.d.ts.map +1 -0
  149. package/dist/schemas/FeatureCardSchema.d.ts +28 -0
  150. package/dist/schemas/FeatureCardSchema.d.ts.map +1 -0
  151. package/dist/schemas/FeatureGridSchema.d.ts +17 -0
  152. package/dist/schemas/FeatureGridSchema.d.ts.map +1 -0
  153. package/dist/schemas/FeatureItemSchema.d.ts +16 -0
  154. package/dist/schemas/FeatureItemSchema.d.ts.map +1 -0
  155. package/dist/schemas/FooterItemSchema.d.ts +15 -0
  156. package/dist/schemas/FooterItemSchema.d.ts.map +1 -0
  157. package/dist/schemas/FooterSchema.d.ts +20 -0
  158. package/dist/schemas/FooterSchema.d.ts.map +1 -0
  159. package/dist/schemas/FooterSectionSchema.d.ts +15 -0
  160. package/dist/schemas/FooterSectionSchema.d.ts.map +1 -0
  161. package/dist/schemas/FormBlockSchema.d.ts +19 -0
  162. package/dist/schemas/FormBlockSchema.d.ts.map +1 -0
  163. package/dist/schemas/HeaderActionSchema.d.ts +17 -0
  164. package/dist/schemas/HeaderActionSchema.d.ts.map +1 -0
  165. package/dist/schemas/HeroBlockSchema.d.ts +22 -0
  166. package/dist/schemas/HeroBlockSchema.d.ts.map +1 -0
  167. package/dist/schemas/HtmlInputFieldSchema.d.ts +18 -0
  168. package/dist/schemas/HtmlInputFieldSchema.d.ts.map +1 -0
  169. package/dist/schemas/MetadataItemSchema.d.ts +13 -0
  170. package/dist/schemas/MetadataItemSchema.d.ts.map +1 -0
  171. package/dist/schemas/PageBannerHeaderSchema.d.ts +28 -0
  172. package/dist/schemas/PageBannerHeaderSchema.d.ts.map +1 -0
  173. package/dist/schemas/PaletteSwitcherSchema.d.ts +16 -0
  174. package/dist/schemas/PaletteSwitcherSchema.d.ts.map +1 -0
  175. package/dist/schemas/ProductCardSchema.d.ts +39 -0
  176. package/dist/schemas/ProductCardSchema.d.ts.map +1 -0
  177. package/dist/schemas/SafeSpanSchema.d.ts +13 -0
  178. package/dist/schemas/SafeSpanSchema.d.ts.map +1 -0
  179. package/dist/schemas/SectionSchema.d.ts +17 -0
  180. package/dist/schemas/SectionSchema.d.ts.map +1 -0
  181. package/dist/schemas/SelectInputFieldSchema.d.ts +27 -0
  182. package/dist/schemas/SelectInputFieldSchema.d.ts.map +1 -0
  183. package/dist/schemas/TextInputFieldSchema.d.ts +22 -0
  184. package/dist/schemas/TextInputFieldSchema.d.ts.map +1 -0
  185. package/dist/schemas/ThemeSwitcherSchema.d.ts +19 -0
  186. package/dist/schemas/ThemeSwitcherSchema.d.ts.map +1 -0
  187. package/dist/schemas/index.d.ts +33 -0
  188. package/dist/schemas/index.d.ts.map +1 -0
  189. package/dist/schemas/types.d.ts +7 -0
  190. package/dist/schemas/types.d.ts.map +1 -0
  191. package/dist/templates/TemplateResolver.d.ts +52 -0
  192. package/dist/templates/TemplateResolver.d.ts.map +1 -0
  193. package/dist/templates/index.d.ts +7 -0
  194. package/dist/templates/index.d.ts.map +1 -0
  195. package/dist/tests/ConsoleWarningTest.d.ts +5 -0
  196. package/dist/tests/ConsoleWarningTest.d.ts.map +1 -0
  197. package/dist/tests/StorageKeyTest.d.ts +6 -0
  198. package/dist/tests/StorageKeyTest.d.ts.map +1 -0
  199. package/dist/tests/ThemeStorageKeyTest.d.ts +6 -0
  200. package/dist/tests/ThemeStorageKeyTest.d.ts.map +1 -0
  201. package/dist/types/CacheProvider.d.ts +18 -0
  202. package/dist/types/CacheProvider.d.ts.map +1 -0
  203. package/dist/types/ContentProxy.d.ts +47 -0
  204. package/dist/types/ContentProxy.d.ts.map +1 -0
  205. package/dist/types/DataBinding.d.ts +7 -0
  206. package/dist/types/DataBinding.d.ts.map +1 -0
  207. package/dist/types/DataProvider.d.ts +7 -0
  208. package/dist/types/DataProvider.d.ts.map +1 -0
  209. package/dist/types/DataTypes.d.ts +185 -0
  210. package/dist/types/DataTypes.d.ts.map +1 -0
  211. package/dist/types/TemplateProvider.d.ts +10 -0
  212. package/dist/types/TemplateProvider.d.ts.map +1 -0
  213. package/dist/types/TemplateResolver.d.ts +23 -0
  214. package/dist/types/TemplateResolver.d.ts.map +1 -0
  215. package/dist/types/index.d.ts +81 -0
  216. package/dist/types/index.d.ts.map +1 -0
  217. package/dist/utils/breakpoints.d.ts +35 -0
  218. package/dist/utils/breakpoints.d.ts.map +1 -0
  219. package/dist/utils/customPaletteManager.d.ts +8 -0
  220. package/dist/utils/customPaletteManager.d.ts.map +1 -0
  221. package/dist/utils/dimensions.d.ts +34 -0
  222. package/dist/utils/dimensions.d.ts.map +1 -0
  223. package/dist/utils/htmlTransform.d.ts +44 -0
  224. package/dist/utils/htmlTransform.d.ts.map +1 -0
  225. package/dist/utils/index.d.ts +15 -0
  226. package/dist/utils/index.d.ts.map +1 -0
  227. package/dist/utils/logger.d.ts +14 -0
  228. package/dist/utils/logger.d.ts.map +1 -0
  229. package/dist/utils/paletteUtils.d.ts +38 -0
  230. package/dist/utils/paletteUtils.d.ts.map +1 -0
  231. package/dist/utils/persistenceUtils.d.ts +31 -0
  232. package/dist/utils/persistenceUtils.d.ts.map +1 -0
  233. package/dist/utils/reactUtils.d.ts +24 -0
  234. package/dist/utils/reactUtils.d.ts.map +1 -0
  235. package/dist/utils/spacing.d.ts +34 -0
  236. package/dist/utils/spacing.d.ts.map +1 -0
  237. package/dist/utils/themePerformanceMonitor.d.ts +32 -0
  238. package/dist/utils/themePerformanceMonitor.d.ts.map +1 -0
  239. package/dist/utils/themeUtils.d.ts +27 -0
  240. package/dist/utils/themeUtils.d.ts.map +1 -0
  241. package/package.json +141 -0
  242. package/src/__tests__/components/Logo.test.js +172 -0
  243. package/src/__tests__/contexts/DataContext.test.js +505 -0
  244. package/src/__tests__/contexts/PaletteContext.test.js +115 -0
  245. package/src/__tests__/contexts/ThemeContext.test.js +123 -0
  246. package/src/__tests__/utils/paletteUtils.test.js +142 -0
  247. package/src/__tests__/utils/themeUtils.test.js +142 -0
  248. package/src/components/AccessibilityChecker.tsx +264 -0
  249. package/src/components/Html.tsx +191 -0
  250. package/src/components/Logo.css +217 -0
  251. package/src/components/Logo.tsx +370 -0
  252. package/src/components/Markdown.tsx +191 -0
  253. package/src/components/QwickApp.css +257 -0
  254. package/src/components/QwickApp.tsx +157 -0
  255. package/src/components/QwickAppsLogo.tsx +77 -0
  256. package/src/components/ResponsiveMenu.css +416 -0
  257. package/src/components/ResponsiveMenu.tsx +310 -0
  258. package/src/components/SafeSpan.tsx +128 -0
  259. package/src/components/Scaffold.css +541 -0
  260. package/src/components/Scaffold.tsx +463 -0
  261. package/src/components/__tests__/Article.test.tsx +419 -0
  262. package/src/components/__tests__/Button.test.tsx +702 -0
  263. package/src/components/__tests__/CardListGrid.test.tsx +478 -0
  264. package/src/components/__tests__/ChoiceInputField.test.tsx +864 -0
  265. package/src/components/__tests__/Code.test.tsx +595 -0
  266. package/src/components/__tests__/Content.integration.test.tsx +193 -0
  267. package/src/components/__tests__/Content.test.tsx +504 -0
  268. package/src/components/__tests__/CoverImageHeader.test.tsx +456 -0
  269. package/src/components/__tests__/FeatureCard.integration.test.tsx +384 -0
  270. package/src/components/__tests__/FeatureGrid.integration.test.tsx +364 -0
  271. package/src/components/__tests__/FeatureGrid.test.tsx +494 -0
  272. package/src/components/__tests__/Footer.test.tsx +544 -0
  273. package/src/components/__tests__/FormBlock.test.tsx +857 -0
  274. package/src/components/__tests__/HeroBlock.integration.test.tsx +272 -0
  275. package/src/components/__tests__/HeroBlock.test.tsx +463 -0
  276. package/src/components/__tests__/Html.test.tsx +174 -0
  277. package/src/components/__tests__/HtmlInputField.test.tsx +856 -0
  278. package/src/components/__tests__/Markdown.test.tsx +233 -0
  279. package/src/components/__tests__/PageBannerHeader.test.tsx +614 -0
  280. package/src/components/__tests__/PaletteSwitcher.test.tsx +864 -0
  281. package/src/components/__tests__/ProductCard.test.tsx +377 -0
  282. package/src/components/__tests__/SafeSpan.integration.test.tsx +123 -0
  283. package/src/components/__tests__/SafeSpan.simple.test.tsx +65 -0
  284. package/src/components/__tests__/SafeSpan.test.tsx +388 -0
  285. package/src/components/__tests__/Section.integration.test.tsx +288 -0
  286. package/src/components/__tests__/Section.test.tsx +494 -0
  287. package/src/components/__tests__/SelectInputField.test.tsx +886 -0
  288. package/src/components/__tests__/TextInputField.test.tsx +749 -0
  289. package/src/components/__tests__/ThemeSwitcher.test.tsx +777 -0
  290. package/src/components/blocks/Article.tsx +194 -0
  291. package/src/components/blocks/CardListGrid.tsx +132 -0
  292. package/src/components/blocks/Code.tsx +313 -0
  293. package/src/components/blocks/Content.tsx +265 -0
  294. package/src/components/blocks/CoverImageHeader.css +17 -0
  295. package/src/components/blocks/CoverImageHeader.tsx +435 -0
  296. package/src/components/blocks/FeatureCard.tsx +321 -0
  297. package/src/components/blocks/FeatureGrid.tsx +147 -0
  298. package/src/components/blocks/Footer.tsx +343 -0
  299. package/src/components/blocks/HeroBlock.tsx +280 -0
  300. package/src/components/blocks/PageBannerHeader.tsx +471 -0
  301. package/src/components/blocks/ProductCard.tsx +472 -0
  302. package/src/components/blocks/Section.tsx +209 -0
  303. package/src/components/blocks/index.ts +37 -0
  304. package/src/components/buttons/Button.tsx +233 -0
  305. package/src/components/buttons/PaletteSwitcher.tsx +268 -0
  306. package/src/components/buttons/ThemeSwitcher.tsx +283 -0
  307. package/src/components/buttons/index.ts +11 -0
  308. package/src/components/forms/FormBlock.tsx +291 -0
  309. package/src/components/forms/index.ts +7 -0
  310. package/src/components/index.ts +37 -0
  311. package/src/components/input/ChoiceInputField.tsx +188 -0
  312. package/src/components/input/HtmlInputField.tsx +326 -0
  313. package/src/components/input/SelectInputField.tsx +197 -0
  314. package/src/components/input/TextField.tsx +47 -0
  315. package/src/components/input/TextInputField.tsx +144 -0
  316. package/src/components/input/index.ts +17 -0
  317. package/src/components/layout/GridCell.tsx +46 -0
  318. package/src/components/layout/GridCellWrapper.tsx +87 -0
  319. package/src/components/layout/GridLayout.tsx +169 -0
  320. package/src/components/layout/index.ts +13 -0
  321. package/src/components/menu/Menu.tsx +0 -0
  322. package/src/components/menu/MenuItem.tsx +32 -0
  323. package/src/components/menu/index.ts +6 -0
  324. package/src/components/pages/FormPage.tsx +108 -0
  325. package/src/components/pages/Page.css +460 -0
  326. package/src/components/pages/Page.tsx +345 -0
  327. package/src/components/pages/index.ts +11 -0
  328. package/src/contexts/DataContext.tsx +355 -0
  329. package/src/contexts/DimensionsContext.tsx +154 -0
  330. package/src/contexts/PaletteContext.tsx +217 -0
  331. package/src/contexts/QwickAppContext.tsx +95 -0
  332. package/src/contexts/ThemeContext.tsx +376 -0
  333. package/src/contexts/index.ts +9 -0
  334. package/src/hooks/__tests__/useDataBinding.test.tsx.disabled +229 -0
  335. package/src/hooks/index.ts +11 -0
  336. package/src/hooks/useBaseProps.ts +267 -0
  337. package/src/hooks/useDataBinding.ts +77 -0
  338. package/src/index.ts +23 -0
  339. package/src/palettes/PaletteAutumn.css +172 -0
  340. package/src/palettes/PaletteAutumn.ts +16 -0
  341. package/src/palettes/PaletteCosmic.css +172 -0
  342. package/src/palettes/PaletteCosmic.ts +16 -0
  343. package/src/palettes/PaletteDefault.css +178 -0
  344. package/src/palettes/PaletteDefault.ts +17 -0
  345. package/src/palettes/PaletteOcean.css +172 -0
  346. package/src/palettes/PaletteOcean.ts +16 -0
  347. package/src/palettes/PaletteSpring.css +160 -0
  348. package/src/palettes/PaletteSpring.ts +16 -0
  349. package/src/palettes/PaletteWinter.css +172 -0
  350. package/src/palettes/PaletteWinter.ts +16 -0
  351. package/src/palettes/index.css +12 -0
  352. package/src/palettes/index.ts +29 -0
  353. package/src/schemas/ActionSchema.ts +140 -0
  354. package/src/schemas/ArticleSchema.ts +35 -0
  355. package/src/schemas/ButtonSchema.ts +99 -0
  356. package/src/schemas/CardListGridSchema.ts +102 -0
  357. package/src/schemas/ChoiceInputFieldSchema.ts +89 -0
  358. package/src/schemas/CodeSchema.ts +88 -0
  359. package/src/schemas/ContentSchema.ts +128 -0
  360. package/src/schemas/CoverImageHeaderSchema.ts +208 -0
  361. package/src/schemas/FeatureCardSchema.ts +161 -0
  362. package/src/schemas/FeatureGridSchema.ts +87 -0
  363. package/src/schemas/FeatureItemSchema.ts +68 -0
  364. package/src/schemas/FooterItemSchema.ts +57 -0
  365. package/src/schemas/FooterSchema.ts +116 -0
  366. package/src/schemas/FooterSectionSchema.ts +50 -0
  367. package/src/schemas/FormBlockSchema.ts +102 -0
  368. package/src/schemas/HeaderActionSchema.ts +83 -0
  369. package/src/schemas/HeroBlockSchema.ts +149 -0
  370. package/src/schemas/HtmlInputFieldSchema.ts +88 -0
  371. package/src/schemas/MetadataItemSchema.ts +35 -0
  372. package/src/schemas/PageBannerHeaderSchema.ts +206 -0
  373. package/src/schemas/PaletteSwitcherSchema.ts +66 -0
  374. package/src/schemas/ProductCardSchema.ts +264 -0
  375. package/src/schemas/SafeSpanSchema.ts +36 -0
  376. package/src/schemas/SectionSchema.ts +106 -0
  377. package/src/schemas/SelectInputFieldSchema.ts +137 -0
  378. package/src/schemas/TextInputFieldSchema.ts +129 -0
  379. package/src/schemas/ThemeSwitcherSchema.ts +97 -0
  380. package/src/schemas/__tests__/builders.test.ts +313 -0
  381. package/src/schemas/index.ts +34 -0
  382. package/src/setupTests.js +60 -0
  383. package/src/stories/Article.stories.tsx +549 -0
  384. package/src/stories/Button.stories.tsx +498 -0
  385. package/src/stories/CardListGrid.stories.tsx +539 -0
  386. package/src/stories/ChoiceInputField.stories.tsx +591 -0
  387. package/src/stories/Code.stories.tsx +711 -0
  388. package/src/stories/Content.stories.tsx +463 -0
  389. package/src/stories/CoverImageHeader.stories.tsx +794 -0
  390. package/src/stories/DataBinding.advanced.stories.tsx +548 -0
  391. package/src/stories/DataBinding.stories.tsx +452 -0
  392. package/src/stories/DataProvider.stories.tsx +1361 -0
  393. package/src/stories/FeatureCard.stories.tsx +642 -0
  394. package/src/stories/FeatureGrid.stories.tsx +669 -0
  395. package/src/stories/Footer.stories.tsx +724 -0
  396. package/src/stories/FormBlock.stories.tsx +834 -0
  397. package/src/stories/HeroBlock.stories.tsx +442 -0
  398. package/src/stories/Html.stories.tsx +264 -0
  399. package/src/stories/HtmlInputField.stories.tsx +558 -0
  400. package/src/stories/Introduction.stories.tsx +721 -0
  401. package/src/stories/LayoutBlocks.stories.tsx +382 -0
  402. package/src/stories/LayoutSystem.stories.tsx +253 -0
  403. package/src/stories/Logo.stories.tsx +400 -0
  404. package/src/stories/Markdown.stories.tsx +349 -0
  405. package/src/stories/Page.stories.tsx +762 -0
  406. package/src/stories/PageBannerHeader.stories.tsx +949 -0
  407. package/src/stories/PaletteSwitcher.stories.tsx +156 -0
  408. package/src/stories/ProductCard.stories.tsx +504 -0
  409. package/src/stories/QwickApp.stories.tsx +461 -0
  410. package/src/stories/ResponsiveMenu.stories.tsx +299 -0
  411. package/src/stories/SafeSpan.stories.tsx +612 -0
  412. package/src/stories/Section.stories.tsx +613 -0
  413. package/src/stories/SelectInputField.stories.tsx +605 -0
  414. package/src/stories/TextInputField.stories.tsx +526 -0
  415. package/src/stories/ThemeSwitcher.stories.tsx +170 -0
  416. package/src/stories/form/FormComponents.stories.tsx +588 -0
  417. package/src/templates/TemplateResolver.ts +156 -0
  418. package/src/templates/index.ts +6 -0
  419. package/src/tests/ConsoleWarningTest.tsx +30 -0
  420. package/src/tests/StorageKeyTest.tsx +110 -0
  421. package/src/tests/ThemeStorageKeyTest.tsx +114 -0
  422. package/src/types/CacheProvider.ts +14 -0
  423. package/src/types/ContentProxy.ts +99 -0
  424. package/src/types/DataTypes.ts +196 -0
  425. package/src/types/TemplateProvider.ts +9 -0
  426. package/src/types/TemplateResolver.ts +26 -0
  427. package/src/types/index.ts +99 -0
  428. package/src/utils/__tests__/createDataDrivenComponent.test.tsx.disabled +193 -0
  429. package/src/utils/__tests__/htmlTransform.test.tsx +255 -0
  430. package/src/utils/breakpoints.ts +87 -0
  431. package/src/utils/customPaletteManager.js +214 -0
  432. package/src/utils/dimensions.ts +147 -0
  433. package/src/utils/htmlTransform.tsx +323 -0
  434. package/src/utils/index.ts +16 -0
  435. package/src/utils/logger.ts +28 -0
  436. package/src/utils/paletteUtils.ts +78 -0
  437. package/src/utils/persistenceUtils.ts +107 -0
  438. package/src/utils/reactUtils.tsx +37 -0
  439. package/src/utils/spacing.ts +155 -0
  440. package/src/utils/themePerformanceMonitor.js +113 -0
  441. package/src/utils/themeUtils.ts +67 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Content Component - General-purpose content container with data binding support
3
+ *
4
+ * Usage:
5
+ * - Traditional: <Content title="Welcome" subtitle="Get started" actions={[...]} />
6
+ * - Data-driven: <Content dataSource="pages.home.intro" />
7
+ *
8
+ * Features:
9
+ * - Optional title, subtitle, and actions
10
+ * - Variant styles: default, elevated, outlined, filled
11
+ * - Responsive spacing, max width, and alignment
12
+ * - Theme-aware and flexible for layouts
13
+ *
14
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
15
+ */
16
+
17
+ import { Box, Paper, Stack, SxProps, Theme, Typography, useTheme } from '@mui/material';
18
+ import { WithDataBinding, ModelProps } from '@qwickapps/schema';
19
+ import React from 'react';
20
+ import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding } from '../../hooks';
21
+ import ContentModel from '../../schemas/ContentSchema';
22
+ import type { BreakpointValue } from '../../types';
23
+ import { mapToMUIBreakpoint } from '../../utils/breakpoints';
24
+ import { Button } from '../buttons/Button';
25
+ import Html from '../Html';
26
+
27
+ type ContentViewProps = ModelProps<ContentModel>;
28
+
29
+ export interface ContentProps extends ContentViewProps, WithDataBinding {}
30
+
31
+ function ContentView({
32
+ title,
33
+ subtitle,
34
+ children,
35
+ actions = [],
36
+ variant = 'default',
37
+ blockSpacing = 'comfortable',
38
+ contentMaxWidth = 'md',
39
+ centered = false,
40
+ ...restProps
41
+ }: ContentViewProps) {
42
+ const { styleProps, htmlProps, restProps: otherProps } = useBaseProps(restProps);
43
+ const theme = useTheme();
44
+
45
+ // Mark as QwickApp component
46
+ (ContentView as any)[QWICKAPP_COMPONENT] = true;
47
+
48
+ // Map spacing to padding values
49
+ const getPadding = () => {
50
+ switch (blockSpacing) {
51
+ case 'none':
52
+ return 0;
53
+ case 'compact':
54
+ return 2; // 16px
55
+ case 'comfortable':
56
+ return 3; // 24px
57
+ case 'spacious':
58
+ return 4; // 32px
59
+ default:
60
+ return 3;
61
+ }
62
+ };
63
+
64
+ // Content wrapper based on variant
65
+ const ContentWrapper: React.FC<{ children: React.ReactNode }> = ({ children }) => {
66
+ const paddingValue = getPadding();
67
+ const mappedMaxWidth = mapToMUIBreakpoint(contentMaxWidth === 'false' ? false : contentMaxWidth as BreakpointValue);
68
+ const commonSx: SxProps<Theme> = {
69
+ textAlign: centered ? 'center' : 'left',
70
+ maxWidth: mappedMaxWidth !== false
71
+ ? theme.breakpoints.values[mappedMaxWidth]
72
+ : '100%',
73
+ width: '100%',
74
+ ...(centered && contentMaxWidth && {
75
+ mx: 'auto',
76
+ }),
77
+ p: paddingValue,
78
+ ...styleProps.sx,
79
+ };
80
+
81
+ switch (variant) {
82
+ case 'elevated':
83
+ return (
84
+ <Paper
85
+ elevation={4}
86
+ {...htmlProps}
87
+ {...otherProps}
88
+ sx={{
89
+ ...commonSx,
90
+ backgroundColor: theme.palette.background.paper,
91
+ }}
92
+ >
93
+ {children}
94
+ </Paper>
95
+ );
96
+ case 'outlined':
97
+ return (
98
+ <Paper
99
+ variant="outlined"
100
+ elevation={0}
101
+ {...htmlProps}
102
+ {...otherProps}
103
+ sx={{
104
+ ...commonSx,
105
+ backgroundColor: 'var(--theme-surface)',
106
+ borderColor: 'var(--theme-border-main)', // Use theme border color
107
+ borderWidth: 1,
108
+ borderStyle: 'solid',
109
+ }}
110
+ >
111
+ {children}
112
+ </Paper>
113
+ );
114
+ case 'filled':
115
+ return (
116
+ <Box
117
+ {...htmlProps}
118
+ {...otherProps}
119
+ sx={{
120
+ ...commonSx,
121
+ backgroundColor: 'var(--theme-surface-variant)', // Use theme surface variant
122
+ borderRadius: 1,
123
+ }}
124
+ >
125
+ {children}
126
+ </Box>
127
+ );
128
+ default:
129
+ return (
130
+ <Box
131
+ {...htmlProps}
132
+ {...otherProps}
133
+ sx={commonSx}
134
+ >
135
+ {children}
136
+ </Box>
137
+ );
138
+ }
139
+ };
140
+
141
+ return (
142
+ <ContentWrapper>
143
+ <Stack spacing={2}>
144
+ {/* Header */}
145
+ {(title || subtitle) && (
146
+ <Box>
147
+ {title && (
148
+ <Typography
149
+ variant="h4"
150
+ component="h2"
151
+ gutterBottom={Boolean(subtitle)}
152
+ sx={{
153
+ fontWeight: 600,
154
+ ...(centered && { textAlign: 'center' })
155
+ }}
156
+ >
157
+ {title}
158
+ </Typography>
159
+ )}
160
+ {subtitle && (
161
+ <Typography
162
+ variant="h6"
163
+ color="text.secondary"
164
+ sx={{
165
+ ...(centered && { textAlign: 'center' })
166
+ }}
167
+ >
168
+ {subtitle}
169
+ </Typography>
170
+ )}
171
+ </Box>
172
+ )}
173
+
174
+ {/* Content */}
175
+ {children && (
176
+ <Box sx={{
177
+ '& > *:not(:last-child)': { mb: 2 },
178
+ ...(centered && { textAlign: 'center' })
179
+ }}>
180
+ {typeof children === 'string' ? (
181
+ // Use Html component for string content (from data binding)
182
+ <Html>{children}</Html>
183
+ ) : (
184
+ // Use React nodes directly (traditional usage)
185
+ children
186
+ )}
187
+ </Box>
188
+ )}
189
+
190
+ {/* Actions */}
191
+ {actions.length > 0 && (
192
+ <Stack
193
+ direction="row"
194
+ spacing={2}
195
+ sx={{
196
+ ...(centered && {
197
+ justifyContent: 'center',
198
+ alignItems: 'center'
199
+ }),
200
+ flexWrap: 'wrap',
201
+ gap: 1,
202
+ }}
203
+ >
204
+ {actions.map((action, index) => (
205
+ <Button
206
+ key={`action-${index}`}
207
+ {...action}
208
+ />
209
+ ))}
210
+ </Stack>
211
+ )}
212
+ </Stack>
213
+ </ContentWrapper>
214
+ );
215
+ }
216
+
217
+ function Content(props: ContentProps) {
218
+ const { dataSource, bindingOptions, ...restProps } = props;
219
+
220
+ // If no dataSource, use traditional props
221
+ if (!dataSource) {
222
+ return <ContentView {...restProps} />;
223
+ }
224
+
225
+ // Use data binding
226
+ const { dataSource: _source, loading, error, cached, ...contentProps } = useDataBinding<ContentModel>(
227
+ dataSource,
228
+ restProps as Partial<ContentModel>,
229
+ ContentModel.getSchema(),
230
+ { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
231
+ );
232
+
233
+ // Show loading state
234
+ if (loading) {
235
+ return (
236
+ <ContentView
237
+ {...restProps}
238
+ title="Loading Content..."
239
+ variant="default"
240
+ blockSpacing="comfortable"
241
+ />
242
+ );
243
+ }
244
+
245
+ if (error) {
246
+ console.error('Error loading content:', error);
247
+ if (process.env.NODE_ENV !== 'production') {
248
+ return (
249
+ <ContentView
250
+ {...restProps}
251
+ title="Error Loading Content"
252
+ subtitle={error.message}
253
+ variant="default"
254
+ blockSpacing="comfortable"
255
+ />
256
+ );
257
+ }
258
+ return null;
259
+ }
260
+
261
+ return <ContentView {...contentProps} />;
262
+ }
263
+
264
+ export default Content;
265
+ export { Content };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * CoverImageHeader Styles
3
+ *
4
+ * Minimal styles since we're using MUI components primarily
5
+ */
6
+
7
+ /* Mobile responsive adjustments for action buttons */
8
+ @media (max-width: 600px) {
9
+ .cover-image-header .MuiButton-root .MuiButton-startIcon + * {
10
+ display: none;
11
+ }
12
+
13
+ .cover-image-header .MuiButton-root {
14
+ min-width: 36px;
15
+ padding: 6px 8px;
16
+ }
17
+ }
@@ -0,0 +1,435 @@
1
+ /**
2
+ * CoverImageHeader - Flexible header with optional image, info section, and context menu
3
+ *
4
+ * Provides a clean header layout similar to modern app interfaces with:
5
+ * - Optional image/avatar on the left
6
+ * - Info section with overline, title, subtitle, and tags
7
+ * - Context menu with up to 3 visible actions + overflow menu
8
+ *
9
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
10
+ */
11
+
12
+ import { MoreVert as MoreIcon } from '@mui/icons-material';
13
+ import {
14
+ Avatar,
15
+ Box,
16
+ Button,
17
+ Chip,
18
+ IconButton,
19
+ Menu,
20
+ MenuItem,
21
+ Paper,
22
+ Typography,
23
+ } from '@mui/material';
24
+ import { WithDataBinding, ModelProps } from '@qwickapps/schema';
25
+ import React, { useState } from 'react';
26
+ import { useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
27
+ import CoverImageHeaderModel from '../../schemas/CoverImageHeaderSchema';
28
+ import './CoverImageHeader.css';
29
+
30
+ export interface HeaderAction {
31
+ /** Unique identifier for the action */
32
+ id: string;
33
+ /** Display label for the action */
34
+ label: string;
35
+ /** Icon component or JSX element */
36
+ icon?: React.ReactNode;
37
+ /** Click handler */
38
+ onClick: () => void;
39
+ /** Whether this action is disabled */
40
+ disabled?: boolean;
41
+ /** Whether this action is destructive (shows with warning styling) */
42
+ destructive?: boolean;
43
+ /** Priority for ordering (lower numbers = higher priority, shown first) */
44
+ priority?: number;
45
+ }
46
+
47
+ type CoverImageHeaderViewProps = Omit<ModelProps<CoverImageHeaderModel>, 'actions' | 'tags' | 'image'> & WithBaseProps & {
48
+ /** Image URL or React component (extended from schema string) */
49
+ image?: string | React.ReactNode;
50
+ /** Array of tag strings or JSX elements (extended from schema string[]) */
51
+ tags?: (string | React.ReactNode)[];
52
+ /** Context menu actions (extended from schema HeaderActionModel[]) */
53
+ actions?: HeaderAction[];
54
+ };
55
+
56
+ export interface CoverImageHeaderProps extends CoverImageHeaderViewProps, WithDataBinding {}
57
+
58
+ function CoverImageHeaderView({
59
+ image,
60
+ imageAlt = '',
61
+ imageSize = 'medium',
62
+ imageShape = 'rounded',
63
+ imageBackgroundColor = 'transparent',
64
+ overline,
65
+ title,
66
+ subtitle,
67
+ tags = [],
68
+ actions = [],
69
+ maxVisibleActions = 3,
70
+ variant = 'default',
71
+ background,
72
+ color,
73
+ ...restProps
74
+ }: CoverImageHeaderViewProps) {
75
+ const { gridProps, styleProps, htmlProps } = useBaseProps(restProps);
76
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
77
+ const isMenuOpen = Boolean(anchorEl);
78
+
79
+ // Sort actions by priority (lower number = higher priority)
80
+ const sortedActions = [...actions].sort((a, b) => (a.priority || 999) - (b.priority || 999));
81
+
82
+ // Split actions into visible and overflow
83
+ const visibleActions = sortedActions.slice(0, maxVisibleActions);
84
+ const overflowActions = sortedActions.slice(maxVisibleActions);
85
+
86
+ const handleMenuOpen = (event: React.MouseEvent<HTMLElement>) => {
87
+ setAnchorEl(event.currentTarget);
88
+ };
89
+
90
+ const handleMenuClose = () => {
91
+ setAnchorEl(null);
92
+ };
93
+
94
+ const getAvatarSize = () => {
95
+ switch (imageSize) {
96
+ case 'small': return 48;
97
+ case 'large': return 80;
98
+ default: return 64;
99
+ }
100
+ };
101
+
102
+ const getAvatarVariant = () => {
103
+ switch (imageShape) {
104
+ case 'circle': return 'circular' as const;
105
+ case 'square': return 'square' as const;
106
+ default: return 'rounded' as const;
107
+ }
108
+ };
109
+
110
+ const renderImage = () => {
111
+ if (!image) return null;
112
+
113
+ const size = getAvatarSize();
114
+
115
+ if (typeof image === 'string') {
116
+ return (
117
+ <Avatar
118
+ src={image}
119
+ alt={imageAlt}
120
+ variant={getAvatarVariant()}
121
+ sx={{ width: size, height: size }}
122
+ />
123
+ );
124
+ }
125
+
126
+ return (
127
+ <Avatar
128
+ variant={getAvatarVariant()}
129
+ sx={{ width: size, height: size, backgroundColor: imageBackgroundColor ||'transparent' }}
130
+ >
131
+ {image}
132
+ </Avatar>
133
+ );
134
+ };
135
+
136
+ const renderTags = () => {
137
+ if (tags.length === 0) return null;
138
+
139
+ return (
140
+ <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, mt: 0.5 }}>
141
+ {tags.map((tag, index) => (
142
+ <Chip
143
+ key={index}
144
+ label={tag}
145
+ size="small"
146
+ color="primary"
147
+ sx={{ fontSize: '0.75rem', height: '24px' }}
148
+ />
149
+ ))}
150
+ </Box>
151
+ );
152
+ };
153
+
154
+ const renderActions = () => {
155
+ if (actions.length === 0) return null;
156
+
157
+ return (
158
+ <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 0.5 }}>
159
+ {/* Visible action buttons */}
160
+ {visibleActions.map((action) => (
161
+ <Button
162
+ key={action.id}
163
+ variant="outlined"
164
+ size="small"
165
+ startIcon={action.icon}
166
+ onClick={action.onClick}
167
+ disabled={action.disabled}
168
+ color={action.destructive ? 'error' : 'primary'}
169
+ sx={{
170
+ minHeight: 36,
171
+ whiteSpace: 'nowrap',
172
+ '& .MuiButton-startIcon': { mr: 0.5 }
173
+ }}
174
+ >
175
+ {action.label}
176
+ </Button>
177
+ ))}
178
+
179
+ {/* Overflow menu */}
180
+ {overflowActions.length > 0 && (
181
+ <>
182
+ <IconButton
183
+ size="small"
184
+ onClick={handleMenuOpen}
185
+ aria-label="More actions"
186
+ color='info'
187
+ sx={{ minHeight: 36, minWidth: 36 }}
188
+ >
189
+ <MoreIcon />
190
+ </IconButton>
191
+
192
+ <Menu
193
+ anchorEl={anchorEl}
194
+ open={isMenuOpen}
195
+ onClose={handleMenuClose}
196
+ anchorOrigin={{
197
+ vertical: 'bottom',
198
+ horizontal: 'right',
199
+ }}
200
+ transformOrigin={{
201
+ vertical: 'top',
202
+ horizontal: 'right',
203
+ }}
204
+ >
205
+ {overflowActions.map((action) => (
206
+ <MenuItem
207
+ key={action.id}
208
+ onClick={() => {
209
+ action.onClick();
210
+ handleMenuClose();
211
+ }}
212
+ disabled={action.disabled}
213
+ sx={{
214
+ color: action.destructive ? 'error.main' : 'inherit',
215
+ gap: 1.5,
216
+ minWidth: 200
217
+ }}
218
+ >
219
+ {action.icon && <Box component="span" sx={{ display: 'flex' }}>{action.icon}</Box>}
220
+ {action.label}
221
+ </MenuItem>
222
+ ))}
223
+ </Menu>
224
+ </>
225
+ )}
226
+ </Box>
227
+ );
228
+ };
229
+
230
+ const getPadding = () => {
231
+ switch (variant) {
232
+ case 'compact': return 2;
233
+ case 'prominent': return 3;
234
+ default: return 2.5;
235
+ }
236
+ };
237
+
238
+ const getGap = () => {
239
+ switch (variant) {
240
+ case 'compact': return 1.5;
241
+ case 'prominent': return 2;
242
+ default: return 2;
243
+ }
244
+ };
245
+
246
+ const getElevation = () => {
247
+ switch (variant) {
248
+ case 'default': return 0;
249
+ case 'compact': return 1;
250
+ case 'prominent': return 1;
251
+ default: return 0;
252
+ }
253
+ };
254
+
255
+ const backgroundStyle = background ? {
256
+ background: background.startsWith('http') || background.startsWith('data:')
257
+ ? `linear-gradient(rgba(0,0,0,0.3), rgba(0,0,0,0.3)), url(${background})`
258
+ : background,
259
+ backgroundSize: 'cover',
260
+ backgroundPosition: 'center'
261
+ } : {'background': '-var(--theme-primary)'};
262
+
263
+ return (
264
+ <Paper
265
+ component="header"
266
+ {...htmlProps}
267
+ {...(gridProps && {
268
+ 'data-grid-span': gridProps.span,
269
+ 'data-grid-xs': gridProps.xs,
270
+ 'data-grid-sm': gridProps.sm,
271
+ 'data-grid-md': gridProps.md,
272
+ 'data-grid-lg': gridProps.lg,
273
+ 'data-grid-xl': gridProps.xl,
274
+ })}
275
+ sx={{
276
+ p: getPadding(),
277
+ borderRadius: getElevation() > 0 ? 2 : 0, // No border radius when elevation is 0
278
+ ...backgroundStyle,
279
+ color: background ? 'white' : 'inherit',
280
+ ...styleProps.sx
281
+ }}
282
+ elevation={getElevation()}
283
+ >
284
+ <Box
285
+ sx={{
286
+ display: 'flex',
287
+ alignItems: variant === 'prominent' ? 'center' : 'flex-start',
288
+ gap: getGap(),
289
+ flexWrap: { xs: 'wrap', sm: 'nowrap' },
290
+ minHeight: variant === 'prominent' ? 120 : 'auto'
291
+ }}
292
+ >
293
+ {/* Image Section */}
294
+ {renderImage()}
295
+
296
+ {/* Info Section */}
297
+ <Box sx={{ flex: 1, minWidth: 0 }}>
298
+ {overline && (
299
+ <Typography
300
+ variant="overline"
301
+ color={color || '--var(--theme-on-primary)'}
302
+ sx={{
303
+ display: 'block',
304
+ fontSize: '0.75rem',
305
+ fontWeight: 600,
306
+ lineHeight: 1.2,
307
+ mb: 0.25
308
+ }}
309
+ >
310
+ {overline}
311
+ </Typography>
312
+ )}
313
+
314
+ <Typography
315
+ variant="h5"
316
+ component="h1"
317
+ sx={{
318
+ fontWeight: 600,
319
+ lineHeight: 1.3,
320
+ wordBreak: 'break-word',
321
+ mb: subtitle ? 0.25 : 0
322
+ }}
323
+ >
324
+ {title}
325
+ </Typography>
326
+
327
+ {subtitle && (
328
+ <Typography
329
+ variant="body2"
330
+ color={color || '--var(--theme-on-primary)'}
331
+ sx={{
332
+ lineHeight: 1.4,
333
+ mb: tags.length > 0 ? 0 : 0
334
+ }}
335
+ >
336
+ {subtitle}
337
+ </Typography>
338
+ )}
339
+
340
+ {renderTags()}
341
+ </Box>
342
+
343
+ {/* Actions Section */}
344
+ <Box
345
+ sx={{
346
+ flexShrink: 0,
347
+ width: { xs: '100%', sm: 'auto' },
348
+ display: 'flex',
349
+ justifyContent: { xs: 'flex-end', sm: 'flex-start' },
350
+ mt: { xs: 1, sm: 0 }
351
+ }}
352
+ >
353
+ {renderActions()}
354
+ </Box>
355
+ </Box>
356
+ </Paper>
357
+ );
358
+ }
359
+
360
+ // Loading state component
361
+ function LoadingState() {
362
+ return (
363
+ <Paper
364
+ variant="outlined"
365
+ sx={{
366
+ p: 3,
367
+ textAlign: 'center'
368
+ }}
369
+ >
370
+ <Typography variant="body2">Loading Cover Image Header...</Typography>
371
+ <Typography variant="caption" color="text.secondary">
372
+ Loading header content from data source...
373
+ </Typography>
374
+ </Paper>
375
+ );
376
+ }
377
+
378
+ // Error state component (development only)
379
+ function ErrorState() {
380
+ return (
381
+ <Paper
382
+ variant="outlined"
383
+ sx={{
384
+ p: 3,
385
+ textAlign: 'center',
386
+ borderColor: 'error.main'
387
+ }}
388
+ >
389
+ <Typography variant="body2" color="error">
390
+ Error loading cover image header
391
+ </Typography>
392
+ </Paper>
393
+ );
394
+ }
395
+
396
+ function CoverImageHeader(props: CoverImageHeaderProps) {
397
+ const { dataSource, bindingOptions, ...restProps } = props;
398
+
399
+ // If no dataSource, use traditional props
400
+ if (!dataSource) {
401
+ return <CoverImageHeaderView {...restProps} />;
402
+ }
403
+
404
+ // Use data binding
405
+ const { dataSource: _source, loading, error, cached, ...coverImageHeaderProps } = useDataBinding<CoverImageHeaderModel>(
406
+ dataSource,
407
+ restProps as Partial<CoverImageHeaderModel>,
408
+ CoverImageHeaderModel.getSchema(),
409
+ { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
410
+ );
411
+
412
+ // Show loading state
413
+ if (loading) {
414
+ return <LoadingState />;
415
+ }
416
+
417
+ if (error) {
418
+ console.error('Error loading cover image header:', error);
419
+ if (process.env.NODE_ENV !== 'production') {
420
+ return <ErrorState />;
421
+ }
422
+ return null;
423
+ }
424
+
425
+ // Convert HeaderActionModel[] to HeaderAction[] if actions exist
426
+ const { actions: modelActions, ...viewProps } = coverImageHeaderProps;
427
+ const convertedActions: HeaderAction[] = modelActions ? modelActions.map(action => ({
428
+ ...action,
429
+ onClick: () => console.log(`Action clicked: ${action.id}`) // Default handler for data-driven actions
430
+ })) : [];
431
+
432
+ return <CoverImageHeaderView {...viewProps} actions={convertedActions} />;
433
+ }
434
+
435
+ export default CoverImageHeader;