@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,463 @@
1
+ /**
2
+ * Scaffold - Complete application scaffolding system
3
+ *
4
+ * Provides proper Material UI compliant layout scaffolding with:
5
+ * - AppBar with responsive behavior
6
+ * - Navigation rail/drawer with proper item limits
7
+ * - Bottom navigation with 3-5 items
8
+ * - Content area with proper spacing to avoid overlap
9
+ * - Responsive breakpoints following Material Design
10
+ *
11
+ * Material UI Navigation Guidelines:
12
+ * - Bottom Navigation: 3-5 destinations (excess in drawer)
13
+ * - Navigation Rail: 3-7 destinations (excess in drawer)
14
+ * - Navigation Drawer: All items, organized by priority
15
+ *
16
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
17
+ */
18
+
19
+ import React, { useState, useEffect } from 'react';
20
+ import { useQwickApp } from '../contexts/QwickAppContext';
21
+ import Logo from './Logo';
22
+ import ThemeSwitcher from './buttons/ThemeSwitcher';
23
+ import PaletteSwitcher from './buttons/PaletteSwitcher';
24
+ import { RadioButtonUnchecked as DefaultIcon } from '@mui/icons-material';
25
+ import './Scaffold.css';
26
+ import { useSafeLocation, useSafeNavigate } from '../utils/reactUtils';
27
+ import { loggers } from '../utils/logger';
28
+ import type { MenuItem } from './menu/MenuItem';
29
+
30
+ const logger = loggers.scaffold;
31
+
32
+ export interface AppBarProps {
33
+ /** Title to display in the app bar */
34
+ title?: string;
35
+ /** Actions to display on the right side */
36
+ actions?: React.ReactNode;
37
+ /** Whether to show the menu button (for drawer toggle) */
38
+ showMenuButton?: boolean;
39
+ /** Custom logo override */
40
+ logo?: React.ReactNode;
41
+ /** Logo position when in app bar */
42
+ logoPosition?: 'left' | 'center';
43
+ }
44
+
45
+ export interface ScaffoldProps {
46
+ /** Child components (page content) */
47
+ children: React.ReactNode;
48
+ /** Primary navigation items */
49
+ navigationItems: MenuItem[];
50
+ /** App bar configuration */
51
+ appBar?: AppBarProps;
52
+ /** Additional CSS class */
53
+ className?: string;
54
+ /** Whether to show app bar (default: true) */
55
+ showAppBar?: boolean;
56
+ /** Custom app bar height (default: 64px) */
57
+ appBarHeight?: number;
58
+ /** Application name for display purposes */
59
+ appName?: string;
60
+ /** Whether to show theme switcher in app bar (default: false) */
61
+ showThemeSwitcher?: boolean;
62
+ /** Whether to show palette switcher in app bar (default: false) */
63
+ showPaletteSwitcher?: boolean;
64
+ /** Callback when logo is clicked */
65
+ onLogoClick?: () => void;
66
+ }
67
+
68
+ type ScreenSize = 'mobile' | 'tablet' | 'desktop';
69
+
70
+ // Material UI breakpoints
71
+ const BREAKPOINTS = {
72
+ mobile: 600, // < 600px
73
+ tablet: 1024, // 600px - 1024px
74
+ desktop: 1024, // > 1024px
75
+ } as const;
76
+
77
+ const Scaffold: React.FC<ScaffoldProps> = ({
78
+ children,
79
+ navigationItems = [],
80
+ appBar,
81
+ className = '',
82
+ showAppBar = true,
83
+ appBarHeight = 64,
84
+ appName: propAppName,
85
+ showThemeSwitcher = false,
86
+ showPaletteSwitcher = false,
87
+ onLogoClick,
88
+ }) => {
89
+ const [screenSize, setScreenSize] = useState<ScreenSize>('desktop');
90
+ const [isDrawerOpen, setIsDrawerOpen] = useState(false);
91
+ const [isRailExpanded, setIsRailExpanded] = useState(false);
92
+ // Use navigation items directly since Page no longer provides menu items
93
+ const combinedMenuItems = navigationItems;
94
+
95
+ // React Router hooks (if available)
96
+ const location = useSafeLocation();
97
+ const navigate = useSafeNavigate();
98
+ const currentPath = location?.pathname;
99
+
100
+ // Debug logging for navigation
101
+ React.useEffect(() => {
102
+ if (currentPath) {
103
+ logger.debug('Current path changed to:', currentPath);
104
+ }
105
+ }, [currentPath]);
106
+
107
+ const { appName: contextAppName, logo: contextLogo } = useQwickApp();
108
+ const appName = propAppName || contextAppName;
109
+
110
+ // Page context integration is simplified - only used for route detection if needed
111
+ // Page-specific menu items and actions are now handled by header components
112
+
113
+ // Determine current screen size using Material UI breakpoints
114
+ useEffect(() => {
115
+ const updateScreenSize = () => {
116
+ const width = window.innerWidth;
117
+ if (width < BREAKPOINTS.mobile) {
118
+ setScreenSize('mobile');
119
+ } else if (width <= BREAKPOINTS.tablet) {
120
+ setScreenSize('tablet');
121
+ } else {
122
+ setScreenSize('desktop');
123
+ }
124
+ };
125
+
126
+ updateScreenSize();
127
+ window.addEventListener('resize', updateScreenSize);
128
+ return () => window.removeEventListener('resize', updateScreenSize);
129
+ }, []);
130
+
131
+ // Page context now only contains route information
132
+ // Page-specific actions and menu items are handled by header components
133
+
134
+ // Sort items by priority
135
+ const sortedItems = [...combinedMenuItems].sort((a, b) => (a.priority || 999) - (b.priority || 999));
136
+
137
+ // Material UI Guidelines: Split items based on screen size
138
+ const getNavigationSplit = () => {
139
+ switch (screenSize) {
140
+ case 'mobile':
141
+ // Bottom Nav: 3-5 items, rest in drawer
142
+ const bottomNavItems = sortedItems.slice(0, 5);
143
+ const drawerItems = sortedItems.slice(5);
144
+ return { primaryItems: bottomNavItems, drawerItems };
145
+
146
+ case 'tablet':
147
+ // Nav Rail: 3-7 items, rest in drawer
148
+ const railItems = sortedItems.slice(0, 7);
149
+ const railDrawerItems = sortedItems.slice(7);
150
+ return { primaryItems: railItems, drawerItems: railDrawerItems };
151
+
152
+ case 'desktop':
153
+ // App Bar: 5-7 items, rest in drawer
154
+ const appBarItems = sortedItems.slice(0, 7);
155
+ const appBarDrawerItems = sortedItems.slice(7);
156
+ return { primaryItems: appBarItems, drawerItems: appBarDrawerItems };
157
+
158
+ default:
159
+ return { primaryItems: sortedItems, drawerItems: [] };
160
+ }
161
+ };
162
+
163
+ const { primaryItems, drawerItems } = getNavigationSplit();
164
+
165
+ // Enhanced app bar configuration with page integration
166
+ const enhancedAppBar = React.useMemo(() => {
167
+ const baseAppBar = appBar || {};
168
+
169
+ return {
170
+ ...baseAppBar,
171
+ title: baseAppBar.title || appName,
172
+ actions: baseAppBar.actions,
173
+ };
174
+ }, [appBar, appName]);
175
+
176
+ // Get the logo to display
177
+ const displayLogo = enhancedAppBar?.logo || contextLogo || <Logo name={enhancedAppBar?.title || appName} size="small" />;
178
+
179
+ // Toggle drawer
180
+ const toggleDrawer = () => {
181
+ setIsDrawerOpen(!isDrawerOpen);
182
+ };
183
+
184
+ // Toggle rail expansion (tablet only)
185
+ const toggleRail = () => {
186
+ setIsRailExpanded(!isRailExpanded);
187
+ };
188
+
189
+ // Render menu item with proper touch targets (48px minimum)
190
+ const renderMenuItem = (item: MenuItem, variant: 'bottom' | 'rail' | 'appbar' | 'drawer' = 'appbar') => {
191
+ // Determine if this item is active
192
+ const isActiveItem = item.active ||
193
+ (item.route && currentPath === item.route) ||
194
+ (!item.active && !item.route && currentPath && currentPath === `/${item.id}`);
195
+
196
+ // Debug logging for route matching
197
+ if (item.route) {
198
+ logger.debug(`Route matching for ${item.id}: ${currentPath} === ${item.route} = ${isActiveItem}`);
199
+ }
200
+
201
+ // Handle click - automatic navigation if no onClick provided
202
+ const handleClick = () => {
203
+ if (item.disabled) return;
204
+
205
+ // Enhanced same-route detection
206
+ const isSameRoute = isActiveItem && item.route === currentPath;
207
+
208
+ if (isSameRoute) {
209
+ logger.debug(`Navigation prevented: Already on route ${item.route}`);
210
+ return;
211
+ }
212
+
213
+ if (item.onClick) {
214
+ try {
215
+ item.onClick();
216
+ } catch (error) {
217
+ logger.error('Menu item onClick error:', error);
218
+ }
219
+ } else if (item.route) {
220
+ if (navigate === undefined) {
221
+ logger.error('No navigation function available! Cannot navigate to:', item.route);
222
+ return;
223
+ }
224
+ // Robust navigation with comprehensive error handling
225
+ try {
226
+ logger.debug(`Navigating from ${currentPath} to ${item.route}`);
227
+
228
+ // Additional safety check to prevent same-route navigation
229
+ if (currentPath && currentPath === item.route) {
230
+ logger.debug('Final check: Same route detected, skipping navigation');
231
+ return;
232
+ }
233
+
234
+ // Perform navigation with React Router v6
235
+ navigate(item.route);
236
+ } catch (error) {
237
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
238
+ logger.error('Navigation error caught:', error);
239
+ logger.error('Navigation context:', {
240
+ from: currentPath,
241
+ to: item.route,
242
+ isActiveItem,
243
+ itemId: item.id,
244
+ errorMessage
245
+ });
246
+
247
+ // Fallback: use window.location for critical navigation
248
+ if (item.route && item.route !== currentPath) {
249
+ try {
250
+ logger.debug('Attempting fallback navigation using window.location');
251
+ window.location.pathname = item.route;
252
+ } catch (fallbackError) {
253
+ logger.error('Fallback navigation also failed:', fallbackError);
254
+ }
255
+ }
256
+ }
257
+ }
258
+ };
259
+
260
+ // For primary navigation (bottom, rail, appbar), enforce icon requirement
261
+ const needsIcon = variant !== 'drawer';
262
+ const displayIcon = item.icon || (needsIcon ? <DefaultIcon /> : null);
263
+
264
+ const content = (
265
+ <>
266
+ {displayIcon && (
267
+ <span className={`menu-item-icon menu-item-icon-${variant}`}>
268
+ {displayIcon}
269
+ </span>
270
+ )}
271
+ <span className={`menu-item-label menu-item-label-${variant}`}>
272
+ {item.label}
273
+ </span>
274
+ {item.badge && (
275
+ <span className="menu-item-badge">{item.badge}</span>
276
+ )}
277
+ </>
278
+ );
279
+
280
+ const commonProps = {
281
+ className: `menu-item menu-item-${variant} ${isActiveItem ? 'active' : ''} ${item.disabled ? 'disabled' : ''}`,
282
+ 'aria-label': item.label,
283
+ 'aria-current': isActiveItem ? 'page' as const : undefined,
284
+ onClick: item.disabled ? undefined : handleClick,
285
+ };
286
+
287
+ // External links
288
+ if (item.href && !item.disabled) {
289
+ return (
290
+ <a key={item.id} href={item.href} {...commonProps} target="_blank" rel="noopener noreferrer">
291
+ {content}
292
+ </a>
293
+ );
294
+ }
295
+
296
+ // Internal navigation or custom click handlers
297
+ return (
298
+ <button
299
+ key={item.id}
300
+ type="button"
301
+ {...commonProps}
302
+ disabled={Boolean(item.disabled || (isActiveItem && item.route === currentPath))}
303
+ >
304
+ {content}
305
+ </button>
306
+ );
307
+ };
308
+
309
+ // Calculate layout spacing
310
+ const getLayoutSpacing = () => {
311
+ let paddingTop = showAppBar ? appBarHeight : 0;
312
+ let paddingBottom = 0;
313
+ let paddingLeft = 0;
314
+
315
+ if (screenSize === 'mobile') {
316
+ paddingBottom = 80; // Bottom nav height
317
+ } else if (screenSize === 'tablet') {
318
+ paddingLeft = isRailExpanded ? 280 : 80; // Rail width
319
+ }
320
+
321
+ return { paddingTop, paddingBottom, paddingLeft };
322
+ };
323
+
324
+ const layoutSpacing = getLayoutSpacing();
325
+
326
+ const AppLogo = () => {
327
+ return <div
328
+ className="appbar-logo"
329
+ onClick={onLogoClick}
330
+ style={{ cursor: onLogoClick ? 'pointer' : 'default' }}
331
+ >
332
+ {displayLogo}
333
+ </div>
334
+ };
335
+
336
+ return (
337
+ <div className={`app-scaffold ${className}`}>
338
+ {/* App Bar */}
339
+ {showAppBar && (
340
+ <header
341
+ className="app-scaffold-appbar"
342
+ style={{ height: appBarHeight }}
343
+ >
344
+ <div className="appbar-content">
345
+ {/* Left section */}
346
+ <div className="appbar-left">
347
+ {/* Menu button for drawer (when needed) */}
348
+ {(drawerItems.length > 0 || screenSize === 'tablet') && (
349
+ <button
350
+ type="button"
351
+ className="menu-button"
352
+ onClick={screenSize === 'tablet' ? toggleRail : toggleDrawer}
353
+ aria-label={screenSize === 'tablet' ? 'Toggle navigation rail' : 'Open drawer menu'}
354
+ >
355
+ <span className="hamburger-icon">
356
+ <span></span>
357
+ <span></span>
358
+ <span></span>
359
+ </span>
360
+ </button>
361
+ )}
362
+
363
+ {/* Logo/Title */}
364
+ {(!enhancedAppBar?.logoPosition || enhancedAppBar.logoPosition === 'left') && <AppLogo />}
365
+ </div>
366
+
367
+ {/* Center section */}
368
+ <div className="appbar-center">
369
+ {enhancedAppBar?.logoPosition === 'center' && <AppLogo />}
370
+
371
+ {/* Desktop navigation items */}
372
+ {screenSize === 'desktop' && (
373
+ <nav className="appbar-navigation">
374
+ {primaryItems.map(item => renderMenuItem(item, 'appbar'))}
375
+ </nav>
376
+ )}
377
+ </div>
378
+
379
+ {/* Right section */}
380
+ <div className="appbar-right">
381
+ {enhancedAppBar?.actions && (
382
+ <div className="appbar-actions">
383
+ {enhancedAppBar.actions}
384
+ </div>
385
+ )}
386
+ {/* Theme and Palette Switchers */}
387
+ <div className="appbar-theme-controls">
388
+ {showThemeSwitcher && <ThemeSwitcher />}
389
+ {showPaletteSwitcher && <PaletteSwitcher />}
390
+ </div>
391
+ </div>
392
+ </div>
393
+ </header>
394
+ )}
395
+
396
+ {/* Navigation Rail (Tablet) */}
397
+ {screenSize === 'tablet' && (
398
+ <nav className={`navigation-rail ${isRailExpanded ? 'expanded' : 'collapsed'}`}>
399
+ <div className="rail-items">
400
+ {primaryItems.map(item => renderMenuItem(item, 'rail'))}
401
+ </div>
402
+ </nav>
403
+ )}
404
+
405
+ {/* Bottom Navigation (Mobile) */}
406
+ {screenSize === 'mobile' && primaryItems.length > 0 && (
407
+ <nav className="bottom-navigation">
408
+ <div className="bottom-nav-items">
409
+ {primaryItems.map(item => renderMenuItem(item, 'bottom'))}
410
+ </div>
411
+ </nav>
412
+ )}
413
+
414
+ {/* Navigation Drawer (Overflow items) */}
415
+ {isDrawerOpen && drawerItems.length > 0 && (
416
+ <div className="drawer-overlay" onClick={toggleDrawer}>
417
+ <nav className="navigation-drawer" onClick={(e) => e.stopPropagation()}>
418
+ <div className="drawer-header">
419
+ <h3>Menu</h3>
420
+ <button
421
+ type="button"
422
+ className="drawer-close"
423
+ onClick={toggleDrawer}
424
+ aria-label="Close drawer"
425
+ >
426
+ ×
427
+ </button>
428
+ </div>
429
+ <div className="drawer-items">
430
+ {/* Show all primary items in drawer for consistency */}
431
+ <div className="drawer-section">
432
+ <h4>Navigation</h4>
433
+ {primaryItems.map(item => renderMenuItem(item, 'drawer'))}
434
+ </div>
435
+
436
+ {/* Additional items */}
437
+ {drawerItems.length > 0 && (
438
+ <div className="drawer-section">
439
+ <h4>More</h4>
440
+ {drawerItems.map(item => renderMenuItem(item, 'drawer'))}
441
+ </div>
442
+ )}
443
+ </div>
444
+ </nav>
445
+ </div>
446
+ )}
447
+
448
+ {/* Main Content */}
449
+ <main
450
+ className="app-scaffold-content"
451
+ style={{
452
+ paddingTop: `${layoutSpacing.paddingTop}px`,
453
+ paddingBottom: `${layoutSpacing.paddingBottom}px`,
454
+ paddingLeft: `${layoutSpacing.paddingLeft}px`,
455
+ }}
456
+ >
457
+ {children}
458
+ </main>
459
+ </div>
460
+ );
461
+ };
462
+
463
+ export default Scaffold;