@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,343 @@
1
+ /**
2
+ * Footer - Reusable footer component with flexible layout options
3
+ *
4
+ * Provides a clean footer layout with:
5
+ * - Configurable orientation (vertical/horizontal)
6
+ * - Optional logo/branding
7
+ * - Multiple sections for links, text, or custom content
8
+ * - Responsive design with MUI components
9
+ * - Copyright and legal information support
10
+ *
11
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
12
+ */
13
+
14
+ import {
15
+ Box,
16
+ Divider,
17
+ Link,
18
+ Paper,
19
+ Typography,
20
+ useMediaQuery,
21
+ useTheme,
22
+ } from '@mui/material';
23
+ import { WithDataBinding } from '@qwickapps/schema';
24
+ import React from 'react';
25
+ import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
26
+ import FooterModel from '../../schemas/FooterSchema';
27
+
28
+ export interface FooterSection {
29
+ /** Unique identifier for the section */
30
+ id: string;
31
+ /** Section title/heading */
32
+ title?: string;
33
+ /** Array of items in this section */
34
+ items: FooterItem[];
35
+ }
36
+
37
+ export interface FooterItem {
38
+ /** Unique identifier for the item */
39
+ id: string;
40
+ /** Display text */
41
+ label: string;
42
+ /** Optional URL for links */
43
+ href?: string;
44
+ /** Click handler for custom actions */
45
+ onClick?: () => void;
46
+ /** Whether to open links in new tab */
47
+ external?: boolean;
48
+ }
49
+
50
+ interface FooterViewProps extends WithBaseProps {
51
+ /** Footer sections */
52
+ sections?: FooterSection[];
53
+ /** Optional logo or branding element */
54
+ logo?: React.ReactNode;
55
+ /** Copyright text */
56
+ copyright?: string;
57
+ /** Additional legal or info text */
58
+ legalText?: string;
59
+ /** Layout orientation */
60
+ orientation?: 'vertical' | 'horizontal';
61
+ /** Background variant */
62
+ variant?: 'default' | 'contained' | 'outlined';
63
+ /** Whether to show divider above footer */
64
+ showDivider?: boolean;
65
+ }
66
+
67
+ export interface FooterProps extends FooterViewProps, WithDataBinding {}
68
+
69
+ function FooterView({
70
+ sections = [],
71
+ logo,
72
+ copyright,
73
+ legalText,
74
+ orientation = 'vertical',
75
+ variant = 'default',
76
+ showDivider = true,
77
+ ...restProps
78
+ }: FooterViewProps) {
79
+ const { gridProps, styleProps, htmlProps } = useBaseProps(restProps);
80
+
81
+ // Mark as QwickApp component
82
+ (FooterView as any)[QWICKAPP_COMPONENT] = true;
83
+ const theme = useTheme();
84
+ const isMobile = useMediaQuery(theme.breakpoints.down('md'));
85
+
86
+ // Force vertical on mobile for better usability
87
+ const effectiveOrientation = isMobile ? 'vertical' : orientation;
88
+
89
+ const renderFooterItem = (item: FooterItem) => {
90
+ const content = (
91
+ <Typography
92
+ variant="body2"
93
+ color="text.secondary"
94
+ sx={{
95
+ textDecoration: item.href ? 'none' : 'inherit',
96
+ '&:hover': item.href ? { color: 'primary.main' } : {},
97
+ cursor: item.href || item.onClick ? 'pointer' : 'default',
98
+ transition: 'color 0.2s'
99
+ }}
100
+ onClick={item.onClick}
101
+ >
102
+ {item.label}
103
+ </Typography>
104
+ );
105
+
106
+ if (item.href) {
107
+ return (
108
+ <Link
109
+ key={item.id}
110
+ href={item.href}
111
+ target={item.external ? '_blank' : undefined}
112
+ rel={item.external ? 'noopener noreferrer' : undefined}
113
+ underline="none"
114
+ sx={{ display: 'block', mb: 0.5 }}
115
+ >
116
+ {content}
117
+ </Link>
118
+ );
119
+ }
120
+
121
+ return (
122
+ <Box key={item.id} sx={{ mb: 0.5 }}>
123
+ {content}
124
+ </Box>
125
+ );
126
+ };
127
+
128
+ const renderSection = (section: FooterSection) => (
129
+ <Box key={section.id} sx={{ minWidth: 0 }}>
130
+ {section.title && (
131
+ <Typography
132
+ variant="subtitle2"
133
+ component="h3"
134
+ sx={{
135
+ fontWeight: 600,
136
+ mb: 1.5,
137
+ color: 'text.primary'
138
+ }}
139
+ >
140
+ {section.title}
141
+ </Typography>
142
+ )}
143
+ <Box>
144
+ {section.items.map(item => renderFooterItem(item))}
145
+ </Box>
146
+ </Box>
147
+ );
148
+
149
+ const getContainerProps = () => {
150
+ const baseProps = {
151
+ component: 'footer' as const,
152
+ ...htmlProps,
153
+ ...styleProps,
154
+ ...(gridProps && {
155
+ 'data-grid-span': gridProps.span,
156
+ 'data-grid-xs': gridProps.xs,
157
+ 'data-grid-sm': gridProps.sm,
158
+ 'data-grid-md': gridProps.md,
159
+ 'data-grid-lg': gridProps.lg,
160
+ 'data-grid-xl': gridProps.xl,
161
+ }),
162
+ sx: {
163
+ mt: 'auto',
164
+ py: 3,
165
+ px: { xs: 2, sm: 3 },
166
+ ...styleProps.sx
167
+ }
168
+ };
169
+
170
+ switch (variant) {
171
+ case 'contained':
172
+ return {
173
+ ...baseProps,
174
+ component: Paper,
175
+ sx: {
176
+ ...baseProps.sx,
177
+ borderRadius: 0,
178
+ backgroundColor: 'background.paper'
179
+ }
180
+ };
181
+ case 'outlined':
182
+ return {
183
+ ...baseProps,
184
+ component: Paper,
185
+ sx: {
186
+ ...baseProps.sx,
187
+ borderRadius: 0,
188
+ border: 1,
189
+ borderColor: 'divider',
190
+ backgroundColor: 'transparent'
191
+ },
192
+ variant: 'outlined' as const
193
+ };
194
+ default:
195
+ return baseProps;
196
+ }
197
+ };
198
+
199
+ const containerProps = getContainerProps();
200
+
201
+ return (
202
+ <>
203
+ {showDivider && <Divider />}
204
+ <Box {...containerProps}>
205
+ <Box
206
+ sx={{
207
+ maxWidth: 'lg',
208
+ mx: 'auto',
209
+ display: 'flex',
210
+ flexDirection: effectiveOrientation === 'vertical' ? 'column' : 'row',
211
+ gap: effectiveOrientation === 'vertical' ? 3 : 4,
212
+ alignItems: effectiveOrientation === 'horizontal' ? 'flex-start' : 'stretch'
213
+ }}
214
+ >
215
+ {/* Logo/Branding Section */}
216
+ {logo && (
217
+ <Box
218
+ sx={{
219
+ flexShrink: 0,
220
+ mb: effectiveOrientation === 'vertical' ? 2 : 0,
221
+ mr: effectiveOrientation === 'horizontal' ? 'auto' : 0
222
+ }}
223
+ >
224
+ {logo}
225
+ </Box>
226
+ )}
227
+
228
+ {/* Footer Sections */}
229
+ {sections.length > 0 && (
230
+ <Box
231
+ sx={{
232
+ display: 'flex',
233
+ flexDirection: { xs: 'column', sm: effectiveOrientation === 'vertical' ? 'column' : 'row' },
234
+ gap: { xs: 2, sm: 4 },
235
+ flex: 1,
236
+ justifyContent: effectiveOrientation === 'horizontal' ? 'space-between' : 'flex-start'
237
+ }}
238
+ >
239
+ {sections.map(section => renderSection(section))}
240
+ </Box>
241
+ )}
242
+ </Box>
243
+
244
+ {/* Copyright and Legal */}
245
+ {(copyright || legalText) && (
246
+ <Box
247
+ sx={{
248
+ mt: 3,
249
+ pt: 2,
250
+ borderTop: 1,
251
+ borderColor: 'divider',
252
+ maxWidth: 'lg',
253
+ mx: 'auto'
254
+ }}
255
+ >
256
+ <Box
257
+ sx={{
258
+ display: 'flex',
259
+ flexDirection: { xs: 'column', sm: 'row' },
260
+ justifyContent: 'space-between',
261
+ alignItems: { xs: 'flex-start', sm: 'center' },
262
+ gap: 1
263
+ }}
264
+ >
265
+ {copyright && (
266
+ <Typography variant="caption" color="text.secondary">
267
+ {copyright}
268
+ </Typography>
269
+ )}
270
+ {legalText && (
271
+ <Typography variant="caption" color="text.secondary">
272
+ {legalText}
273
+ </Typography>
274
+ )}
275
+ </Box>
276
+ </Box>
277
+ )}
278
+ </Box>
279
+ </>
280
+ );
281
+ }
282
+
283
+ function Footer(props: FooterProps) {
284
+ const { dataSource, bindingOptions, ...restProps } = props;
285
+
286
+ // If no dataSource, use traditional props
287
+ if (!dataSource) {
288
+ return <FooterView {...restProps} />;
289
+ }
290
+
291
+ // Use data binding
292
+ const { dataSource: _source, loading, error, cached, ...footerProps } = useDataBinding<FooterModel>(
293
+ dataSource,
294
+ restProps as Partial<FooterModel>,
295
+ FooterModel.getSchema(),
296
+ { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
297
+ );
298
+
299
+ // Show loading state
300
+ if (loading) {
301
+ return (
302
+ <Box
303
+ component="footer"
304
+ sx={{
305
+ mt: 'auto',
306
+ py: 3,
307
+ px: { xs: 2, sm: 3 },
308
+ textAlign: 'center'
309
+ }}
310
+ >
311
+ <Typography variant="body2" color="text.secondary">
312
+ Loading Footer...
313
+ </Typography>
314
+ </Box>
315
+ );
316
+ }
317
+
318
+ if (error) {
319
+ console.error('Error loading footer:', error);
320
+ if (process.env.NODE_ENV !== 'production') {
321
+ return (
322
+ <Box
323
+ component="footer"
324
+ sx={{
325
+ mt: 'auto',
326
+ py: 3,
327
+ px: { xs: 2, sm: 3 },
328
+ textAlign: 'center'
329
+ }}
330
+ >
331
+ <Typography variant="body2" color="error">
332
+ Error Loading Footer: {error.message}
333
+ </Typography>
334
+ </Box>
335
+ );
336
+ }
337
+ return null;
338
+ }
339
+
340
+ return <FooterView {...footerProps} />;
341
+ }
342
+
343
+ export default Footer;
@@ -0,0 +1,280 @@
1
+ /**
2
+ * HeroBlock Component - Full-width hero section with data binding support
3
+ *
4
+ * Enhanced with data binding support through dataSource prop.
5
+ *
6
+ * Usage:
7
+ * - Traditional: <HeroBlock title="Welcome" subtitle="Get started" actions={[...]} />
8
+ * - Data-driven: <HeroBlock dataSource="pages.home.hero" />
9
+ *
10
+ * Features:
11
+ * - Responsive headline, subtitle, and actions
12
+ * - Supports background images, gradients, and theme colors
13
+ * - Overlay for image backgrounds
14
+ * - Customizable height, alignment, and overlay opacity
15
+ *
16
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
17
+ */
18
+
19
+ import { Box, Container, Stack, Typography, useTheme } from '@mui/material';
20
+ import { WithDataBinding, ModelProps } from '@qwickapps/schema';
21
+ import React from 'react';
22
+ import { QWICKAPP_COMPONENT, useBaseProps, useDataBinding, WithBaseProps } from '../../hooks';
23
+ import HeroBlockModel from '../../schemas/HeroBlockSchema';
24
+ import { Button, ButtonProps } from '../buttons/Button';
25
+
26
+ type HeroBlockViewProps = Partial<ModelProps<HeroBlockModel>> & WithBaseProps & {
27
+ /** Action buttons (data-driven) */
28
+ actions?: ButtonProps[];
29
+ /** Additional content below the text */
30
+ children?: React.ReactNode;
31
+ };
32
+
33
+ export interface HeroBlockProps extends HeroBlockViewProps, WithDataBinding {}
34
+
35
+ /**
36
+ * Core HeroBlock View component - handles hero section rendering
37
+ */
38
+ function HeroBlockView({
39
+ title = '',
40
+ subtitle,
41
+ backgroundImage,
42
+ backgroundGradient,
43
+ backgroundColor = 'primary',
44
+ actions = [],
45
+ children,
46
+ textAlign = 'center',
47
+ blockHeight = 'medium',
48
+ overlayOpacity = 0.5,
49
+ ...restProps
50
+ }: HeroBlockViewProps) {
51
+ const { gridProps, styleProps, htmlProps } = useBaseProps(restProps);
52
+
53
+ // Mark as QwickApp component
54
+ (HeroBlockView as any)[QWICKAPP_COMPONENT] = true;
55
+ const theme = useTheme();
56
+
57
+ // Map height variants to actual heights
58
+ const getHeight = () => {
59
+ switch (blockHeight) {
60
+ case 'small':
61
+ return 300;
62
+ case 'medium':
63
+ return 400;
64
+ case 'large':
65
+ return 600;
66
+ case 'viewport':
67
+ return '100vh';
68
+ default:
69
+ return 400;
70
+ }
71
+ };
72
+
73
+ // Get background color from theme
74
+ const getBackgroundColor = () => {
75
+ if (backgroundImage || backgroundGradient) {
76
+ return 'transparent';
77
+ }
78
+
79
+ switch (backgroundColor) {
80
+ case 'primary':
81
+ return theme.palette.primary.main;
82
+ case 'secondary':
83
+ return theme.palette.secondary.main;
84
+ case 'surface':
85
+ return theme.palette.background.paper;
86
+ default:
87
+ return theme.palette.background.default;
88
+ }
89
+ };
90
+
91
+ // Get text color based on background
92
+ const getTextColor = () => {
93
+ if (backgroundImage || backgroundGradient) {
94
+ return '#ffffff'; // White text on images/gradients
95
+ }
96
+
97
+ switch (backgroundColor) {
98
+ case 'primary':
99
+ return theme.palette.primary.contrastText;
100
+ case 'secondary':
101
+ return theme.palette.secondary.contrastText;
102
+ case 'surface':
103
+ return theme.palette.getContrastText(theme.palette.background.paper);
104
+ default:
105
+ return theme.palette.text.primary;
106
+ }
107
+ };
108
+
109
+ return (
110
+ <Box
111
+ component="section"
112
+ {...htmlProps}
113
+ {...styleProps}
114
+ {...(gridProps && {
115
+ 'data-grid-span': gridProps.span,
116
+ 'data-grid-xs': gridProps.xs,
117
+ 'data-grid-sm': gridProps.sm,
118
+ 'data-grid-md': gridProps.md,
119
+ 'data-grid-lg': gridProps.lg,
120
+ 'data-grid-xl': gridProps.xl,
121
+ })}
122
+ sx={{
123
+ position: 'relative',
124
+ display: 'flex',
125
+ alignItems: 'center',
126
+ justifyContent: 'center',
127
+ minHeight: getHeight(),
128
+ backgroundColor: getBackgroundColor(),
129
+ color: getTextColor(),
130
+ backgroundImage: backgroundImage ? `url(${backgroundImage})` : backgroundGradient || 'none',
131
+ backgroundSize: backgroundImage ? 'cover' : 'auto',
132
+ backgroundPosition: backgroundImage ? 'center' : 'initial',
133
+ backgroundRepeat: 'no-repeat',
134
+ overflow: 'hidden',
135
+ ...styleProps.sx,
136
+ }}
137
+ >
138
+ {/* Overlay for background images */}
139
+ {backgroundImage && (
140
+ <Box
141
+ sx={{
142
+ position: 'absolute',
143
+ top: 0,
144
+ left: 0,
145
+ right: 0,
146
+ bottom: 0,
147
+ backgroundColor: 'rgba(0, 0, 0, 0.4)',
148
+ opacity: overlayOpacity,
149
+ zIndex: 1,
150
+ }}
151
+ />
152
+ )}
153
+
154
+ {/* Content */}
155
+ <Container
156
+ maxWidth="md"
157
+ sx={{
158
+ position: 'relative',
159
+ zIndex: 2,
160
+ textAlign,
161
+ py: 4,
162
+ }}
163
+ >
164
+ <Stack spacing={3} alignItems={textAlign === 'center' ? 'center' : textAlign === 'right' ? 'flex-end' : 'flex-start'}>
165
+ {/* Title */}
166
+ <Typography
167
+ variant="h2"
168
+ component="h1"
169
+ sx={{
170
+ fontWeight: 700,
171
+ fontSize: {
172
+ xs: '2rem',
173
+ sm: '2.5rem',
174
+ md: '3rem',
175
+ lg: '3.5rem',
176
+ },
177
+ lineHeight: 1.2,
178
+ maxWidth: '800px',
179
+ }}
180
+ >
181
+ {title}
182
+ </Typography>
183
+
184
+ {/* Subtitle */}
185
+ {subtitle && (
186
+ <Typography
187
+ variant="h5"
188
+ component="p"
189
+ sx={{
190
+ opacity: 0.9,
191
+ maxWidth: '600px',
192
+ fontWeight: 400,
193
+ }}
194
+ >
195
+ {subtitle}
196
+ </Typography>
197
+ )}
198
+
199
+ {/* Actions */}
200
+ {actions.length > 0 && (
201
+ <Stack
202
+ direction="row"
203
+ spacing={2}
204
+ sx={{
205
+ mt: 2,
206
+ flexWrap: 'wrap',
207
+ gap: 1,
208
+ justifyContent: textAlign === 'center' ? 'center' : textAlign === 'right' ? 'flex-end' : 'flex-start',
209
+ }}
210
+ >
211
+ {actions.map((action, index) => (
212
+ <Button
213
+ key={`hero-action-${index}`}
214
+ buttonSize="large"
215
+ {...action}
216
+ />
217
+ ))}
218
+ </Stack>
219
+ )}
220
+
221
+ {/* Additional content */}
222
+ {children && (
223
+ <Box sx={{ maxWidth: '800px' }}>
224
+ {children}
225
+ </Box>
226
+ )}
227
+ </Stack>
228
+ </Container>
229
+ </Box>
230
+ );
231
+ }
232
+
233
+ function HeroBlock(props: HeroBlockProps) {
234
+ const { dataSource, bindingOptions, ...restProps } = props;
235
+
236
+ // If no dataSource, use traditional props
237
+ if (!dataSource) {
238
+ return <HeroBlockView {...restProps} />;
239
+ }
240
+
241
+ // Use data binding
242
+ const { dataSource: _source, loading, error, cached, ...heroProps } = useDataBinding<HeroBlockModel>(
243
+ dataSource,
244
+ restProps as Partial<HeroBlockModel>,
245
+ HeroBlockModel.getSchema(),
246
+ { cache: true, cacheTTL: 300000, strict: false, ...bindingOptions }
247
+ );
248
+
249
+ // Show loading state
250
+ if (loading) {
251
+ return (
252
+ <HeroBlockView
253
+ title="Loading Hero..."
254
+ backgroundColor="default"
255
+ blockHeight="medium"
256
+ textAlign="center"
257
+ />
258
+ );
259
+ }
260
+
261
+ if (error) {
262
+ console.error('Error loading hero block:', error);
263
+ if (process.env.NODE_ENV !== 'production') {
264
+ return (
265
+ <HeroBlockView
266
+ title="Error Loading Hero"
267
+ subtitle={error.message}
268
+ backgroundColor="default"
269
+ blockHeight="medium"
270
+ textAlign="center"
271
+ />
272
+ );
273
+ }
274
+ return null;
275
+ }
276
+
277
+ return <HeroBlockView {...heroProps} />;
278
+ }
279
+
280
+ export default HeroBlock;