@qwickapps/react-framework 1.3.5 → 1.4.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 (320) hide show
  1. package/README.md +1681 -2
  2. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts +66 -0
  3. package/dist/__tests__/schemas/transformers/MockSerializableComponent.d.ts.map +1 -0
  4. package/dist/components/ErrorBoundary.d.ts +7 -0
  5. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  6. package/dist/components/Html.d.ts +28 -18
  7. package/dist/components/Html.d.ts.map +1 -1
  8. package/dist/components/Logo.d.ts +12 -35
  9. package/dist/components/Logo.d.ts.map +1 -1
  10. package/dist/components/Markdown.d.ts +18 -13
  11. package/dist/components/Markdown.d.ts.map +1 -1
  12. package/dist/components/QwickApp.d.ts +16 -3
  13. package/dist/components/QwickApp.d.ts.map +1 -1
  14. package/dist/components/QwickIcon.d.ts +23 -0
  15. package/dist/components/QwickIcon.d.ts.map +1 -0
  16. package/dist/components/SafeSpan.d.ts +12 -5
  17. package/dist/components/SafeSpan.d.ts.map +1 -1
  18. package/dist/components/Scaffold.d.ts.map +1 -1
  19. package/dist/components/base/ModelView.d.ts +101 -0
  20. package/dist/components/base/ModelView.d.ts.map +1 -0
  21. package/dist/components/base/index.d.ts +11 -0
  22. package/dist/components/base/index.d.ts.map +1 -0
  23. package/dist/components/blocks/Article.d.ts +12 -2
  24. package/dist/components/blocks/Article.d.ts.map +1 -1
  25. package/dist/components/blocks/Code.d.ts +13 -2
  26. package/dist/components/blocks/Code.d.ts.map +1 -1
  27. package/dist/components/blocks/CoverImageHeader.d.ts.map +1 -1
  28. package/dist/components/blocks/FeatureCard.d.ts.map +1 -1
  29. package/dist/components/blocks/FeatureGrid.d.ts.map +1 -1
  30. package/dist/components/blocks/Footer.d.ts.map +1 -1
  31. package/dist/components/blocks/HeroBlock.d.ts +27 -13
  32. package/dist/components/blocks/HeroBlock.d.ts.map +1 -1
  33. package/dist/components/blocks/Image.d.ts +41 -0
  34. package/dist/components/blocks/Image.d.ts.map +1 -0
  35. package/dist/components/blocks/PageBannerHeader.d.ts.map +1 -1
  36. package/dist/components/blocks/Section.d.ts +16 -2
  37. package/dist/components/blocks/Section.d.ts.map +1 -1
  38. package/dist/components/blocks/Text.d.ts +41 -0
  39. package/dist/components/blocks/Text.d.ts.map +1 -0
  40. package/dist/components/blocks/index.d.ts +4 -0
  41. package/dist/components/blocks/index.d.ts.map +1 -1
  42. package/dist/components/buttons/Button.d.ts +23 -7
  43. package/dist/components/buttons/Button.d.ts.map +1 -1
  44. package/dist/components/forms/FormBlock.d.ts +19 -13
  45. package/dist/components/forms/FormBlock.d.ts.map +1 -1
  46. package/dist/components/index.d.ts +4 -0
  47. package/dist/components/index.d.ts.map +1 -1
  48. package/dist/components/input/ChoiceInputField.d.ts +17 -11
  49. package/dist/components/input/ChoiceInputField.d.ts.map +1 -1
  50. package/dist/components/input/HtmlInputField.d.ts +17 -11
  51. package/dist/components/input/HtmlInputField.d.ts.map +1 -1
  52. package/dist/components/input/SelectInputField.d.ts +16 -10
  53. package/dist/components/input/SelectInputField.d.ts.map +1 -1
  54. package/dist/components/input/SwitchInputField.d.ts +16 -10
  55. package/dist/components/input/SwitchInputField.d.ts.map +1 -1
  56. package/dist/components/input/TextField.d.ts.map +1 -1
  57. package/dist/components/input/TextInputField.d.ts +16 -11
  58. package/dist/components/input/TextInputField.d.ts.map +1 -1
  59. package/dist/components/layout/GridCell.d.ts +23 -6
  60. package/dist/components/layout/GridCell.d.ts.map +1 -1
  61. package/dist/components/layout/GridLayout.d.ts +24 -23
  62. package/dist/components/layout/GridLayout.d.ts.map +1 -1
  63. package/dist/components/pages/FormPage.d.ts.map +1 -1
  64. package/dist/components/pages/Page.d.ts +49 -87
  65. package/dist/components/pages/Page.d.ts.map +1 -1
  66. package/dist/components/pages/index.d.ts +2 -2
  67. package/dist/components/pages/index.d.ts.map +1 -1
  68. package/dist/config/AppConfig.d.ts +49 -0
  69. package/dist/config/AppConfig.d.ts.map +1 -0
  70. package/dist/config/AppConfigBuilder.d.ts +75 -0
  71. package/dist/config/AppConfigBuilder.d.ts.map +1 -0
  72. package/dist/config/index.d.ts +13 -0
  73. package/dist/config/index.d.ts.map +1 -0
  74. package/dist/config/types.d.ts +130 -0
  75. package/dist/config/types.d.ts.map +1 -0
  76. package/dist/config.d.ts +15 -0
  77. package/dist/config.d.ts.map +1 -0
  78. package/dist/config.esm.js +451 -0
  79. package/dist/config.js +455 -0
  80. package/dist/contexts/PrintModeContext.d.ts +27 -0
  81. package/dist/contexts/PrintModeContext.d.ts.map +1 -0
  82. package/dist/contexts/QwickAppContext.d.ts +2 -2
  83. package/dist/contexts/QwickAppContext.d.ts.map +1 -1
  84. package/dist/contexts/index.d.ts +2 -0
  85. package/dist/contexts/index.d.ts.map +1 -1
  86. package/dist/hooks/index.d.ts +2 -0
  87. package/dist/hooks/index.d.ts.map +1 -1
  88. package/dist/hooks/usePrintMode.d.ts +39 -0
  89. package/dist/hooks/usePrintMode.d.ts.map +1 -0
  90. package/dist/index.css +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.esm.css +1 -1
  94. package/dist/index.esm.js +10951 -6238
  95. package/dist/index.js +11014 -6287
  96. package/dist/schemas/CodeSchema.d.ts +2 -1
  97. package/dist/schemas/CodeSchema.d.ts.map +1 -1
  98. package/dist/schemas/CollapsibleLayoutSchema.d.ts +2 -1
  99. package/dist/schemas/CollapsibleLayoutSchema.d.ts.map +1 -1
  100. package/dist/schemas/ContentSchema.d.ts +2 -1
  101. package/dist/schemas/ContentSchema.d.ts.map +1 -1
  102. package/dist/schemas/GridCellSchema.d.ts +25 -0
  103. package/dist/schemas/GridCellSchema.d.ts.map +1 -0
  104. package/dist/schemas/GridLayoutSchema.d.ts +23 -0
  105. package/dist/schemas/GridLayoutSchema.d.ts.map +1 -0
  106. package/dist/schemas/HtmlSchema.d.ts +14 -0
  107. package/dist/schemas/HtmlSchema.d.ts.map +1 -0
  108. package/dist/schemas/ImageSchema.d.ts +32 -0
  109. package/dist/schemas/ImageSchema.d.ts.map +1 -0
  110. package/dist/schemas/LogoSchema.d.ts +35 -0
  111. package/dist/schemas/LogoSchema.d.ts.map +1 -0
  112. package/dist/schemas/MarkdownSchema.d.ts +14 -0
  113. package/dist/schemas/MarkdownSchema.d.ts.map +1 -0
  114. package/dist/schemas/PageTemplateSchema.d.ts +31 -0
  115. package/dist/schemas/PageTemplateSchema.d.ts.map +1 -0
  116. package/dist/schemas/PrintConfigSchema.d.ts +31 -0
  117. package/dist/schemas/PrintConfigSchema.d.ts.map +1 -0
  118. package/dist/schemas/SectionSchema.d.ts +2 -1
  119. package/dist/schemas/SectionSchema.d.ts.map +1 -1
  120. package/dist/schemas/TextSchema.d.ts +37 -0
  121. package/dist/schemas/TextSchema.d.ts.map +1 -0
  122. package/dist/schemas/ViewModelSchema.d.ts +23 -0
  123. package/dist/schemas/ViewModelSchema.d.ts.map +1 -0
  124. package/dist/schemas/index.d.ts +15 -1
  125. package/dist/schemas/index.d.ts.map +1 -1
  126. package/dist/schemas/transformers/ComponentTransformer.d.ts +116 -0
  127. package/dist/schemas/transformers/ComponentTransformer.d.ts.map +1 -0
  128. package/dist/schemas/transformers/ReactNodeTransformer.d.ts +53 -0
  129. package/dist/schemas/transformers/ReactNodeTransformer.d.ts.map +1 -0
  130. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts +66 -0
  131. package/dist/schemas/transformers/__tests__/MockSerializableComponent.d.ts.map +1 -0
  132. package/dist/schemas/transformers/registry.d.ts +15 -0
  133. package/dist/schemas/transformers/registry.d.ts.map +1 -0
  134. package/dist/schemas/types/Serializable.d.ts +46 -0
  135. package/dist/schemas/types/Serializable.d.ts.map +1 -0
  136. package/dist/utils/htmlTransform.d.ts.map +1 -1
  137. package/dist/utils/reactUtils.d.ts +12 -3
  138. package/dist/utils/reactUtils.d.ts.map +1 -1
  139. package/package.json +17 -3
  140. package/src/{components/__tests__ → __tests__/components}/AccessibilityProvider.test.tsx +1 -1
  141. package/src/{components/__tests__ → __tests__/components}/Article.test.tsx +1 -1
  142. package/src/{components/__tests__ → __tests__/components}/Breadcrumbs.test.tsx +1 -1
  143. package/src/{components/__tests__ → __tests__/components}/Button.test.tsx +1 -1
  144. package/src/{components/__tests__ → __tests__/components}/CardListGrid.test.tsx +2 -2
  145. package/src/{components/__tests__ → __tests__/components}/ChoiceInputField.test.tsx +1 -1
  146. package/src/{components/__tests__ → __tests__/components}/Code.test.tsx +1 -1
  147. package/src/{components/__tests__ → __tests__/components}/Content.integration.test.tsx +1 -1
  148. package/src/{components/__tests__ → __tests__/components}/Content.test.tsx +1 -1
  149. package/src/{components/__tests__ → __tests__/components}/CoverImageHeader.test.tsx +2 -2
  150. package/src/{components/__tests__ → __tests__/components}/ErrorBoundary.test.tsx +1 -1
  151. package/src/{components/__tests__ → __tests__/components}/FeatureCard.integration.test.tsx +2 -2
  152. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.integration.test.tsx +2 -2
  153. package/src/{components/__tests__ → __tests__/components}/FeatureGrid.test.tsx +2 -2
  154. package/src/{components/__tests__ → __tests__/components}/Footer.test.tsx +4 -4
  155. package/src/{components/__tests__ → __tests__/components}/FormBlock.test.tsx +1 -1
  156. package/src/{components/__tests__ → __tests__/components}/HeroBlock.integration.test.tsx +2 -2
  157. package/src/{components/__tests__ → __tests__/components}/HeroBlock.test.tsx +233 -7
  158. package/src/{components/__tests__ → __tests__/components}/Html.test.tsx +11 -2
  159. package/src/{components/__tests__ → __tests__/components}/HtmlInputField.test.tsx +3 -3
  160. package/src/__tests__/components/Logo.test.js +3 -3
  161. package/src/{components/__tests__ → __tests__/components}/Markdown.test.tsx +1 -1
  162. package/src/{components/__tests__ → __tests__/components}/PageBannerHeader.test.tsx +3 -3
  163. package/src/{components/__tests__ → __tests__/components}/PaletteSwitcher.test.tsx +3 -3
  164. package/src/{components/__tests__ → __tests__/components}/ProductCard.test.tsx +4 -4
  165. package/src/{components/__tests__ → __tests__/components}/SafeSpan.integration.test.tsx +2 -2
  166. package/src/{components/__tests__ → __tests__/components}/SafeSpan.simple.test.tsx +1 -1
  167. package/src/{components/__tests__ → __tests__/components}/SafeSpan.test.tsx +1 -1
  168. package/src/{components/__tests__ → __tests__/components}/Section.integration.test.tsx +1 -1
  169. package/src/{components/__tests__ → __tests__/components}/Section.test.tsx +1 -1
  170. package/src/{components/__tests__ → __tests__/components}/SelectInputField.test.tsx +1 -1
  171. package/src/{components/__tests__ → __tests__/components}/TextInputField.test.tsx +3 -3
  172. package/src/{components/__tests__ → __tests__/components}/ThemeSwitcher.test.tsx +3 -3
  173. package/src/__tests__/components/base/ModelView.test.tsx +220 -0
  174. package/src/__tests__/components/blocks/Code.performance.test.tsx +625 -0
  175. package/src/__tests__/components/blocks/Code.serialization.test.tsx +507 -0
  176. package/src/__tests__/components/blocks/HeroBlock.serialization.test.tsx +414 -0
  177. package/src/__tests__/components/blocks/Image.serialization.test.tsx +257 -0
  178. package/src/__tests__/components/blocks/Section.serialization.test.tsx +553 -0
  179. package/src/__tests__/components/blocks/Text.performance.test.tsx +442 -0
  180. package/src/__tests__/components/blocks/Text.serialization.test.tsx +491 -0
  181. package/src/__tests__/components/buttons/Button.serialization.test.tsx +443 -0
  182. package/src/__tests__/components/input/FormComponents.serialization.test.tsx +482 -0
  183. package/src/__tests__/components/input/SelectInputField.serialization.test.tsx +439 -0
  184. package/src/__tests__/components/input/TextInputField.serialization.test.tsx +359 -0
  185. package/src/{components/layout/CollapsibleLayout/__tests__ → __tests__/components/layout}/CollapsibleLayout.test.tsx +4 -4
  186. package/src/__tests__/components/layout/GridCell.serialization.test.tsx +403 -0
  187. package/src/__tests__/components/layout/GridLayout.serialization.test.tsx +311 -0
  188. package/src/__tests__/hooks/usePrintMode.test.ts +89 -0
  189. package/src/__tests__/schemas/PageTemplateSchema.test.ts +161 -0
  190. package/src/__tests__/schemas/PrintConfigSchema.test.ts +127 -0
  191. package/src/__tests__/schemas/ViewModelSchema.test.ts +80 -0
  192. package/src/__tests__/schemas/transformers/ComponentSerializationPatterns.test.tsx +602 -0
  193. package/src/__tests__/schemas/transformers/ComponentTransformer.htmlPatterns.test.ts +301 -0
  194. package/src/__tests__/schemas/transformers/ComponentTransformer.test.ts +521 -0
  195. package/src/__tests__/schemas/transformers/CrossBrowserCompatibility.test.ts +586 -0
  196. package/src/__tests__/schemas/transformers/MockSerializableComponent.ts +103 -0
  197. package/src/__tests__/schemas/transformers/RealWorldScenarios.test.tsx +1165 -0
  198. package/src/__tests__/schemas/transformers/SerializationErrorHandling.test.ts +602 -0
  199. package/src/__tests__/schemas/transformers/SerializationIntegration.test.tsx +691 -0
  200. package/src/__tests__/schemas/transformers/SerializationPerformance.test.ts +460 -0
  201. package/src/__tests__/schemas/transformers/TestAutomation.test.ts +597 -0
  202. package/src/{utils/__tests__ → __tests__/utils}/nested-dom-fix.test.tsx +1 -1
  203. package/src/components/ErrorBoundary.tsx +8 -8
  204. package/src/components/Html.tsx +147 -44
  205. package/src/components/Logo.tsx +198 -100
  206. package/src/components/Markdown.tsx +125 -16
  207. package/src/components/QwickApp.tsx +64 -31
  208. package/src/components/QwickIcon.tsx +59 -0
  209. package/src/components/SafeSpan.tsx +65 -10
  210. package/src/components/Scaffold.tsx +2 -8
  211. package/src/components/base/ModelView.tsx +199 -0
  212. package/src/components/base/index.ts +11 -0
  213. package/src/components/blocks/Article.tsx +57 -18
  214. package/src/components/blocks/Code.md +529 -0
  215. package/src/components/blocks/Code.tsx +102 -15
  216. package/src/components/blocks/CoverImageHeader.tsx +9 -4
  217. package/src/components/blocks/FeatureCard.tsx +1 -2
  218. package/src/components/blocks/FeatureGrid.tsx +19 -1
  219. package/src/components/blocks/Footer.tsx +13 -1
  220. package/src/components/blocks/HeroBlock.tsx +87 -20
  221. package/src/components/blocks/Image.tsx +395 -0
  222. package/src/components/blocks/PageBannerHeader.tsx +14 -12
  223. package/src/components/blocks/ProductCard.tsx +1 -1
  224. package/src/components/blocks/Section.tsx +113 -8
  225. package/src/components/blocks/Text.tsx +285 -0
  226. package/src/components/blocks/index.ts +4 -0
  227. package/src/components/buttons/Button.tsx +184 -15
  228. package/src/components/forms/FormBlock.tsx +70 -17
  229. package/src/components/index.ts +5 -0
  230. package/src/components/input/ChoiceInputField.tsx +48 -18
  231. package/src/components/input/HtmlInputField.tsx +48 -18
  232. package/src/components/input/SelectInputField.tsx +48 -16
  233. package/src/components/input/SwitchInputField.tsx +48 -17
  234. package/src/components/input/TextField.tsx +41 -1
  235. package/src/components/input/TextInputField.tsx +52 -18
  236. package/src/components/layout/GridCell.tsx +118 -9
  237. package/src/components/layout/GridLayout.tsx +125 -24
  238. package/src/components/pages/FormPage.tsx +0 -1
  239. package/src/components/pages/Page.css +304 -332
  240. package/src/components/pages/Page.tsx +307 -255
  241. package/src/components/pages/index.ts +2 -2
  242. package/src/config/AppConfig.ts +133 -0
  243. package/src/config/AppConfigBuilder.ts +421 -0
  244. package/src/config/__tests__/AppConfig.test.ts +385 -0
  245. package/src/config/__tests__/AppConfigBuilder.test.ts +432 -0
  246. package/src/config/index.ts +24 -0
  247. package/src/config/types.ts +170 -0
  248. package/src/config.ts +25 -0
  249. package/src/contexts/PrintModeContext.tsx +332 -0
  250. package/src/contexts/QwickAppContext.tsx +2 -2
  251. package/src/contexts/index.ts +2 -0
  252. package/src/hooks/index.ts +5 -1
  253. package/src/hooks/usePrintMode.ts +73 -0
  254. package/src/index.ts +3 -0
  255. package/src/schemas/CodeSchema.ts +3 -3
  256. package/src/schemas/CollapsibleLayoutSchema.ts +2 -1
  257. package/src/schemas/ContentSchema.ts +2 -1
  258. package/src/schemas/GridCellSchema.ts +164 -0
  259. package/src/schemas/GridLayoutSchema.ts +133 -0
  260. package/src/schemas/HtmlSchema.ts +47 -0
  261. package/src/schemas/ImageSchema.ts +235 -0
  262. package/src/schemas/LogoSchema.ts +241 -0
  263. package/src/schemas/MarkdownSchema.ts +47 -0
  264. package/src/schemas/PageTemplateSchema.ts +186 -0
  265. package/src/schemas/PrintConfigSchema.ts +207 -0
  266. package/src/schemas/README.md +661 -0
  267. package/src/schemas/SectionSchema.ts +2 -1
  268. package/src/schemas/TextSchema.ts +329 -0
  269. package/src/schemas/ViewModelSchema.ts +115 -0
  270. package/src/schemas/index.ts +21 -2
  271. package/src/schemas/transformers/ComponentTransformer.ts +403 -0
  272. package/src/schemas/transformers/ReactNodeTransformer.ts +236 -0
  273. package/src/schemas/transformers/registry.ts +72 -0
  274. package/src/schemas/types/Serializable.ts +51 -0
  275. package/src/stories/AccessibilityProvider.stories.tsx +253 -253
  276. package/src/stories/Article.stories.tsx +433 -433
  277. package/src/stories/Button.stories.tsx +1 -1
  278. package/src/stories/CardListGrid.stories.tsx +451 -451
  279. package/src/stories/ChoiceInputField.stories.tsx +503 -503
  280. package/src/stories/Code.stories.tsx +1 -1
  281. package/src/stories/CollapsibleLayout.stories.tsx +1414 -1414
  282. package/src/stories/Content.stories.tsx +393 -393
  283. package/src/stories/CoverImageHeader.stories.tsx +701 -701
  284. package/src/stories/DataBinding.advanced.stories.tsx +432 -432
  285. package/src/stories/DataProvider.stories.tsx +1192 -1192
  286. package/src/stories/FeatureCard.stories.tsx +557 -557
  287. package/src/stories/FeatureGrid.stories.tsx +594 -594
  288. package/src/stories/Footer.stories.tsx +640 -640
  289. package/src/stories/FormBlock.stories.tsx +760 -760
  290. package/src/stories/FormComponents.stories.tsx +349 -541
  291. package/src/stories/GridCell.stories.tsx +417 -0
  292. package/src/stories/GridLayout.stories.tsx +353 -0
  293. package/src/stories/HeroBlock.stories.tsx +862 -373
  294. package/src/stories/HtmlInputField.stories.tsx +474 -474
  295. package/src/stories/Image.stories.tsx +819 -0
  296. package/src/stories/Introduction.stories.tsx +667 -667
  297. package/src/stories/LayoutBlocks.stories.tsx +324 -324
  298. package/src/stories/Logo.stories.tsx +165 -6
  299. package/src/stories/Markdown.stories.tsx +137 -137
  300. package/src/stories/ModelView.stories.tsx +477 -0
  301. package/src/stories/Page.stories.tsx +688 -688
  302. package/src/stories/PageBannerHeader.stories.tsx +864 -864
  303. package/src/stories/PaletteSwitcher.stories.tsx +119 -119
  304. package/src/stories/ProductCard.stories.tsx +424 -424
  305. package/src/stories/QwickApp.stories.tsx +368 -368
  306. package/src/stories/ResponsiveMenu.stories.tsx +249 -249
  307. package/src/stories/SafeSpan.stories.tsx +531 -531
  308. package/src/stories/Section.stories.tsx +90 -2
  309. package/src/stories/SelectInputField.stories.tsx +524 -524
  310. package/src/stories/Text.stories.tsx +560 -0
  311. package/src/stories/TextInputField.stories.tsx +443 -443
  312. package/src/stories/ThemeSwitcher.stories.tsx +123 -123
  313. package/src/utils/htmlTransform.tsx +74 -53
  314. package/src/utils/reactUtils.tsx +57 -6
  315. package/dist/index.bundled.css +0 -12
  316. /package/src/{hooks/__tests__ → __tests__/hooks}/useDataBinding.test.tsx.disabled +0 -0
  317. /package/src/{schemas/__tests__ → __tests__/schemas}/builders.test.ts +0 -0
  318. /package/src/{utils/__tests__ → __tests__/utils}/createDataDrivenComponent.test.tsx.disabled +0 -0
  319. /package/src/{utils/__tests__ → __tests__/utils}/htmlTransform.test.tsx +0 -0
  320. /package/src/{utils/__tests__ → __tests__/utils}/optional-logging.test.ts +0 -0
