@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,255 @@
1
+ /**
2
+ * HTML Transform Utilities Tests
3
+ */
4
+
5
+ import { render } from '@testing-library/react';
6
+ import React from 'react';
7
+ import {
8
+ transformElement,
9
+ transformHtmlToReact,
10
+ stripHeaderFromContent,
11
+ defaultArticleRules,
12
+ defaultMarkdownRules
13
+ } from '../htmlTransform';
14
+
15
+ // Helper function to create DOM elements for testing
16
+ function createElementFromHTML(html: string): Element {
17
+ const parser = new DOMParser();
18
+ const doc = parser.parseFromString(html, 'text/html');
19
+ return doc.body.firstElementChild!;
20
+ }
21
+
22
+ describe('HTML Transform Utilities', () => {
23
+
24
+ describe('stripHeaderFromContent', () => {
25
+ it('removes blog headers from HTML content', () => {
26
+ const html = '<header class="blog-header"><h1>Title</h1></header><p>Content</p>';
27
+ const result = stripHeaderFromContent(html);
28
+ expect(result).not.toContain('<header');
29
+ expect(result).toContain('<p>Content</p>');
30
+ });
31
+
32
+ it('removes standalone h1 elements', () => {
33
+ const html = '<h1>Main Title</h1><p>Content follows</p>';
34
+ const result = stripHeaderFromContent(html);
35
+ expect(result).not.toContain('<h1>Main Title</h1>');
36
+ expect(result).toContain('<p>Content follows</p>');
37
+ });
38
+
39
+ it('preserves content when no headers present', () => {
40
+ const html = '<p>Just content</p><div>More content</div>';
41
+ const result = stripHeaderFromContent(html);
42
+ expect(result).toBe(html);
43
+ });
44
+
45
+ it('handles multiple header types', () => {
46
+ const html = '<header class="blog-header">Header 1</header><div class="blog-header">Header 2</div><p>Content</p>';
47
+ const result = stripHeaderFromContent(html);
48
+ expect(result).not.toContain('Header 1');
49
+ expect(result).not.toContain('Header 2');
50
+ expect(result).toContain('<p>Content</p>');
51
+ });
52
+ });
53
+
54
+ describe('transformElement', () => {
55
+ it('transforms pre+code elements to Code components', () => {
56
+ const element = createElementFromHTML('<pre><code class="language-javascript">console.log("test");</code></pre>');
57
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
58
+
59
+ const { container } = render(<>{result}</>);
60
+ expect(container.textContent).toContain('console.log("test");');
61
+ });
62
+
63
+ it('transforms blog sections to Section components', () => {
64
+ const element = createElementFromHTML('<section class="blog-section"><h2>Section Title</h2><p>Content</p></section>');
65
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
66
+
67
+ const { container } = render(<>{result}</>);
68
+ expect(container.textContent).toContain('Section Title');
69
+ expect(container.textContent).toContain('Content');
70
+ });
71
+
72
+ it('transforms button elements to Button components', () => {
73
+ const element = createElementFromHTML('<button data-variant="contained">Click Me</button>');
74
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
75
+
76
+ const { container } = render(<>{result}</>);
77
+ expect(container.textContent).toContain('Click Me');
78
+ });
79
+
80
+ it('handles standalone code blocks', () => {
81
+ const element = createElementFromHTML('<code>multi\nline\ncode</code>');
82
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
83
+
84
+ const { container } = render(<>{result}</>);
85
+ expect(container.textContent).toContain('multi\nline\ncode');
86
+ });
87
+
88
+ it('preserves inline code in paragraphs', () => {
89
+ const element = createElementFromHTML('<p>Text with <code>inline code</code> here</p>');
90
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
91
+
92
+ const { container } = render(<>{result}</>);
93
+ expect(container.textContent).toContain('inline code');
94
+ });
95
+
96
+ it('handles void elements correctly', () => {
97
+ const element = createElementFromHTML('<img src="test.jpg" alt="test" />');
98
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
99
+
100
+ const { container } = render(<>{result}</>);
101
+ const img = container.querySelector('img');
102
+ expect(img).toHaveAttribute('src', 'test.jpg');
103
+ expect(img).toHaveAttribute('alt', 'test');
104
+ });
105
+
106
+ it('falls back to SafeSpan for unknown elements', () => {
107
+ const element = createElementFromHTML('<div class="unknown">Some content</div>');
108
+ const result = transformElement(element, 'test-key', { rules: defaultArticleRules });
109
+
110
+ const { container } = render(<>{result}</>);
111
+ expect(container.textContent).toContain('Some content');
112
+ });
113
+ });
114
+
115
+ describe('transformHtmlToReact', () => {
116
+ it('transforms entire HTML documents', () => {
117
+ const html = '<h1>Title</h1><p>Paragraph</p><pre><code>code block</code></pre>';
118
+ const components = transformHtmlToReact(html, { rules: defaultArticleRules });
119
+
120
+ expect(components).toHaveLength(3); // h1, p, and code block
121
+
122
+ const { container } = render(<>{components}</>);
123
+ expect(container.textContent).toContain('Title');
124
+ expect(container.textContent).toContain('Paragraph');
125
+ expect(container.textContent).toContain('code block');
126
+ });
127
+
128
+ it('returns empty array for empty HTML', () => {
129
+ const components = transformHtmlToReact('', { rules: defaultArticleRules });
130
+ expect(components).toEqual([]);
131
+ });
132
+
133
+ it('handles whitespace-only HTML', () => {
134
+ const components = transformHtmlToReact(' \n ', { rules: defaultArticleRules });
135
+ expect(components).toEqual([]);
136
+ });
137
+
138
+ it('transforms complex nested structures', () => {
139
+ const html = `
140
+ <div class="container">
141
+ <section class="blog-section">
142
+ <h2>Section</h2>
143
+ <pre><code class="language-python">print("hello")</code></pre>
144
+ </section>
145
+ </div>
146
+ `;
147
+ const components = transformHtmlToReact(html, { rules: defaultArticleRules });
148
+
149
+ const { container } = render(<>{components}</>);
150
+ expect(container.textContent).toContain('Section');
151
+ expect(container.textContent).toContain('print("hello")');
152
+ });
153
+ });
154
+
155
+ describe('defaultArticleRules', () => {
156
+ it('includes pre+code transformation rule', () => {
157
+ const preRule = defaultArticleRules.find(rule => rule.selector === 'pre');
158
+ expect(preRule).toBeDefined();
159
+ });
160
+
161
+ it('includes standalone code transformation rule', () => {
162
+ const codeRule = defaultArticleRules.find(rule => rule.selector === 'code');
163
+ expect(codeRule).toBeDefined();
164
+ });
165
+
166
+ it('includes blog section transformation rule', () => {
167
+ const sectionRule = defaultArticleRules.find(rule => rule.selector === 'section.blog-section');
168
+ expect(sectionRule).toBeDefined();
169
+ });
170
+
171
+ it('includes button transformation rule', () => {
172
+ const buttonRule = defaultArticleRules.find(rule => rule.selector === 'button');
173
+ expect(buttonRule).toBeDefined();
174
+ });
175
+ });
176
+
177
+ describe('defaultMarkdownRules', () => {
178
+ it('includes pre+code transformation rule', () => {
179
+ const preRule = defaultMarkdownRules.find(rule => rule.selector === 'pre');
180
+ expect(preRule).toBeDefined();
181
+ });
182
+
183
+ it('includes code rule that preserves inline code', () => {
184
+ const codeRule = defaultMarkdownRules.find(rule => rule.selector === 'code');
185
+ expect(codeRule).toBeDefined();
186
+
187
+ // Test that inline code returns null (no transformation)
188
+ const element = createElementFromHTML('<code>inline</code>');
189
+ const result = codeRule!.transform(element, 'test');
190
+ expect(result).toBeNull();
191
+ });
192
+
193
+ it('has fewer rules than article rules (more conservative)', () => {
194
+ expect(defaultMarkdownRules.length).toBeLessThan(defaultArticleRules.length);
195
+ });
196
+ });
197
+
198
+ describe('Custom Transform Rules', () => {
199
+ it('applies custom transformation rules', () => {
200
+ const customRules = [{
201
+ selector: 'em',
202
+ transform: (element: Element, key: string) => (
203
+ <strong key={key}>EMPHASIZED: {element.textContent}</strong>
204
+ )
205
+ }];
206
+
207
+ const element = createElementFromHTML('<em>italic text</em>');
208
+ const result = transformElement(element, 'test', { rules: customRules });
209
+
210
+ const { container } = render(<>{result}</>);
211
+ expect(container.textContent).toContain('EMPHASIZED: italic text');
212
+ });
213
+
214
+ it('combines custom rules with default rules', () => {
215
+ const customRules = [...defaultArticleRules, {
216
+ selector: 'span.highlight',
217
+ transform: (element: Element, key: string) => (
218
+ <mark key={key}>{element.textContent}</mark>
219
+ )
220
+ }];
221
+
222
+ const html = '<span class="highlight">highlighted</span><pre><code>code</code></pre>';
223
+ const components = transformHtmlToReact(html, { rules: customRules });
224
+
225
+ const { container } = render(<>{components}</>);
226
+ expect(container.textContent).toContain('highlighted');
227
+ expect(container.textContent).toContain('code');
228
+ });
229
+ });
230
+
231
+ describe('Error Handling', () => {
232
+ it('handles malformed HTML elements', () => {
233
+ const element = createElementFromHTML('<div>unclosed content');
234
+ const result = transformElement(element, 'test', { rules: defaultArticleRules });
235
+
236
+ const { container } = render(<>{result}</>);
237
+ expect(container.textContent).toContain('unclosed content');
238
+ });
239
+
240
+ it('handles elements with missing attributes', () => {
241
+ const element = createElementFromHTML('<button>No attributes</button>');
242
+ const result = transformElement(element, 'test', { rules: defaultArticleRules });
243
+
244
+ const { container } = render(<>{result}</>);
245
+ expect(container.textContent).toContain('No attributes');
246
+ });
247
+
248
+ it('handles empty elements', () => {
249
+ const element = createElementFromHTML('<div></div>');
250
+ const result = transformElement(element, 'test', { rules: defaultArticleRules });
251
+
252
+ expect(result).toBeDefined();
253
+ });
254
+ });
255
+ });
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Breakpoint utilities for QwickApps React Framework
3
+ *
4
+ * Consolidates all breakpoint-related logic and type conversions
5
+ * to ensure consistency across components.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import type { MUIBreakpoint, BreakpointValue, ExtendedBreakpoint } from '../types';
11
+
12
+ /**
13
+ * Standard MUI breakpoint pixel values
14
+ */
15
+ export const MUI_BREAKPOINT_VALUES: Record<MUIBreakpoint, number> = {
16
+ xs: 0,
17
+ sm: 600,
18
+ md: 900,
19
+ lg: 1200,
20
+ xl: 1536,
21
+ };
22
+
23
+ /**
24
+ * Mapping from extended names to MUI breakpoint names
25
+ */
26
+ const EXTENDED_TO_MUI_MAP: Record<ExtendedBreakpoint, MUIBreakpoint> = {
27
+ 'extra-small': 'xs',
28
+ 'small': 'sm',
29
+ 'medium': 'md',
30
+ 'large': 'lg',
31
+ 'extra-large': 'xl',
32
+ };
33
+
34
+ /**
35
+ * Converts any breakpoint value to MUI breakpoint format
36
+ * Handles extended names, MUI names, and false values
37
+ */
38
+ export function mapToMUIBreakpoint(value?: BreakpointValue): MUIBreakpoint | false {
39
+ if (value === false || value === undefined) {
40
+ return false;
41
+ }
42
+
43
+ // Direct MUI breakpoint
44
+ if (value in MUI_BREAKPOINT_VALUES) {
45
+ return value as MUIBreakpoint;
46
+ }
47
+
48
+ // Extended breakpoint name
49
+ if (value in EXTENDED_TO_MUI_MAP) {
50
+ return EXTENDED_TO_MUI_MAP[value as ExtendedBreakpoint];
51
+ }
52
+
53
+ // Default fallback
54
+ return 'lg';
55
+ }
56
+
57
+ /**
58
+ * Gets the pixel value for a breakpoint
59
+ */
60
+ export function getBreakpointPixelValue(breakpoint: MUIBreakpoint | BreakpointValue): number {
61
+ const muiBreakpoint = mapToMUIBreakpoint(breakpoint as BreakpointValue);
62
+ if (muiBreakpoint === false) {
63
+ return Infinity; // No max width
64
+ }
65
+ return MUI_BREAKPOINT_VALUES[muiBreakpoint];
66
+ }
67
+
68
+ /**
69
+ * Type guard to check if a value is a valid MUI breakpoint
70
+ */
71
+ export function isMUIBreakpoint(value: unknown): value is MUIBreakpoint {
72
+ return typeof value === 'string' && value in MUI_BREAKPOINT_VALUES;
73
+ }
74
+
75
+ /**
76
+ * Type guard to check if a value is an extended breakpoint name
77
+ */
78
+ export function isExtendedBreakpoint(value: unknown): value is ExtendedBreakpoint {
79
+ return typeof value === 'string' && value in EXTENDED_TO_MUI_MAP;
80
+ }
81
+
82
+ /**
83
+ * Type guard to check if a value is any valid breakpoint
84
+ */
85
+ export function isBreakpointValue(value: unknown): value is BreakpointValue {
86
+ return value === false || isMUIBreakpoint(value) || isExtendedBreakpoint(value);
87
+ }
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Custom Palette Manager - Create and manage custom color palettes
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+
7
+ /**
8
+ * Saves a custom palette to localStorage
9
+ * @param {Object} palette - Palette object with id, name, colors, etc.
10
+ */
11
+ export const saveCustomPalette = (palette) => {
12
+ const customPalettes = getCustomPalettes();
13
+ const updatedPalettes = customPalettes.filter(p => p.id !== palette.id);
14
+ updatedPalettes.push(palette);
15
+
16
+ localStorage.setItem('qwickapps-custom-palettes', JSON.stringify(updatedPalettes));
17
+
18
+ // Dispatch event to notify components
19
+ window.dispatchEvent(new CustomEvent('custom-palettes-changed', {
20
+ detail: { palettes: updatedPalettes }
21
+ }));
22
+ };
23
+
24
+ /**
25
+ * Gets all custom palettes from localStorage
26
+ * @returns {Array} Array of custom palette objects
27
+ */
28
+ export const getCustomPalettes = () => {
29
+ try {
30
+ const stored = localStorage.getItem('qwickapps-custom-palettes');
31
+ return stored ? JSON.parse(stored) : [];
32
+ } catch (error) {
33
+ console.warn('Failed to load custom palettes:', error);
34
+ return [];
35
+ }
36
+ };
37
+
38
+ /**
39
+ * Deletes a custom palette
40
+ * @param {string} paletteId - ID of the palette to delete
41
+ */
42
+ export const deleteCustomPalette = (paletteId) => {
43
+ const customPalettes = getCustomPalettes();
44
+ const updatedPalettes = customPalettes.filter(p => p.id !== paletteId);
45
+
46
+ localStorage.setItem('qwickapps-custom-palettes', JSON.stringify(updatedPalettes));
47
+
48
+ // Dispatch event to notify components
49
+ window.dispatchEvent(new CustomEvent('custom-palettes-changed', {
50
+ detail: { palettes: updatedPalettes }
51
+ }));
52
+ };
53
+
54
+ /**
55
+ * Exports a palette to a JSON file
56
+ * @param {Object} palette - Palette to export
57
+ */
58
+ export const exportPalette = (palette) => {
59
+ const dataStr = JSON.stringify(palette, null, 2);
60
+ const dataBlob = new Blob([dataStr], { type: 'application/json' });
61
+
62
+ const link = document.createElement('a');
63
+ link.href = URL.createObjectURL(dataBlob);
64
+ link.download = `qwickapps-palette-${palette.id}.json`;
65
+ link.click();
66
+
67
+ URL.revokeObjectURL(link.href);
68
+ };
69
+
70
+ /**
71
+ * Imports a palette from a JSON file
72
+ * @param {File} file - JSON file containing palette data
73
+ * @returns {Promise<Object>} Parsed palette object
74
+ */
75
+ export const importPalette = (file) => {
76
+ return new Promise((resolve, reject) => {
77
+ const reader = new FileReader();
78
+
79
+ reader.onload = (event) => {
80
+ try {
81
+ const palette = JSON.parse(event.target.result);
82
+
83
+ // Basic validation
84
+ if (!palette.id || !palette.name || !palette.primaryColor) {
85
+ reject(new Error('Invalid palette format'));
86
+ return;
87
+ }
88
+
89
+ // Ensure unique ID
90
+ const customPalettes = getCustomPalettes();
91
+ if (customPalettes.find(p => p.id === palette.id)) {
92
+ palette.id = `${palette.id}-${Date.now()}`;
93
+ }
94
+
95
+ resolve(palette);
96
+ } catch (error) {
97
+ reject(new Error('Failed to parse palette file'));
98
+ }
99
+ };
100
+
101
+ reader.onerror = () => reject(new Error('Failed to read file'));
102
+ reader.readAsText(file);
103
+ });
104
+ };
105
+
106
+ /**
107
+ * Creates a new custom palette from current theme colors
108
+ * @param {string} name - Name for the new palette
109
+ * @param {string} description - Description for the palette
110
+ * @returns {Object} New palette object
111
+ */
112
+ export const createPaletteFromCurrentTheme = (name, description) => {
113
+ const root = document.documentElement;
114
+ const style = getComputedStyle(root);
115
+
116
+ // Extract current colors
117
+ const palette = {
118
+ id: `custom-${Date.now()}`,
119
+ name,
120
+ description,
121
+ isCustom: true,
122
+ createdAt: new Date().toISOString(),
123
+ primaryColor: style.getPropertyValue('--palette-primary-main').trim(),
124
+ colors: {
125
+ primary: {
126
+ main: style.getPropertyValue('--palette-primary-main').trim(),
127
+ light: style.getPropertyValue('--palette-primary-light').trim(),
128
+ dark: style.getPropertyValue('--palette-primary-dark').trim(),
129
+ },
130
+ secondary: {
131
+ main: style.getPropertyValue('--palette-secondary-main').trim(),
132
+ light: style.getPropertyValue('--palette-secondary-light').trim(),
133
+ dark: style.getPropertyValue('--palette-secondary-dark').trim(),
134
+ },
135
+ background: {
136
+ main: style.getPropertyValue('--palette-background-main').trim(),
137
+ secondary: style.getPropertyValue('--palette-background-dark').trim(),
138
+ },
139
+ surface: {
140
+ main: style.getPropertyValue('--palette-surface-main').trim(),
141
+ variant: style.getPropertyValue('--palette-surface-variant').trim(),
142
+ elevated: style.getPropertyValue('--palette-surface-elevated').trim(),
143
+ },
144
+ text: {
145
+ primary: style.getPropertyValue('--palette-text-primary').trim(),
146
+ secondary: style.getPropertyValue('--palette-text-secondary').trim(),
147
+ disabled: style.getPropertyValue('--palette-text-disabled').trim(),
148
+ },
149
+ border: {
150
+ main: style.getPropertyValue('--palette-border-main').trim(),
151
+ light: style.getPropertyValue('--palette-border-light').trim(),
152
+ medium: style.getPropertyValue('--palette-border-medium').trim(),
153
+ },
154
+ success: {
155
+ main: style.getPropertyValue('--palette-success-main').trim(),
156
+ light: style.getPropertyValue('--palette-success-light').trim(),
157
+ dark: style.getPropertyValue('--palette-success-dark').trim(),
158
+ },
159
+ error: {
160
+ main: style.getPropertyValue('--palette-error-main').trim(),
161
+ light: style.getPropertyValue('--palette-error-light').trim(),
162
+ dark: style.getPropertyValue('--palette-error-dark').trim(),
163
+ },
164
+ warning: {
165
+ main: style.getPropertyValue('--palette-warning-main').trim(),
166
+ light: style.getPropertyValue('--palette-warning-light').trim(),
167
+ dark: style.getPropertyValue('--palette-warning-dark').trim(),
168
+ },
169
+ info: {
170
+ main: style.getPropertyValue('--palette-info-main').trim(),
171
+ light: style.getPropertyValue('--palette-info-light').trim(),
172
+ dark: style.getPropertyValue('--palette-info-dark').trim(),
173
+ },
174
+ }
175
+ };
176
+
177
+ return palette;
178
+ };
179
+
180
+ /**
181
+ * Applies a custom palette dynamically
182
+ * @param {Object} palette - Custom palette object
183
+ */
184
+ export const applyCustomPalette = (palette) => {
185
+ const root = document.documentElement;
186
+
187
+ // Apply colors to CSS custom properties
188
+ if (palette.colors) {
189
+ const { colors } = palette;
190
+
191
+ // Apply primary colors
192
+ if (colors.primary) {
193
+ root.style.setProperty('--palette-primary-main', colors.primary.main);
194
+ root.style.setProperty('--palette-primary-light', colors.primary.light);
195
+ root.style.setProperty('--palette-primary-dark', colors.primary.dark);
196
+ }
197
+
198
+ // Apply secondary colors
199
+ if (colors.secondary) {
200
+ root.style.setProperty('--palette-secondary-main', colors.secondary.main);
201
+ root.style.setProperty('--palette-secondary-light', colors.secondary.light);
202
+ root.style.setProperty('--palette-secondary-dark', colors.secondary.dark);
203
+ }
204
+
205
+ // Apply background colors
206
+ if (colors.background) {
207
+ root.style.setProperty('--palette-background-main', colors.background.main);
208
+ root.style.setProperty('--palette-background-dark', colors.background.secondary);
209
+ }
210
+
211
+ // Apply other color categories as needed...
212
+ // (This could be expanded to apply all color categories)
213
+ }
214
+ };
@@ -0,0 +1,147 @@
1
+ /**
2
+ * Dimension utilities for QwickApps React Framework
3
+ *
4
+ * Provides standardized dimension value resolution with t-shirt sizing
5
+ * and MUI breakpoint compatibility
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import type { DimensionValue, TShirtSize, MUIBreakpoint } from '../types';
11
+
12
+ // Re-export the type for backward compatibility
13
+ export type { DimensionValue };
14
+ import { MUI_BREAKPOINT_VALUES } from './breakpoints';
15
+
16
+ export type DimensionContext = 'width' | 'height' | 'maxWidth' | 'maxHeight' | 'minWidth' | 'minHeight';
17
+
18
+ /**
19
+ * T-shirt size mappings for different dimension contexts
20
+ */
21
+ const TSHIRT_SIZES: Record<DimensionContext, Record<TShirtSize, number>> = {
22
+ width: {
23
+ tiny: 120,
24
+ small: 200,
25
+ medium: 300,
26
+ large: 400,
27
+ 'x-large': 500,
28
+ huge: 600,
29
+ },
30
+ height: {
31
+ tiny: 200,
32
+ small: 300,
33
+ medium: 400,
34
+ large: 500,
35
+ 'x-large': 600,
36
+ huge: 800,
37
+ },
38
+ maxWidth: {
39
+ tiny: 300,
40
+ small: 600,
41
+ medium: 900,
42
+ large: 1200,
43
+ 'x-large': 1536,
44
+ huge: 1920,
45
+ },
46
+ maxHeight: {
47
+ tiny: 200,
48
+ small: 400,
49
+ medium: 600,
50
+ large: 800,
51
+ 'x-large': 1000,
52
+ huge: 1200,
53
+ },
54
+ minWidth: {
55
+ tiny: 50,
56
+ small: 100,
57
+ medium: 200,
58
+ large: 300,
59
+ 'x-large': 400,
60
+ huge: 500,
61
+ },
62
+ minHeight: {
63
+ tiny: 50,
64
+ small: 100,
65
+ medium: 200,
66
+ large: 300,
67
+ 'x-large': 400,
68
+ huge: 500,
69
+ },
70
+ };
71
+
72
+ /**
73
+ * CSS value pattern for validation
74
+ */
75
+ const CSS_VALUE_PATTERN = /^(\d+(\.\d+)?(px|%|em|rem|vh|vw|fr|ch|ex)|auto|inherit|initial|unset|min-content|max-content|fit-content)$/;
76
+
77
+ /**
78
+ * Resolves a dimension value to a valid CSS value
79
+ */
80
+ export function resolveDimension(
81
+ value: DimensionValue,
82
+ context: DimensionContext = 'width'
83
+ ): string | number | undefined {
84
+ if (value === undefined || value === null) {
85
+ return undefined;
86
+ }
87
+
88
+ // Number values are returned as-is
89
+ if (typeof value === 'number') {
90
+ return value;
91
+ }
92
+
93
+ // Auto and grow are always valid
94
+ if (value === 'auto') {
95
+ return 'auto';
96
+ }
97
+
98
+ if (value === 'grow') {
99
+ return '1'; // Flex grow: 1 for CSS flexbox
100
+ }
101
+
102
+ // Check for t-shirt sizes
103
+ const tshirtSizes = TSHIRT_SIZES[context];
104
+ if (tshirtSizes && value in tshirtSizes) {
105
+ return tshirtSizes[value as TShirtSize];
106
+ }
107
+
108
+ // Check for MUI breakpoint values (for maxWidth/width contexts)
109
+ if ((context === 'maxWidth' || context === 'width') && value in MUI_BREAKPOINT_VALUES) {
110
+ return MUI_BREAKPOINT_VALUES[value as MUIBreakpoint];
111
+ }
112
+
113
+ // Validate CSS string values
114
+ if (typeof value === 'string') {
115
+ if (CSS_VALUE_PATTERN.test(value)) {
116
+ return value;
117
+ } else {
118
+ console.warn(
119
+ `[QwickApps] Invalid CSS dimension value: "${value}". Using as-is but consider using a valid CSS value or t-shirt size.`
120
+ );
121
+ return value;
122
+ }
123
+ }
124
+
125
+ return undefined;
126
+ }
127
+
128
+ /**
129
+ * Resolves multiple dimension props at once
130
+ */
131
+ export function resolveDimensions(props: {
132
+ width?: DimensionValue;
133
+ height?: DimensionValue;
134
+ minWidth?: DimensionValue;
135
+ minHeight?: DimensionValue;
136
+ maxWidth?: DimensionValue;
137
+ maxHeight?: DimensionValue;
138
+ }) {
139
+ return {
140
+ width: resolveDimension(props.width, 'width'),
141
+ height: resolveDimension(props.height, 'height'),
142
+ minWidth: resolveDimension(props.minWidth, 'minWidth'),
143
+ minHeight: resolveDimension(props.minHeight, 'minHeight'),
144
+ maxWidth: resolveDimension(props.maxWidth, 'maxWidth'),
145
+ maxHeight: resolveDimension(props.maxHeight, 'maxHeight'),
146
+ };
147
+ }