@shohojdhara/atomix 0.3.14 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/build-tools/EXAMPLES.md +372 -0
- package/build-tools/README.md +242 -0
- package/build-tools/__tests__/error-handler.test.js +230 -0
- package/build-tools/__tests__/index.test.js +141 -0
- package/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/build-tools/__tests__/utils.test.js +161 -0
- package/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/build-tools/error-handler.js +308 -0
- package/build-tools/index.d.ts +44 -0
- package/build-tools/index.js +88 -0
- package/build-tools/package.json +50 -0
- package/build-tools/rollup-plugin.js +236 -0
- package/build-tools/types.d.ts +163 -0
- package/build-tools/utils.js +203 -0
- package/build-tools/vite-plugin.js +161 -0
- package/build-tools/webpack-loader.js +123 -0
- package/dist/atomix.css +21044 -2618
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +77 -3
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/EXAMPLES.md +372 -0
- package/dist/build-tools/README.md +242 -0
- package/dist/build-tools/__tests__/error-handler.test.js +230 -0
- package/dist/build-tools/__tests__/index.test.js +141 -0
- package/dist/build-tools/__tests__/rollup-plugin.test.js +194 -0
- package/dist/build-tools/__tests__/utils.test.js +161 -0
- package/dist/build-tools/__tests__/vite-plugin.test.js +129 -0
- package/dist/build-tools/__tests__/webpack-loader.test.js +190 -0
- package/dist/build-tools/error-handler.js +308 -0
- package/dist/build-tools/index.d.ts +44 -0
- package/dist/build-tools/index.js +88 -0
- package/dist/build-tools/package.json +50 -0
- package/dist/build-tools/rollup-plugin.js +236 -0
- package/dist/build-tools/types.d.ts +163 -0
- package/dist/build-tools/utils.js +203 -0
- package/dist/build-tools/vite-plugin.js +161 -0
- package/dist/build-tools/webpack-loader.js +123 -0
- package/dist/charts.d.ts +1 -1
- package/dist/charts.js +86 -57
- package/dist/charts.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.js +136 -112
- package/dist/core.js.map +1 -1
- package/dist/forms.d.ts +2 -5
- package/dist/forms.js +140 -128
- package/dist/forms.js.map +1 -1
- package/dist/heavy.d.ts +1 -1
- package/dist/heavy.js +136 -112
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +152 -78
- package/dist/index.esm.js +346 -340
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +359 -353
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.js.map +1 -1
- package/dist/theme.d.ts +9 -9
- package/dist/theme.js.map +1 -1
- package/package.json +23 -8
- package/scripts/atomix-cli.js +170 -73
- package/scripts/cli/__tests__/README.md +81 -0
- package/scripts/cli/__tests__/basic.test.js +115 -0
- package/scripts/cli/__tests__/component-generator.test.js +332 -0
- package/scripts/cli/__tests__/integration.test.js +327 -0
- package/scripts/cli/__tests__/test-setup.js +133 -0
- package/scripts/cli/__tests__/token-manager.test.js +251 -0
- package/scripts/cli/__tests__/utils.test.js +161 -0
- package/scripts/cli/component-generator.js +253 -299
- package/scripts/cli/dependency-checker.js +355 -0
- package/scripts/cli/interactive-init.js +46 -5
- package/scripts/cli/template-manager.js +0 -2
- package/scripts/cli/templates/common-templates.js +636 -0
- package/scripts/cli/templates/composable-templates.js +148 -126
- package/scripts/cli/templates/index.js +23 -16
- package/scripts/cli/templates/project-templates.js +151 -23
- package/scripts/cli/templates/react-templates.js +280 -210
- package/scripts/cli/templates/scss-templates.js +90 -91
- package/scripts/cli/templates/testing-templates.js +206 -27
- package/scripts/cli/templates/testing-utils.js +278 -0
- package/scripts/cli/templates/types-templates.js +70 -56
- package/scripts/cli/theme-bridge.js +8 -2
- package/scripts/cli/token-manager.js +318 -206
- package/scripts/cli/utils.js +0 -1
- package/src/components/Accordion/Accordion.stories.tsx +358 -850
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +99 -94
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +80 -39
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +103 -81
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/__snapshots__/AtomixGlass.test.tsx.snap +8 -7
- package/src/components/AtomixGlass/glass-utils.ts +6 -5
- package/src/components/AtomixGlass/shader-utils.ts +133 -52
- package/src/components/AtomixGlass/stories/Customization.stories.tsx +131 -0
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2957 -2853
- package/src/components/AtomixGlass/stories/Modes.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Overview.stories.tsx +348 -0
- package/src/components/AtomixGlass/stories/Performance.stories.tsx +103 -0
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +51 -36
- package/src/components/AtomixGlass/stories/{ShaderVariants.stories.tsx → Shaders.stories.tsx} +2 -2
- package/src/components/AtomixGlass/stories/shared-components.tsx +90 -190
- package/src/components/Avatar/Avatar.stories.tsx +195 -0
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +122 -352
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +30 -11
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +142 -23
- package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
- package/src/components/Button/Button.stories.tsx +454 -1126
- package/src/components/Button/Button.test.tsx +123 -0
- package/src/components/Button/Button.tsx +88 -60
- package/src/components/Button/ButtonGroup.stories.tsx +376 -215
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +316 -568
- package/src/components/Card/Card.stories.tsx +292 -81
- package/src/components/Card/Card.tsx +30 -14
- package/src/components/Chart/AreaChart.tsx +1 -1
- package/src/components/Chart/CandlestickChart.tsx +23 -16
- package/src/components/Chart/Chart.stories.tsx +153 -16
- package/src/components/Chart/Chart.tsx +40 -44
- package/src/components/Chart/ChartRenderer.tsx +39 -12
- package/src/components/Chart/ChartToolbar.tsx +21 -5
- package/src/components/Chart/DonutChart.tsx +1 -1
- package/src/components/Chart/FunnelChart.tsx +4 -1
- package/src/components/Chart/GaugeChart.tsx +3 -1
- package/src/components/Chart/HeatmapChart.tsx +50 -37
- package/src/components/Chart/LineChart.tsx +3 -2
- package/src/components/Chart/MultiAxisChart.tsx +24 -16
- package/src/components/Chart/RadarChart.tsx +19 -17
- package/src/components/Chart/ScatterChart.tsx +29 -21
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +152 -66
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +114 -7
- package/src/components/DataTable/DataTable.stories.tsx +349 -144
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +310 -1066
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +153 -36
- package/src/components/Dropdown/Dropdown.tsx +313 -299
- package/src/components/EdgePanel/EdgePanel.stories.tsx +221 -25
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Footer/Footer.stories.tsx +396 -327
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.stories.tsx +140 -6
- package/src/components/Form/Checkbox.test.tsx +63 -0
- package/src/components/Form/Checkbox.tsx +122 -78
- package/src/components/Form/Form.stories.tsx +110 -19
- package/src/components/Form/FormGroup.stories.tsx +127 -4
- package/src/components/Form/Input.stories.tsx +22 -39
- package/src/components/Form/Input.test.tsx +38 -44
- package/src/components/Form/Radio.stories.tsx +146 -17
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.stories.tsx +140 -8
- package/src/components/Form/Select.tsx +184 -182
- package/src/components/Form/Textarea.stories.tsx +149 -6
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +372 -38
- package/src/components/Hero/Hero.tsx +201 -55
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.stories.tsx +141 -3
- package/src/components/List/List.tsx +19 -23
- package/src/components/Modal/Modal.stories.tsx +183 -43
- package/src/components/Modal/Modal.tsx +130 -127
- package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
- package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
- package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
- package/src/components/Pagination/Pagination.stories.tsx +7 -4
- package/src/components/Pagination/Pagination.tsx +199 -202
- package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
- package/src/components/Popover/Popover.stories.tsx +354 -97
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +160 -7
- package/src/components/River/River.stories.tsx +3 -2
- package/src/components/SectionIntro/SectionIntro.stories.tsx +239 -47
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +104 -8
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +173 -42
- package/src/components/Tabs/Tabs.stories.tsx +141 -12
- package/src/components/Tabs/Tabs.tsx +74 -72
- package/src/components/Testimonial/Testimonial.stories.tsx +120 -3
- package/src/components/Todo/Todo.stories.tsx +198 -9
- package/src/components/Toggle/Toggle.stories.tsx +137 -36
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +194 -100
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +241 -150
- package/src/components/Upload/Upload.tsx +287 -283
- package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
- package/src/components/index.ts +13 -2
- package/src/layouts/Grid/Grid.stories.tsx +9 -3
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
- package/src/lib/README.md +2 -2
- package/src/lib/__tests__/theme-tools.test.ts +219 -0
- package/src/lib/composables/index.ts +2 -2
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +126 -97
- package/src/lib/composables/useChartExport.ts +3 -8
- package/src/lib/composables/useDataTable.ts +72 -43
- package/src/lib/composables/useHero.ts +58 -14
- package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
- package/src/lib/composables/useInput.ts +10 -8
- package/src/lib/composables/useSideMenu.ts +6 -5
- package/src/lib/composables/useTooltip.ts +1 -2
- package/src/lib/composables/useVideoPlayer.ts +44 -35
- package/src/lib/config/index.ts +154 -154
- package/src/lib/constants/components.ts +9 -32
- package/src/lib/constants/cssVariables.ts +29 -29
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
- package/src/lib/hooks/index.ts +1 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -17
- package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
- package/src/lib/patterns/__tests__/slots.test.ts +1 -1
- package/src/lib/patterns/index.ts +1 -1
- package/src/lib/patterns/slots.tsx +8 -13
- package/src/lib/storybook/InteractiveDemo.tsx +13 -18
- package/src/lib/storybook/PreviewContainer.tsx +1 -1
- package/src/lib/storybook/VariantsGrid.tsx +3 -7
- package/src/lib/storybook/index.ts +1 -1
- package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
- package/src/lib/theme/adapters/index.ts +3 -9
- package/src/lib/theme/adapters/themeAdapter.ts +41 -26
- package/src/lib/theme/config/index.ts +1 -1
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +10 -5
- package/src/lib/theme/constants/constants.ts +2 -2
- package/src/lib/theme/constants/index.ts +1 -2
- package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
- package/src/lib/theme/core/composeTheme.ts +32 -26
- package/src/lib/theme/core/createTheme.ts +1 -1
- package/src/lib/theme/core/createThemeObject.ts +308 -301
- package/src/lib/theme/core/index.ts +3 -3
- package/src/lib/theme/devtools/CLI.ts +107 -105
- package/src/lib/theme/devtools/Comparator.tsx +50 -32
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
- package/src/lib/theme/devtools/Inspector.tsx +75 -60
- package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
- package/src/lib/theme/devtools/Preview.tsx +150 -106
- package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
- package/src/lib/theme/devtools/index.ts +3 -9
- package/src/lib/theme/devtools/useHistory.ts +23 -21
- package/src/lib/theme/errors/errors.ts +12 -11
- package/src/lib/theme/errors/index.ts +2 -7
- package/src/lib/theme/generators/generateCSS.ts +9 -13
- package/src/lib/theme/generators/generateCSSNested.ts +1 -6
- package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
- package/src/lib/theme/generators/index.ts +1 -4
- package/src/lib/theme/i18n/index.ts +1 -1
- package/src/lib/theme/i18n/rtl.ts +13 -13
- package/src/lib/theme/index.ts +7 -16
- package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
- package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
- package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
- package/src/lib/theme/runtime/index.ts +2 -5
- package/src/lib/theme/runtime/useTheme.ts +18 -18
- package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
- package/src/lib/theme/test/testTheme.ts +15 -16
- package/src/lib/theme/tokens/index.ts +2 -7
- package/src/lib/theme/tokens/tokens.ts +25 -24
- package/src/lib/theme/types.ts +428 -411
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
- package/src/lib/theme/utils/componentTheming.ts +18 -18
- package/src/lib/theme/utils/domUtils.ts +277 -289
- package/src/lib/theme/utils/index.ts +1 -2
- package/src/lib/theme/utils/injectCSS.ts +10 -14
- package/src/lib/theme/utils/naming.ts +20 -16
- package/src/lib/theme/utils/themeHelpers.ts +10 -12
- package/src/lib/theme/utils/themeUtils.ts +85 -86
- package/src/lib/theme/utils/themeValidation.ts +82 -33
- package/src/lib/theme-tools.ts +8 -6
- package/src/lib/types/components.ts +172 -71
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/csv.test.ts +45 -0
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +19 -0
- package/src/lib/utils/dataTableExport.ts +2 -15
- package/src/lib/utils/fontPreloader.ts +10 -19
- package/src/lib/utils/icons.ts +4 -1
- package/src/lib/utils/index.ts +2 -6
- package/src/lib/utils/memoryMonitor.ts +10 -8
- package/src/lib/utils/themeNaming.ts +2 -2
- package/src/styles/01-settings/_index.scss +1 -1
- package/src/styles/01-settings/_settings.accordion.scss +28 -7
- package/src/styles/01-settings/_settings.colors.scss +11 -11
- package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.spacing.scss +3 -4
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.typography.scss +4 -4
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +38 -12
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.accordion.scss +56 -14
- package/src/styles/06-components/_components.atomix-glass.scss +13 -9
- package/src/styles/06-components/_components.button.scss +16 -4
- package/src/styles/06-components/_components.callout.scss +27 -21
- package/src/styles/06-components/_components.card.scss +5 -14
- package/src/styles/06-components/_components.chart.scss +22 -19
- package/src/styles/06-components/_components.checkbox.scss +25 -17
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
- package/src/styles/06-components/_components.edge-panel.scss +9 -2
- package/src/styles/06-components/_components.footer.scss +1 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -5
- package/src/styles/06-components/_components.toggle.scss +18 -0
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/06-components/old.chart.styles.scss +0 -2
- package/src/styles/99-utilities/_index.scss +2 -0
- package/src/styles/99-utilities/_utilities.border.scss +69 -27
- package/src/styles/99-utilities/_utilities.display.scss +1 -1
- package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
- package/src/styles/99-utilities/_utilities.position.scss +16 -9
- package/src/styles/99-utilities/_utilities.scss +2 -0
- package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
- package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
- package/src/styles/99-utilities/_utilities.text-gradient.scss +45 -0
- package/src/styles/99-utilities/_utilities.text.scss +67 -46
- package/themes/dark-complementary/README.md +98 -0
- package/themes/dark-complementary/index.scss +158 -0
- package/themes/default-light/README.md +81 -0
- package/themes/default-light/index.scss +154 -0
- package/themes/high-contrast/README.md +105 -0
- package/themes/high-contrast/index.scss +172 -0
- package/themes/test-theme/README.md +38 -0
- package/themes/test-theme/index.scss +47 -0
- package/scripts/cli/templates-original-backup.js +0 -1655
- package/scripts/cli/templates_backup.js +0 -684
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +0 -1438
- package/src/lib/composables/useButton.ts +0 -93
- package/src/lib/composables/useCheckbox.ts +0 -70
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Provider
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* React context provider for theme management with separated concerns
|
|
5
5
|
* Updated to use the new simplified theme system
|
|
6
6
|
*/
|
|
@@ -89,8 +89,6 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
|
89
89
|
return defaultTheme;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
92
|
// Default fallback
|
|
95
93
|
return 'default';
|
|
96
94
|
}, [defaultTheme, enablePersistence, storageKey]);
|
|
@@ -176,235 +174,230 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
|
176
174
|
}, []);
|
|
177
175
|
|
|
178
176
|
// Function to set theme with proper type handling
|
|
179
|
-
const setTheme = useCallback(
|
|
180
|
-
theme: string | DesignTokens | Partial<DesignTokens>,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
abortControllerRef.current.abort();
|
|
186
|
-
}
|
|
177
|
+
const setTheme = useCallback(
|
|
178
|
+
async (theme: string | DesignTokens | Partial<DesignTokens>, options?: ThemeLoadOptions) => {
|
|
179
|
+
// Cancel previous theme load if in progress
|
|
180
|
+
if (abortControllerRef.current) {
|
|
181
|
+
abortControllerRef.current.abort();
|
|
182
|
+
}
|
|
187
183
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
184
|
+
// Create new AbortController for this theme load
|
|
185
|
+
const abortController = new AbortController();
|
|
186
|
+
abortControllerRef.current = abortController;
|
|
191
187
|
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
setIsLoading(true);
|
|
189
|
+
setError(null);
|
|
194
190
|
|
|
195
|
-
|
|
196
|
-
|
|
191
|
+
try {
|
|
192
|
+
let themeName: string;
|
|
197
193
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
194
|
+
if (typeof theme === 'string') {
|
|
195
|
+
themeName = theme;
|
|
196
|
+
} else {
|
|
197
|
+
// Check if aborted before processing
|
|
198
|
+
if (abortController.signal.aborted) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
205
201
|
|
|
206
|
-
|
|
207
|
-
|
|
202
|
+
// Validate and merge DesignTokens
|
|
203
|
+
const { tokens: validatedTokens, validation } = validateAndMergeTokens(theme);
|
|
204
|
+
|
|
205
|
+
if (!validation.valid) {
|
|
206
|
+
const errorMsg = `Invalid DesignTokens provided: ${validation.errors.join(', ')}`;
|
|
207
|
+
const validationError = new Error(errorMsg);
|
|
208
|
+
logger.error('Theme validation failed', validationError, {
|
|
209
|
+
errors: validation.errors,
|
|
210
|
+
warnings: validation.warnings,
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// Check if we should fallback to default theme
|
|
214
|
+
const shouldFallback = options?.fallbackOnError !== false; // Default to true
|
|
215
|
+
if (shouldFallback) {
|
|
216
|
+
logger.warn('Falling back to default theme due to validation errors');
|
|
217
|
+
// Use default tokens instead
|
|
218
|
+
const { tokens: defaultTokens } = validateAndMergeTokens({});
|
|
219
|
+
const css = createTheme(defaultTokens);
|
|
220
|
+
const themeId = 'tokens-theme-fallback';
|
|
221
|
+
|
|
222
|
+
// Check if aborted before state update
|
|
223
|
+
if (abortController.signal.aborted) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
208
226
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const validationError = new Error(errorMsg);
|
|
212
|
-
logger.error('Theme validation failed', validationError, {
|
|
213
|
-
errors: validation.errors,
|
|
214
|
-
warnings: validation.warnings,
|
|
215
|
-
});
|
|
227
|
+
// Remove any previously loaded theme CSS
|
|
228
|
+
removeCSS(`theme-${currentTheme}`);
|
|
216
229
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// Check if aborted before state update
|
|
227
|
-
if (abortController.signal.aborted) {
|
|
230
|
+
// Inject new theme CSS
|
|
231
|
+
injectCSS(css, `theme-${themeId}`);
|
|
232
|
+
|
|
233
|
+
// Store default tokens
|
|
234
|
+
setActiveTokens(defaultTokens);
|
|
235
|
+
setCurrentTheme(themeId);
|
|
236
|
+
handleThemeChange(defaultTokens);
|
|
237
|
+
handleError(validationError, themeId);
|
|
238
|
+
setIsLoading(false);
|
|
228
239
|
return;
|
|
240
|
+
} else {
|
|
241
|
+
// No fallback, throw the error
|
|
242
|
+
throw validationError;
|
|
229
243
|
}
|
|
244
|
+
}
|
|
230
245
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
// Inject new theme CSS
|
|
235
|
-
injectCSS(css, `theme-${themeId}`);
|
|
246
|
+
// For valid DesignTokens, create CSS and inject it
|
|
247
|
+
const css = createTheme(validatedTokens);
|
|
248
|
+
const themeId = 'tokens-theme';
|
|
236
249
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
setCurrentTheme(themeId);
|
|
240
|
-
handleThemeChange(defaultTokens);
|
|
241
|
-
handleError(validationError, themeId);
|
|
242
|
-
setIsLoading(false);
|
|
250
|
+
// Check if aborted after async operation
|
|
251
|
+
if (abortController.signal.aborted) {
|
|
243
252
|
return;
|
|
244
|
-
} else {
|
|
245
|
-
// No fallback, throw the error
|
|
246
|
-
throw validationError;
|
|
247
253
|
}
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// For valid DesignTokens, create CSS and inject it
|
|
251
|
-
const css = createTheme(validatedTokens);
|
|
252
|
-
const themeId = 'tokens-theme';
|
|
253
254
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return;
|
|
257
|
-
}
|
|
255
|
+
// Remove any previously loaded theme CSS
|
|
256
|
+
removeCSS(`theme-${currentTheme}`);
|
|
258
257
|
|
|
259
|
-
|
|
260
|
-
|
|
258
|
+
// Inject new theme CSS
|
|
259
|
+
injectCSS(css, `theme-${themeId}`);
|
|
261
260
|
|
|
262
|
-
|
|
263
|
-
injectCSS(css, `theme-${themeId}`);
|
|
264
|
-
|
|
265
|
-
// Store validated tokens for reference
|
|
266
|
-
|
|
267
|
-
// Check if aborted before state update
|
|
268
|
-
if (abortController.signal.aborted) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
setActiveTokens(validatedTokens);
|
|
273
|
-
setCurrentTheme(themeId);
|
|
274
|
-
handleThemeChange(validatedTokens);
|
|
275
|
-
setIsLoading(false);
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
261
|
+
// Store validated tokens for reference
|
|
278
262
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
// Check if theme is already loading
|
|
282
|
-
if (themePromisesRef.current[theme]) {
|
|
283
|
-
try {
|
|
284
|
-
await themePromisesRef.current[theme];
|
|
285
|
-
// Check if aborted
|
|
286
|
-
if (abortController.signal.aborted) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
setCurrentTheme(theme);
|
|
290
|
-
setActiveTokens(null);
|
|
291
|
-
handleThemeChange(theme);
|
|
292
|
-
setIsLoading(false);
|
|
263
|
+
// Check if aborted before state update
|
|
264
|
+
if (abortController.signal.aborted) {
|
|
293
265
|
return;
|
|
294
|
-
} catch {
|
|
295
|
-
// If previous load failed, continue with new load
|
|
296
266
|
}
|
|
267
|
+
|
|
268
|
+
setActiveTokens(validatedTokens);
|
|
269
|
+
setCurrentTheme(themeId);
|
|
270
|
+
handleThemeChange(validatedTokens);
|
|
271
|
+
setIsLoading(false);
|
|
272
|
+
return;
|
|
297
273
|
}
|
|
298
274
|
|
|
299
|
-
//
|
|
300
|
-
|
|
301
|
-
//
|
|
302
|
-
|
|
275
|
+
// If it's a string theme name, load the associated CSS
|
|
276
|
+
if (typeof theme === 'string' && themes[theme]) {
|
|
277
|
+
// Check if theme is already loading
|
|
278
|
+
if (themePromisesRef.current[theme]) {
|
|
303
279
|
try {
|
|
280
|
+
await themePromisesRef.current[theme];
|
|
304
281
|
// Check if aborted
|
|
305
282
|
if (abortController.signal.aborted) {
|
|
306
|
-
resolve();
|
|
307
283
|
return;
|
|
308
284
|
}
|
|
285
|
+
setCurrentTheme(theme);
|
|
286
|
+
setActiveTokens(null);
|
|
287
|
+
handleThemeChange(theme);
|
|
288
|
+
setIsLoading(false);
|
|
289
|
+
return;
|
|
290
|
+
} catch {
|
|
291
|
+
// If previous load failed, continue with new load
|
|
292
|
+
}
|
|
293
|
+
}
|
|
309
294
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
theme,
|
|
316
|
-
basePath,
|
|
317
|
-
useMinified,
|
|
318
|
-
cdnPath
|
|
319
|
-
);
|
|
320
|
-
|
|
295
|
+
// Load CSS theme
|
|
296
|
+
const themeLoadPromise = new Promise<void>((resolve, reject) => {
|
|
297
|
+
// Handle the async operations inside the promise without making the executor async
|
|
298
|
+
const loadTheme = async () => {
|
|
299
|
+
try {
|
|
321
300
|
// Check if aborted
|
|
322
301
|
if (abortController.signal.aborted) {
|
|
323
302
|
resolve();
|
|
324
303
|
return;
|
|
325
304
|
}
|
|
326
305
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
306
|
+
const themeMetadata = themes[theme];
|
|
307
|
+
|
|
308
|
+
if (themeMetadata) {
|
|
309
|
+
// Build CSS path using utility function
|
|
310
|
+
const cssPath = buildThemePath(theme, basePath, useMinified, cdnPath);
|
|
311
|
+
|
|
312
|
+
// Check if aborted
|
|
313
|
+
if (abortController.signal.aborted) {
|
|
314
|
+
resolve();
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Load CSS file (using loadThemeCSS from domUtils)
|
|
319
|
+
const { loadThemeCSS } = await import('../utils/domUtils');
|
|
320
|
+
await loadThemeCSS(cssPath, `theme-${theme}`);
|
|
321
|
+
|
|
322
|
+
// Check if aborted after async operation
|
|
323
|
+
if (abortController.signal.aborted) {
|
|
324
|
+
resolve();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// Remove any previously loaded theme CSS
|
|
329
|
+
removeCSS(`theme-${String(currentTheme)}`);
|
|
330
330
|
|
|
331
|
-
|
|
331
|
+
loadedThemesRef.current.add(theme);
|
|
332
|
+
|
|
333
|
+
setCurrentTheme(theme);
|
|
334
|
+
setActiveTokens(null);
|
|
335
|
+
handleThemeChange(theme);
|
|
336
|
+
resolve();
|
|
337
|
+
} else {
|
|
338
|
+
throw new Error(`Theme metadata not found for theme: ${theme}`);
|
|
339
|
+
}
|
|
340
|
+
} catch (err) {
|
|
341
|
+
// Don't reject if aborted
|
|
332
342
|
if (abortController.signal.aborted) {
|
|
333
343
|
resolve();
|
|
334
344
|
return;
|
|
335
345
|
}
|
|
336
346
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
setCurrentTheme(theme);
|
|
343
|
-
setActiveTokens(null);
|
|
344
|
-
handleThemeChange(theme);
|
|
345
|
-
resolve();
|
|
346
|
-
} else {
|
|
347
|
-
throw new Error(`Theme metadata not found for theme: ${theme}`);
|
|
348
|
-
}
|
|
349
|
-
} catch (err) {
|
|
350
|
-
// Don't reject if aborted
|
|
351
|
-
if (abortController.signal.aborted) {
|
|
352
|
-
resolve();
|
|
353
|
-
return;
|
|
347
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
348
|
+
setError(error);
|
|
349
|
+
handleError(error, String(theme));
|
|
350
|
+
reject(error);
|
|
354
351
|
}
|
|
352
|
+
};
|
|
355
353
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
reject(error);
|
|
360
|
-
}
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
// Start the async operation
|
|
364
|
-
loadTheme();
|
|
365
|
-
});
|
|
354
|
+
// Start the async operation
|
|
355
|
+
loadTheme();
|
|
356
|
+
});
|
|
366
357
|
|
|
367
|
-
|
|
358
|
+
themePromisesRef.current[theme] = themeLoadPromise;
|
|
368
359
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
360
|
+
try {
|
|
361
|
+
await themeLoadPromise;
|
|
362
|
+
} catch {
|
|
363
|
+
// Error already handled in promise
|
|
364
|
+
}
|
|
374
365
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
366
|
+
// Clean up completed promise after a delay to prevent memory leak
|
|
367
|
+
setTimeout(() => {
|
|
368
|
+
if (themePromisesRef.current[theme] === themeLoadPromise) {
|
|
369
|
+
delete themePromisesRef.current[theme];
|
|
370
|
+
}
|
|
371
|
+
}, 1000);
|
|
372
|
+
} else {
|
|
373
|
+
// Check if aborted
|
|
374
|
+
if (abortController.signal.aborted) {
|
|
375
|
+
return;
|
|
379
376
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
377
|
+
|
|
378
|
+
// For string theme that isn't in our themes record, just set the name
|
|
379
|
+
setCurrentTheme(themeName);
|
|
380
|
+
setActiveTokens(null);
|
|
381
|
+
handleThemeChange(themeName);
|
|
382
|
+
}
|
|
383
|
+
} catch (err) {
|
|
384
|
+
// Don't set error if aborted
|
|
383
385
|
if (abortController.signal.aborted) {
|
|
384
386
|
return;
|
|
385
387
|
}
|
|
386
388
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
const error = err instanceof Error ? err : new Error(String(err));
|
|
399
|
-
setError(error);
|
|
400
|
-
handleError(error, String(theme));
|
|
401
|
-
} finally {
|
|
402
|
-
// Only update loading state if not aborted
|
|
403
|
-
if (!abortController.signal.aborted) {
|
|
404
|
-
setIsLoading(false);
|
|
389
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
390
|
+
setError(error);
|
|
391
|
+
handleError(error, String(theme));
|
|
392
|
+
} finally {
|
|
393
|
+
// Only update loading state if not aborted
|
|
394
|
+
if (!abortController.signal.aborted) {
|
|
395
|
+
setIsLoading(false);
|
|
396
|
+
}
|
|
405
397
|
}
|
|
406
|
-
}
|
|
407
|
-
|
|
398
|
+
},
|
|
399
|
+
[themes, currentTheme, handleThemeChange, handleError, basePath, useMinified, cdnPath]
|
|
400
|
+
);
|
|
408
401
|
|
|
409
402
|
// Check if theme is loaded
|
|
410
403
|
const isThemeLoaded = useCallback((themeName: string) => {
|
|
@@ -412,32 +405,30 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
|
412
405
|
}, []);
|
|
413
406
|
|
|
414
407
|
// Preload theme function
|
|
415
|
-
const preloadTheme = useCallback(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
408
|
+
const preloadTheme = useCallback(
|
|
409
|
+
async (themeName: string) => {
|
|
410
|
+
if (!themes[themeName] || isThemeLoaded(themeName)) {
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
419
413
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
setIsLoading(false);
|
|
439
|
-
}
|
|
440
|
-
}, [themes, isThemeLoaded, handleError, basePath, useMinified, cdnPath]);
|
|
414
|
+
setIsLoading(true);
|
|
415
|
+
try {
|
|
416
|
+
// Build CSS path using utility function
|
|
417
|
+
const cssPath = buildThemePath(themeName, basePath, useMinified, cdnPath);
|
|
418
|
+
|
|
419
|
+
// Preload CSS by fetching it
|
|
420
|
+
await fetch(cssPath);
|
|
421
|
+
loadedThemesRef.current.add(themeName);
|
|
422
|
+
} catch (err) {
|
|
423
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
424
|
+
setError(error);
|
|
425
|
+
handleError(error, themeName);
|
|
426
|
+
} finally {
|
|
427
|
+
setIsLoading(false);
|
|
428
|
+
}
|
|
429
|
+
},
|
|
430
|
+
[themes, isThemeLoaded, handleError, basePath, useMinified, cdnPath]
|
|
431
|
+
);
|
|
441
432
|
|
|
442
433
|
// Create a mock theme manager instance for the context
|
|
443
434
|
const themeManager = useMemo(() => {
|
|
@@ -449,40 +440,40 @@ export const ThemeProvider: React.FC<ThemeProviderProps> = ({
|
|
|
449
440
|
}, []);
|
|
450
441
|
|
|
451
442
|
// Memoize available themes to prevent unnecessary recalculations
|
|
452
|
-
const availableThemes = useMemo(
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
443
|
+
const availableThemes = useMemo(
|
|
444
|
+
() =>
|
|
445
|
+
Object.entries(themes).map(([name, metadata]) => ({
|
|
446
|
+
...metadata,
|
|
447
|
+
name: name, // Ensure name is set from the key
|
|
448
|
+
})),
|
|
457
449
|
[themes]
|
|
458
450
|
);
|
|
459
451
|
|
|
460
452
|
// Theme context value
|
|
461
|
-
const contextValue = useMemo(
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
<ThemeContext.Provider value={contextValue}>
|
|
485
|
-
{children}
|
|
486
|
-
</ThemeContext.Provider>
|
|
453
|
+
const contextValue = useMemo(
|
|
454
|
+
() => ({
|
|
455
|
+
theme: currentTheme,
|
|
456
|
+
activeTokens,
|
|
457
|
+
setTheme,
|
|
458
|
+
availableThemes,
|
|
459
|
+
isLoading,
|
|
460
|
+
error,
|
|
461
|
+
isThemeLoaded,
|
|
462
|
+
preloadTheme,
|
|
463
|
+
themeManager,
|
|
464
|
+
}),
|
|
465
|
+
[
|
|
466
|
+
currentTheme,
|
|
467
|
+
activeTokens,
|
|
468
|
+
setTheme,
|
|
469
|
+
availableThemes, // Use memoized value
|
|
470
|
+
isLoading,
|
|
471
|
+
error,
|
|
472
|
+
isThemeLoaded,
|
|
473
|
+
preloadTheme,
|
|
474
|
+
themeManager,
|
|
475
|
+
]
|
|
487
476
|
);
|
|
488
|
-
|
|
477
|
+
|
|
478
|
+
return <ThemeContext.Provider value={contextValue}>{children}</ThemeContext.Provider>;
|
|
479
|
+
};
|