@shohojdhara/atomix 0.3.1 → 0.3.3

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 (449) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/README.md +41 -24
  3. package/dist/atomix.css +540 -666
  4. package/dist/atomix.min.css +3 -3
  5. package/dist/index.d.ts +7559 -5717
  6. package/dist/index.esm.js +5013 -2301
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +5084 -2356
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/dist/themes/applemix.css +1683 -722
  13. package/dist/themes/applemix.css.map +1 -0
  14. package/dist/themes/applemix.min.css +13 -10
  15. package/dist/themes/boomdevs.css +1358 -544
  16. package/dist/themes/boomdevs.css.map +1 -0
  17. package/dist/themes/boomdevs.min.css +13 -10
  18. package/dist/themes/esrar.css +1743 -718
  19. package/dist/themes/esrar.css.map +1 -0
  20. package/dist/themes/esrar.min.css +41 -7
  21. package/dist/themes/flashtrade.css +1735 -752
  22. package/dist/themes/flashtrade.css.map +1 -0
  23. package/dist/themes/flashtrade.min.css +19 -13
  24. package/dist/themes/mashroom.css +1765 -787
  25. package/dist/themes/mashroom.css.map +1 -0
  26. package/dist/themes/mashroom.min.css +87 -38
  27. package/dist/themes/shaj-default.css +1685 -713
  28. package/dist/themes/shaj-default.css.map +1 -0
  29. package/dist/themes/shaj-default.min.css +11 -7
  30. package/package.json +95 -26
  31. package/scripts/atomix-cli.js +1428 -0
  32. package/scripts/build-themes.js +208 -0
  33. package/scripts/cli/interactive-init.js +528 -0
  34. package/scripts/cli/migration-tools.js +603 -0
  35. package/scripts/cli/token-manager.js +519 -0
  36. package/scripts/sync-theme-config.js +309 -0
  37. package/src/components/List/ListGroup.tsx +1 -2
  38. package/src/components/Popover/Popover.tsx +2 -2
  39. package/src/components/Tooltip/Tooltip.stories.tsx +49 -12
  40. package/src/components/Tooltip/Tooltip.tsx +32 -58
  41. package/src/lib/composables/useAtomixGlass.ts +46 -46
  42. package/src/lib/composables/useTooltip.ts +285 -0
  43. package/src/lib/constants/cssVariables.ts +390 -0
  44. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +151 -0
  45. package/src/lib/hooks/index.ts +19 -0
  46. package/src/lib/hooks/useComponentCustomization.ts +175 -0
  47. package/src/lib/index.ts +10 -1
  48. package/src/lib/patterns/__tests__/slots.test.ts +108 -0
  49. package/src/lib/patterns/index.ts +35 -0
  50. package/src/lib/patterns/slots.tsx +421 -0
  51. package/src/lib/theme/__tests__/ThemeBuilder.test.ts +223 -0
  52. package/src/lib/theme/builders/ThemeBuilder.ts +372 -0
  53. package/src/lib/theme/config/index.ts +21 -0
  54. package/src/lib/theme/config/loader.ts +276 -0
  55. package/src/lib/theme/config/types.ts +98 -0
  56. package/src/lib/theme/config/validator.ts +326 -0
  57. package/src/lib/theme/constants.ts +183 -0
  58. package/src/lib/theme/core/ThemeCache.ts +283 -0
  59. package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
  60. package/src/lib/theme/core/ThemeEngine.ts +657 -0
  61. package/src/lib/theme/core/ThemeRegistry.ts +284 -0
  62. package/src/lib/theme/core/ThemeValidator.ts +530 -0
  63. package/src/lib/theme/core/index.ts +24 -0
  64. package/src/lib/theme/createTheme.ts +83 -204
  65. package/src/lib/theme/cssVariableMapper.ts +261 -0
  66. package/src/lib/theme/devtools/CLI.ts +279 -0
  67. package/src/lib/theme/devtools/Inspector.tsx +594 -0
  68. package/src/lib/theme/devtools/Preview.tsx +392 -0
  69. package/src/lib/theme/devtools/index.ts +21 -0
  70. package/src/lib/theme/errors.test.ts +207 -0
  71. package/src/lib/theme/errors.ts +233 -0
  72. package/src/lib/theme/generateCSSVariables.ts +93 -9
  73. package/src/lib/theme/generators/CSSGenerator.ts +311 -0
  74. package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
  75. package/src/lib/theme/generators/TypeGenerator.ts +228 -0
  76. package/src/lib/theme/generators/index.ts +21 -0
  77. package/src/lib/theme/i18n/index.ts +9 -0
  78. package/src/lib/theme/i18n/rtl.ts +325 -0
  79. package/src/lib/theme/index.ts +36 -109
  80. package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
  81. package/src/lib/theme/monitoring/index.ts +17 -0
  82. package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
  83. package/src/lib/theme/overrides/index.ts +15 -0
  84. package/src/lib/theme/runtime/ThemeApplicator.ts +252 -0
  85. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
  86. package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
  87. package/src/lib/theme/runtime/ThemeManager.ts +442 -0
  88. package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
  89. package/src/lib/theme/runtime/index.ts +17 -0
  90. package/src/lib/theme/runtime/useTheme.ts +52 -0
  91. package/src/lib/theme/themeUtils.ts +27 -5
  92. package/src/lib/theme/types.ts +62 -1
  93. package/src/lib/theme/utils.ts +23 -22
  94. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
  95. package/src/lib/theme/whitelabel/index.ts +13 -0
  96. package/src/lib/theme-tools.ts +185 -0
  97. package/src/lib/types/components.ts +194 -0
  98. package/src/lib/types/partProps.ts +426 -0
  99. package/src/lib/utils/__tests__/componentUtils.test.ts +144 -0
  100. package/src/lib/utils/componentUtils.ts +163 -0
  101. package/src/lib/utils/index.ts +17 -57
  102. package/src/styles/01-settings/_settings.badge.scss +1 -1
  103. package/src/styles/01-settings/_settings.callout.scss +1 -1
  104. package/src/styles/01-settings/_settings.card.scss +1 -1
  105. package/src/styles/01-settings/_settings.colors.scss +10 -10
  106. package/src/styles/01-settings/_settings.input.scss +1 -1
  107. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  108. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  109. package/src/styles/01-settings/_settings.upload.scss +1 -1
  110. package/src/styles/06-components/_components.chart.scss +2 -2
  111. package/src/styles/06-components/_components.tooltip.scss +31 -81
  112. package/src/styles/99-utilities/_utilities.border.scss +27 -58
  113. package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
  114. package/src/styles/99-utilities/_utilities.position.scss +8 -15
  115. package/src/styles/99-utilities/_utilities.scss +2 -0
  116. package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
  117. package/src/styles/99-utilities/_utilities.text.scss +30 -49
  118. package/src/themes/README.md +443 -0
  119. package/src/themes/THEME_CHECKLIST.md +74 -0
  120. package/src/themes/applemix/01-settings/_index.scss +24 -0
  121. package/src/themes/applemix/01-settings/_settings.animations.scss +0 -0
  122. package/src/themes/applemix/01-settings/_settings.background.scss +6 -0
  123. package/src/themes/applemix/01-settings/_settings.colors.scss +75 -0
  124. package/src/themes/applemix/01-settings/_settings.config.scss +15 -0
  125. package/src/themes/applemix/01-settings/_settings.typography.scss +30 -0
  126. package/src/themes/applemix/02-tools/_index.scss +4 -0
  127. package/src/themes/applemix/03-generic/_index.scss +7 -0
  128. package/src/themes/applemix/04-elements/_index.scss +7 -0
  129. package/src/themes/applemix/05-objects/_index.scss +7 -0
  130. package/src/themes/applemix/06-components/_index.scss +15 -0
  131. package/src/themes/applemix/99-utilities/_index.scss +7 -0
  132. package/src/themes/applemix/README.md +378 -0
  133. package/src/themes/applemix/index.scss +33 -0
  134. package/src/themes/boomdevs/01-settings/_index.scss +38 -0
  135. package/src/themes/boomdevs/01-settings/_settings.accordion.scss +12 -0
  136. package/src/themes/boomdevs/01-settings/_settings.animations.scss +11 -0
  137. package/src/themes/boomdevs/01-settings/_settings.avatar.scss +9 -0
  138. package/src/themes/boomdevs/01-settings/_settings.badge.scss +11 -0
  139. package/src/themes/boomdevs/01-settings/_settings.border-radius.scss +16 -0
  140. package/src/themes/boomdevs/01-settings/_settings.border.scss +10 -0
  141. package/src/themes/boomdevs/01-settings/_settings.box-shadow.scss +14 -0
  142. package/src/themes/boomdevs/01-settings/_settings.breadcrumb.scss +13 -0
  143. package/src/themes/boomdevs/01-settings/_settings.breakpoints.scss +15 -0
  144. package/src/themes/boomdevs/01-settings/_settings.button.scss +9 -0
  145. package/src/themes/boomdevs/01-settings/_settings.callout.scss +9 -0
  146. package/src/themes/boomdevs/01-settings/_settings.card.scss +11 -0
  147. package/src/themes/boomdevs/01-settings/_settings.checkbox.scss +9 -0
  148. package/src/themes/boomdevs/01-settings/_settings.colors.scss +145 -0
  149. package/src/themes/boomdevs/01-settings/_settings.dropdown.scss +11 -0
  150. package/src/themes/boomdevs/01-settings/_settings.grid.scss +16 -0
  151. package/src/themes/boomdevs/01-settings/_settings.input.scss +14 -0
  152. package/src/themes/boomdevs/01-settings/_settings.link.scss +11 -0
  153. package/src/themes/boomdevs/01-settings/_settings.list.scss +10 -0
  154. package/src/themes/boomdevs/01-settings/_settings.modal.scss +16 -0
  155. package/src/themes/boomdevs/01-settings/_settings.navbar.scss +16 -0
  156. package/src/themes/boomdevs/01-settings/_settings.pagination.scss +13 -0
  157. package/src/themes/boomdevs/01-settings/_settings.progress.scss +11 -0
  158. package/src/themes/boomdevs/01-settings/_settings.rating.scss +10 -0
  159. package/src/themes/boomdevs/01-settings/_settings.spacing.scss +33 -0
  160. package/src/themes/boomdevs/01-settings/_settings.spinner.scss +11 -0
  161. package/src/themes/boomdevs/01-settings/_settings.steps.scss +12 -0
  162. package/src/themes/boomdevs/01-settings/_settings.tabs.scss +12 -0
  163. package/src/themes/boomdevs/01-settings/_settings.todo.scss +15 -0
  164. package/src/themes/boomdevs/01-settings/_settings.toggle.scss +14 -0
  165. package/src/themes/boomdevs/01-settings/_settings.tooltip.scss +13 -0
  166. package/src/themes/boomdevs/01-settings/_settings.typography.scss +58 -0
  167. package/src/themes/boomdevs/01-settings/_settings.video-player.scss +12 -0
  168. package/src/themes/boomdevs/02-tools/_index.scss +7 -0
  169. package/src/themes/boomdevs/03-generic/_index.scss +7 -0
  170. package/src/themes/boomdevs/04-elements/_index.scss +7 -0
  171. package/src/themes/boomdevs/05-objects/_index.scss +7 -0
  172. package/src/themes/boomdevs/06-components/_components.button.scss +11 -0
  173. package/src/themes/boomdevs/06-components/_index.scss +11 -0
  174. package/src/themes/boomdevs/99-utilities/_index.scss +7 -0
  175. package/src/themes/boomdevs/index.scss +26 -0
  176. package/src/themes/esrar/01-settings/_index.scss +15 -0
  177. package/src/themes/esrar/01-settings/_settings.colors.scss +91 -0
  178. package/src/themes/esrar/02-tools/_index.scss +8 -0
  179. package/src/themes/esrar/02-tools/_tools.animations.scss +342 -0
  180. package/src/themes/esrar/06-components/_components.accordion.scss +49 -0
  181. package/src/themes/esrar/06-components/_components.avatar-group.scss +14 -0
  182. package/src/themes/esrar/06-components/_components.avatar.scss +61 -0
  183. package/src/themes/esrar/06-components/_components.badge.scss +117 -0
  184. package/src/themes/esrar/06-components/_components.breadcrumb.scss +65 -0
  185. package/src/themes/esrar/06-components/_components.btn-group.scss +19 -0
  186. package/src/themes/esrar/06-components/_components.button.scss +224 -0
  187. package/src/themes/esrar/06-components/_components.callout.scss +51 -0
  188. package/src/themes/esrar/06-components/_components.card.scss +134 -0
  189. package/src/themes/esrar/06-components/_components.chart.scss +24 -0
  190. package/src/themes/esrar/06-components/_components.checkbox-group.scss +26 -0
  191. package/src/themes/esrar/06-components/_components.checkbox.scss +71 -0
  192. package/src/themes/esrar/06-components/_components.color-mode-toggle.scss +29 -0
  193. package/src/themes/esrar/06-components/_components.countdown.scss +67 -0
  194. package/src/themes/esrar/06-components/_components.data-table.scss +22 -0
  195. package/src/themes/esrar/06-components/_components.datepicker.scss +20 -0
  196. package/src/themes/esrar/06-components/_components.dropdown.scss +272 -0
  197. package/src/themes/esrar/06-components/_components.edge-panel.scss +10 -0
  198. package/src/themes/esrar/06-components/_components.form-group.scss +15 -0
  199. package/src/themes/esrar/06-components/_components.form.scss +66 -0
  200. package/src/themes/esrar/06-components/_components.hero.scss +251 -0
  201. package/src/themes/esrar/06-components/_components.icon.scss +33 -0
  202. package/src/themes/esrar/06-components/_components.image-gallery.scss +29 -0
  203. package/src/themes/esrar/06-components/_components.input.scss +91 -0
  204. package/src/themes/esrar/06-components/_components.list-group.scss +26 -0
  205. package/src/themes/esrar/06-components/_components.modal.scss +148 -0
  206. package/src/themes/esrar/06-components/_components.notification.scss +80 -0
  207. package/src/themes/esrar/06-components/_components.pagination.scss +84 -0
  208. package/src/themes/esrar/06-components/_components.popover.scss +10 -0
  209. package/src/themes/esrar/06-components/_components.progress.scss +64 -0
  210. package/src/themes/esrar/06-components/_components.rating.scss +26 -0
  211. package/src/themes/esrar/06-components/_components.skeleton.scss +15 -0
  212. package/src/themes/esrar/06-components/_components.slider.scss +90 -0
  213. package/src/themes/esrar/06-components/_components.spinner.scss +71 -0
  214. package/src/themes/esrar/06-components/_components.steps.scss +76 -0
  215. package/src/themes/esrar/06-components/_components.tab.scss +58 -0
  216. package/src/themes/esrar/06-components/_components.tag.scss +21 -0
  217. package/src/themes/esrar/06-components/_components.timeline.scss +19 -0
  218. package/src/themes/esrar/06-components/_components.toast.scss +91 -0
  219. package/src/themes/esrar/06-components/_components.toggle.scss +74 -0
  220. package/src/themes/esrar/06-components/_components.tooltip.scss +45 -0
  221. package/src/themes/esrar/06-components/_components.upload.scss +102 -0
  222. package/src/themes/esrar/06-components/_index.scss +42 -0
  223. package/src/themes/esrar/index.scss +30 -0
  224. package/src/themes/flashtrade/01-settings/_index.scss +19 -0
  225. package/src/themes/flashtrade/01-settings/_settings.animations.scss +11 -0
  226. package/src/themes/flashtrade/01-settings/_settings.background.scss +9 -0
  227. package/src/themes/flashtrade/01-settings/_settings.colors.scss +79 -0
  228. package/src/themes/flashtrade/01-settings/_settings.config.scss +16 -0
  229. package/src/themes/flashtrade/01-settings/_settings.typography.scss +35 -0
  230. package/src/themes/flashtrade/02-tools/_index.scss +8 -0
  231. package/src/themes/flashtrade/03-generic/_index.scss +8 -0
  232. package/src/themes/flashtrade/04-elements/_index.scss +12 -0
  233. package/src/themes/flashtrade/05-objects/_index.scss +8 -0
  234. package/src/themes/flashtrade/06-components/_components.badge.scss +156 -0
  235. package/src/themes/flashtrade/06-components/_components.button.scss +135 -0
  236. package/src/themes/flashtrade/06-components/_components.card.scss +214 -0
  237. package/src/themes/flashtrade/06-components/_components.navbar.scss +227 -0
  238. package/src/themes/flashtrade/06-components/_index.scss +13 -0
  239. package/src/themes/flashtrade/99-utilities/_index.scss +9 -0
  240. package/src/themes/flashtrade/99-utilities/_utilities.trading.scss +187 -0
  241. package/src/themes/flashtrade/README.md +386 -0
  242. package/src/themes/flashtrade/demo.html +272 -0
  243. package/src/themes/flashtrade/index.scss +36 -0
  244. package/src/themes/mashroom/01-settings/_index.scss +69 -0
  245. package/src/themes/mashroom/01-settings/_settings.accordion.scss +32 -0
  246. package/src/themes/mashroom/01-settings/_settings.animations.scss +26 -0
  247. package/src/themes/mashroom/01-settings/_settings.avatar-group.scss +22 -0
  248. package/src/themes/mashroom/01-settings/_settings.avatar.scss +57 -0
  249. package/src/themes/mashroom/01-settings/_settings.badge.scss +19 -0
  250. package/src/themes/mashroom/01-settings/_settings.border-radius.scss +24 -0
  251. package/src/themes/mashroom/01-settings/_settings.border.scss +14 -0
  252. package/src/themes/mashroom/01-settings/_settings.box-shadow.scss +40 -0
  253. package/src/themes/mashroom/01-settings/_settings.breadcrumb.scss +0 -0
  254. package/src/themes/mashroom/01-settings/_settings.breakpoints.scss +17 -0
  255. package/src/themes/mashroom/01-settings/_settings.btn-group.scss +5 -0
  256. package/src/themes/mashroom/01-settings/_settings.button.scss +50 -0
  257. package/src/themes/mashroom/01-settings/_settings.callout.scss +81 -0
  258. package/src/themes/mashroom/01-settings/_settings.card.scss +52 -0
  259. package/src/themes/mashroom/01-settings/_settings.checkbox-group.scss +5 -0
  260. package/src/themes/mashroom/01-settings/_settings.checkbox.scss +23 -0
  261. package/src/themes/mashroom/01-settings/_settings.color-mode.scss +7 -0
  262. package/src/themes/mashroom/01-settings/_settings.colors.scss +180 -0
  263. package/src/themes/mashroom/01-settings/_settings.config.scss +4 -0
  264. package/src/themes/mashroom/01-settings/_settings.countdown.scss +20 -0
  265. package/src/themes/mashroom/01-settings/_settings.data-table.scss +56 -0
  266. package/src/themes/mashroom/01-settings/_settings.datepicker.scss +45 -0
  267. package/src/themes/mashroom/01-settings/_settings.design-tokens.scss +3 -0
  268. package/src/themes/mashroom/01-settings/_settings.dropdown.scss +45 -0
  269. package/src/themes/mashroom/01-settings/_settings.edge-panel.scss +24 -0
  270. package/src/themes/mashroom/01-settings/_settings.fonts.scss +8 -0
  271. package/src/themes/mashroom/01-settings/_settings.form-group.scss +14 -0
  272. package/src/themes/mashroom/01-settings/_settings.form.scss +6 -0
  273. package/src/themes/mashroom/01-settings/_settings.grid.scss +23 -0
  274. package/src/themes/mashroom/01-settings/_settings.hero.scss +41 -0
  275. package/src/themes/mashroom/01-settings/_settings.input.scss +51 -0
  276. package/src/themes/mashroom/01-settings/_settings.link.scss +13 -0
  277. package/src/themes/mashroom/01-settings/_settings.list-group.scss +16 -0
  278. package/src/themes/mashroom/01-settings/_settings.list.scss +13 -0
  279. package/src/themes/mashroom/01-settings/_settings.masonry-grid.scss +23 -0
  280. package/src/themes/mashroom/01-settings/_settings.menu.scss +50 -0
  281. package/src/themes/mashroom/01-settings/_settings.messages.scss +98 -0
  282. package/src/themes/mashroom/01-settings/_settings.modal.scss +41 -0
  283. package/src/themes/mashroom/01-settings/_settings.nav.scss +20 -0
  284. package/src/themes/mashroom/01-settings/_settings.navbar.scss +54 -0
  285. package/src/themes/mashroom/01-settings/_settings.pagination.scss +30 -0
  286. package/src/themes/mashroom/01-settings/_settings.photoviewer.scss +45 -0
  287. package/src/themes/mashroom/01-settings/_settings.popover.scss +20 -0
  288. package/src/themes/mashroom/01-settings/_settings.position.scss +9 -0
  289. package/src/themes/mashroom/01-settings/_settings.progress.scss +17 -0
  290. package/src/themes/mashroom/01-settings/_settings.rating.scss +11 -0
  291. package/src/themes/mashroom/01-settings/_settings.river.scss +50 -0
  292. package/src/themes/mashroom/01-settings/_settings.sectionintro.scss +31 -0
  293. package/src/themes/mashroom/01-settings/_settings.select.scss +47 -0
  294. package/src/themes/mashroom/01-settings/_settings.side-menu.scss +79 -0
  295. package/src/themes/mashroom/01-settings/_settings.skeleton.scss +24 -0
  296. package/src/themes/mashroom/01-settings/_settings.spacing.scss +66 -0
  297. package/src/themes/mashroom/01-settings/_settings.spinner.scss +34 -0
  298. package/src/themes/mashroom/01-settings/_settings.steps.scss +33 -0
  299. package/src/themes/mashroom/01-settings/_settings.tabs.scss +33 -0
  300. package/src/themes/mashroom/01-settings/_settings.testimonials.scss +24 -0
  301. package/src/themes/mashroom/01-settings/_settings.todo.scss +52 -0
  302. package/src/themes/mashroom/01-settings/_settings.toggle.scss +49 -0
  303. package/src/themes/mashroom/01-settings/_settings.tooltip.scss +20 -0
  304. package/src/themes/mashroom/01-settings/_settings.typography.scss +95 -0
  305. package/src/themes/mashroom/01-settings/_settings.upload.scss +96 -0
  306. package/src/themes/mashroom/01-settings/_settings.z-layers.scss +19 -0
  307. package/src/themes/mashroom/02-tools/_index.scss +8 -0
  308. package/src/themes/mashroom/02-tools/_tools.psychedelic-gradients.scss +78 -0
  309. package/src/themes/mashroom/02-tools/_tools.trippy-effects.scss +114 -0
  310. package/src/themes/mashroom/03-generic/_index.scss +6 -0
  311. package/src/themes/mashroom/04-elements/_index.scss +6 -0
  312. package/src/themes/mashroom/05-objects/_index.scss +6 -0
  313. package/src/themes/mashroom/06-components/_components.accordion.scss +187 -0
  314. package/src/themes/mashroom/06-components/_components.avatar-group.scss +276 -0
  315. package/src/themes/mashroom/06-components/_components.avatar.scss +114 -0
  316. package/src/themes/mashroom/06-components/_components.badge.scss +152 -0
  317. package/src/themes/mashroom/06-components/_components.breadcrumb.scss +162 -0
  318. package/src/themes/mashroom/06-components/_components.btn-group.scss +404 -0
  319. package/src/themes/mashroom/06-components/_components.button.scss +160 -0
  320. package/src/themes/mashroom/06-components/_components.callout.scss +140 -0
  321. package/src/themes/mashroom/06-components/_components.card.scss +225 -0
  322. package/src/themes/mashroom/06-components/_components.checkbox.scss +186 -0
  323. package/src/themes/mashroom/06-components/_components.color-mode-toggle.scss +308 -0
  324. package/src/themes/mashroom/06-components/_components.countdown.scss +402 -0
  325. package/src/themes/mashroom/06-components/_components.data-table.scss +354 -0
  326. package/src/themes/mashroom/06-components/_components.datepicker.scss +349 -0
  327. package/src/themes/mashroom/06-components/_components.dropdown.scss +334 -0
  328. package/src/themes/mashroom/06-components/_components.edge-panel.scss +413 -0
  329. package/src/themes/mashroom/06-components/_components.form-group.scss +433 -0
  330. package/src/themes/mashroom/06-components/_components.form.scss +358 -0
  331. package/src/themes/mashroom/06-components/_components.hero.scss +151 -0
  332. package/src/themes/mashroom/06-components/_components.input.scss +147 -0
  333. package/src/themes/mashroom/06-components/_components.list-group.scss +456 -0
  334. package/src/themes/mashroom/06-components/_components.list.scss +145 -0
  335. package/src/themes/mashroom/06-components/_components.menu.scss +497 -0
  336. package/src/themes/mashroom/06-components/_components.messages.scss +277 -0
  337. package/src/themes/mashroom/06-components/_components.modal.scss +264 -0
  338. package/src/themes/mashroom/06-components/_components.nav.scss +181 -0
  339. package/src/themes/mashroom/06-components/_components.navbar.scss +538 -0
  340. package/src/themes/mashroom/06-components/_components.pagination.scss +400 -0
  341. package/src/themes/mashroom/06-components/_components.photoviewer.scss +498 -0
  342. package/src/themes/mashroom/06-components/_components.popover.scss +383 -0
  343. package/src/themes/mashroom/06-components/_components.product-review.scss +408 -0
  344. package/src/themes/mashroom/06-components/_components.progress.scss +249 -0
  345. package/src/themes/mashroom/06-components/_components.rating.scss +300 -0
  346. package/src/themes/mashroom/06-components/_components.river.scss +570 -0
  347. package/src/themes/mashroom/06-components/_components.sectionintro.scss +546 -0
  348. package/src/themes/mashroom/06-components/_components.select.scss +455 -0
  349. package/src/themes/mashroom/06-components/_components.side-menu.scss +635 -0
  350. package/src/themes/mashroom/06-components/_components.skeleton.scss +447 -0
  351. package/src/themes/mashroom/06-components/_components.slider.scss +414 -0
  352. package/src/themes/mashroom/06-components/_components.spinner.scss +198 -0
  353. package/src/themes/mashroom/06-components/_components.steps.scss +350 -0
  354. package/src/themes/mashroom/06-components/_components.tabs.scss +269 -0
  355. package/src/themes/mashroom/06-components/_components.testimonials.scss +561 -0
  356. package/src/themes/mashroom/06-components/_components.toggle.scss +231 -0
  357. package/src/themes/mashroom/06-components/_components.tooltip.scss +167 -0
  358. package/src/themes/mashroom/06-components/_components.upload.scss +537 -0
  359. package/src/themes/mashroom/06-components/_components.video-player.scss +560 -0
  360. package/src/themes/mashroom/06-components/_index.scss +55 -0
  361. package/src/themes/mashroom/99-utilities/_index.scss +6 -0
  362. package/src/themes/mashroom/index.scss +26 -0
  363. package/src/themes/shaj-default/01-settings/_index.scss +69 -0
  364. package/src/themes/shaj-default/01-settings/_settings.accordion.scss +38 -0
  365. package/src/themes/shaj-default/01-settings/_settings.animations.scss +32 -0
  366. package/src/themes/shaj-default/01-settings/_settings.avatar-group.scss +28 -0
  367. package/src/themes/shaj-default/01-settings/_settings.avatar.scss +63 -0
  368. package/src/themes/shaj-default/01-settings/_settings.badge.scss +25 -0
  369. package/src/themes/shaj-default/01-settings/_settings.border-radius.scss +24 -0
  370. package/src/themes/shaj-default/01-settings/_settings.border.scss +20 -0
  371. package/src/themes/shaj-default/01-settings/_settings.box-shadow.scss +46 -0
  372. package/src/themes/shaj-default/01-settings/_settings.breadcrumb.scss +0 -0
  373. package/src/themes/shaj-default/01-settings/_settings.breakpoints.scss +23 -0
  374. package/src/themes/shaj-default/01-settings/_settings.btn-group.scss +11 -0
  375. package/src/themes/shaj-default/01-settings/_settings.button.scss +56 -0
  376. package/src/themes/shaj-default/01-settings/_settings.callout.scss +87 -0
  377. package/src/themes/shaj-default/01-settings/_settings.card.scss +52 -0
  378. package/src/themes/shaj-default/01-settings/_settings.checkbox-group.scss +11 -0
  379. package/src/themes/shaj-default/01-settings/_settings.checkbox.scss +29 -0
  380. package/src/themes/shaj-default/01-settings/_settings.color-mode.scss +13 -0
  381. package/src/themes/shaj-default/01-settings/_settings.colors.scss +91 -0
  382. package/src/themes/shaj-default/01-settings/_settings.config.scss +4 -0
  383. package/src/themes/shaj-default/01-settings/_settings.countdown.scss +26 -0
  384. package/src/themes/shaj-default/01-settings/_settings.data-table.scss +62 -0
  385. package/src/themes/shaj-default/01-settings/_settings.datepicker.scss +51 -0
  386. package/src/themes/shaj-default/01-settings/_settings.design-tokens.scss +9 -0
  387. package/src/themes/shaj-default/01-settings/_settings.dropdown.scss +51 -0
  388. package/src/themes/shaj-default/01-settings/_settings.edge-panel.scss +30 -0
  389. package/src/themes/shaj-default/01-settings/_settings.fonts.scss +13 -0
  390. package/src/themes/shaj-default/01-settings/_settings.form-group.scss +20 -0
  391. package/src/themes/shaj-default/01-settings/_settings.form.scss +12 -0
  392. package/src/themes/shaj-default/01-settings/_settings.grid.scss +29 -0
  393. package/src/themes/shaj-default/01-settings/_settings.hero.scss +47 -0
  394. package/src/themes/shaj-default/01-settings/_settings.input.scss +57 -0
  395. package/src/themes/shaj-default/01-settings/_settings.link.scss +19 -0
  396. package/src/themes/shaj-default/01-settings/_settings.list-group.scss +22 -0
  397. package/src/themes/shaj-default/01-settings/_settings.list.scss +19 -0
  398. package/src/themes/shaj-default/01-settings/_settings.masonry-grid.scss +29 -0
  399. package/src/themes/shaj-default/01-settings/_settings.menu.scss +56 -0
  400. package/src/themes/shaj-default/01-settings/_settings.messages.scss +104 -0
  401. package/src/themes/shaj-default/01-settings/_settings.modal.scss +47 -0
  402. package/src/themes/shaj-default/01-settings/_settings.nav.scss +26 -0
  403. package/src/themes/shaj-default/01-settings/_settings.navbar.scss +60 -0
  404. package/src/themes/shaj-default/01-settings/_settings.pagination.scss +36 -0
  405. package/src/themes/shaj-default/01-settings/_settings.photoviewer.scss +51 -0
  406. package/src/themes/shaj-default/01-settings/_settings.popover.scss +26 -0
  407. package/src/themes/shaj-default/01-settings/_settings.position.scss +15 -0
  408. package/src/themes/shaj-default/01-settings/_settings.progress.scss +23 -0
  409. package/src/themes/shaj-default/01-settings/_settings.rating.scss +17 -0
  410. package/src/themes/shaj-default/01-settings/_settings.river.scss +56 -0
  411. package/src/themes/shaj-default/01-settings/_settings.sectionintro.scss +37 -0
  412. package/src/themes/shaj-default/01-settings/_settings.select.scss +53 -0
  413. package/src/themes/shaj-default/01-settings/_settings.side-menu.scss +85 -0
  414. package/src/themes/shaj-default/01-settings/_settings.skeleton.scss +30 -0
  415. package/src/themes/shaj-default/01-settings/_settings.spacing.scss +72 -0
  416. package/src/themes/shaj-default/01-settings/_settings.spinner.scss +24 -0
  417. package/src/themes/shaj-default/01-settings/_settings.steps.scss +39 -0
  418. package/src/themes/shaj-default/01-settings/_settings.tabs.scss +39 -0
  419. package/src/themes/shaj-default/01-settings/_settings.testimonials.scss +30 -0
  420. package/src/themes/shaj-default/01-settings/_settings.todo.scss +58 -0
  421. package/src/themes/shaj-default/01-settings/_settings.toggle.scss +55 -0
  422. package/src/themes/shaj-default/01-settings/_settings.tooltip.scss +26 -0
  423. package/src/themes/shaj-default/01-settings/_settings.typography.scss +101 -0
  424. package/src/themes/shaj-default/01-settings/_settings.upload.scss +102 -0
  425. package/src/themes/shaj-default/01-settings/_settings.z-layers.scss +25 -0
  426. package/src/themes/shaj-default/02-tools/_index.scss +0 -0
  427. package/src/themes/shaj-default/03-generic/_generic.root.scss +0 -0
  428. package/src/themes/shaj-default/03-generic/_index.scss +2 -0
  429. package/src/themes/shaj-default/04-elements/_index.scss +0 -0
  430. package/src/themes/shaj-default/05-objects/_index.scss +0 -0
  431. package/src/themes/shaj-default/06-components/_components.button.scss +55 -0
  432. package/src/themes/shaj-default/06-components/_components.card.scss +57 -0
  433. package/src/themes/shaj-default/06-components/_components.input.scss +58 -0
  434. package/src/themes/shaj-default/06-components/_components.navbar.scss +99 -0
  435. package/src/themes/shaj-default/06-components/_components.tooltip.scss +0 -0
  436. package/src/themes/shaj-default/06-components/_index.scss +13 -0
  437. package/src/themes/shaj-default/99-utilities/_index.scss +0 -0
  438. package/src/themes/shaj-default/index.scss +25 -0
  439. package/src/themes/themes.config.js +219 -0
  440. package/theme.config.ts +360 -0
  441. package/src/lib/theme/ThemeManager.integration.test.ts +0 -124
  442. package/src/lib/theme/ThemeManager.stories.tsx +0 -472
  443. package/src/lib/theme/ThemeManager.test.ts +0 -190
  444. package/src/lib/theme/ThemeManager.ts +0 -645
  445. package/src/lib/theme/ThemeProvider.tsx +0 -377
  446. package/src/lib/theme/createTheme.test.ts +0 -475
  447. package/src/lib/theme/useTheme.test.tsx +0 -67
  448. package/src/lib/theme/useTheme.ts +0 -64
  449. package/src/lib/theme/utils.test.ts +0 -140
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Theme Applicator
3
+ *
4
+ * Applies theme configurations to the DOM, including CSS variables,
5
+ * component overrides, typography, spacing, and color palettes.
6
+ */
7
+
8
+ import { applyCSSVariables, removeCSSVariables } from '../cssVariableMapper';
9
+ import type { Theme, ThemeComponentOverrides, ComponentThemeOverride } from '../types';
10
+
11
+ /**
12
+ * Theme applicator class for runtime theme application
13
+ */
14
+ export class ThemeApplicator {
15
+ private appliedVars: Set<string> = new Set();
16
+ private root: HTMLElement;
17
+
18
+ constructor(root: HTMLElement = document.documentElement) {
19
+ this.root = root;
20
+ }
21
+
22
+ /**
23
+ * Apply a complete theme configuration
24
+ */
25
+ applyTheme(theme: Theme): void {
26
+ // Clear previously applied variables
27
+ this.clearAppliedVars();
28
+
29
+ // Apply global CSS variables
30
+ if (theme.cssVars) {
31
+ this.applyGlobalCSSVars(theme.cssVars);
32
+ }
33
+
34
+ // Apply typography system
35
+ if (theme.typography) {
36
+ this.applyTypography(theme.typography);
37
+ }
38
+
39
+ // Apply spacing system
40
+ if (theme.spacing) {
41
+ this.applySpacing(theme.spacing);
42
+ }
43
+
44
+ // Apply color palette
45
+ if (theme.palette) {
46
+ this.applyPalette(theme.palette);
47
+ }
48
+
49
+ // Apply component overrides
50
+ if (theme.components) {
51
+ this.applyComponentOverrides(theme.components);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Apply global CSS variables
57
+ */
58
+ private applyGlobalCSSVars(vars: Record<string, string | number>): void {
59
+ Object.entries(vars).forEach(([key, value]) => {
60
+ this.root.style.setProperty(key, String(value));
61
+ this.appliedVars.add(key);
62
+ });
63
+ }
64
+
65
+ /**
66
+ * Apply typography system
67
+ */
68
+ private applyTypography(typography: Theme['typography']): void {
69
+ if (!typography) return;
70
+
71
+ const vars: Record<string, string | number> = {};
72
+
73
+ if (typography.fontFamily) {
74
+ vars['--atomix-font-family'] = typography.fontFamily;
75
+ }
76
+
77
+ if (typography.fontSize) {
78
+ Object.entries(typography.fontSize).forEach(([key, value]) => {
79
+ vars[`--atomix-font-size-${key}`] = value;
80
+ });
81
+ }
82
+
83
+ if (typography.fontWeight) {
84
+ Object.entries(typography.fontWeight).forEach(([key, value]) => {
85
+ vars[`--atomix-font-weight-${key}`] = value;
86
+ });
87
+ }
88
+
89
+ if (typography.lineHeight) {
90
+ Object.entries(typography.lineHeight).forEach(([key, value]) => {
91
+ vars[`--atomix-line-height-${key}`] = value;
92
+ });
93
+ }
94
+
95
+ this.applyGlobalCSSVars(vars);
96
+ }
97
+
98
+ /**
99
+ * Apply spacing system
100
+ */
101
+ private applySpacing(spacing: Record<string, string | number>): void {
102
+ const vars: Record<string, string | number> = {};
103
+
104
+ Object.entries(spacing).forEach(([key, value]) => {
105
+ vars[`--atomix-space-${key}`] = value;
106
+ });
107
+
108
+ this.applyGlobalCSSVars(vars);
109
+ }
110
+
111
+ /**
112
+ * Apply color palette
113
+ */
114
+ private applyPalette(palette: Theme['palette']): void {
115
+ if (!palette) return;
116
+
117
+ const vars: Record<string, string | number> = {};
118
+
119
+ Object.entries(palette).forEach(([colorName, colorScale]) => {
120
+ if (colorScale) {
121
+ Object.entries(colorScale).forEach(([shade, value]) => {
122
+ if (value) {
123
+ vars[`--atomix-color-${colorName}-${shade}`] = value;
124
+ }
125
+ });
126
+ }
127
+ });
128
+
129
+ this.applyGlobalCSSVars(vars);
130
+ }
131
+
132
+ /**
133
+ * Apply component-level overrides
134
+ */
135
+ private applyComponentOverrides(overrides: ThemeComponentOverrides): void {
136
+ Object.entries(overrides).forEach(([componentName, override]) => {
137
+ if (override) {
138
+ this.applyComponentOverride(componentName, override);
139
+ }
140
+ });
141
+ }
142
+
143
+ /**
144
+ * Apply override for a specific component
145
+ */
146
+ private applyComponentOverride(
147
+ componentName: string,
148
+ override: ComponentThemeOverride
149
+ ): void {
150
+ const vars: Record<string, string | number> = {};
151
+ const componentKey = componentName.toLowerCase();
152
+
153
+ // Apply component-level CSS variables
154
+ if (override.cssVars) {
155
+ Object.entries(override.cssVars).forEach(([key, value]) => {
156
+ // If key doesn't start with --, add component prefix
157
+ const varKey = key.startsWith('--')
158
+ ? key
159
+ : `--atomix-${componentKey}-${key}`;
160
+ vars[varKey] = value;
161
+ });
162
+ }
163
+
164
+ // Apply part-specific CSS variables
165
+ if (override.parts) {
166
+ Object.entries(override.parts).forEach(([partName, partOverride]) => {
167
+ if (partOverride.cssVars) {
168
+ Object.entries(partOverride.cssVars).forEach(([key, value]) => {
169
+ const varKey = key.startsWith('--')
170
+ ? key
171
+ : `--atomix-${componentKey}-${partName}-${key}`;
172
+ vars[varKey] = value;
173
+ });
174
+ }
175
+ });
176
+ }
177
+
178
+ // Apply variant-specific CSS variables
179
+ if (override.variants) {
180
+ Object.entries(override.variants).forEach(([variantName, variantOverride]) => {
181
+ if (variantOverride.cssVars) {
182
+ Object.entries(variantOverride.cssVars).forEach(([key, value]) => {
183
+ const varKey = key.startsWith('--')
184
+ ? key
185
+ : `--atomix-${componentKey}-${variantName}-${key}`;
186
+ vars[varKey] = value;
187
+ });
188
+ }
189
+ });
190
+ }
191
+
192
+ this.applyGlobalCSSVars(vars);
193
+ }
194
+
195
+ /**
196
+ * Clear all applied CSS variables
197
+ */
198
+ private clearAppliedVars(): void {
199
+ removeCSSVariables(Array.from(this.appliedVars), this.root);
200
+ this.appliedVars.clear();
201
+ }
202
+
203
+ /**
204
+ * Get all currently applied variables
205
+ */
206
+ getAppliedVars(): string[] {
207
+ return Array.from(this.appliedVars);
208
+ }
209
+
210
+ /**
211
+ * Remove theme application
212
+ */
213
+ removeTheme(): void {
214
+ this.clearAppliedVars();
215
+ }
216
+
217
+ /**
218
+ * Update specific CSS variables without clearing all
219
+ */
220
+ updateCSSVars(vars: Record<string, string | number>): void {
221
+ this.applyGlobalCSSVars(vars);
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Global theme applicator instance
227
+ */
228
+ let globalApplicator: ThemeApplicator | null = null;
229
+
230
+ /**
231
+ * Get or create global theme applicator
232
+ */
233
+ export function getThemeApplicator(): ThemeApplicator {
234
+ if (!globalApplicator) {
235
+ globalApplicator = new ThemeApplicator();
236
+ }
237
+ return globalApplicator;
238
+ }
239
+
240
+ /**
241
+ * Apply theme using global applicator
242
+ */
243
+ export function applyTheme(theme: Theme): void {
244
+ getThemeApplicator().applyTheme(theme);
245
+ }
246
+
247
+ /**
248
+ * Remove theme using global applicator
249
+ */
250
+ export function removeTheme(): void {
251
+ getThemeApplicator().removeTheme();
252
+ }
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Theme Error Boundary
3
+ *
4
+ * React error boundary for catching and handling theme-related errors.
5
+ * Prevents the entire app from crashing when theme errors occur.
6
+ */
7
+
8
+ import React, { Component, type ReactNode, type ErrorInfo } from 'react';
9
+ import { ThemeError, ThemeErrorCode, getLogger } from '../errors';
10
+
11
+ /**
12
+ * Error boundary state
13
+ */
14
+ interface ThemeErrorBoundaryState {
15
+ /** Whether an error has occurred */
16
+ hasError: boolean;
17
+ /** The error that occurred */
18
+ error: Error | null;
19
+ /** Error information */
20
+ errorInfo: ErrorInfo | null;
21
+ }
22
+
23
+ /**
24
+ * Error boundary props
25
+ */
26
+ export interface ThemeErrorBoundaryProps {
27
+ /** Child components */
28
+ children: ReactNode;
29
+ /** Fallback UI to render when error occurs */
30
+ fallback?: (error: Error, errorInfo: ErrorInfo) => ReactNode;
31
+ /** Callback when error occurs */
32
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
33
+ /** Whether to reset error on children change */
34
+ resetOnPropsChange?: boolean;
35
+ /** Custom error message */
36
+ errorMessage?: string;
37
+ }
38
+
39
+ /**
40
+ * Default fallback UI
41
+ */
42
+ const DefaultFallback: React.FC<{ error: Error; errorInfo: ErrorInfo }> = ({ error, errorInfo }) => {
43
+ const isThemeError = error instanceof ThemeError;
44
+ const errorCode = isThemeError ? error.code : ThemeErrorCode.UNKNOWN_ERROR;
45
+ const context = isThemeError ? error.context : undefined;
46
+
47
+ return (
48
+ <div
49
+ style={{
50
+ padding: '2rem',
51
+ margin: '1rem',
52
+ border: '1px solid #e0e0e0',
53
+ borderRadius: '8px',
54
+ backgroundColor: '#fafafa',
55
+ color: '#333',
56
+ }}
57
+ role="alert"
58
+ >
59
+ <h2 style={{ marginTop: 0, color: '#d32f2f' }}>Theme Error</h2>
60
+ <p>
61
+ <strong>Error:</strong> {error.message}
62
+ </p>
63
+ {isThemeError && (
64
+ <p>
65
+ <strong>Error Code:</strong> {errorCode}
66
+ </p>
67
+ )}
68
+ {context && Object.keys(context).length > 0 && (
69
+ <details style={{ marginTop: '1rem' }}>
70
+ <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>
71
+ Error Context
72
+ </summary>
73
+ <pre
74
+ style={{
75
+ marginTop: '0.5rem',
76
+ padding: '0.5rem',
77
+ backgroundColor: '#f5f5f5',
78
+ borderRadius: '4px',
79
+ overflow: 'auto',
80
+ }}
81
+ >
82
+ {JSON.stringify(context, null, 2)}
83
+ </pre>
84
+ </details>
85
+ )}
86
+ {process.env.NODE_ENV === 'development' && errorInfo && (
87
+ <details style={{ marginTop: '1rem' }}>
88
+ <summary style={{ cursor: 'pointer', fontWeight: 'bold' }}>
89
+ Stack Trace (Development Only)
90
+ </summary>
91
+ <pre
92
+ style={{
93
+ marginTop: '0.5rem',
94
+ padding: '0.5rem',
95
+ backgroundColor: '#f5f5f5',
96
+ borderRadius: '4px',
97
+ overflow: 'auto',
98
+ fontSize: '0.875rem',
99
+ }}
100
+ >
101
+ {errorInfo.componentStack}
102
+ </pre>
103
+ </details>
104
+ )}
105
+ <button
106
+ onClick={() => window.location.reload()}
107
+ style={{
108
+ marginTop: '1rem',
109
+ padding: '0.5rem 1rem',
110
+ backgroundColor: '#1976d2',
111
+ color: 'white',
112
+ border: 'none',
113
+ borderRadius: '4px',
114
+ cursor: 'pointer',
115
+ }}
116
+ >
117
+ Reload Page
118
+ </button>
119
+ </div>
120
+ );
121
+ };
122
+
123
+ /**
124
+ * Theme Error Boundary Component
125
+ *
126
+ * Catches errors in the theme system and displays a fallback UI
127
+ * instead of crashing the entire application.
128
+ */
129
+ export class ThemeErrorBoundary extends Component<
130
+ ThemeErrorBoundaryProps,
131
+ ThemeErrorBoundaryState
132
+ > {
133
+ private logger = getLogger();
134
+
135
+ constructor(props: ThemeErrorBoundaryProps) {
136
+ super(props);
137
+ this.state = {
138
+ hasError: false,
139
+ error: null,
140
+ errorInfo: null,
141
+ };
142
+ }
143
+
144
+ static getDerivedStateFromError(error: Error): Partial<ThemeErrorBoundaryState> {
145
+ return {
146
+ hasError: true,
147
+ error,
148
+ };
149
+ }
150
+
151
+ componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
152
+ // Log error
153
+ const themeError = error instanceof ThemeError
154
+ ? error
155
+ : new ThemeError(
156
+ error.message,
157
+ ThemeErrorCode.UNKNOWN_ERROR,
158
+ { componentStack: errorInfo.componentStack }
159
+ );
160
+
161
+ this.logger.error(
162
+ 'Theme error boundary caught an error',
163
+ themeError,
164
+ {
165
+ componentStack: errorInfo.componentStack,
166
+ errorBoundary: 'ThemeErrorBoundary',
167
+ }
168
+ );
169
+
170
+ // Update state with error info
171
+ this.setState({
172
+ error,
173
+ errorInfo,
174
+ });
175
+
176
+ // Call custom error handler
177
+ if (this.props.onError) {
178
+ try {
179
+ this.props.onError(error, errorInfo);
180
+ } catch (handlerError) {
181
+ this.logger.error(
182
+ 'Error in onError callback',
183
+ handlerError instanceof Error ? handlerError : new Error(String(handlerError)),
184
+ { originalError: error.message }
185
+ );
186
+ }
187
+ }
188
+ }
189
+
190
+ componentDidUpdate(prevProps: ThemeErrorBoundaryProps): void {
191
+ // Reset error if resetOnPropsChange is true and children changed
192
+ if (
193
+ this.props.resetOnPropsChange &&
194
+ this.state.hasError &&
195
+ prevProps.children !== this.props.children
196
+ ) {
197
+ this.setState({
198
+ hasError: false,
199
+ error: null,
200
+ errorInfo: null,
201
+ });
202
+ }
203
+ }
204
+
205
+ render(): ReactNode {
206
+ if (this.state.hasError && this.state.error && this.state.errorInfo) {
207
+ // Use custom fallback if provided
208
+ if (this.props.fallback) {
209
+ return this.props.fallback(this.state.error, this.state.errorInfo);
210
+ }
211
+
212
+ // Use default fallback
213
+ return <DefaultFallback error={this.state.error} errorInfo={this.state.errorInfo} />;
214
+ }
215
+
216
+ return this.props.children;
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Hook to reset error boundary
222
+ *
223
+ * @param reset - Function to reset the error boundary
224
+ */
225
+ export function useThemeErrorReset(): () => void {
226
+ return () => {
227
+ // This would need to be implemented with a context or ref
228
+ // For now, it's a placeholder
229
+ window.location.reload();
230
+ };
231
+ }
232
+
233
+ export default ThemeErrorBoundary;
@@ -0,0 +1,176 @@
1
+ /**
2
+ * ThemeManager Tests
3
+ *
4
+ * Tests for the ThemeManager class
5
+ */
6
+
7
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
8
+ import { ThemeManager } from './ThemeManager';
9
+ import { ThemeError, ThemeErrorCode } from '../errors';
10
+ import type { ThemeMetadata } from '../types';
11
+
12
+ // Mock dependencies
13
+ vi.mock('../core/ThemeEngine');
14
+ vi.mock('../config/loader');
15
+ vi.mock('../utils', () => ({
16
+ isBrowser: () => true,
17
+ isServer: () => false,
18
+ createLocalStorageAdapter: () => ({
19
+ getItem: vi.fn(),
20
+ setItem: vi.fn(),
21
+ removeItem: vi.fn(),
22
+ isAvailable: () => true,
23
+ }),
24
+ }));
25
+
26
+ describe('ThemeManager', () => {
27
+ let themeManager: ThemeManager;
28
+ const mockThemes: Record<string, ThemeMetadata> = {
29
+ 'test-theme': {
30
+ name: 'Test Theme',
31
+ class: 'test-theme',
32
+ description: 'A test theme',
33
+ },
34
+ };
35
+
36
+ beforeEach(() => {
37
+ vi.clearAllMocks();
38
+ });
39
+
40
+ afterEach(() => {
41
+ if (themeManager) {
42
+ themeManager.destroy();
43
+ }
44
+ });
45
+
46
+ describe('constructor', () => {
47
+ it('should create ThemeManager with default config', () => {
48
+ themeManager = new ThemeManager({ themes: {} });
49
+ expect(themeManager).toBeInstanceOf(ThemeManager);
50
+ });
51
+
52
+ it('should create ThemeManager with custom config', () => {
53
+ themeManager = new ThemeManager({
54
+ themes: mockThemes,
55
+ basePath: '/custom-themes',
56
+ storageKey: 'custom-key',
57
+ });
58
+ expect(themeManager).toBeInstanceOf(ThemeManager);
59
+ });
60
+
61
+ it('should initialize with themes from config', () => {
62
+ themeManager = new ThemeManager({ themes: mockThemes });
63
+ const available = themeManager.getAvailableThemes();
64
+ expect(available.length).toBeGreaterThanOrEqual(0);
65
+ });
66
+ });
67
+
68
+ describe('getTheme', () => {
69
+ it('should return current theme', () => {
70
+ themeManager = new ThemeManager({ themes: mockThemes });
71
+ const theme = themeManager.getTheme();
72
+ expect(typeof theme).toBe('string');
73
+ });
74
+
75
+ it('should return default theme if no theme set', () => {
76
+ themeManager = new ThemeManager({
77
+ themes: mockThemes,
78
+ defaultTheme: 'test-theme',
79
+ });
80
+ const theme = themeManager.getTheme();
81
+ expect(theme).toBe('test-theme');
82
+ });
83
+ });
84
+
85
+ describe('getAvailableThemes', () => {
86
+ it('should return available themes', () => {
87
+ themeManager = new ThemeManager({ themes: mockThemes });
88
+ const themes = themeManager.getAvailableThemes();
89
+ expect(Array.isArray(themes)).toBe(true);
90
+ });
91
+ });
92
+
93
+ describe('event listeners', () => {
94
+ it('should add theme change listener', () => {
95
+ themeManager = new ThemeManager({ themes: mockThemes });
96
+ const listener = vi.fn();
97
+ themeManager.on('themeChange', listener);
98
+ // Note: Actual event emission would require theme switching
99
+ expect(() => themeManager.on('themeChange', listener)).not.toThrow();
100
+ });
101
+
102
+ it('should remove theme change listener', () => {
103
+ themeManager = new ThemeManager({ themes: mockThemes });
104
+ const listener = vi.fn();
105
+ themeManager.on('themeChange', listener);
106
+ themeManager.off('themeChange', listener);
107
+ expect(() => themeManager.off('themeChange', listener)).not.toThrow();
108
+ });
109
+
110
+ it('should add theme load listener', () => {
111
+ themeManager = new ThemeManager({ themes: mockThemes });
112
+ const listener = vi.fn();
113
+ themeManager.on('themeLoad', listener);
114
+ expect(() => themeManager.on('themeLoad', listener)).not.toThrow();
115
+ });
116
+
117
+ it('should add theme error listener', () => {
118
+ themeManager = new ThemeManager({ themes: mockThemes });
119
+ const listener = vi.fn();
120
+ themeManager.on('themeError', listener);
121
+ expect(() => themeManager.on('themeError', listener)).not.toThrow();
122
+ });
123
+ });
124
+
125
+ describe('isThemeLoaded', () => {
126
+ it('should check if theme is loaded', () => {
127
+ themeManager = new ThemeManager({ themes: mockThemes });
128
+ const isLoaded = themeManager.isThemeLoaded('test-theme');
129
+ expect(typeof isLoaded).toBe('boolean');
130
+ });
131
+ });
132
+
133
+ describe('destroy', () => {
134
+ it('should destroy theme manager', () => {
135
+ themeManager = new ThemeManager({ themes: mockThemes });
136
+ expect(() => themeManager.destroy()).not.toThrow();
137
+ });
138
+
139
+ it('should clear event listeners on destroy', () => {
140
+ themeManager = new ThemeManager({ themes: mockThemes });
141
+ const listener = vi.fn();
142
+ themeManager.on('themeChange', listener);
143
+ themeManager.destroy();
144
+ // After destroy, listeners should be cleared
145
+ expect(() => themeManager.destroy()).not.toThrow();
146
+ });
147
+ });
148
+
149
+ describe('RTL support', () => {
150
+ it('should get RTL manager when configured', () => {
151
+ themeManager = new ThemeManager({
152
+ themes: mockThemes,
153
+ rtl: { enabled: true, direction: 'ltr' },
154
+ });
155
+ const rtlManager = themeManager.getRTLManager();
156
+ expect(rtlManager).toBeDefined();
157
+ });
158
+
159
+ it('should set direction', () => {
160
+ themeManager = new ThemeManager({
161
+ themes: mockThemes,
162
+ rtl: { enabled: true, direction: 'ltr' },
163
+ });
164
+ expect(() => themeManager.setDirection('rtl')).not.toThrow();
165
+ });
166
+
167
+ it('should get direction', () => {
168
+ themeManager = new ThemeManager({
169
+ themes: mockThemes,
170
+ rtl: { enabled: true, direction: 'ltr' },
171
+ });
172
+ const direction = themeManager.getDirection();
173
+ expect(['ltr', 'rtl']).toContain(direction);
174
+ });
175
+ });
176
+ });