@@ -14,13 +14,13 @@ import { usePalette } from '../contexts/PaletteContext';
14
14
  import { Box, Typography, Button, Card, CardContent } from '@mui/material';
15
15
 
16
16
  const meta = {
17
- title: 'Components/ThemeSwitcher',
18
- component: ThemeSwitcher,
19
- parameters: {
20
- layout: 'centered',
21
- docs: {
22
- description: {
23
- component: `ThemeSwitcher provides users with light, dark, and system theme mode options for optimal viewing experience.
17
+ title: 'Components/ThemeSwitcher',
18
+ component: ThemeSwitcher,
19
+ parameters: {
20
+ layout: 'centered',
21
+ docs: {
22
+ description: {
23
+ component: `ThemeSwitcher provides users with light, dark, and system theme mode options for optimal viewing experience.
24
24
 
25
25
  **Key Features:**
26
26
  - **Three Theme Modes**: Light, dark, and automatic system preference detection
@@ -38,10 +38,10 @@ const meta = {
38
38
  - Multi-theme applications requiring user choice
39
39
  - Dashboard and admin panel customization
40
40
  - Design system demonstrations and showcases`,
41
- },
42
- },
43
- },
44
- tags: ['autodocs'],
41
+ },
42
+ },
43
+ },
44
+ tags: ['autodocs'],
45
45
  } satisfies Meta<typeof ThemeSwitcher>;
46
46
 
47
47
  export default meta;
@@ -49,122 +49,122 @@ type Story = StoryObj<typeof meta>;
49
49
 
50
50
  // Component that uses the theme context
51
51
  function ThemeDemo() {
52
- const { currentTheme, actualThemeMode } = useTheme();
53
- const { currentPalette } = usePalette();
54
-
55
- return (
56
- <Box sx={{ p: 3, maxWidth: 600, margin: '0 auto' }}>
57
- <div style={{ marginBottom: '20px', textAlign: 'center' }}>
58
- <Typography variant="h5" gutterBottom>
59
- Try switching themes and palettes!
60
- </Typography>
61
- <Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}>
62
- Use the theme and palette switchers to see how different combinations affect the appearance.
63
- </Typography>
64
- <Box sx={{ display: 'flex', gap: 2, justifyContent: 'center', alignItems: 'center' }}>
65
- <ThemeSwitcher />
66
- <PaletteSwitcher />
67
- </Box>
68
- </div>
52
+ const { currentTheme, actualThemeMode } = useTheme();
53
+ const { currentPalette } = usePalette();
54
+
55
+ return (
56
+ <Box sx={{ p: 3, maxWidth: 600, margin: '0 auto' }}>
57
+ <div style={{ marginBottom: '20px', textAlign: 'center' }}>
58
+ <Typography variant="h5" gutterBottom>
59
+ Try switching themes and palettes!
60
+ </Typography>
61
+ <Typography variant="body1" color="text.secondary" sx={{ mb: 2 }}>
62
+ Use the theme and palette switchers to see how different combinations affect the appearance.
63
+ </Typography>
64
+ <Box sx={{ display: 'flex', gap: 2, justifyContent: 'center', alignItems: 'center' }}>
65
+ <ThemeSwitcher />
66
+ <PaletteSwitcher />
67
+ </Box>
68
+ </div>
69
69
 
70
- <Card sx={{ mt: 3 }}>
71
- <CardContent>
72
- <Typography variant="h6" gutterBottom>
73
- Theme & Palette Demo Content
74
- </Typography>
75
- <Typography variant="body2" color="text.secondary" paragraph>
76
- Current Theme: <strong>{currentTheme}</strong> → Actual: <strong>{actualThemeMode}</strong>
77
- </Typography>
78
- <Typography variant="body2" color="text.secondary" paragraph>
79
- Current Palette: <strong>{currentPalette}</strong>
80
- </Typography>
81
- <Typography variant="body2" color="text.secondary" paragraph>
82
- This content changes appearance based on both the selected theme mode and color palette,
83
- demonstrating the full theming system integration with Material-UI.
84
- </Typography>
85
-
86
- {/* AccessibilityChecker Integration */}
87
- <Box sx={{
88
- p: 2,
89
- backgroundColor: 'background.paper',
90
- border: '1px solid',
91
- borderColor: 'divider',
92
- borderRadius: 1,
93
- mb: 2
94
- }}>
95
- <Typography variant="subtitle2" gutterBottom>
96
- 🔍 Accessibility Monitoring
97
- </Typography>
98
- <Typography variant="caption" color="text.secondary" paragraph>
99
- The AccessibilityChecker automatically monitors color contrast and accessibility compliance as you switch themes and palettes.
100
- </Typography>
101
- <AccessibilityChecker />
102
- </Box>
103
-
104
- <Box sx={{
105
- display: 'flex',
106
- gap: 2,
107
- flexWrap: 'wrap',
108
- justifyContent: 'center',
109
- mb: 3
110
- }}>
111
- <Button variant="contained" color="primary">
112
- Primary Button
113
- </Button>
114
- <Button variant="outlined" color="secondary">
115
- Secondary Button
116
- </Button>
117
- <Button variant="text">
118
- Text Button
119
- </Button>
120
- </Box>
70
+ <Card sx={{ mt: 3 }}>
71
+ <CardContent>
72
+ <Typography variant="h6" gutterBottom>
73
+ Theme & Palette Demo Content
74
+ </Typography>
75
+ <Typography variant="body2" color="text.secondary" paragraph>
76
+ Current Theme: <strong>{currentTheme}</strong> → Actual: <strong>{actualThemeMode}</strong>
77
+ </Typography>
78
+ <Typography variant="body2" color="text.secondary" paragraph>
79
+ Current Palette: <strong>{currentPalette}</strong>
80
+ </Typography>
81
+ <Typography variant="body2" color="text.secondary" paragraph>
82
+ This content changes appearance based on both the selected theme mode and color palette,
83
+ demonstrating the full theming system integration with Material-UI.
84
+ </Typography>
85
+
86
+ {/* AccessibilityChecker Integration */}
87
+ <Box sx={{
88
+ p: 2,
89
+ backgroundColor: 'background.paper',
90
+ border: '1px solid',
91
+ borderColor: 'divider',
92
+ borderRadius: 1,
93
+ mb: 2
94
+ }}>
95
+ <Typography variant="subtitle2" gutterBottom>
96
+ Accessibility Monitoring
97
+ </Typography>
98
+ <Typography variant="caption" color="text.secondary" paragraph>
99
+ The AccessibilityChecker automatically monitors color contrast and accessibility compliance as you switch themes and palettes.
100
+ </Typography>
101
+ <AccessibilityChecker />
102
+ </Box>
103
+
104
+ <Box sx={{
105
+ display: 'flex',
106
+ gap: 2,
107
+ flexWrap: 'wrap',
108
+ justifyContent: 'center',
109
+ mb: 3
110
+ }}>
111
+ <Button variant="contained" color="primary">
112
+ Primary Button
113
+ </Button>
114
+ <Button variant="outlined" color="secondary">
115
+ Secondary Button
116
+ </Button>
117
+ <Button variant="text">
118
+ Text Button
119
+ </Button>
120
+ </Box>
121
121
 
122
- <Box sx={{
123
- display: 'grid',
124
- gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
125
- gap: 2,
126
- mt: 2
127
- }}>
128
- {[
129
- { name: 'Primary', color: 'primary.main' },
130
- { name: 'Secondary', color: 'secondary.main' },
131
- { name: 'Background', color: 'background.default' },
132
- { name: 'Surface', color: 'background.paper' },
133
- ].map(({ name, color }) => (
134
- <Box key={name} sx={{ textAlign: 'center' }}>
135
- <Box sx={{
136
- width: '100%',
137
- height: 40,
138
- backgroundColor: color,
139
- border: color.includes('background') ? '1px solid' : 'none',
140
- borderColor: 'divider',
141
- borderRadius: 1,
142
- mb: 1
143
- }} />
144
- <Typography variant="caption" color="text.secondary">
145
- {name}
146
- </Typography>
147
- </Box>
148
- ))}
149
- </Box>
150
- </CardContent>
151
- </Card>
152
- </Box>
153
- );
122
+ <Box sx={{
123
+ display: 'grid',
124
+ gridTemplateColumns: 'repeat(auto-fit, minmax(120px, 1fr))',
125
+ gap: 2,
126
+ mt: 2
127
+ }}>
128
+ {[
129
+ { name: 'Primary', color: 'primary.main' },
130
+ { name: 'Secondary', color: 'secondary.main' },
131
+ { name: 'Background', color: 'background.default' },
132
+ { name: 'Surface', color: 'background.paper' },
133
+ ].map(({ name, color }) => (
134
+ <Box key={name} sx={{ textAlign: 'center' }}>
135
+ <Box sx={{
136
+ width: '100%',
137
+ height: 40,
138
+ backgroundColor: color,
139
+ border: color.includes('background') ? '1px solid' : 'none',
140
+ borderColor: 'divider',
141
+ borderRadius: 1,
142
+ mb: 1
143
+ }} />
144
+ <Typography variant="caption" color="text.secondary">
145
+ {name}
146
+ </Typography>
147
+ </Box>
148
+ ))}
149
+ </Box>
150
+ </CardContent>
151
+ </Card>
152
+ </Box>
153
+ );
154
154
  }
155
155
 
156
156
  // Default story - Interactive Theme Demo
157
157
  export const Default: Story = {
158
- render: () => (
159
- <QwickApp appId="com.qwickapps.storybook" appName="QwickApps Storybook">
160
- <ThemeDemo />
161
- </QwickApp>
162
- ),
163
- parameters: {
164
- docs: {
165
- description: {
166
- story: 'Interactive theme and palette switcher demo showing how different theme modes and color palettes work together. Switch between light/dark/system modes and try different color palettes to see the full theming system in action.',
167
- },
168
- },
169
- },
158
+ render: () => (
159
+ <QwickApp appId="com.qwickapps.storybook" appName="QwickApps Storybook">
160
+ <ThemeDemo />
161
+ </QwickApp>
162
+ ),
163
+ parameters: {
164
+ docs: {
165
+ description: {
166
+ story: 'Interactive theme and palette switcher demo showing how different theme modes and color palettes work together. Switch between light/dark/system modes and try different color palettes to see the full theming system in action.',
167
+ },
168
+ },
169
+ },
170
170
  };
@@ -9,10 +9,7 @@
9
9
 
10
10
  import { Box, Typography } from '@mui/material';
11
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';
12
+ import { ComponentTransformer } from '../schemas/transformers/ComponentTransformer';
16
13
 
17
14
  export interface TransformRule {
18
15
  selector: string;
@@ -30,7 +27,7 @@ export interface TransformConfig {
30
27
  * Default transformation rules for article/blog content
31
28
  */
32
29
  export const defaultArticleRules: TransformRule[] = [
33
- // Pre + Code blocks → Code component with syntax highlighting
30
+ // Pre + Code blocks → Code component via ComponentTransformer
34
31
  {
35
32
  selector: 'pre',
36
33
  transform: (element: Element, key: string) => {
@@ -41,15 +38,20 @@ export const defaultArticleRules: TransformRule[] = [
41
38
  .find(cls => cls.startsWith('language-'))
42
39
  ?.replace('language-', '') || 'text';
43
40
 
41
+ // Use ComponentTransformer to create Code component
42
+ const codeData = {
43
+ tagName: 'Code',
44
+ props: {
45
+ language,
46
+ showCopy: true,
47
+ showLineNumbers: false,
48
+ children: codeChild.textContent || ''
49
+ }
50
+ };
51
+
44
52
  return (
45
53
  <Box key={key} sx={{ my: 1.5 }}>
46
- <Code
47
- language={language}
48
- showCopy={true}
49
- showLineNumbers={false}
50
- >
51
- {codeChild.textContent || ''}
52
- </Code>
54
+ {ComponentTransformer.deserialize(codeData)}
53
55
  </Box>
54
56
  );
55
57
  }
@@ -71,15 +73,20 @@ export const defaultArticleRules: TransformRule[] = [
71
73
  const isInInlineContext = inlineParents.some(tag => element.closest(tag));
72
74
 
73
75
  if ((hasMultipleLines || hasComplexContent) && !isInInlineContext) {
76
+ // Use ComponentTransformer to create Code component
77
+ const codeData = {
78
+ tagName: 'Code',
79
+ props: {
80
+ language: 'text',
81
+ showCopy: true,
82
+ showLineNumbers: false,
83
+ children: text
84
+ }
85
+ };
86
+
74
87
  return (
75
88
  <Box key={key} sx={{ my: 1.5 }}>
76
- <Code
77
- language="text"
78
- showCopy={true}
79
- showLineNumbers={false}
80
- >
81
- {text}
82
- </Code>
89
+ {ComponentTransformer.deserialize(codeData)}
83
90
  </Box>
84
91
  );
85
92
  }
@@ -97,22 +104,29 @@ export const defaultArticleRules: TransformRule[] = [
97
104
  const content = children.filter(child => child.tagName !== 'H2');
98
105
  const spacing = element.getAttribute('data-padding') || 'none';
99
106
 
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
- );
107
+ // Use ComponentTransformer to create Section component
108
+ const sectionData = {
109
+ tagName: 'Section',
110
+ props: {
111
+ padding: spacing || 'medium',
112
+ children: [
113
+ title && {
114
+ tagName: 'Typography',
115
+ props: {
116
+ variant: 'h4',
117
+ component: 'h2',
118
+ sx: { mb: 2 },
119
+ children: title
120
+ }
121
+ },
122
+ ...content.map((child, index) =>
123
+ transformElement(child, `${key}-${index}`, { rules: defaultArticleRules })
124
+ )
125
+ ].filter(Boolean)
126
+ }
127
+ };
128
+
129
+ return ComponentTransformer.deserialize(sectionData);
116
130
  }
117
131
  },
118
132
 
@@ -124,15 +138,17 @@ export const defaultArticleRules: TransformRule[] = [
124
138
  const variant = element.getAttribute('data-variant') || 'contained';
125
139
  const disabled = element.hasAttribute('disabled');
126
140
 
127
- return (
128
- <Button
129
- key={key}
130
- variant={variant as any}
131
- disabled={disabled}
132
- >
133
- {text}
134
- </Button>
135
- );
141
+ // Use ComponentTransformer to create Button component
142
+ const buttonData = {
143
+ tagName: 'Button',
144
+ props: {
145
+ variant,
146
+ disabled,
147
+ label: text
148
+ }
149
+ };
150
+
151
+ return ComponentTransformer.deserialize(buttonData);
136
152
  }
137
153
  }
138
154
  ];
@@ -152,15 +168,20 @@ export const defaultMarkdownRules: TransformRule[] = [
152
168
  .find(cls => cls.startsWith('language-'))
153
169
  ?.replace('language-', '') || 'text';
154
170
 
171
+ // Use ComponentTransformer to create Code component
172
+ const codeData = {
173
+ tagName: 'Code',
174
+ props: {
175
+ language,
176
+ showCopy: true,
177
+ showLineNumbers: false,
178
+ children: codeChild.textContent || ''
179
+ }
180
+ };
181
+
155
182
  return (
156
183
  <Box key={key} sx={{ my: 1.5 }}>
157
- <Code
158
- language={language}
159
- showCopy={true}
160
- showLineNumbers={false}
161
- >
162
- {codeChild.textContent || ''}
163
- </Code>
184
+ {ComponentTransformer.deserialize(codeData)}
164
185
  </Box>
165
186
  );
166
187
  }
@@ -192,7 +213,7 @@ function parseStyleString(styleStr: string): React.CSSProperties {
192
213
  if (property && value) {
193
214
  // Convert kebab-case to camelCase
194
215
  const camelProperty = property.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
195
- styles[camelProperty as keyof React.CSSProperties] = value;
216
+ styles[camelProperty as keyof React.CSSProperties] = value as any;
196
217
  }
197
218
  });
198
219
 
@@ -236,7 +257,7 @@ export const defaultFallback = (element: Element, key: string): React.ReactNode
236
257
  return React.createElement(
237
258
  tagName,
238
259
  props,
239
- React.createElement(SafeSpan, { html: element.innerHTML })
260
+ element.innerHTML
240
261
  );
241
262
  };
242
263
 
@@ -5,6 +5,7 @@
5
5
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
6
6
  */
7
7
 
8
+ import { ReactNode } from 'react';
8
9
  import { useLocation, useNavigate } from 'react-router-dom';
9
10
 
10
11
  /** Location type for React Router */
@@ -24,14 +25,64 @@ export const useSafeLocation = (): LocationType | undefined => {
24
25
  };
25
26
 
26
27
  /**
27
- * Custom hook to get the navigate function
28
- * @returns {Function | undefined} - The navigate function if React Router is available, otherwise undefined
28
+ * Custom hook to get the navigate function with fallback
29
+ * @returns {Function} - The navigate function (React Router or window.location fallback)
29
30
  */
30
- export const useSafeNavigate = (): Function | undefined => {
31
+ export const useSafeNavigate = (): Function => {
31
32
  try {
32
- return useNavigate();
33
+ const navigate = useNavigate();
34
+ return navigate;
33
35
  } catch (error) {
34
- console.warn('React Router context not available:', error);
35
- return undefined;
36
+ // Return fallback function that uses window.location.href
37
+ return (to: string | number, options?: any) => {
38
+ console.warn('React Router context not available, using window.location as fallback to navigate to:', to);
39
+ if (typeof to === 'string') {
40
+ // Handle relative and absolute paths
41
+ if (typeof window !== 'undefined') {
42
+ window.location.href = to;
43
+ }
44
+ } else if (typeof to === 'number') {
45
+ // Handle history.go() equivalent
46
+ if (typeof window !== 'undefined' && window.history) {
47
+ window.history.go(to);
48
+ }
49
+ }
50
+ };
36
51
  }
37
52
  };
53
+
54
+ /**
55
+ * Extract text content from ReactNode for code processing
56
+ * Handles natural React usage like <Code>const x = 1;</Code>
57
+ *
58
+ * @param node - The ReactNode to extract text from
59
+ * @returns String representation of the node's text content
60
+ */
61
+ export function extractTextFromReactNode(node: ReactNode): string {
62
+ if (node === null || node === undefined) {
63
+ return '';
64
+ }
65
+
66
+ if (typeof node === 'string' || typeof node === 'number') {
67
+ return String(node);
68
+ }
69
+
70
+ if (typeof node === 'boolean') {
71
+ return node ? 'true' : 'false';
72
+ }
73
+
74
+ if (Array.isArray(node)) {
75
+ return node.map(child => extractTextFromReactNode(child)).join('');
76
+ }
77
+
78
+ // For React elements, try to extract text content
79
+ if (typeof node === 'object' && node !== null && 'props' in node) {
80
+ const element = node as any;
81
+ if (element.props && element.props.children) {
82
+ return extractTextFromReactNode(element.props.children);
83
+ }
84
+ }
85
+
86
+ // Fallback: convert to string
87
+ return String(node);
88
+ }