@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,156 @@
1
+ /**
2
+ * ContentResolver provides a unified interface to fetch and render content
3
+ * using data providers, template resolvers, and optional caching.
4
+ *
5
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
6
+ */
7
+ import { Logger } from '@qwickapps/logging';
8
+ import { CachedDataProvider, DataResponse, ICacheProvider, IDataProvider, MemoryCacheProvider, Model, MustacheTemplateProvider, SelectOptions } from '@qwickapps/schema';
9
+ import {
10
+ DataProxy,
11
+ ITemplateResolver,
12
+ TemplateProvider,
13
+ TemplateResolverConfig
14
+ } from "../types";
15
+
16
+ /**
17
+ * ContentResolver - Combines data, template, and cache providers
18
+ *
19
+ * This class follows the orchestrator pattern:
20
+ * - Delegates data fetching to IDataProvider
21
+ * - Delegates template resolution to ITemplateResolver
22
+ * - Optionally wraps data provider with ICacheProvider
23
+ * - Creates ContentProxy objects for framework compatibility
24
+ *
25
+ * Usage:
26
+ * ```typescript
27
+ * const resolver = new ContentResolver({
28
+ * dataProvider: new JsonDataProvider({ data: {...} }),
29
+ * templateResolver: new MustacheTemplateResolver(),
30
+ * cacheProvider: new MemoryCacheProvider({ maxSize: 50, defaultTtl: 60000 })
31
+ * });
32
+ *
33
+ * // Or with boolean cacheProvider (uses default MemoryCacheProvider)
34
+ * const resolver = new ContentResolver({
35
+ * dataProvider: new JsonDataProvider({ data: {...} }),
36
+ * cacheProvider: true
37
+ * });
38
+ *
39
+ * // Or no caching
40
+ * const resolver = new ContentResolver({
41
+ * dataProvider: new JsonDataProvider({ data: {...} }),
42
+ * cacheProvider: false // or omit entirely
43
+ * });
44
+ * ```
45
+ */
46
+ export class TemplateResolver implements ITemplateResolver {
47
+ private dataProvider: IDataProvider;
48
+ private templateResolver: TemplateProvider;
49
+ private cacheProvider?: ICacheProvider<any[]>;
50
+ private enableLogging: boolean;
51
+ private log: Logger;
52
+
53
+ constructor(config: TemplateResolverConfig) {
54
+ this.log = new Logger({
55
+ namespace: 'ContentResolver',
56
+ enabled: config.enableLogging || false
57
+ });
58
+
59
+ this.enableLogging = config.enableLogging || false;
60
+ this.templateResolver = config.templateResolver || new MustacheTemplateProvider();
61
+ if (config.cacheProvider === true) {
62
+ const cacheProvider = new MemoryCacheProvider<any[]>({enableLogging: config.enableLogging || false});
63
+ this.dataProvider = new CachedDataProvider(config.dataProvider);
64
+ } else if (config.cacheProvider === false) {
65
+ this.dataProvider = config.dataProvider;
66
+ } else {
67
+ const cacheProvider = new MemoryCacheProvider<any[]>({enableLogging: config.enableLogging || false});
68
+ this.dataProvider = new CachedDataProvider(config.dataProvider);
69
+ }
70
+
71
+
72
+ this.log.debug('ContentResolver initialized', {
73
+ dataProvider: config.dataProvider ? config.dataProvider.constructor.name : 'none',
74
+ templateResolver: this.templateResolver.constructor.name,
75
+ cacheProvider: config.cacheProvider ?
76
+ (config.cacheProvider === true ? 'MemoryCacheProvider(default)' : config.cacheProvider.constructor.name) :
77
+ 'disabled'
78
+ });
79
+ }
80
+
81
+ async get<T extends Model>(slug: string): Promise<DataResponse<T>> {
82
+ return this.dataProvider.get<T>(slug);
83
+ }
84
+
85
+ async select<T extends Model>(schema: string, options?: SelectOptions): Promise<DataResponse<T[]>> {
86
+ return this.dataProvider.select<T>(schema, options);
87
+ }
88
+
89
+ /**
90
+ * Resolve template with lazy context loading
91
+ */
92
+ async resolveTemplate(template: string): Promise < string > {
93
+ this.log.debug(`Resolving template: ${template}`);
94
+
95
+ if(!template || !template.includes('{{')) {
96
+ // No mustache syntax, return as-is
97
+ return template;
98
+ }
99
+
100
+ // Create lazy context proxy
101
+ const context = await this.createLazyContext(template);
102
+
103
+ // Resolve using template resolver
104
+ try {
105
+ const resolved = this.templateResolver.resolve(template, context);
106
+ this.log.debug(`Template resolved: ${template} -> ${resolved}`);
107
+ return resolved;
108
+ } catch (error) {
109
+ this.log.debug(`Template resolution failed: ${error instanceof Error ? error.message : String(error)}`);
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Create lazy loading context for template resolution
116
+ * Only fetches data when accessed by mustache template
117
+ */
118
+ private async createLazyContext(template: string): Promise<any> {
119
+ // Extract field group IDs from template
120
+ const mustachePattern = /\{\{([^}]+)\}\}/g;
121
+ const matches = Array.from(template.matchAll(mustachePattern));
122
+ const fieldGroups = new Set<string>();
123
+
124
+ for (const match of matches) {
125
+ const fullPath = match[1].trim();
126
+ const [fieldGroupId] = fullPath.split('.');
127
+ fieldGroups.add(fieldGroupId);
128
+ }
129
+
130
+ // Fetch all needed data
131
+ const contextData: Record<string, any> = {};
132
+
133
+ for (const fieldGroupId of fieldGroups) {
134
+ try {
135
+ // First try to get it as an array using select
136
+ const arrayData = await this.select(fieldGroupId);
137
+
138
+ if (arrayData.data && arrayData.data.length > 0) {
139
+ // Use first item for template context - use data directly
140
+ contextData[fieldGroupId] = arrayData.data[0];
141
+ } else {
142
+ // Fallback to get single item
143
+ const data = await this.get(fieldGroupId);
144
+ if (data.data) {
145
+ contextData[fieldGroupId] = data.data;
146
+ }
147
+ }
148
+ } catch (error) {
149
+ this.log.error(`Failed to load data for ${fieldGroupId}: ${error instanceof Error ? error.message : String(error)}`);
150
+ // Continue with other field groups
151
+ }
152
+ }
153
+
154
+ return contextData;
155
+ }
156
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Index file for templates module
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export * from './TemplateResolver';
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Quick test to verify console warning functionality
3
+ */
4
+
5
+ import React from 'react';
6
+ import { PaletteProvider, PaletteSwitcher } from '../index';
7
+ import { Typography, Box } from '@mui/material';
8
+
9
+ export default function ConsoleWarningTest() {
10
+ return (
11
+ <Box sx={{ p: 3 }}>
12
+ <Typography variant="h5" gutterBottom>
13
+ Console Warning Test
14
+ </Typography>
15
+ <Typography variant="body1" sx={{ mb: 2 }}>
16
+ Open your browser's developer console to see the warning message for auto-generated storage keys.
17
+ </Typography>
18
+
19
+ {/* This should trigger the console warning */}
20
+ <PaletteProvider>
21
+ <Box sx={{ p: 2, border: '1px solid', borderColor: 'divider', borderRadius: 1 }}>
22
+ <Typography variant="h6" gutterBottom>
23
+ Auto Key (Default - triggers warning)
24
+ </Typography>
25
+ <PaletteSwitcher />
26
+ </Box>
27
+ </PaletteProvider>
28
+ </Box>
29
+ );
30
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Storage Key Strategy Test Component
3
+ * Demonstrates the three different storage strategies
4
+ */
5
+
6
+ import React from 'react';
7
+ import { PaletteProvider, PaletteSwitcher, usePalette } from '../index';
8
+ import { Box, Typography, Paper } from '@mui/material';
9
+
10
+ function PaletteInfo({
11
+ title,
12
+ appId,
13
+ description
14
+ }: {
15
+ title: string;
16
+ appId: string | true | false;
17
+ description: string;
18
+ }) {
19
+ const { currentPalette } = usePalette();
20
+
21
+ // Helper to show what the actual storage key would be
22
+ const getActualKey = () => {
23
+ if (appId === false) return null;
24
+ if (appId === true || appId === undefined) {
25
+ return 'qwickapps-react-framework-palette';
26
+ }
27
+ return `${appId}.palette`;
28
+ };
29
+
30
+ const actualKey = getActualKey();
31
+
32
+ return (
33
+ <Paper sx={{ p: 2, mb: 2 }}>
34
+ <Typography variant="h6" gutterBottom>
35
+ {title}
36
+ </Typography>
37
+ <Typography variant="body2" sx={{ mb: 1, color: 'text.secondary' }}>
38
+ {description}
39
+ </Typography>
40
+ <Typography variant="body2" sx={{ mb: 1 }}>
41
+ Config: <code>{String(appId)}</code>
42
+ </Typography>
43
+ <Typography variant="body2" sx={{ mb: 1 }}>
44
+ Actual Key: <code>{actualKey || 'none (no persistence)'}</code>
45
+ </Typography>
46
+ <Typography variant="body2" sx={{ mb: 2 }}>
47
+ Current Palette: <strong>{currentPalette}</strong>
48
+ </Typography>
49
+ <Typography variant="body2" sx={{ mb: 2 }}>
50
+ localStorage: <code>{actualKey ? (localStorage.getItem(actualKey) || 'null') : 'disabled'}</code>
51
+ </Typography>
52
+ <PaletteSwitcher />
53
+ </Paper>
54
+ );
55
+ }
56
+
57
+ export default function StorageKeyTest() {
58
+ return (
59
+ <Box sx={{ p: 3, maxWidth: 900, margin: '0 auto' }}>
60
+ <Typography variant="h4" gutterBottom>
61
+ Storage Key Strategy Test
62
+ </Typography>
63
+
64
+ <Typography variant="body1" sx={{ mb: 3 }}>
65
+ This test demonstrates the three storage strategies. Change palettes in each section
66
+ and notice the different behaviors. Reload the page to see persistence differences.
67
+ </Typography>
68
+
69
+ <PaletteProvider appId="com.test.explicit-key">
70
+ <PaletteInfo
71
+ title="1. Explicit App ID Strategy"
72
+ appId="com.test.explicit-key"
73
+ description="Uses appId to generate storage key 'com.test.explicit-key.palette'. Recommended for production apps."
74
+ />
75
+ </PaletteProvider>
76
+
77
+ <PaletteProvider appId={true}>
78
+ <PaletteInfo
79
+ title="2. Default Key Strategy"
80
+ appId={true}
81
+ description="Uses default key 'qwickapps-react-framework-palette'. Good for development/demos. Shows console warning."
82
+ />
83
+ </PaletteProvider>
84
+
85
+ <PaletteProvider appId={false}>
86
+ <PaletteInfo
87
+ title="3. No Persistence Strategy"
88
+ appId={false}
89
+ description="Session-only storage, no localStorage persistence. Settings reset on page reload."
90
+ />
91
+ </PaletteProvider>
92
+
93
+ <Paper sx={{ p: 2, mt: 3, backgroundColor: 'var(--palette-surface-variant)' }}>
94
+ <Typography variant="h6" gutterBottom>
95
+ Test Instructions:
96
+ </Typography>
97
+ <Typography variant="body2" component="div">
98
+ <ol style={{ paddingLeft: '20px' }}>
99
+ <li>Select different palettes in each section above</li>
100
+ <li>Notice the three different behaviors: explicit app ID, default key with warning, and no persistence</li>
101
+ <li>Section 1 uses custom appId, Section 2 uses default key with warning, Section 3 has no persistence</li>
102
+ <li>Reload the page - Sections 1 & 2 remember their selections, Section 3 resets</li>
103
+ <li>Open browser DevTools → Application → Local Storage to see the different keys</li>
104
+ <li>Check the console to see the warning for the default key usage</li>
105
+ </ol>
106
+ </Typography>
107
+ </Paper>
108
+ </Box>
109
+ );
110
+ }
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Theme Storage Key Strategy Test Component
3
+ * Demonstrates the three different storage strategies for ThemeProvider
4
+ */
5
+
6
+ import React from 'react';
7
+ import { ThemeProvider, ThemeSwitcher, useTheme } from '../index';
8
+ import { Box, Typography, Paper } from '@mui/material';
9
+
10
+ function ThemeInfo({
11
+ title,
12
+ appId,
13
+ description
14
+ }: {
15
+ title: string;
16
+ appId: string | true | false;
17
+ description: string;
18
+ }) {
19
+ const { currentTheme, actualThemeMode } = useTheme();
20
+
21
+ // Helper to show what the actual storage key would be
22
+ const getActualKey = () => {
23
+ if (appId === false) return null;
24
+ if (appId === true) {
25
+ return 'qwickapps-react-framework-theme';
26
+ }
27
+ return `${appId}.theme`;
28
+ };
29
+
30
+ const actualKey = getActualKey();
31
+
32
+ return (
33
+ <Paper sx={{ p: 2, mb: 2 }}>
34
+ <Typography variant="h6" gutterBottom>
35
+ {title}
36
+ </Typography>
37
+ <Typography variant="body2" sx={{ mb: 1, color: 'text.secondary' }}>
38
+ {description}
39
+ </Typography>
40
+ <Typography variant="body2" sx={{ mb: 1 }}>
41
+ Config: <code>{String(appId)}</code>
42
+ </Typography>
43
+ <Typography variant="body2" sx={{ mb: 1 }}>
44
+ Actual Key: <code>{actualKey || 'none (no persistence)'}</code>
45
+ </Typography>
46
+ <Typography variant="body2" sx={{ mb: 1 }}>
47
+ Theme Mode: <strong>{currentTheme}</strong>
48
+ </Typography>
49
+ <Typography variant="body2" sx={{ mb: 2 }}>
50
+ Actual Theme: <strong>{actualThemeMode}</strong>
51
+ </Typography>
52
+ <Typography variant="body2" sx={{ mb: 2 }}>
53
+ localStorage: <code>{actualKey ? (localStorage.getItem(actualKey) || 'null') : 'disabled'}</code>
54
+ </Typography>
55
+ <ThemeSwitcher />
56
+ </Paper>
57
+ );
58
+ }
59
+
60
+ export default function ThemeStorageKeyTest() {
61
+ return (
62
+ <Box sx={{ p: 3, maxWidth: 900, margin: '0 auto' }}>
63
+ <Typography variant="h4" gutterBottom>
64
+ Theme Storage Key Strategy Test
65
+ </Typography>
66
+
67
+ <Typography variant="body1" sx={{ mb: 3 }}>
68
+ This test demonstrates the three storage strategies for ThemeProvider. Change themes in each section
69
+ and notice the different behaviors. Reload the page to see persistence differences.
70
+ </Typography>
71
+
72
+ <ThemeProvider appId="com.test.explicit-theme">
73
+ <ThemeInfo
74
+ title="1. Explicit App ID Strategy"
75
+ appId="com.test.explicit-theme"
76
+ description="Uses appId to generate storage key 'com.test.explicit-theme.theme'. Recommended for production apps."
77
+ />
78
+ </ThemeProvider>
79
+
80
+ <ThemeProvider>
81
+ <ThemeInfo
82
+ title="2. Default Key Strategy"
83
+ appId={true}
84
+ description="Uses default key 'qwickapps-react-framework-theme'. Good for development/demos. Shows console warning."
85
+ />
86
+ </ThemeProvider>
87
+
88
+ <ThemeProvider appId={false}>
89
+ <ThemeInfo
90
+ title="3. No Persistence Strategy"
91
+ appId={false}
92
+ description="Disables localStorage persistence. Theme resets to 'system' on page reload."
93
+ />
94
+ </ThemeProvider>
95
+
96
+ <Paper sx={{ p: 2, mt: 3, backgroundColor: 'var(--palette-surface-variant)' }}>
97
+ <Typography variant="h6" gutterBottom>
98
+ Test Instructions:
99
+ </Typography>
100
+ <Typography variant="body2" component="div">
101
+ <ol style={{ paddingLeft: '20px' }}>
102
+ <li>Select different themes in each section above</li>
103
+ <li>Notice that sections 1 & 2 save to localStorage with different keys, section 3 doesn't persist</li>
104
+ <li>Section 1 uses custom appId, Section 2 uses default key with warning, Section 3 has no persistence</li>
105
+ <li>Reload the page - sections 1 & 2 remember their selections, section 3 resets to system</li>
106
+ <li>Open browser DevTools → Application → Local Storage to see the different keys</li>
107
+ <li>Check the console to see the warning for the default key usage</li>
108
+ <li>Try switching your OS theme preference to see "system" mode behavior</li>
109
+ </ol>
110
+ </Typography>
111
+ </Paper>
112
+ </Box>
113
+ );
114
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pure cache provider interface - Single Responsibility: Caching only
3
+ */
4
+
5
+ export interface ICacheProvider<T> {
6
+ /** Get cached value by key */
7
+ get(key: string): T | null;
8
+ /** Set cached value with optional TTL */
9
+ set(key: string, value: T, ttl?: number): void;
10
+ /** Clear cache entry or all entries */
11
+ clear(key?: string): void;
12
+ /** Get cache statistics */
13
+ getStats?(): { size: number; maxSize: number; keys: string[]; };
14
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * DataProxy class to enhance Data with nested property access
3
+ * This class wraps a Data object and provides a proxy to allow
4
+ * accessing nested properties using dot notation, e.g., {{company.name}}
5
+ *
6
+ * Copyright (c) 2024 QwickApps.com. All rights reserved.
7
+ */
8
+ import { Data, Field, FieldGroup, Action } from "./DataTypes";
9
+
10
+ /**
11
+ * Enhanced data with nested property access for template resolution
12
+ * Supports deep nested access like {{company.profile.address.city}}
13
+ */
14
+ export class DataProxy implements Data {
15
+ public name!: string;
16
+ public type!: string;
17
+ public title?: string;
18
+ public subtitle?: string;
19
+ public overline?: string;
20
+ public icon?: string;
21
+ public fields?: Field[];
22
+ public fieldGroups?: FieldGroup[];
23
+ public actions?: Action[];
24
+ public repeatable?: boolean;
25
+ public minRows?: number;
26
+ public maxRows?: number;
27
+ public autoCreate?: boolean;
28
+
29
+ private data: Record<string, any>;
30
+
31
+ constructor(content: Data, data: Record<string, any> = {}) {
32
+ Object.assign(this, content);
33
+ this.data = data;
34
+
35
+ // Create proxy to enable nested property access
36
+ return new Proxy(this, {
37
+ get: (target, prop: string | symbol) => {
38
+ // Return existing properties first
39
+ if (prop in target || typeof prop === 'symbol') {
40
+ return target[prop as keyof DataProxy];
41
+ }
42
+
43
+ // Handle nested property access for data
44
+ return this.getNestedValue(String(prop));
45
+ }
46
+ });
47
+ }
48
+
49
+ /**
50
+ * Get nested value from data using dot notation
51
+ * Supports: company.name, user.profile.avatar.url, etc.
52
+ */
53
+ private getNestedValue(path: string): any {
54
+ const keys = path.split('.');
55
+ let current = this.data;
56
+
57
+ for (const key of keys) {
58
+ if (current === null || current === undefined) {
59
+ return undefined;
60
+ }
61
+ current = current[key];
62
+ }
63
+
64
+ return current;
65
+ }
66
+
67
+ /**
68
+ * Set nested value in data using dot notation
69
+ */
70
+ public setNestedValue(path: string, value: any): void {
71
+ const keys = path.split('.');
72
+ const lastKey = keys.pop()!;
73
+ let current = this.data;
74
+
75
+ // Create nested objects as needed
76
+ for (const key of keys) {
77
+ if (!(key in current) || typeof current[key] !== 'object') {
78
+ current[key] = {};
79
+ }
80
+ current = current[key];
81
+ }
82
+
83
+ current[lastKey] = value;
84
+ }
85
+
86
+ /**
87
+ * Get all data including nested structures
88
+ */
89
+ public getData(): Record<string, any> {
90
+ return this.data;
91
+ }
92
+
93
+ /**
94
+ * Update data while preserving nested structure
95
+ */
96
+ public updateData(newData: Record<string, any>): void {
97
+ this.data = { ...this.data, ...newData };
98
+ }
99
+ }