@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,323 @@
1
+ /**
2
+ * HTML Transform Utilities - Shared transformation logic for HTML content
3
+ *
4
+ * Provides configurable HTML element transformation rules to convert
5
+ * standard HTML elements into Framework components.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+
10
+ import { Box, Typography } from '@mui/material';
11
+ import React from 'react';
12
+ import Code from '../components/blocks/Code';
13
+ import Section from '../components/blocks/Section';
14
+ import { Button } from '../components/buttons/Button';
15
+ import SafeSpan from '../components/SafeSpan';
16
+
17
+ export interface TransformRule {
18
+ selector: string;
19
+ transform: (element: Element, key: string) => React.ReactNode;
20
+ }
21
+
22
+ export interface TransformConfig {
23
+ rules: TransformRule[];
24
+ sanitize?: boolean;
25
+ sanitizeOptions?: any;
26
+ fallbackComponent?: (element: Element, key: string) => React.ReactNode;
27
+ }
28
+
29
+ /**
30
+ * Default transformation rules for article/blog content
31
+ */
32
+ export const defaultArticleRules: TransformRule[] = [
33
+ // Pre + Code blocks → Code component with syntax highlighting
34
+ {
35
+ selector: 'pre',
36
+ transform: (element: Element, key: string) => {
37
+ const codeChild = element.querySelector('code');
38
+ if (!codeChild) return null;
39
+
40
+ const language = Array.from(codeChild.classList)
41
+ .find(cls => cls.startsWith('language-'))
42
+ ?.replace('language-', '') || 'text';
43
+
44
+ return (
45
+ <Box key={key} sx={{ my: 1.5 }}>
46
+ <Code
47
+ language={language}
48
+ showCopy={true}
49
+ showLineNumbers={false}
50
+ >
51
+ {codeChild.textContent || ''}
52
+ </Code>
53
+ </Box>
54
+ );
55
+ }
56
+ },
57
+
58
+ // Standalone complex code blocks → Code component
59
+ {
60
+ selector: 'code',
61
+ transform: (element: Element, key: string) => {
62
+ // Skip if inside pre (already handled above)
63
+ if (element.closest('pre')) return null;
64
+
65
+ const text = element.textContent || '';
66
+ const hasMultipleLines = text.includes('\n');
67
+ const hasComplexContent = element.children.length > 0;
68
+
69
+ // Check if code is in an inline context (would violate DOM nesting rules)
70
+ const inlineParents = ['p', 'span', 'a', 'strong', 'em', 'b', 'i', 'u', 'small'];
71
+ const isInInlineContext = inlineParents.some(tag => element.closest(tag));
72
+
73
+ if ((hasMultipleLines || hasComplexContent) && !isInInlineContext) {
74
+ return (
75
+ <Box key={key} sx={{ my: 1.5 }}>
76
+ <Code
77
+ language="text"
78
+ showCopy={true}
79
+ showLineNumbers={false}
80
+ >
81
+ {text}
82
+ </Code>
83
+ </Box>
84
+ );
85
+ }
86
+
87
+ return null; // Let default handling take over
88
+ }
89
+ },
90
+
91
+ // Blog sections → Section component
92
+ {
93
+ selector: 'section.blog-section',
94
+ transform: (element: Element, key: string) => {
95
+ const children = Array.from(element.children);
96
+ const title = element.querySelector('h2')?.textContent || '';
97
+ const content = children.filter(child => child.tagName !== 'H2');
98
+ const spacing = element.getAttribute('data-padding') || 'none';
99
+
100
+ return (
101
+ <Section key={key} padding={spacing as any}>
102
+ <Box sx={{ maxWidth: 'lg', mx: 'auto' }}>
103
+ {title && (
104
+ <Typography variant="h4" component="h2" sx={{ mb: 2 }}>
105
+ {title}
106
+ </Typography>
107
+ )}
108
+ <Box>
109
+ {content.map((child, index) =>
110
+ transformElement(child, `${key}-${index}`, { rules: defaultArticleRules })
111
+ )}
112
+ </Box>
113
+ </Box>
114
+ </Section>
115
+ );
116
+ }
117
+ },
118
+
119
+ // Button elements → Button component
120
+ {
121
+ selector: 'button',
122
+ transform: (element: Element, key: string) => {
123
+ const text = element.textContent || '';
124
+ const variant = element.getAttribute('data-variant') || 'contained';
125
+ const disabled = element.hasAttribute('disabled');
126
+
127
+ return (
128
+ <Button
129
+ key={key}
130
+ variant={variant as any}
131
+ disabled={disabled}
132
+ >
133
+ {text}
134
+ </Button>
135
+ );
136
+ }
137
+ }
138
+ ];
139
+
140
+ /**
141
+ * Transform rules optimized for Markdown content
142
+ */
143
+ export const defaultMarkdownRules: TransformRule[] = [
144
+ // Pre + Code blocks → Code component (same as article)
145
+ {
146
+ selector: 'pre',
147
+ transform: (element: Element, key: string) => {
148
+ const codeChild = element.querySelector('code');
149
+ if (!codeChild) return null;
150
+
151
+ const language = Array.from(codeChild.classList)
152
+ .find(cls => cls.startsWith('language-'))
153
+ ?.replace('language-', '') || 'text';
154
+
155
+ return (
156
+ <Box key={key} sx={{ my: 1.5 }}>
157
+ <Code
158
+ language={language}
159
+ showCopy={true}
160
+ showLineNumbers={false}
161
+ >
162
+ {codeChild.textContent || ''}
163
+ </Code>
164
+ </Box>
165
+ );
166
+ }
167
+ },
168
+
169
+ // Inline code → preserve as regular code element (no transformation)
170
+ {
171
+ selector: 'code',
172
+ transform: (element: Element, key: string) => {
173
+ // Skip if inside pre (already handled above)
174
+ if (element.closest('pre')) return null;
175
+
176
+ // For Markdown, keep inline code as-is
177
+ return null;
178
+ }
179
+ }
180
+ ];
181
+
182
+ /**
183
+ * Default fallback component - renders element as-is with SafeSpan content
184
+ */
185
+ export const defaultFallback = (element: Element, key: string): React.ReactNode => {
186
+ const tagName = element.tagName.toLowerCase();
187
+
188
+ // Check if this is a void element (self-closing)
189
+ const voidElements = new Set([
190
+ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
191
+ 'link', 'meta', 'param', 'source', 'track', 'wbr'
192
+ ]);
193
+
194
+ const props = {
195
+ key,
196
+ ...(element.className ? { className: element.className } : {}),
197
+ ...(element.id ? { id: element.id } : {}),
198
+ ...Object.fromEntries(
199
+ Array.from(element.attributes)
200
+ .filter(attr => !['class', 'id'].includes(attr.name))
201
+ .map(attr => [attr.name, attr.value])
202
+ )
203
+ };
204
+
205
+ if (voidElements.has(tagName)) {
206
+ // Void elements can't have children
207
+ return React.createElement(tagName, props);
208
+ }
209
+
210
+ // Regular elements with content
211
+ return React.createElement(
212
+ tagName,
213
+ props,
214
+ React.createElement(SafeSpan, { html: element.innerHTML })
215
+ );
216
+ };
217
+
218
+ /**
219
+ * Check if an element needs recursive processing
220
+ */
221
+ function needsRecursiveTransform(element: Element, rules: TransformRule[]): boolean {
222
+ const children = Array.from(element.children);
223
+
224
+ return children.some(child => {
225
+ // Check if any rule applies to this child
226
+ const matchingRule = rules.find(rule => child.matches(rule.selector));
227
+ if (matchingRule) return true;
228
+
229
+ // Check if child has transformable descendants
230
+ return rules.some(rule => child.querySelector(rule.selector));
231
+ });
232
+ }
233
+
234
+ /**
235
+ * Transform a single HTML element to React component
236
+ */
237
+ export function transformElement(
238
+ element: Element,
239
+ key: string,
240
+ config: TransformConfig = { rules: defaultArticleRules }
241
+ ): React.ReactNode {
242
+ const { rules, fallbackComponent = defaultFallback } = config;
243
+
244
+ // Try to find a matching rule for this element
245
+ const matchingRule = rules.find(rule => element.matches(rule.selector));
246
+ if (matchingRule) {
247
+ const result = matchingRule.transform(element, key);
248
+ if (result !== null) return result;
249
+ }
250
+
251
+ // Check if this element needs recursive processing
252
+ if (needsRecursiveTransform(element, rules)) {
253
+ const children = Array.from(element.children);
254
+ const tagName = element.tagName.toLowerCase();
255
+
256
+ const transformedChildren = children.map((child, index) =>
257
+ transformElement(child, `${key}-${index}`, config)
258
+ );
259
+
260
+ return React.createElement(
261
+ tagName,
262
+ {
263
+ key,
264
+ ...(element.className ? { className: element.className } : {}),
265
+ ...(element.id ? { id: element.id } : {}),
266
+ ...Object.fromEntries(
267
+ Array.from(element.attributes)
268
+ .filter(attr => !['class', 'id'].includes(attr.name))
269
+ .map(attr => [attr.name, attr.value])
270
+ )
271
+ },
272
+ ...transformedChildren
273
+ );
274
+ }
275
+
276
+ // No transformation needed - use fallback
277
+ return fallbackComponent(element, key);
278
+ }
279
+
280
+ /**
281
+ * Transform HTML string to React components
282
+ */
283
+ export function transformHtmlToReact(
284
+ html: string,
285
+ config: TransformConfig = { rules: defaultArticleRules }
286
+ ): React.ReactNode[] {
287
+ if (!html.trim()) return [];
288
+
289
+ const parser = new DOMParser();
290
+ const doc = parser.parseFromString(html, 'text/html');
291
+
292
+ return Array.from(doc.body.children).map((element, index) =>
293
+ transformElement(element, index.toString(), config)
294
+ );
295
+ }
296
+
297
+ /**
298
+ * Strip header elements from HTML content (for articles)
299
+ */
300
+ export function stripHeaderFromContent(html: string): string {
301
+ const parser = new DOMParser();
302
+ const doc = parser.parseFromString(html, 'text/html');
303
+
304
+ // Remove header elements that are handled by PageBannerHeader
305
+ const elementsToRemove = [
306
+ 'header.blog-header',
307
+ '.blog-header',
308
+ 'header[class*="blog"]',
309
+ ];
310
+
311
+ elementsToRemove.forEach(selector => {
312
+ const elements = doc.querySelectorAll(selector);
313
+ elements.forEach(el => el.remove());
314
+ });
315
+
316
+ // Remove standalone h1 if it's the first child and looks like a title
317
+ const firstChild = doc.body.firstElementChild;
318
+ if (firstChild && firstChild.tagName === 'H1') {
319
+ firstChild.remove();
320
+ }
321
+
322
+ return doc.body.innerHTML;
323
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Utility functions and types for QwickApps React Framework
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export * from './customPaletteManager';
7
+ export * from './dimensions';
8
+ export * from './logger';
9
+ export * from './paletteUtils';
10
+ export * from './persistenceUtils';
11
+ export * from './reactUtils';
12
+ export * from './spacing';
13
+ export * from './themePerformanceMonitor';
14
+ export * from './themeUtils';
15
+
16
+ // Old data binding utilities removed - using new schema system in schemas/
@@ -0,0 +1,28 @@
1
+ /**
2
+ * QwickApps React Framework - Logger Utility
3
+ *
4
+ * Re-exports from @qwickapps/logging with framework-specific loggers
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+
9
+ // Re-export everything from the logging package
10
+ export * from '@qwickapps/logging';
11
+
12
+ // Import createLogger and Logger type to create framework-specific loggers
13
+ import { createLogger, Logger } from '@qwickapps/logging';
14
+
15
+ /**
16
+ * Framework-specific loggers
17
+ */
18
+ export const loggers: Record<string, Logger> = {
19
+ scaffold: createLogger('Scaffold'),
20
+ navigation: createLogger('Navigation'),
21
+ auth: createLogger('Auth'),
22
+ theme: createLogger('Theme'),
23
+ palette: createLogger('Palette'),
24
+ form: createLogger('Form'),
25
+ layout: createLogger('Layout'),
26
+ menu: createLogger('Menu'),
27
+ router: createLogger('Router'),
28
+ };
@@ -0,0 +1,78 @@
1
+ // Palette utilities for QwickApps Theme System
2
+
3
+ import { PaletteConfig } from '../contexts/PaletteContext';
4
+
5
+ /**
6
+ * Available palette options
7
+ */
8
+ export const AVAILABLE_PALETTES: PaletteConfig[] = [
9
+ { id: 'default', name: 'Default', description: 'Classic blue and neutral colors', primaryColor: '#007bff' },
10
+ { id: 'winter', name: 'Winter', description: 'Cool blues and icy whites', primaryColor: '#0077be' },
11
+ { id: 'autumn', name: 'Autumn', description: 'Warm oranges and golden yellows', primaryColor: '#ea580c' },
12
+ { id: 'spring', name: 'Spring', description: 'Fresh greens and soft pinks', primaryColor: '#16a34a' },
13
+ { id: 'ocean', name: 'Ocean', description: 'Deep blues and aqua teals', primaryColor: '#0891b2' }
14
+ ];
15
+
16
+ /**
17
+ * Get the current palette from CSS variables
18
+ */
19
+ export const getCurrentPalette = (): string => {
20
+ const root = document.documentElement;
21
+ return root.getAttribute('data-palette') || 'default';
22
+ };
23
+
24
+ /**
25
+ * Set palette and update CSS variables
26
+ */
27
+ export const setPalette = (palette: string): void => {
28
+ const root = document.documentElement;
29
+ root.setAttribute('data-palette', palette);
30
+
31
+ // Trigger custom event for palette change
32
+ window.dispatchEvent(new CustomEvent('paletteChange', { detail: { palette } }));
33
+ };
34
+
35
+ /**
36
+ * Get palette display name
37
+ */
38
+ export const getPaletteName = (paletteId: string): string => {
39
+ const palette = AVAILABLE_PALETTES.find(p => p.id === paletteId);
40
+ return palette ? palette.name : paletteId;
41
+ };
42
+
43
+ /**
44
+ * Get palette configuration by ID
45
+ */
46
+ export const getPaletteConfig = (paletteId: string): PaletteConfig | undefined => {
47
+ return AVAILABLE_PALETTES.find(p => p.id === paletteId);
48
+ };
49
+
50
+ /**
51
+ * Initialize palette system
52
+ */
53
+ export const initializePalette = (): void => {
54
+ const savedPalette = localStorage.getItem('palette') || 'default';
55
+ setPalette(savedPalette);
56
+ };
57
+
58
+ /**
59
+ * Save palette preference to localStorage
60
+ */
61
+ export const savePalettePreference = (palette: string): void => {
62
+ localStorage.setItem('palette', palette);
63
+ setPalette(palette);
64
+ };
65
+
66
+ /**
67
+ * Get CSS custom property value
68
+ */
69
+ export const getCSSVariable = (property: string): string => {
70
+ return getComputedStyle(document.documentElement).getPropertyValue(property).trim();
71
+ };
72
+
73
+ /**
74
+ * Set CSS custom property value
75
+ */
76
+ export const setCSSVariable = (property: string, value: string): void => {
77
+ document.documentElement.style.setProperty(property, value);
78
+ };
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Persistence utilities for theme and palette preferences
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+
7
+ import type { ThemeMode } from '../contexts/ThemeContext';
8
+
9
+ /**
10
+ * Load user theme preference from localStorage
11
+ */
12
+ export const loadUserThemePreference = (storageKey: string | null): ThemeMode | null => {
13
+ if (!storageKey || typeof window === 'undefined') {
14
+ return null;
15
+ }
16
+
17
+ try {
18
+ const saved = localStorage.getItem(storageKey) as ThemeMode;
19
+ if (saved && ['light', 'dark', 'system'].includes(saved)) {
20
+ return saved;
21
+ }
22
+ } catch (error) {
23
+ console.warn('[persistenceUtils] Theme localStorage read failed:', error);
24
+ }
25
+
26
+ return null;
27
+ };
28
+
29
+ /**
30
+ * Save user theme preference to localStorage
31
+ */
32
+ export const saveUserThemePreference = (storageKey: string | null, theme: ThemeMode): void => {
33
+ if (!storageKey || typeof window === 'undefined') {
34
+ return;
35
+ }
36
+
37
+ try {
38
+ localStorage.setItem(storageKey, theme);
39
+ } catch (error) {
40
+ console.warn('[persistenceUtils] Theme localStorage write failed:', error);
41
+ }
42
+ };
43
+
44
+ /**
45
+ * Clear user theme preference from localStorage
46
+ */
47
+ export const clearUserThemePreference = (storageKey: string | null): void => {
48
+ if (!storageKey || typeof window === 'undefined') {
49
+ return;
50
+ }
51
+
52
+ try {
53
+ localStorage.removeItem(storageKey);
54
+ } catch (error) {
55
+ console.warn('[persistenceUtils] Theme localStorage clear failed:', error);
56
+ }
57
+ };
58
+
59
+ /**
60
+ * Load user palette preference from localStorage
61
+ */
62
+ export const loadUserPalettePreference = (storageKey: string | null, availablePalettes: string[]): string | null => {
63
+ if (!storageKey || typeof window === 'undefined') {
64
+ return null;
65
+ }
66
+
67
+ try {
68
+ const saved = localStorage.getItem(storageKey);
69
+ if (saved && availablePalettes.includes(saved)) {
70
+ return saved;
71
+ }
72
+ } catch (error) {
73
+ console.warn('[persistenceUtils] Palette localStorage read failed:', error);
74
+ }
75
+
76
+ return null;
77
+ };
78
+
79
+ /**
80
+ * Save user palette preference to localStorage
81
+ */
82
+ export const saveUserPalettePreference = (storageKey: string | null, palette: string): void => {
83
+ if (!storageKey || typeof window === 'undefined') {
84
+ return;
85
+ }
86
+
87
+ try {
88
+ localStorage.setItem(storageKey, palette);
89
+ } catch (error) {
90
+ console.warn('[persistenceUtils] Palette localStorage write failed:', error);
91
+ }
92
+ };
93
+
94
+ /**
95
+ * Clear user palette preference from localStorage
96
+ */
97
+ export const clearUserPalettePreference = (storageKey: string | null): void => {
98
+ if (!storageKey || typeof window === 'undefined') {
99
+ return;
100
+ }
101
+
102
+ try {
103
+ localStorage.removeItem(storageKey);
104
+ } catch (error) {
105
+ console.warn('[persistenceUtils] Palette localStorage clear failed:', error);
106
+ }
107
+ };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * QwickApps React Framework - React Utilities
3
+ * This module provides utility functions for React components in the QwickApps React Framework.
4
+ *
5
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
6
+ */
7
+
8
+ import { useLocation, useNavigate } from 'react-router-dom';
9
+
10
+ /** Location type for React Router */
11
+ type LocationType = { pathname: string, search: string, hash: string };
12
+
13
+ /**
14
+ * Custom hook to get the current location
15
+ * @returns {object | undefined} - The location object if React Router is available, otherwise undefined
16
+ */
17
+ export const useSafeLocation = (): LocationType | undefined => {
18
+ try {
19
+ return useLocation();
20
+ } catch (error) {
21
+ console.warn('React Router context not available:', error);
22
+ return undefined;
23
+ }
24
+ };
25
+
26
+ /**
27
+ * Custom hook to get the navigate function
28
+ * @returns {Function | undefined} - The navigate function if React Router is available, otherwise undefined
29
+ */
30
+ export const useSafeNavigate = (): Function | undefined => {
31
+ try {
32
+ return useNavigate();
33
+ } catch (error) {
34
+ console.warn('React Router context not available:', error);
35
+ return undefined;
36
+ }
37
+ };