@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.
- package/CHANGELOG.md +0 -1
- package/README.md +41 -24
- package/dist/atomix.css +540 -666
- package/dist/atomix.min.css +3 -3
- package/dist/index.d.ts +7559 -5717
- package/dist/index.esm.js +5013 -2301
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5084 -2356
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/themes/applemix.css +1683 -722
- package/dist/themes/applemix.css.map +1 -0
- package/dist/themes/applemix.min.css +13 -10
- package/dist/themes/boomdevs.css +1358 -544
- package/dist/themes/boomdevs.css.map +1 -0
- package/dist/themes/boomdevs.min.css +13 -10
- package/dist/themes/esrar.css +1743 -718
- package/dist/themes/esrar.css.map +1 -0
- package/dist/themes/esrar.min.css +41 -7
- package/dist/themes/flashtrade.css +1735 -752
- package/dist/themes/flashtrade.css.map +1 -0
- package/dist/themes/flashtrade.min.css +19 -13
- package/dist/themes/mashroom.css +1765 -787
- package/dist/themes/mashroom.css.map +1 -0
- package/dist/themes/mashroom.min.css +87 -38
- package/dist/themes/shaj-default.css +1685 -713
- package/dist/themes/shaj-default.css.map +1 -0
- package/dist/themes/shaj-default.min.css +11 -7
- package/package.json +95 -26
- package/scripts/atomix-cli.js +1428 -0
- package/scripts/build-themes.js +208 -0
- package/scripts/cli/interactive-init.js +528 -0
- package/scripts/cli/migration-tools.js +603 -0
- package/scripts/cli/token-manager.js +519 -0
- package/scripts/sync-theme-config.js +309 -0
- package/src/components/List/ListGroup.tsx +1 -2
- package/src/components/Popover/Popover.tsx +2 -2
- package/src/components/Tooltip/Tooltip.stories.tsx +49 -12
- package/src/components/Tooltip/Tooltip.tsx +32 -58
- package/src/lib/composables/useAtomixGlass.ts +46 -46
- package/src/lib/composables/useTooltip.ts +285 -0
- package/src/lib/constants/cssVariables.ts +390 -0
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +151 -0
- package/src/lib/hooks/index.ts +19 -0
- package/src/lib/hooks/useComponentCustomization.ts +175 -0
- package/src/lib/index.ts +10 -1
- package/src/lib/patterns/__tests__/slots.test.ts +108 -0
- package/src/lib/patterns/index.ts +35 -0
- package/src/lib/patterns/slots.tsx +421 -0
- package/src/lib/theme/__tests__/ThemeBuilder.test.ts +223 -0
- package/src/lib/theme/builders/ThemeBuilder.ts +372 -0
- package/src/lib/theme/config/index.ts +21 -0
- package/src/lib/theme/config/loader.ts +276 -0
- package/src/lib/theme/config/types.ts +98 -0
- package/src/lib/theme/config/validator.ts +326 -0
- package/src/lib/theme/constants.ts +183 -0
- package/src/lib/theme/core/ThemeCache.ts +283 -0
- package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
- package/src/lib/theme/core/ThemeEngine.ts +657 -0
- package/src/lib/theme/core/ThemeRegistry.ts +284 -0
- package/src/lib/theme/core/ThemeValidator.ts +530 -0
- package/src/lib/theme/core/index.ts +24 -0
- package/src/lib/theme/createTheme.ts +83 -204
- package/src/lib/theme/cssVariableMapper.ts +261 -0
- package/src/lib/theme/devtools/CLI.ts +279 -0
- package/src/lib/theme/devtools/Inspector.tsx +594 -0
- package/src/lib/theme/devtools/Preview.tsx +392 -0
- package/src/lib/theme/devtools/index.ts +21 -0
- package/src/lib/theme/errors.test.ts +207 -0
- package/src/lib/theme/errors.ts +233 -0
- package/src/lib/theme/generateCSSVariables.ts +93 -9
- package/src/lib/theme/generators/CSSGenerator.ts +311 -0
- package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
- package/src/lib/theme/generators/TypeGenerator.ts +228 -0
- package/src/lib/theme/generators/index.ts +21 -0
- package/src/lib/theme/i18n/index.ts +9 -0
- package/src/lib/theme/i18n/rtl.ts +325 -0
- package/src/lib/theme/index.ts +36 -109
- package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
- package/src/lib/theme/monitoring/index.ts +17 -0
- package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
- package/src/lib/theme/overrides/index.ts +15 -0
- package/src/lib/theme/runtime/ThemeApplicator.ts +252 -0
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
- package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
- package/src/lib/theme/runtime/ThemeManager.ts +442 -0
- package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
- package/src/lib/theme/runtime/index.ts +17 -0
- package/src/lib/theme/runtime/useTheme.ts +52 -0
- package/src/lib/theme/themeUtils.ts +27 -5
- package/src/lib/theme/types.ts +62 -1
- package/src/lib/theme/utils.ts +23 -22
- package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
- package/src/lib/theme/whitelabel/index.ts +13 -0
- package/src/lib/theme-tools.ts +185 -0
- package/src/lib/types/components.ts +194 -0
- package/src/lib/types/partProps.ts +426 -0
- package/src/lib/utils/__tests__/componentUtils.test.ts +144 -0
- package/src/lib/utils/componentUtils.ts +163 -0
- package/src/lib/utils/index.ts +17 -57
- package/src/styles/01-settings/_settings.badge.scss +1 -1
- package/src/styles/01-settings/_settings.callout.scss +1 -1
- package/src/styles/01-settings/_settings.card.scss +1 -1
- package/src/styles/01-settings/_settings.colors.scss +10 -10
- package/src/styles/01-settings/_settings.input.scss +1 -1
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.upload.scss +1 -1
- package/src/styles/06-components/_components.chart.scss +2 -2
- package/src/styles/06-components/_components.tooltip.scss +31 -81
- package/src/styles/99-utilities/_utilities.border.scss +27 -58
- package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
- package/src/styles/99-utilities/_utilities.position.scss +8 -15
- package/src/styles/99-utilities/_utilities.scss +2 -0
- package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
- package/src/styles/99-utilities/_utilities.text.scss +30 -49
- package/src/themes/README.md +443 -0
- package/src/themes/THEME_CHECKLIST.md +74 -0
- package/src/themes/applemix/01-settings/_index.scss +24 -0
- package/src/themes/applemix/01-settings/_settings.animations.scss +0 -0
- package/src/themes/applemix/01-settings/_settings.background.scss +6 -0
- package/src/themes/applemix/01-settings/_settings.colors.scss +75 -0
- package/src/themes/applemix/01-settings/_settings.config.scss +15 -0
- package/src/themes/applemix/01-settings/_settings.typography.scss +30 -0
- package/src/themes/applemix/02-tools/_index.scss +4 -0
- package/src/themes/applemix/03-generic/_index.scss +7 -0
- package/src/themes/applemix/04-elements/_index.scss +7 -0
- package/src/themes/applemix/05-objects/_index.scss +7 -0
- package/src/themes/applemix/06-components/_index.scss +15 -0
- package/src/themes/applemix/99-utilities/_index.scss +7 -0
- package/src/themes/applemix/README.md +378 -0
- package/src/themes/applemix/index.scss +33 -0
- package/src/themes/boomdevs/01-settings/_index.scss +38 -0
- package/src/themes/boomdevs/01-settings/_settings.accordion.scss +12 -0
- package/src/themes/boomdevs/01-settings/_settings.animations.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.avatar.scss +9 -0
- package/src/themes/boomdevs/01-settings/_settings.badge.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.border-radius.scss +16 -0
- package/src/themes/boomdevs/01-settings/_settings.border.scss +10 -0
- package/src/themes/boomdevs/01-settings/_settings.box-shadow.scss +14 -0
- package/src/themes/boomdevs/01-settings/_settings.breadcrumb.scss +13 -0
- package/src/themes/boomdevs/01-settings/_settings.breakpoints.scss +15 -0
- package/src/themes/boomdevs/01-settings/_settings.button.scss +9 -0
- package/src/themes/boomdevs/01-settings/_settings.callout.scss +9 -0
- package/src/themes/boomdevs/01-settings/_settings.card.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.checkbox.scss +9 -0
- package/src/themes/boomdevs/01-settings/_settings.colors.scss +145 -0
- package/src/themes/boomdevs/01-settings/_settings.dropdown.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.grid.scss +16 -0
- package/src/themes/boomdevs/01-settings/_settings.input.scss +14 -0
- package/src/themes/boomdevs/01-settings/_settings.link.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.list.scss +10 -0
- package/src/themes/boomdevs/01-settings/_settings.modal.scss +16 -0
- package/src/themes/boomdevs/01-settings/_settings.navbar.scss +16 -0
- package/src/themes/boomdevs/01-settings/_settings.pagination.scss +13 -0
- package/src/themes/boomdevs/01-settings/_settings.progress.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.rating.scss +10 -0
- package/src/themes/boomdevs/01-settings/_settings.spacing.scss +33 -0
- package/src/themes/boomdevs/01-settings/_settings.spinner.scss +11 -0
- package/src/themes/boomdevs/01-settings/_settings.steps.scss +12 -0
- package/src/themes/boomdevs/01-settings/_settings.tabs.scss +12 -0
- package/src/themes/boomdevs/01-settings/_settings.todo.scss +15 -0
- package/src/themes/boomdevs/01-settings/_settings.toggle.scss +14 -0
- package/src/themes/boomdevs/01-settings/_settings.tooltip.scss +13 -0
- package/src/themes/boomdevs/01-settings/_settings.typography.scss +58 -0
- package/src/themes/boomdevs/01-settings/_settings.video-player.scss +12 -0
- package/src/themes/boomdevs/02-tools/_index.scss +7 -0
- package/src/themes/boomdevs/03-generic/_index.scss +7 -0
- package/src/themes/boomdevs/04-elements/_index.scss +7 -0
- package/src/themes/boomdevs/05-objects/_index.scss +7 -0
- package/src/themes/boomdevs/06-components/_components.button.scss +11 -0
- package/src/themes/boomdevs/06-components/_index.scss +11 -0
- package/src/themes/boomdevs/99-utilities/_index.scss +7 -0
- package/src/themes/boomdevs/index.scss +26 -0
- package/src/themes/esrar/01-settings/_index.scss +15 -0
- package/src/themes/esrar/01-settings/_settings.colors.scss +91 -0
- package/src/themes/esrar/02-tools/_index.scss +8 -0
- package/src/themes/esrar/02-tools/_tools.animations.scss +342 -0
- package/src/themes/esrar/06-components/_components.accordion.scss +49 -0
- package/src/themes/esrar/06-components/_components.avatar-group.scss +14 -0
- package/src/themes/esrar/06-components/_components.avatar.scss +61 -0
- package/src/themes/esrar/06-components/_components.badge.scss +117 -0
- package/src/themes/esrar/06-components/_components.breadcrumb.scss +65 -0
- package/src/themes/esrar/06-components/_components.btn-group.scss +19 -0
- package/src/themes/esrar/06-components/_components.button.scss +224 -0
- package/src/themes/esrar/06-components/_components.callout.scss +51 -0
- package/src/themes/esrar/06-components/_components.card.scss +134 -0
- package/src/themes/esrar/06-components/_components.chart.scss +24 -0
- package/src/themes/esrar/06-components/_components.checkbox-group.scss +26 -0
- package/src/themes/esrar/06-components/_components.checkbox.scss +71 -0
- package/src/themes/esrar/06-components/_components.color-mode-toggle.scss +29 -0
- package/src/themes/esrar/06-components/_components.countdown.scss +67 -0
- package/src/themes/esrar/06-components/_components.data-table.scss +22 -0
- package/src/themes/esrar/06-components/_components.datepicker.scss +20 -0
- package/src/themes/esrar/06-components/_components.dropdown.scss +272 -0
- package/src/themes/esrar/06-components/_components.edge-panel.scss +10 -0
- package/src/themes/esrar/06-components/_components.form-group.scss +15 -0
- package/src/themes/esrar/06-components/_components.form.scss +66 -0
- package/src/themes/esrar/06-components/_components.hero.scss +251 -0
- package/src/themes/esrar/06-components/_components.icon.scss +33 -0
- package/src/themes/esrar/06-components/_components.image-gallery.scss +29 -0
- package/src/themes/esrar/06-components/_components.input.scss +91 -0
- package/src/themes/esrar/06-components/_components.list-group.scss +26 -0
- package/src/themes/esrar/06-components/_components.modal.scss +148 -0
- package/src/themes/esrar/06-components/_components.notification.scss +80 -0
- package/src/themes/esrar/06-components/_components.pagination.scss +84 -0
- package/src/themes/esrar/06-components/_components.popover.scss +10 -0
- package/src/themes/esrar/06-components/_components.progress.scss +64 -0
- package/src/themes/esrar/06-components/_components.rating.scss +26 -0
- package/src/themes/esrar/06-components/_components.skeleton.scss +15 -0
- package/src/themes/esrar/06-components/_components.slider.scss +90 -0
- package/src/themes/esrar/06-components/_components.spinner.scss +71 -0
- package/src/themes/esrar/06-components/_components.steps.scss +76 -0
- package/src/themes/esrar/06-components/_components.tab.scss +58 -0
- package/src/themes/esrar/06-components/_components.tag.scss +21 -0
- package/src/themes/esrar/06-components/_components.timeline.scss +19 -0
- package/src/themes/esrar/06-components/_components.toast.scss +91 -0
- package/src/themes/esrar/06-components/_components.toggle.scss +74 -0
- package/src/themes/esrar/06-components/_components.tooltip.scss +45 -0
- package/src/themes/esrar/06-components/_components.upload.scss +102 -0
- package/src/themes/esrar/06-components/_index.scss +42 -0
- package/src/themes/esrar/index.scss +30 -0
- package/src/themes/flashtrade/01-settings/_index.scss +19 -0
- package/src/themes/flashtrade/01-settings/_settings.animations.scss +11 -0
- package/src/themes/flashtrade/01-settings/_settings.background.scss +9 -0
- package/src/themes/flashtrade/01-settings/_settings.colors.scss +79 -0
- package/src/themes/flashtrade/01-settings/_settings.config.scss +16 -0
- package/src/themes/flashtrade/01-settings/_settings.typography.scss +35 -0
- package/src/themes/flashtrade/02-tools/_index.scss +8 -0
- package/src/themes/flashtrade/03-generic/_index.scss +8 -0
- package/src/themes/flashtrade/04-elements/_index.scss +12 -0
- package/src/themes/flashtrade/05-objects/_index.scss +8 -0
- package/src/themes/flashtrade/06-components/_components.badge.scss +156 -0
- package/src/themes/flashtrade/06-components/_components.button.scss +135 -0
- package/src/themes/flashtrade/06-components/_components.card.scss +214 -0
- package/src/themes/flashtrade/06-components/_components.navbar.scss +227 -0
- package/src/themes/flashtrade/06-components/_index.scss +13 -0
- package/src/themes/flashtrade/99-utilities/_index.scss +9 -0
- package/src/themes/flashtrade/99-utilities/_utilities.trading.scss +187 -0
- package/src/themes/flashtrade/README.md +386 -0
- package/src/themes/flashtrade/demo.html +272 -0
- package/src/themes/flashtrade/index.scss +36 -0
- package/src/themes/mashroom/01-settings/_index.scss +69 -0
- package/src/themes/mashroom/01-settings/_settings.accordion.scss +32 -0
- package/src/themes/mashroom/01-settings/_settings.animations.scss +26 -0
- package/src/themes/mashroom/01-settings/_settings.avatar-group.scss +22 -0
- package/src/themes/mashroom/01-settings/_settings.avatar.scss +57 -0
- package/src/themes/mashroom/01-settings/_settings.badge.scss +19 -0
- package/src/themes/mashroom/01-settings/_settings.border-radius.scss +24 -0
- package/src/themes/mashroom/01-settings/_settings.border.scss +14 -0
- package/src/themes/mashroom/01-settings/_settings.box-shadow.scss +40 -0
- package/src/themes/mashroom/01-settings/_settings.breadcrumb.scss +0 -0
- package/src/themes/mashroom/01-settings/_settings.breakpoints.scss +17 -0
- package/src/themes/mashroom/01-settings/_settings.btn-group.scss +5 -0
- package/src/themes/mashroom/01-settings/_settings.button.scss +50 -0
- package/src/themes/mashroom/01-settings/_settings.callout.scss +81 -0
- package/src/themes/mashroom/01-settings/_settings.card.scss +52 -0
- package/src/themes/mashroom/01-settings/_settings.checkbox-group.scss +5 -0
- package/src/themes/mashroom/01-settings/_settings.checkbox.scss +23 -0
- package/src/themes/mashroom/01-settings/_settings.color-mode.scss +7 -0
- package/src/themes/mashroom/01-settings/_settings.colors.scss +180 -0
- package/src/themes/mashroom/01-settings/_settings.config.scss +4 -0
- package/src/themes/mashroom/01-settings/_settings.countdown.scss +20 -0
- package/src/themes/mashroom/01-settings/_settings.data-table.scss +56 -0
- package/src/themes/mashroom/01-settings/_settings.datepicker.scss +45 -0
- package/src/themes/mashroom/01-settings/_settings.design-tokens.scss +3 -0
- package/src/themes/mashroom/01-settings/_settings.dropdown.scss +45 -0
- package/src/themes/mashroom/01-settings/_settings.edge-panel.scss +24 -0
- package/src/themes/mashroom/01-settings/_settings.fonts.scss +8 -0
- package/src/themes/mashroom/01-settings/_settings.form-group.scss +14 -0
- package/src/themes/mashroom/01-settings/_settings.form.scss +6 -0
- package/src/themes/mashroom/01-settings/_settings.grid.scss +23 -0
- package/src/themes/mashroom/01-settings/_settings.hero.scss +41 -0
- package/src/themes/mashroom/01-settings/_settings.input.scss +51 -0
- package/src/themes/mashroom/01-settings/_settings.link.scss +13 -0
- package/src/themes/mashroom/01-settings/_settings.list-group.scss +16 -0
- package/src/themes/mashroom/01-settings/_settings.list.scss +13 -0
- package/src/themes/mashroom/01-settings/_settings.masonry-grid.scss +23 -0
- package/src/themes/mashroom/01-settings/_settings.menu.scss +50 -0
- package/src/themes/mashroom/01-settings/_settings.messages.scss +98 -0
- package/src/themes/mashroom/01-settings/_settings.modal.scss +41 -0
- package/src/themes/mashroom/01-settings/_settings.nav.scss +20 -0
- package/src/themes/mashroom/01-settings/_settings.navbar.scss +54 -0
- package/src/themes/mashroom/01-settings/_settings.pagination.scss +30 -0
- package/src/themes/mashroom/01-settings/_settings.photoviewer.scss +45 -0
- package/src/themes/mashroom/01-settings/_settings.popover.scss +20 -0
- package/src/themes/mashroom/01-settings/_settings.position.scss +9 -0
- package/src/themes/mashroom/01-settings/_settings.progress.scss +17 -0
- package/src/themes/mashroom/01-settings/_settings.rating.scss +11 -0
- package/src/themes/mashroom/01-settings/_settings.river.scss +50 -0
- package/src/themes/mashroom/01-settings/_settings.sectionintro.scss +31 -0
- package/src/themes/mashroom/01-settings/_settings.select.scss +47 -0
- package/src/themes/mashroom/01-settings/_settings.side-menu.scss +79 -0
- package/src/themes/mashroom/01-settings/_settings.skeleton.scss +24 -0
- package/src/themes/mashroom/01-settings/_settings.spacing.scss +66 -0
- package/src/themes/mashroom/01-settings/_settings.spinner.scss +34 -0
- package/src/themes/mashroom/01-settings/_settings.steps.scss +33 -0
- package/src/themes/mashroom/01-settings/_settings.tabs.scss +33 -0
- package/src/themes/mashroom/01-settings/_settings.testimonials.scss +24 -0
- package/src/themes/mashroom/01-settings/_settings.todo.scss +52 -0
- package/src/themes/mashroom/01-settings/_settings.toggle.scss +49 -0
- package/src/themes/mashroom/01-settings/_settings.tooltip.scss +20 -0
- package/src/themes/mashroom/01-settings/_settings.typography.scss +95 -0
- package/src/themes/mashroom/01-settings/_settings.upload.scss +96 -0
- package/src/themes/mashroom/01-settings/_settings.z-layers.scss +19 -0
- package/src/themes/mashroom/02-tools/_index.scss +8 -0
- package/src/themes/mashroom/02-tools/_tools.psychedelic-gradients.scss +78 -0
- package/src/themes/mashroom/02-tools/_tools.trippy-effects.scss +114 -0
- package/src/themes/mashroom/03-generic/_index.scss +6 -0
- package/src/themes/mashroom/04-elements/_index.scss +6 -0
- package/src/themes/mashroom/05-objects/_index.scss +6 -0
- package/src/themes/mashroom/06-components/_components.accordion.scss +187 -0
- package/src/themes/mashroom/06-components/_components.avatar-group.scss +276 -0
- package/src/themes/mashroom/06-components/_components.avatar.scss +114 -0
- package/src/themes/mashroom/06-components/_components.badge.scss +152 -0
- package/src/themes/mashroom/06-components/_components.breadcrumb.scss +162 -0
- package/src/themes/mashroom/06-components/_components.btn-group.scss +404 -0
- package/src/themes/mashroom/06-components/_components.button.scss +160 -0
- package/src/themes/mashroom/06-components/_components.callout.scss +140 -0
- package/src/themes/mashroom/06-components/_components.card.scss +225 -0
- package/src/themes/mashroom/06-components/_components.checkbox.scss +186 -0
- package/src/themes/mashroom/06-components/_components.color-mode-toggle.scss +308 -0
- package/src/themes/mashroom/06-components/_components.countdown.scss +402 -0
- package/src/themes/mashroom/06-components/_components.data-table.scss +354 -0
- package/src/themes/mashroom/06-components/_components.datepicker.scss +349 -0
- package/src/themes/mashroom/06-components/_components.dropdown.scss +334 -0
- package/src/themes/mashroom/06-components/_components.edge-panel.scss +413 -0
- package/src/themes/mashroom/06-components/_components.form-group.scss +433 -0
- package/src/themes/mashroom/06-components/_components.form.scss +358 -0
- package/src/themes/mashroom/06-components/_components.hero.scss +151 -0
- package/src/themes/mashroom/06-components/_components.input.scss +147 -0
- package/src/themes/mashroom/06-components/_components.list-group.scss +456 -0
- package/src/themes/mashroom/06-components/_components.list.scss +145 -0
- package/src/themes/mashroom/06-components/_components.menu.scss +497 -0
- package/src/themes/mashroom/06-components/_components.messages.scss +277 -0
- package/src/themes/mashroom/06-components/_components.modal.scss +264 -0
- package/src/themes/mashroom/06-components/_components.nav.scss +181 -0
- package/src/themes/mashroom/06-components/_components.navbar.scss +538 -0
- package/src/themes/mashroom/06-components/_components.pagination.scss +400 -0
- package/src/themes/mashroom/06-components/_components.photoviewer.scss +498 -0
- package/src/themes/mashroom/06-components/_components.popover.scss +383 -0
- package/src/themes/mashroom/06-components/_components.product-review.scss +408 -0
- package/src/themes/mashroom/06-components/_components.progress.scss +249 -0
- package/src/themes/mashroom/06-components/_components.rating.scss +300 -0
- package/src/themes/mashroom/06-components/_components.river.scss +570 -0
- package/src/themes/mashroom/06-components/_components.sectionintro.scss +546 -0
- package/src/themes/mashroom/06-components/_components.select.scss +455 -0
- package/src/themes/mashroom/06-components/_components.side-menu.scss +635 -0
- package/src/themes/mashroom/06-components/_components.skeleton.scss +447 -0
- package/src/themes/mashroom/06-components/_components.slider.scss +414 -0
- package/src/themes/mashroom/06-components/_components.spinner.scss +198 -0
- package/src/themes/mashroom/06-components/_components.steps.scss +350 -0
- package/src/themes/mashroom/06-components/_components.tabs.scss +269 -0
- package/src/themes/mashroom/06-components/_components.testimonials.scss +561 -0
- package/src/themes/mashroom/06-components/_components.toggle.scss +231 -0
- package/src/themes/mashroom/06-components/_components.tooltip.scss +167 -0
- package/src/themes/mashroom/06-components/_components.upload.scss +537 -0
- package/src/themes/mashroom/06-components/_components.video-player.scss +560 -0
- package/src/themes/mashroom/06-components/_index.scss +55 -0
- package/src/themes/mashroom/99-utilities/_index.scss +6 -0
- package/src/themes/mashroom/index.scss +26 -0
- package/src/themes/shaj-default/01-settings/_index.scss +69 -0
- package/src/themes/shaj-default/01-settings/_settings.accordion.scss +38 -0
- package/src/themes/shaj-default/01-settings/_settings.animations.scss +32 -0
- package/src/themes/shaj-default/01-settings/_settings.avatar-group.scss +28 -0
- package/src/themes/shaj-default/01-settings/_settings.avatar.scss +63 -0
- package/src/themes/shaj-default/01-settings/_settings.badge.scss +25 -0
- package/src/themes/shaj-default/01-settings/_settings.border-radius.scss +24 -0
- package/src/themes/shaj-default/01-settings/_settings.border.scss +20 -0
- package/src/themes/shaj-default/01-settings/_settings.box-shadow.scss +46 -0
- package/src/themes/shaj-default/01-settings/_settings.breadcrumb.scss +0 -0
- package/src/themes/shaj-default/01-settings/_settings.breakpoints.scss +23 -0
- package/src/themes/shaj-default/01-settings/_settings.btn-group.scss +11 -0
- package/src/themes/shaj-default/01-settings/_settings.button.scss +56 -0
- package/src/themes/shaj-default/01-settings/_settings.callout.scss +87 -0
- package/src/themes/shaj-default/01-settings/_settings.card.scss +52 -0
- package/src/themes/shaj-default/01-settings/_settings.checkbox-group.scss +11 -0
- package/src/themes/shaj-default/01-settings/_settings.checkbox.scss +29 -0
- package/src/themes/shaj-default/01-settings/_settings.color-mode.scss +13 -0
- package/src/themes/shaj-default/01-settings/_settings.colors.scss +91 -0
- package/src/themes/shaj-default/01-settings/_settings.config.scss +4 -0
- package/src/themes/shaj-default/01-settings/_settings.countdown.scss +26 -0
- package/src/themes/shaj-default/01-settings/_settings.data-table.scss +62 -0
- package/src/themes/shaj-default/01-settings/_settings.datepicker.scss +51 -0
- package/src/themes/shaj-default/01-settings/_settings.design-tokens.scss +9 -0
- package/src/themes/shaj-default/01-settings/_settings.dropdown.scss +51 -0
- package/src/themes/shaj-default/01-settings/_settings.edge-panel.scss +30 -0
- package/src/themes/shaj-default/01-settings/_settings.fonts.scss +13 -0
- package/src/themes/shaj-default/01-settings/_settings.form-group.scss +20 -0
- package/src/themes/shaj-default/01-settings/_settings.form.scss +12 -0
- package/src/themes/shaj-default/01-settings/_settings.grid.scss +29 -0
- package/src/themes/shaj-default/01-settings/_settings.hero.scss +47 -0
- package/src/themes/shaj-default/01-settings/_settings.input.scss +57 -0
- package/src/themes/shaj-default/01-settings/_settings.link.scss +19 -0
- package/src/themes/shaj-default/01-settings/_settings.list-group.scss +22 -0
- package/src/themes/shaj-default/01-settings/_settings.list.scss +19 -0
- package/src/themes/shaj-default/01-settings/_settings.masonry-grid.scss +29 -0
- package/src/themes/shaj-default/01-settings/_settings.menu.scss +56 -0
- package/src/themes/shaj-default/01-settings/_settings.messages.scss +104 -0
- package/src/themes/shaj-default/01-settings/_settings.modal.scss +47 -0
- package/src/themes/shaj-default/01-settings/_settings.nav.scss +26 -0
- package/src/themes/shaj-default/01-settings/_settings.navbar.scss +60 -0
- package/src/themes/shaj-default/01-settings/_settings.pagination.scss +36 -0
- package/src/themes/shaj-default/01-settings/_settings.photoviewer.scss +51 -0
- package/src/themes/shaj-default/01-settings/_settings.popover.scss +26 -0
- package/src/themes/shaj-default/01-settings/_settings.position.scss +15 -0
- package/src/themes/shaj-default/01-settings/_settings.progress.scss +23 -0
- package/src/themes/shaj-default/01-settings/_settings.rating.scss +17 -0
- package/src/themes/shaj-default/01-settings/_settings.river.scss +56 -0
- package/src/themes/shaj-default/01-settings/_settings.sectionintro.scss +37 -0
- package/src/themes/shaj-default/01-settings/_settings.select.scss +53 -0
- package/src/themes/shaj-default/01-settings/_settings.side-menu.scss +85 -0
- package/src/themes/shaj-default/01-settings/_settings.skeleton.scss +30 -0
- package/src/themes/shaj-default/01-settings/_settings.spacing.scss +72 -0
- package/src/themes/shaj-default/01-settings/_settings.spinner.scss +24 -0
- package/src/themes/shaj-default/01-settings/_settings.steps.scss +39 -0
- package/src/themes/shaj-default/01-settings/_settings.tabs.scss +39 -0
- package/src/themes/shaj-default/01-settings/_settings.testimonials.scss +30 -0
- package/src/themes/shaj-default/01-settings/_settings.todo.scss +58 -0
- package/src/themes/shaj-default/01-settings/_settings.toggle.scss +55 -0
- package/src/themes/shaj-default/01-settings/_settings.tooltip.scss +26 -0
- package/src/themes/shaj-default/01-settings/_settings.typography.scss +101 -0
- package/src/themes/shaj-default/01-settings/_settings.upload.scss +102 -0
- package/src/themes/shaj-default/01-settings/_settings.z-layers.scss +25 -0
- package/src/themes/shaj-default/02-tools/_index.scss +0 -0
- package/src/themes/shaj-default/03-generic/_generic.root.scss +0 -0
- package/src/themes/shaj-default/03-generic/_index.scss +2 -0
- package/src/themes/shaj-default/04-elements/_index.scss +0 -0
- package/src/themes/shaj-default/05-objects/_index.scss +0 -0
- package/src/themes/shaj-default/06-components/_components.button.scss +55 -0
- package/src/themes/shaj-default/06-components/_components.card.scss +57 -0
- package/src/themes/shaj-default/06-components/_components.input.scss +58 -0
- package/src/themes/shaj-default/06-components/_components.navbar.scss +99 -0
- package/src/themes/shaj-default/06-components/_components.tooltip.scss +0 -0
- package/src/themes/shaj-default/06-components/_index.scss +13 -0
- package/src/themes/shaj-default/99-utilities/_index.scss +0 -0
- package/src/themes/shaj-default/index.scss +25 -0
- package/src/themes/themes.config.js +219 -0
- package/theme.config.ts +360 -0
- package/src/lib/theme/ThemeManager.integration.test.ts +0 -124
- package/src/lib/theme/ThemeManager.stories.tsx +0 -472
- package/src/lib/theme/ThemeManager.test.ts +0 -190
- package/src/lib/theme/ThemeManager.ts +0 -645
- package/src/lib/theme/ThemeProvider.tsx +0 -377
- package/src/lib/theme/createTheme.test.ts +0 -475
- package/src/lib/theme/useTheme.test.tsx +0 -67
- package/src/lib/theme/useTheme.ts +0 -64
- package/src/lib/theme/utils.test.ts +0 -140
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Provider
|
|
3
|
+
*
|
|
4
|
+
* React context provider for theme management
|
|
5
|
+
* Updated to use the new ThemeEngine architecture
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
9
|
+
import { ThemeManager } from './ThemeManager';
|
|
10
|
+
import { ThemeContext } from '../ThemeContext';
|
|
11
|
+
import type { ThemeProviderProps, ThemeMetadata, Theme, ThemeLoadOptions } from '../types';
|
|
12
|
+
import { isJSTheme } from '../themeUtils';
|
|
13
|
+
import { getLogger } from '../errors';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* ThemeProvider component
|
|
17
|
+
*
|
|
18
|
+
* Provides theme context to child components and manages theme state.
|
|
19
|
+
* Uses the new ThemeEngine-based ThemeManager.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```tsx
|
|
23
|
+
* import { ThemeProvider } from '@shohojdhara/atomix/theme';
|
|
24
|
+
*
|
|
25
|
+
* function App() {
|
|
26
|
+
* return (
|
|
27
|
+
* <ThemeProvider>
|
|
28
|
+
* <YourApp />
|
|
29
|
+
* </ThemeProvider>
|
|
30
|
+
* );
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
35
|
+
children,
|
|
36
|
+
defaultTheme,
|
|
37
|
+
themes = {},
|
|
38
|
+
basePath = '/themes',
|
|
39
|
+
cdnPath = null,
|
|
40
|
+
preload = [],
|
|
41
|
+
lazy = true,
|
|
42
|
+
storageKey = 'atomix-theme',
|
|
43
|
+
dataAttribute = 'data-theme',
|
|
44
|
+
enablePersistence = true,
|
|
45
|
+
useMinified = false,
|
|
46
|
+
onThemeChange,
|
|
47
|
+
onError,
|
|
48
|
+
}) => {
|
|
49
|
+
// Store callbacks in refs to avoid recreating ThemeManager when they change
|
|
50
|
+
const onThemeChangeRef = useRef(onThemeChange);
|
|
51
|
+
const onErrorRef = useRef(onError);
|
|
52
|
+
|
|
53
|
+
// Update refs when callbacks change
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
onThemeChangeRef.current = onThemeChange;
|
|
56
|
+
onErrorRef.current = onError;
|
|
57
|
+
}, [onThemeChange, onError]);
|
|
58
|
+
|
|
59
|
+
// Create stable wrapper functions that read from refs
|
|
60
|
+
const handleThemeChange = useCallback((theme: string | Theme) => {
|
|
61
|
+
onThemeChangeRef.current?.(theme);
|
|
62
|
+
}, []);
|
|
63
|
+
|
|
64
|
+
const handleError = useCallback((error: Error, themeName: string) => {
|
|
65
|
+
onErrorRef.current?.(error, themeName);
|
|
66
|
+
}, []);
|
|
67
|
+
|
|
68
|
+
// Stabilize themes object reference to prevent unnecessary recreations
|
|
69
|
+
const themesRef = useRef(themes);
|
|
70
|
+
const themesStable = useMemo(() => {
|
|
71
|
+
// Only update if themes object actually changed (shallow comparison)
|
|
72
|
+
const currentKeys = Object.keys(themes);
|
|
73
|
+
const prevKeys = Object.keys(themesRef.current);
|
|
74
|
+
|
|
75
|
+
if (currentKeys.length !== prevKeys.length) {
|
|
76
|
+
themesRef.current = themes;
|
|
77
|
+
return themes;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const hasChanged = currentKeys.some(key => themes[key] !== themesRef.current[key]);
|
|
81
|
+
if (hasChanged) {
|
|
82
|
+
themesRef.current = themes;
|
|
83
|
+
return themes;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return themesRef.current;
|
|
87
|
+
}, [themes]);
|
|
88
|
+
|
|
89
|
+
const logger = useMemo(() => getLogger(), []);
|
|
90
|
+
|
|
91
|
+
// Initialize theme manager (only recreate when config changes, not callbacks)
|
|
92
|
+
const themeManager = useMemo(() => {
|
|
93
|
+
try {
|
|
94
|
+
return new ThemeManager({
|
|
95
|
+
themes: themesStable,
|
|
96
|
+
defaultTheme,
|
|
97
|
+
basePath,
|
|
98
|
+
cdnPath,
|
|
99
|
+
preload,
|
|
100
|
+
lazy,
|
|
101
|
+
storageKey,
|
|
102
|
+
dataAttribute,
|
|
103
|
+
enablePersistence,
|
|
104
|
+
useMinified,
|
|
105
|
+
onThemeChange: handleThemeChange,
|
|
106
|
+
onError: handleError,
|
|
107
|
+
});
|
|
108
|
+
} catch (error) {
|
|
109
|
+
logger.error(
|
|
110
|
+
'Failed to create ThemeManager',
|
|
111
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
112
|
+
{ themes: Object.keys(themesStable), defaultTheme }
|
|
113
|
+
);
|
|
114
|
+
// Return a minimal manager that won't crash
|
|
115
|
+
return new ThemeManager({
|
|
116
|
+
themes: {},
|
|
117
|
+
defaultTheme,
|
|
118
|
+
basePath,
|
|
119
|
+
storageKey,
|
|
120
|
+
enablePersistence: false,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}, [
|
|
124
|
+
themesStable,
|
|
125
|
+
defaultTheme,
|
|
126
|
+
basePath,
|
|
127
|
+
cdnPath,
|
|
128
|
+
preload,
|
|
129
|
+
lazy,
|
|
130
|
+
storageKey,
|
|
131
|
+
dataAttribute,
|
|
132
|
+
enablePersistence,
|
|
133
|
+
useMinified,
|
|
134
|
+
handleThemeChange,
|
|
135
|
+
handleError,
|
|
136
|
+
logger,
|
|
137
|
+
]);
|
|
138
|
+
|
|
139
|
+
// State for React re-renders
|
|
140
|
+
const [currentTheme, setCurrentTheme] = useState<string>(() => {
|
|
141
|
+
if (typeof defaultTheme === 'string') {
|
|
142
|
+
return defaultTheme;
|
|
143
|
+
}
|
|
144
|
+
if (isJSTheme(defaultTheme)) {
|
|
145
|
+
return defaultTheme.name || 'js-theme';
|
|
146
|
+
}
|
|
147
|
+
return ''; // No default theme - use built-in styles
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const [activeTheme, setActiveTheme] = useState<Theme | null>(() => {
|
|
151
|
+
if (isJSTheme(defaultTheme)) {
|
|
152
|
+
return defaultTheme;
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const [availableThemes, setAvailableThemes] = useState<ThemeMetadata[]>(() => {
|
|
158
|
+
return themeManager.getAvailableThemes();
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
162
|
+
const [error, setError] = useState<Error | null>(null);
|
|
163
|
+
|
|
164
|
+
// Use refs to store stable event handlers
|
|
165
|
+
const themeChangeHandlerRef = useRef<() => void>();
|
|
166
|
+
const themeLoadHandlerRef = useRef<() => void>();
|
|
167
|
+
const themeErrorHandlerRef = useRef<(err: Error) => void>();
|
|
168
|
+
|
|
169
|
+
// Track if we've initialized to prevent loops
|
|
170
|
+
const initializedRef = useRef(false);
|
|
171
|
+
|
|
172
|
+
// Update state when theme changes
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
let isMounted = true;
|
|
175
|
+
|
|
176
|
+
// Create stable handlers that use the current themeManager
|
|
177
|
+
themeChangeHandlerRef.current = () => {
|
|
178
|
+
if (!isMounted) return;
|
|
179
|
+
setCurrentTheme(prev => {
|
|
180
|
+
const current = themeManager.getTheme();
|
|
181
|
+
// Prevent unnecessary updates
|
|
182
|
+
if (current === prev) return prev;
|
|
183
|
+
return current;
|
|
184
|
+
});
|
|
185
|
+
setActiveTheme(prev => {
|
|
186
|
+
const current = themeManager.getActiveTheme();
|
|
187
|
+
// Prevent unnecessary updates by comparing references
|
|
188
|
+
if (current === prev) return prev;
|
|
189
|
+
if (!current && !prev) return prev;
|
|
190
|
+
return current;
|
|
191
|
+
});
|
|
192
|
+
setAvailableThemes(prev => {
|
|
193
|
+
const current = themeManager.getAvailableThemes();
|
|
194
|
+
// Only update if actually different
|
|
195
|
+
if (current.length !== prev.length) return current;
|
|
196
|
+
// Compare by name since ThemeMetadata doesn't have id
|
|
197
|
+
const hasChanged = current.some((t, i) => t.name !== prev[i]?.name || t.class !== prev[i]?.class);
|
|
198
|
+
return hasChanged ? current : prev;
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
themeLoadHandlerRef.current = () => {
|
|
203
|
+
if (!isMounted) return;
|
|
204
|
+
setCurrentTheme(prev => {
|
|
205
|
+
const current = themeManager.getTheme();
|
|
206
|
+
if (current === prev) return prev;
|
|
207
|
+
return current;
|
|
208
|
+
});
|
|
209
|
+
setActiveTheme(prev => {
|
|
210
|
+
const current = themeManager.getActiveTheme();
|
|
211
|
+
if (current === prev) return prev;
|
|
212
|
+
if (!current && !prev) return prev;
|
|
213
|
+
return current;
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
themeErrorHandlerRef.current = (err: Error) => {
|
|
218
|
+
if (!isMounted) return;
|
|
219
|
+
setError(err);
|
|
220
|
+
setIsLoading(false);
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// Wrapper functions that call the refs
|
|
224
|
+
const onThemeChangeEvent = () => themeChangeHandlerRef.current?.();
|
|
225
|
+
const onThemeLoadEvent = () => themeLoadHandlerRef.current?.();
|
|
226
|
+
const onThemeErrorEvent = (err: Error) => themeErrorHandlerRef.current?.(err);
|
|
227
|
+
|
|
228
|
+
// Set initial state only once on first mount
|
|
229
|
+
// Use functional updates to avoid stale closures
|
|
230
|
+
if (!initializedRef.current) {
|
|
231
|
+
initializedRef.current = true;
|
|
232
|
+
// Use functional updates to get current state and compare
|
|
233
|
+
setCurrentTheme(prev => {
|
|
234
|
+
const current = themeManager.getTheme();
|
|
235
|
+
return current !== prev ? current : prev;
|
|
236
|
+
});
|
|
237
|
+
setActiveTheme(prev => {
|
|
238
|
+
const current = themeManager.getActiveTheme();
|
|
239
|
+
return current !== prev ? current : prev;
|
|
240
|
+
});
|
|
241
|
+
setAvailableThemes(prev => {
|
|
242
|
+
const current = themeManager.getAvailableThemes();
|
|
243
|
+
if (current.length !== prev.length) return current;
|
|
244
|
+
const hasChanged = current.some((t, i) => t.name !== prev[i]?.name || t.class !== prev[i]?.class);
|
|
245
|
+
return hasChanged ? current : prev;
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Register event listeners
|
|
250
|
+
themeManager.on('themeChange', onThemeChangeEvent);
|
|
251
|
+
themeManager.on('themeLoad', onThemeLoadEvent);
|
|
252
|
+
themeManager.on('themeError', onThemeErrorEvent);
|
|
253
|
+
|
|
254
|
+
return () => {
|
|
255
|
+
isMounted = false;
|
|
256
|
+
themeManager.off('themeChange', onThemeChangeEvent);
|
|
257
|
+
themeManager.off('themeLoad', onThemeLoadEvent);
|
|
258
|
+
themeManager.off('themeError', onThemeErrorEvent);
|
|
259
|
+
};
|
|
260
|
+
}, [themeManager]);
|
|
261
|
+
|
|
262
|
+
// Cleanup on unmount
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
return () => {
|
|
265
|
+
themeManager.destroy();
|
|
266
|
+
};
|
|
267
|
+
}, [themeManager]);
|
|
268
|
+
|
|
269
|
+
// Context value
|
|
270
|
+
const contextValue = useMemo(() => ({
|
|
271
|
+
theme: currentTheme,
|
|
272
|
+
activeTheme,
|
|
273
|
+
setTheme: async (theme: string | Theme, options?: ThemeLoadOptions) => {
|
|
274
|
+
setIsLoading(true);
|
|
275
|
+
setError(null);
|
|
276
|
+
try {
|
|
277
|
+
await themeManager.setTheme(theme, options);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
280
|
+
setError(error);
|
|
281
|
+
throw err;
|
|
282
|
+
} finally {
|
|
283
|
+
setIsLoading(false);
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
availableThemes,
|
|
287
|
+
isLoading,
|
|
288
|
+
error,
|
|
289
|
+
isThemeLoaded: (themeName: string) => themeManager.isThemeLoaded(themeName),
|
|
290
|
+
preloadTheme: async (themeName: string) => {
|
|
291
|
+
setIsLoading(true);
|
|
292
|
+
try {
|
|
293
|
+
await themeManager.preloadTheme(themeName);
|
|
294
|
+
} catch (err) {
|
|
295
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
296
|
+
setError(error);
|
|
297
|
+
} finally {
|
|
298
|
+
setIsLoading(false);
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
themeManager: themeManager,
|
|
302
|
+
}), [
|
|
303
|
+
currentTheme,
|
|
304
|
+
activeTheme,
|
|
305
|
+
availableThemes,
|
|
306
|
+
isLoading,
|
|
307
|
+
error,
|
|
308
|
+
themeManager,
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
return (
|
|
312
|
+
<ThemeContext.Provider value={contextValue}>
|
|
313
|
+
{children}
|
|
314
|
+
</ThemeContext.Provider>
|
|
315
|
+
);
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
export default ThemeProvider;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Runtime Module
|
|
3
|
+
*
|
|
4
|
+
* Runtime components for theme management
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { ThemeManager } from './ThemeManager';
|
|
8
|
+
export { ThemeProvider } from './ThemeProvider';
|
|
9
|
+
export { ThemeErrorBoundary } from './ThemeErrorBoundary';
|
|
10
|
+
export { useTheme } from './useTheme';
|
|
11
|
+
export type { ThemeErrorBoundaryProps } from './ThemeErrorBoundary';
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
ThemeManagerConfig,
|
|
15
|
+
ThemeChangeEvent,
|
|
16
|
+
ThemeLoadOptions,
|
|
17
|
+
} from '../types';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useTheme Hook
|
|
3
|
+
*
|
|
4
|
+
* React hook for accessing theme context
|
|
5
|
+
* Updated to work with new ThemeEngine architecture
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { useContext } from 'react';
|
|
9
|
+
import { ThemeContext } from '../ThemeContext';
|
|
10
|
+
import type { UseThemeReturn } from '../types';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* useTheme hook
|
|
14
|
+
*
|
|
15
|
+
* Access theme context and theme management functions
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* function MyComponent() {
|
|
20
|
+
* const { theme, setTheme, availableThemes } = useTheme();
|
|
21
|
+
*
|
|
22
|
+
* return (
|
|
23
|
+
* <div>
|
|
24
|
+
* <p>Current theme: {theme}</p>
|
|
25
|
+
* <button onClick={() => setTheme('dark-theme')}>
|
|
26
|
+
* Switch to Dark
|
|
27
|
+
* </button>
|
|
28
|
+
* </div>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function useTheme(): UseThemeReturn {
|
|
34
|
+
const context = useContext(ThemeContext);
|
|
35
|
+
|
|
36
|
+
if (!context) {
|
|
37
|
+
throw new Error('useTheme must be used within a ThemeProvider');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
theme: context.theme,
|
|
42
|
+
activeTheme: context.activeTheme,
|
|
43
|
+
setTheme: context.setTheme,
|
|
44
|
+
availableThemes: context.availableThemes,
|
|
45
|
+
isLoading: context.isLoading,
|
|
46
|
+
error: context.error,
|
|
47
|
+
isThemeLoaded: context.isThemeLoaded,
|
|
48
|
+
preloadTheme: context.preloadTheme,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default useTheme;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* spacing helpers, and theme value accessors.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type { Theme, SpacingFunction } from './types';
|
|
8
|
+
import type { Theme, SpacingFunction, SpacingOptions } from './types';
|
|
9
9
|
|
|
10
10
|
// ============================================================================
|
|
11
11
|
// Color Manipulation Utilities
|
|
@@ -150,15 +150,37 @@ export function emphasize(color: string, coefficient: number = 0.15): string {
|
|
|
150
150
|
// ============================================================================
|
|
151
151
|
|
|
152
152
|
/**
|
|
153
|
-
* Create a spacing function
|
|
153
|
+
* Create a spacing function from various input types
|
|
154
154
|
*
|
|
155
|
-
* @param
|
|
155
|
+
* @param spacingInput - Spacing configuration (number, array, or function), default 4
|
|
156
156
|
* @returns Spacing function
|
|
157
157
|
*/
|
|
158
|
-
export function createSpacing(
|
|
158
|
+
export function createSpacing(spacingInput: SpacingOptions = 4): SpacingFunction {
|
|
159
|
+
// If it's already a function, return it
|
|
160
|
+
if (typeof spacingInput === 'function') {
|
|
161
|
+
return spacingInput;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// If it's a number, create a function that multiplies by that number
|
|
165
|
+
if (typeof spacingInput === 'number') {
|
|
166
|
+
return (...values: number[]) => {
|
|
167
|
+
if (values.length === 0) return '0px';
|
|
168
|
+
return values.map((value) => `${value * spacingInput}px`).join(' ');
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// If it's an array, use it as a scale
|
|
173
|
+
if (Array.isArray(spacingInput)) {
|
|
174
|
+
return (...values: number[]) => {
|
|
175
|
+
if (values.length === 0) return '0px';
|
|
176
|
+
return values.map((value) => `${spacingInput[value] || value}px`).join(' ');
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Default to 4px base
|
|
159
181
|
return (...values: number[]) => {
|
|
160
182
|
if (values.length === 0) return '0px';
|
|
161
|
-
return values.map((value) => `${value *
|
|
183
|
+
return values.map((value) => `${value * 4}px`).join(' ');
|
|
162
184
|
};
|
|
163
185
|
}
|
|
164
186
|
|
package/src/lib/theme/types.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* TypeScript types and interfaces for the Atomix Design System theme management system.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { ThemeManager as ThemeManagerType } from './ThemeManager';
|
|
7
|
+
import type { ThemeManager as ThemeManagerType } from './runtime/ThemeManager';
|
|
8
|
+
import type { PartStyleProps } from '../types/partProps';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Theme metadata interface matching themes.config.js structure
|
|
@@ -71,6 +72,8 @@ export interface ThemeManagerConfig {
|
|
|
71
72
|
onThemeChange?: (theme: string | Theme) => void;
|
|
72
73
|
/** Callback when theme load fails */
|
|
73
74
|
onError?: (error: Error, themeName: string) => void;
|
|
75
|
+
/** RTL configuration */
|
|
76
|
+
rtl?: import('./i18n/rtl').RTLConfig;
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
/**
|
|
@@ -182,6 +185,62 @@ export interface UseThemeReturn {
|
|
|
182
185
|
preloadTheme: (themeName: string) => Promise<void>;
|
|
183
186
|
}
|
|
184
187
|
|
|
188
|
+
/**
|
|
189
|
+
* Component-level theme override configuration
|
|
190
|
+
*/
|
|
191
|
+
export interface ComponentThemeOverride {
|
|
192
|
+
/** CSS variable overrides for the component */
|
|
193
|
+
cssVars?: Record<string, string | number>;
|
|
194
|
+
|
|
195
|
+
/** Default prop overrides */
|
|
196
|
+
defaultProps?: Record<string, any>;
|
|
197
|
+
|
|
198
|
+
/** Part-specific overrides */
|
|
199
|
+
parts?: Record<string, {
|
|
200
|
+
cssVars?: Record<string, string | number>;
|
|
201
|
+
className?: string;
|
|
202
|
+
}>;
|
|
203
|
+
|
|
204
|
+
/** Variant overrides */
|
|
205
|
+
variants?: Record<string, {
|
|
206
|
+
cssVars?: Record<string, string | number>;
|
|
207
|
+
className?: string;
|
|
208
|
+
}>;
|
|
209
|
+
|
|
210
|
+
/** Additional className for the component */
|
|
211
|
+
className?: string;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Theme component overrides for all components
|
|
216
|
+
*/
|
|
217
|
+
export interface ThemeComponentOverrides {
|
|
218
|
+
Button?: ComponentThemeOverride;
|
|
219
|
+
Card?: ComponentThemeOverride;
|
|
220
|
+
Input?: ComponentThemeOverride;
|
|
221
|
+
Modal?: ComponentThemeOverride;
|
|
222
|
+
Dropdown?: ComponentThemeOverride;
|
|
223
|
+
Badge?: ComponentThemeOverride;
|
|
224
|
+
Tabs?: ComponentThemeOverride;
|
|
225
|
+
Progress?: ComponentThemeOverride;
|
|
226
|
+
Tooltip?: ComponentThemeOverride;
|
|
227
|
+
Select?: ComponentThemeOverride;
|
|
228
|
+
Checkbox?: ComponentThemeOverride;
|
|
229
|
+
Radio?: ComponentThemeOverride;
|
|
230
|
+
Textarea?: ComponentThemeOverride;
|
|
231
|
+
FormGroup?: ComponentThemeOverride;
|
|
232
|
+
Navbar?: ComponentThemeOverride;
|
|
233
|
+
Accordion?: ComponentThemeOverride;
|
|
234
|
+
DataTable?: ComponentThemeOverride;
|
|
235
|
+
Avatar?: ComponentThemeOverride;
|
|
236
|
+
List?: ComponentThemeOverride;
|
|
237
|
+
Popover?: ComponentThemeOverride;
|
|
238
|
+
Messages?: ComponentThemeOverride;
|
|
239
|
+
Callout?: ComponentThemeOverride;
|
|
240
|
+
Spinner?: ComponentThemeOverride;
|
|
241
|
+
[key: string]: ComponentThemeOverride | undefined;
|
|
242
|
+
}
|
|
243
|
+
|
|
185
244
|
/**
|
|
186
245
|
* Theme provider props
|
|
187
246
|
*/
|
|
@@ -557,6 +616,8 @@ export interface Theme extends ThemeMetadata {
|
|
|
557
616
|
borderRadius: Required<BorderRadiusOptions>;
|
|
558
617
|
/** Custom properties */
|
|
559
618
|
custom: ThemeCustomProperties;
|
|
619
|
+
/** Global CSS variables to apply */
|
|
620
|
+
cssVars?: Record<string, string | number>;
|
|
560
621
|
/** Indicates this is a JS theme (not CSS-only) */
|
|
561
622
|
__isJSTheme: true;
|
|
562
623
|
}
|
package/src/lib/theme/utils.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { ThemeMetadata, ThemeValidationResult } from './types';
|
|
9
|
+
import { THEME_LINK_ID_PREFIX } from './constants';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Check if code is running in a browser environment
|
|
@@ -25,7 +26,7 @@ export const isServer = (): boolean => {
|
|
|
25
26
|
* Generate a unique ID for theme link elements
|
|
26
27
|
*/
|
|
27
28
|
export const getThemeLinkId = (themeName: string): string => {
|
|
28
|
-
return
|
|
29
|
+
return `${THEME_LINK_ID_PREFIX}${themeName}`;
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
/**
|
|
@@ -65,28 +66,24 @@ export const buildThemePath = (
|
|
|
65
66
|
return `${cleanBasePath}/${cleanFileName}`;
|
|
66
67
|
};
|
|
67
68
|
|
|
69
|
+
|
|
70
|
+
|
|
68
71
|
/**
|
|
69
|
-
* Load theme CSS
|
|
72
|
+
* Load theme CSS from a full path
|
|
70
73
|
*
|
|
71
|
-
* @param
|
|
72
|
-
* @param
|
|
73
|
-
* @param useMinified - Whether to use minified CSS
|
|
74
|
-
* @param cdnPath - Optional CDN path
|
|
74
|
+
* @param fullPath - Full path to the CSS file
|
|
75
|
+
* @param linkId - ID for the link element
|
|
75
76
|
* @returns Promise that resolves when CSS is loaded
|
|
76
77
|
*/
|
|
77
78
|
export const loadThemeCSS = (
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
useMinified: boolean = false,
|
|
81
|
-
cdnPath: string | null = null
|
|
79
|
+
fullPath: string,
|
|
80
|
+
linkId: string
|
|
82
81
|
): Promise<void> => {
|
|
83
82
|
if (isServer()) {
|
|
84
83
|
return Promise.resolve();
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
return new Promise((resolve, reject) => {
|
|
88
|
-
const linkId = getThemeLinkId(themeName);
|
|
89
|
-
|
|
90
87
|
// Check if theme is already loaded
|
|
91
88
|
const existingLink = document.getElementById(linkId);
|
|
92
89
|
if (existingLink) {
|
|
@@ -99,10 +96,10 @@ export const loadThemeCSS = (
|
|
|
99
96
|
link.id = linkId;
|
|
100
97
|
link.rel = 'stylesheet';
|
|
101
98
|
link.type = 'text/css';
|
|
102
|
-
link.href =
|
|
99
|
+
link.href = fullPath;
|
|
103
100
|
|
|
104
101
|
// Add data attribute for tracking
|
|
105
|
-
link.setAttribute('data-atomix-theme',
|
|
102
|
+
link.setAttribute('data-atomix-theme', 'true');
|
|
106
103
|
|
|
107
104
|
// Handle load success
|
|
108
105
|
link.onload = () => {
|
|
@@ -113,7 +110,7 @@ export const loadThemeCSS = (
|
|
|
113
110
|
link.onerror = () => {
|
|
114
111
|
// Remove failed link element
|
|
115
112
|
link.remove();
|
|
116
|
-
reject(new Error(`Failed to load theme: ${
|
|
113
|
+
reject(new Error(`Failed to load theme CSS: ${fullPath}`));
|
|
117
114
|
};
|
|
118
115
|
|
|
119
116
|
// Append to head
|
|
@@ -124,15 +121,19 @@ export const loadThemeCSS = (
|
|
|
124
121
|
/**
|
|
125
122
|
* Remove theme CSS from the DOM
|
|
126
123
|
*
|
|
127
|
-
* @param
|
|
124
|
+
* @param themeNameOrLinkId - Name of the theme or link ID to remove
|
|
128
125
|
*/
|
|
129
|
-
export const removeThemeCSS = (
|
|
126
|
+
export const removeThemeCSS = (themeNameOrLinkId: string): void => {
|
|
130
127
|
if (isServer()) {
|
|
131
128
|
return;
|
|
132
129
|
}
|
|
133
130
|
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
// Try as link ID first, then as theme name
|
|
132
|
+
let link = document.getElementById(themeNameOrLinkId);
|
|
133
|
+
if (!link) {
|
|
134
|
+
const linkId = getThemeLinkId(themeNameOrLinkId);
|
|
135
|
+
link = document.getElementById(linkId);
|
|
136
|
+
}
|
|
136
137
|
|
|
137
138
|
if (link) {
|
|
138
139
|
link.remove();
|
|
@@ -154,12 +155,12 @@ export const removeAllThemeCSS = (): void => {
|
|
|
154
155
|
/**
|
|
155
156
|
* Apply theme data attributes to the document
|
|
156
157
|
*
|
|
157
|
-
* @param themeName - Name of the theme
|
|
158
158
|
* @param dataAttribute - Data attribute name (default: 'data-theme')
|
|
159
|
+
* @param themeName - Name of the theme
|
|
159
160
|
*/
|
|
160
161
|
export const applyThemeAttributes = (
|
|
161
|
-
|
|
162
|
-
|
|
162
|
+
dataAttribute: string,
|
|
163
|
+
themeName: string
|
|
163
164
|
): void => {
|
|
164
165
|
if (isServer()) {
|
|
165
166
|
return;
|