@shohojdhara/atomix 0.3.5 → 0.3.7
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/README.md +101 -199
- package/atomix.config.ts +241 -0
- package/dist/atomix.css +260 -179
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +250 -179
- package/dist/atomix.min.css.map +1 -1
- package/dist/charts.js +69 -166
- package/dist/charts.js.map +1 -1
- package/dist/core.js +184 -263
- package/dist/core.js.map +1 -1
- package/dist/forms.js +55 -131
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +184 -263
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +1831 -1657
- package/dist/index.esm.js +4497 -4318
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +4510 -4328
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/theme.d.ts +1431 -1472
- package/dist/theme.js +4175 -4138
- package/dist/theme.js.map +1 -1
- package/package.json +6 -20
- package/src/components/Accordion/Accordion.stories.tsx +50 -17
- package/src/components/AtomixGlass/AtomixGlass.tsx +128 -322
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +12 -5
- package/src/components/AtomixGlass/stories/AtomixGlass.stories.tsx +1 -32
- package/src/components/AtomixGlass/stories/Examples.stories.tsx +2 -2
- package/src/components/AtomixGlass/stories/shared-components.tsx +0 -31
- package/src/components/Avatar/Avatar.stories.tsx +7 -0
- package/src/components/Badge/Badge.stories.tsx +91 -13
- package/src/components/Block/Block.stories.tsx +7 -23
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
- package/src/components/Button/Button.stories.tsx +141 -22
- package/src/components/Button/Button.tsx +85 -167
- package/src/components/Button/ButtonGroup.stories.tsx +315 -0
- package/src/components/Button/ButtonGroup.tsx +67 -0
- package/src/components/Button/index.ts +2 -0
- package/src/components/Callout/Callout.stories.tsx +8 -6
- package/src/components/Card/Card.stories.tsx +82 -28
- package/src/components/Chart/AnimatedChart.tsx +0 -1
- package/src/components/Chart/AreaChart.tsx +0 -1
- package/src/components/Chart/BarChart.tsx +0 -1
- package/src/components/Chart/BubbleChart.tsx +0 -1
- package/src/components/Chart/CandlestickChart.tsx +0 -1
- package/src/components/Chart/Chart.stories.tsx +5 -7
- package/src/components/Chart/Chart.tsx +0 -16
- package/src/components/Chart/ChartRenderer.tsx +1 -1
- package/src/components/Chart/DonutChart.tsx +0 -1
- package/src/components/Chart/FunnelChart.tsx +0 -1
- package/src/components/Chart/GaugeChart.tsx +0 -1
- package/src/components/Chart/HeatmapChart.tsx +0 -1
- package/src/components/Chart/LineChart.tsx +0 -1
- package/src/components/Chart/MultiAxisChart.tsx +0 -1
- package/src/components/Chart/PieChart.tsx +0 -1
- package/src/components/Chart/RadarChart.tsx +0 -1
- package/src/components/Chart/ScatterChart.tsx +0 -1
- package/src/components/Chart/WaterfallChart.tsx +0 -1
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
- package/src/components/DataTable/DataTable.stories.tsx +23 -16
- package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
- package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
- package/src/components/EdgePanel/EdgePanel.stories.tsx +1 -0
- package/src/components/Footer/Footer.stories.tsx +8 -6
- package/src/components/Footer/FooterLink.tsx +9 -2
- package/src/components/Form/Checkbox.stories.tsx +7 -0
- package/src/components/Form/Form.stories.tsx +7 -0
- package/src/components/Form/FormGroup.stories.tsx +9 -1
- package/src/components/Form/Input.stories.tsx +69 -16
- package/src/components/Form/Radio.stories.tsx +9 -1
- package/src/components/Form/Select.stories.tsx +9 -1
- package/src/components/Form/Textarea.stories.tsx +10 -2
- package/src/components/Hero/Hero.stories.tsx +7 -0
- package/src/components/List/List.stories.tsx +7 -0
- package/src/components/Messages/Messages.stories.tsx +8 -7
- package/src/components/Modal/Modal.stories.tsx +17 -6
- package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
- package/src/components/Navigation/Nav/Nav.stories.tsx +7 -0
- package/src/components/Navigation/Navbar/Navbar.stories.tsx +1 -0
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +1 -1
- package/src/components/Pagination/Pagination.stories.tsx +188 -111
- package/src/components/Pagination/Pagination.tsx +83 -3
- package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
- package/src/components/Popover/Popover.stories.tsx +191 -115
- package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
- package/src/components/Progress/Progress.stories.tsx +79 -49
- package/src/components/Rating/Rating.stories.tsx +109 -84
- package/src/components/River/River.stories.tsx +194 -114
- package/src/components/SectionIntro/SectionIntro.stories.tsx +19 -9
- package/src/components/Slider/Slider.stories.tsx +7 -0
- package/src/components/Spinner/Spinner.stories.tsx +15 -11
- package/src/components/Steps/Steps.stories.tsx +132 -98
- package/src/components/Tabs/Tabs.stories.tsx +163 -112
- package/src/components/Testimonial/Testimonial.stories.tsx +114 -68
- package/src/components/Todo/Todo.stories.tsx +38 -12
- package/src/components/Toggle/Toggle.stories.tsx +61 -28
- package/src/components/Tooltip/Tooltip.stories.tsx +318 -200
- package/src/components/Upload/Upload.stories.tsx +122 -84
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
- package/src/components/index.ts +1 -0
- package/src/lib/composables/useAtomixGlass.ts +9 -10
- package/src/lib/composables/useNavbar.ts +0 -10
- package/src/lib/config/loader.ts +4 -4
- package/src/lib/constants/components.ts +17 -0
- package/src/lib/hooks/useComponentCustomization.ts +1 -1
- package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
- package/src/lib/hooks/useThemeTokens.ts +105 -0
- package/src/lib/theme/README.md +174 -0
- package/src/lib/theme/adapters/index.ts +31 -0
- package/src/lib/theme/adapters/themeAdapter.ts +287 -0
- package/src/lib/theme/config/__tests__/configLoader.test.ts +207 -0
- package/src/lib/theme/config/configLoader.ts +95 -0
- package/src/lib/theme/config/loader.ts +37 -54
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +15 -91
- package/src/lib/theme/{constants.ts → constants/constants.ts} +1 -19
- package/src/lib/theme/constants/index.ts +8 -0
- package/src/lib/theme/core/ThemeRegistry.ts +75 -266
- package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
- package/src/lib/theme/core/composeTheme.ts +105 -0
- package/src/lib/theme/core/createTheme.ts +108 -0
- package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +12 -8
- package/src/lib/theme/core/index.ts +19 -19
- package/src/lib/theme/devtools/Comparator.tsx +346 -22
- package/src/lib/theme/devtools/IMPROVEMENTS.md +139 -38
- package/src/lib/theme/devtools/Inspector.tsx +335 -51
- package/src/lib/theme/devtools/LiveEditor.tsx +478 -107
- package/src/lib/theme/devtools/Preview.tsx +471 -221
- package/src/lib/theme/{core → devtools}/ThemeValidator.ts +1 -1
- package/src/lib/theme/devtools/index.ts +14 -4
- package/src/lib/theme/devtools/useHistory.ts +130 -0
- package/src/lib/theme/{errors.ts → errors/errors.ts} +1 -1
- package/src/lib/theme/errors/index.ts +12 -0
- package/src/lib/theme/generators/cssFile.ts +79 -0
- package/src/lib/theme/generators/generateCSS.ts +89 -0
- package/src/lib/theme/generators/generateCSSNested.ts +130 -0
- package/src/lib/theme/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +3 -13
- package/src/lib/theme/generators/index.ts +25 -0
- package/src/lib/theme/i18n/rtl.ts +5 -6
- package/src/lib/theme/index.ts +149 -19
- package/src/lib/theme/runtime/ThemeApplicator.ts +53 -112
- package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +5 -5
- package/src/lib/theme/runtime/ThemeProvider.tsx +266 -282
- package/src/lib/theme/runtime/index.ts +2 -2
- package/src/lib/theme/runtime/useTheme.ts +1 -2
- package/src/lib/theme/runtime/useThemeTokens.ts +131 -0
- package/src/lib/theme/test/testTheme.ts +385 -0
- package/src/lib/theme/tokens/index.ts +12 -0
- package/src/lib/theme/tokens/tokens.ts +721 -0
- package/src/lib/theme/types.ts +6 -42
- package/src/lib/theme/utils/componentTheming.ts +132 -0
- package/src/lib/theme/{utils.ts → utils/domUtils.ts} +2 -2
- package/src/lib/theme/utils/index.ts +11 -0
- package/src/lib/theme/utils/injectCSS.ts +90 -0
- package/src/lib/theme/utils/naming.ts +100 -0
- package/src/lib/theme/utils/themeHelpers.ts +78 -0
- package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +7 -7
- package/src/lib/theme-tools.ts +7 -8
- package/src/lib/types/components.ts +40 -130
- package/src/lib/utils/componentUtils.ts +2 -2
- package/src/lib/utils/memoryMonitor.ts +3 -3
- package/src/lib/utils/themeNaming.ts +135 -0
- package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
- package/src/styles/02-tools/_tools.button.scss +66 -79
- package/src/styles/06-components/_components.atomix-glass.scss +13 -3
- package/src/styles/06-components/_components.pagination.scss +88 -0
- package/scripts/sync-theme-config.js +0 -309
- package/src/lib/theme/composeTheme.ts +0 -370
- package/src/lib/theme/core/ThemeCache.ts +0 -283
- package/src/lib/theme/core/ThemeEngine.test.ts +0 -146
- package/src/lib/theme/core/ThemeEngine.ts +0 -665
- package/src/lib/theme/createThemeFromConfig.ts +0 -132
- package/src/lib/theme/devtools/CLI.ts +0 -364
- package/src/lib/theme/runtime/ThemeManager.test.ts +0 -192
- package/src/lib/theme/runtime/ThemeManager.ts +0 -446
- package/src/styles/03-generic/_generated-root.css +0 -26
- package/src/themes/README.md +0 -442
- package/src/themes/themes.config.js +0 -68
- /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Theme Configuration Loader
|
|
4
|
+
*
|
|
5
|
+
* Provides functions to load theme configurations from atomix.config.ts
|
|
6
|
+
* Includes both sync and async versions, with automatic fallbacks
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { Theme } from '../types';
|
|
10
|
+
import type { DesignTokens } from '../tokens/tokens';
|
|
11
|
+
import { createTokens } from '../tokens/tokens';
|
|
12
|
+
import { themeToDesignTokens, createDesignTokensFromTheme } from '../adapters/themeAdapter';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Load theme from config file (synchronous, Node.js only)
|
|
16
|
+
* @param configPath - Path to config file (default: atomix.config.ts)
|
|
17
|
+
* @returns DesignTokens from theme configuration
|
|
18
|
+
* @throws Error if config loading is not available in browser environment
|
|
19
|
+
*/
|
|
20
|
+
export function loadThemeFromConfigSync(options?: { configPath?: string; required?: boolean }): DesignTokens {
|
|
21
|
+
// Check if we're in a browser environment
|
|
22
|
+
if (typeof window !== 'undefined') {
|
|
23
|
+
throw new Error('loadThemeFromConfigSync: Not available in browser environment. Config loading requires Node.js/SSR environment.');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Use dynamic import to load the config loader
|
|
27
|
+
// This allows bundlers to handle external dependencies properly
|
|
28
|
+
let loadAtomixConfig: any;
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
32
|
+
const { loadAtomixConfig: loader } = require('../../config/loader');
|
|
33
|
+
loadAtomixConfig = loader;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
if (options?.required !== false) {
|
|
36
|
+
throw new Error('Config loader module not available');
|
|
37
|
+
}
|
|
38
|
+
// Return empty tokens if config is not required
|
|
39
|
+
return createTokens({});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const config = loadAtomixConfig({
|
|
43
|
+
configPath: options?.configPath || 'atomix.config.ts',
|
|
44
|
+
required: options?.required !== false,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!config?.theme) {
|
|
48
|
+
return createTokens({});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (isThemeObject(config.theme)) {
|
|
52
|
+
return createDesignTokensFromTheme(config.theme);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return createTokens(config.theme);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Load theme from config file (asynchronous)
|
|
60
|
+
* @param configPath - Path to config file (default: atomix.config.ts)
|
|
61
|
+
* @returns Promise resolving to DesignTokens from theme configuration
|
|
62
|
+
*/
|
|
63
|
+
export async function loadThemeFromConfig(options?: { configPath?: string; required?: boolean }): Promise<DesignTokens> {
|
|
64
|
+
// Check if we're in a browser environment
|
|
65
|
+
if (typeof window !== 'undefined') {
|
|
66
|
+
throw new Error('loadThemeFromConfig: Not available in browser environment. Config loading requires Node.js/SSR environment.');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Dynamic import for config loader
|
|
70
|
+
const { loadAtomixConfig } = await import('../../config/loader');
|
|
71
|
+
|
|
72
|
+
const config = await loadAtomixConfig({
|
|
73
|
+
configPath: options?.configPath || 'atomix.config.ts',
|
|
74
|
+
required: options?.required !== false,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (!config?.theme) {
|
|
78
|
+
return createTokens({});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (isThemeObject(config.theme)) {
|
|
82
|
+
return createDesignTokensFromTheme(config.theme);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return createTokens(config.theme);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if the provided object is a Theme object
|
|
90
|
+
* @param theme - Object to check
|
|
91
|
+
* @returns True if the object is a Theme object, false otherwise
|
|
92
|
+
*/
|
|
93
|
+
function isThemeObject(theme: any): theme is Theme {
|
|
94
|
+
return typeof theme === 'object' && theme !== null;
|
|
95
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Configuration Loader
|
|
3
3
|
*
|
|
4
|
-
* Loads and validates the theme configuration from
|
|
4
|
+
* Loads and validates the theme configuration from atomix.config.ts
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type {
|
|
@@ -10,12 +10,9 @@ import type {
|
|
|
10
10
|
ConfigValidationResult,
|
|
11
11
|
} from './types';
|
|
12
12
|
import { validateConfig } from './validator';
|
|
13
|
-
import { ThemeError, ThemeErrorCode, getLogger } from '../errors';
|
|
13
|
+
import { ThemeError, ThemeErrorCode, getLogger } from '../errors/errors';
|
|
14
14
|
import {
|
|
15
|
-
DEFAULT_CONFIG_PATH,
|
|
16
15
|
DEFAULT_ATOMIX_CONFIG_PATH,
|
|
17
|
-
DEFAULT_CONFIG_RELATIVE_PATH,
|
|
18
|
-
DEFAULT_LEGACY_CONFIG_RELATIVE_PATH,
|
|
19
16
|
DEFAULT_BASE_PATH,
|
|
20
17
|
DEFAULT_STORAGE_KEY,
|
|
21
18
|
DEFAULT_DATA_ATTRIBUTE,
|
|
@@ -24,7 +21,7 @@ import {
|
|
|
24
21
|
DEFAULT_BUILD_OUTPUT_DIR,
|
|
25
22
|
DEFAULT_SASS_CONFIG,
|
|
26
23
|
ENV_DEFAULTS,
|
|
27
|
-
} from '../constants';
|
|
24
|
+
} from '../constants/constants';
|
|
28
25
|
|
|
29
26
|
/**
|
|
30
27
|
* Cache for loaded configuration
|
|
@@ -37,7 +34,7 @@ let cachedConfig: LoadedThemeConfig | null = null;
|
|
|
37
34
|
const logger = getLogger();
|
|
38
35
|
|
|
39
36
|
/**
|
|
40
|
-
* Load theme configuration from
|
|
37
|
+
* Load theme configuration from atomix.config.ts
|
|
41
38
|
*
|
|
42
39
|
* @param options - Loader options
|
|
43
40
|
* @returns Loaded and validated theme configuration
|
|
@@ -92,36 +89,26 @@ export function loadThemeConfig(
|
|
|
92
89
|
let configModule: ConfigModule;
|
|
93
90
|
|
|
94
91
|
// Try require (Node.js/CommonJS)
|
|
92
|
+
// Use process.cwd() to resolve config path - avoids bundling issues with relative paths
|
|
95
93
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
configModule = nodeRequire(DEFAULT_CONFIG_RELATIVE_PATH) as ConfigModule;
|
|
99
|
-
} catch {
|
|
100
|
-
// Try fallback to legacy relative path
|
|
101
|
-
try {
|
|
102
|
-
configModule = nodeRequire(DEFAULT_LEGACY_CONFIG_RELATIVE_PATH) as ConfigModule;
|
|
103
|
-
} catch {
|
|
104
|
-
// If relative paths fail, try to resolve from process.cwd()
|
|
105
|
-
const path = nodeRequire('path') as typeof import('path');
|
|
106
|
-
const fs = nodeRequire('fs') as typeof import('fs');
|
|
94
|
+
const path = nodeRequire('path') as typeof import('path');
|
|
95
|
+
const fs = nodeRequire('fs') as typeof import('fs');
|
|
107
96
|
|
|
108
|
-
|
|
97
|
+
let configFilePath = path.resolve(process.cwd(), configPath);
|
|
109
98
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
99
|
+
// If atomix.config.ts not found at the root, use the default path
|
|
100
|
+
if (!fs.existsSync(configFilePath) && configPath === DEFAULT_ATOMIX_CONFIG_PATH) {
|
|
101
|
+
configFilePath = path.resolve(process.cwd(), DEFAULT_ATOMIX_CONFIG_PATH);
|
|
102
|
+
}
|
|
114
103
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
configModule = nodeRequire(configFilePath) as ConfigModule;
|
|
121
|
-
} else {
|
|
122
|
-
throw new Error(`Config file not found: ${configFilePath}`);
|
|
123
|
-
}
|
|
104
|
+
if (fs.existsSync(configFilePath)) {
|
|
105
|
+
const resolvedPath = nodeRequire.resolve(configFilePath);
|
|
106
|
+
if (nodeRequire.cache && nodeRequire.cache[resolvedPath]) {
|
|
107
|
+
delete nodeRequire.cache[resolvedPath];
|
|
124
108
|
}
|
|
109
|
+
configModule = nodeRequire(configFilePath) as ConfigModule;
|
|
110
|
+
} else {
|
|
111
|
+
throw new Error(`Config file not found: ${configFilePath}`);
|
|
125
112
|
}
|
|
126
113
|
} catch (requireError) {
|
|
127
114
|
const errorMessage = requireError instanceof Error
|
|
@@ -136,36 +123,30 @@ export function loadThemeConfig(
|
|
|
136
123
|
|
|
137
124
|
const rawConfig = configModule.default || configModule;
|
|
138
125
|
|
|
139
|
-
//
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
__extend: rawConfig.theme.extend,
|
|
152
|
-
};
|
|
153
|
-
} else {
|
|
154
|
-
// Legacy ThemeConfig structure
|
|
155
|
-
processedConfig = { ...rawConfig };
|
|
156
|
-
}
|
|
126
|
+
// Process the AtomixConfig structure
|
|
127
|
+
const processedConfig: LoadedThemeConfig = {
|
|
128
|
+
themes: rawConfig.theme?.themes || {},
|
|
129
|
+
build: rawConfig.build || {},
|
|
130
|
+
runtime: rawConfig.runtime || {},
|
|
131
|
+
integration: rawConfig.integration || {},
|
|
132
|
+
dependencies: rawConfig.dependencies || {},
|
|
133
|
+
validated: false, // Will be set after validation
|
|
134
|
+
// Store tokens for generator
|
|
135
|
+
__tokens: rawConfig.theme?.tokens,
|
|
136
|
+
__extend: rawConfig.theme?.extend,
|
|
137
|
+
};
|
|
157
138
|
|
|
158
139
|
// Apply environment-specific overrides
|
|
159
|
-
|
|
140
|
+
const finalConfig = applyEnvOverrides(processedConfig, env);
|
|
160
141
|
|
|
161
142
|
// Validate if requested
|
|
162
143
|
let validationResult: ConfigValidationResult | null = null;
|
|
163
144
|
if (validate) {
|
|
164
|
-
validationResult = validateConfig(
|
|
145
|
+
validationResult = validateConfig(finalConfig);
|
|
165
146
|
}
|
|
166
147
|
|
|
167
148
|
config = {
|
|
168
|
-
...
|
|
149
|
+
...finalConfig,
|
|
169
150
|
validated: validate,
|
|
170
151
|
errors: validationResult?.errors,
|
|
171
152
|
warnings: validationResult?.warnings,
|
|
@@ -212,6 +193,8 @@ export function loadThemeConfig(
|
|
|
212
193
|
validated: false,
|
|
213
194
|
errors: [`Failed to load config: ${error instanceof Error ? error.message : String(error)}`],
|
|
214
195
|
warnings: [],
|
|
196
|
+
__tokens: {},
|
|
197
|
+
__extend: {},
|
|
215
198
|
};
|
|
216
199
|
}
|
|
217
200
|
|
|
@@ -307,4 +290,4 @@ export function reloadThemeConfig(
|
|
|
307
290
|
): LoadedThemeConfig {
|
|
308
291
|
clearConfigCache();
|
|
309
292
|
return loadThemeConfig(options);
|
|
310
|
-
}
|
|
293
|
+
}
|
|
@@ -18,7 +18,7 @@ import type {
|
|
|
18
18
|
* Configuration loader options
|
|
19
19
|
*/
|
|
20
20
|
export interface ConfigLoaderOptions {
|
|
21
|
-
/** Path to theme config file (default: '
|
|
21
|
+
/** Path to theme config file (default: 'atomix.config.ts') */
|
|
22
22
|
configPath?: string;
|
|
23
23
|
/** Enable validation */
|
|
24
24
|
validate?: boolean;
|
|
@@ -109,4 +109,4 @@ export type {
|
|
|
109
109
|
BuildConfig,
|
|
110
110
|
RuntimeConfig,
|
|
111
111
|
IntegrationConfig,
|
|
112
|
-
};
|
|
112
|
+
};
|
|
@@ -4,13 +4,7 @@
|
|
|
4
4
|
* Validates theme configuration structure and values
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type {
|
|
8
|
-
AtomixConfig,
|
|
9
|
-
ThemeDefinition,
|
|
10
|
-
CSSThemeDefinition,
|
|
11
|
-
JSThemeDefinition,
|
|
12
|
-
ConfigValidationResult,
|
|
13
|
-
} from './types';
|
|
7
|
+
import type { ConfigValidationResult } from './types';
|
|
14
8
|
|
|
15
9
|
/**
|
|
16
10
|
* Validate theme configuration
|
|
@@ -37,31 +31,25 @@ export function validateConfig(config: any): ConfigValidationResult {
|
|
|
37
31
|
warnings.push(...themeErrors.warnings);
|
|
38
32
|
}
|
|
39
33
|
|
|
40
|
-
// Validate build config
|
|
34
|
+
// Validate build config (only if provided)
|
|
41
35
|
if (config.build) {
|
|
42
36
|
const buildErrors = validateBuildConfig(config.build);
|
|
43
37
|
errors.push(...buildErrors.errors);
|
|
44
38
|
warnings.push(...buildErrors.warnings);
|
|
45
|
-
} else {
|
|
46
|
-
warnings.push('No build configuration provided, using defaults');
|
|
47
39
|
}
|
|
48
40
|
|
|
49
|
-
// Validate runtime config
|
|
41
|
+
// Validate runtime config (only if provided)
|
|
50
42
|
if (config.runtime) {
|
|
51
43
|
const runtimeErrors = validateRuntimeConfig(config.runtime);
|
|
52
44
|
errors.push(...runtimeErrors.errors);
|
|
53
45
|
warnings.push(...runtimeErrors.warnings);
|
|
54
|
-
} else {
|
|
55
|
-
warnings.push('No runtime configuration provided, using defaults');
|
|
56
46
|
}
|
|
57
47
|
|
|
58
|
-
// Validate integration config
|
|
48
|
+
// Validate integration config (only if provided)
|
|
59
49
|
if (config.integration) {
|
|
60
50
|
const integrationErrors = validateIntegrationConfig(config.integration);
|
|
61
51
|
errors.push(...integrationErrors.errors);
|
|
62
52
|
warnings.push(...integrationErrors.warnings);
|
|
63
|
-
} else {
|
|
64
|
-
warnings.push('No integration configuration provided, using defaults');
|
|
65
53
|
}
|
|
66
54
|
|
|
67
55
|
// Validate dependencies
|
|
@@ -127,23 +115,9 @@ function validateThemes(themes: Record<string, any>): ConfigValidationResult {
|
|
|
127
115
|
warnings.push(...jsErrors.warnings);
|
|
128
116
|
}
|
|
129
117
|
|
|
130
|
-
// Validate
|
|
131
|
-
if (theme.
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (theme.status && !['stable', 'beta', 'experimental', 'deprecated'].includes(theme.status)) {
|
|
136
|
-
warnings.push(`Theme "${themeId}" has invalid status: ${theme.status}`);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Validate color format
|
|
140
|
-
if (theme.color && !isValidColor(theme.color)) {
|
|
141
|
-
warnings.push(`Theme "${themeId}" has invalid color format: ${theme.color}`);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Validate accessibility
|
|
145
|
-
if (theme.a11y) {
|
|
146
|
-
if (theme.a11y.contrastTarget && (theme.a11y.contrastTarget < 1 || theme.a11y.contrastTarget > 21)) {
|
|
118
|
+
// Validate accessibility (only critical checks)
|
|
119
|
+
if (theme.a11y?.contrastTarget) {
|
|
120
|
+
if (typeof theme.a11y.contrastTarget !== 'number' || theme.a11y.contrastTarget < 1 || theme.a11y.contrastTarget > 21) {
|
|
147
121
|
warnings.push(`Theme "${themeId}" has invalid contrast target: ${theme.a11y.contrastTarget}`);
|
|
148
122
|
}
|
|
149
123
|
}
|
|
@@ -187,23 +161,13 @@ function validateBuildConfig(build: any): ConfigValidationResult {
|
|
|
187
161
|
const errors: string[] = [];
|
|
188
162
|
const warnings: string[] = [];
|
|
189
163
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (!build.output.directory || typeof build.output.directory !== 'string') {
|
|
194
|
-
errors.push('Build output must have a "directory" string');
|
|
195
|
-
}
|
|
196
|
-
if (!build.output.formats || typeof build.output.formats !== 'object') {
|
|
197
|
-
errors.push('Build output must have a "formats" object');
|
|
198
|
-
}
|
|
164
|
+
// Only validate structure if provided
|
|
165
|
+
if (build.output && typeof build.output !== 'object') {
|
|
166
|
+
errors.push('Build output must be an object');
|
|
199
167
|
}
|
|
200
168
|
|
|
201
|
-
if (
|
|
202
|
-
errors.push('Build config must
|
|
203
|
-
} else {
|
|
204
|
-
if (build.sass.style && !['expanded', 'compressed', 'compact', 'nested'].includes(build.sass.style)) {
|
|
205
|
-
warnings.push(`Invalid Sass style: ${build.sass.style}`);
|
|
206
|
-
}
|
|
169
|
+
if (build.sass && typeof build.sass !== 'object') {
|
|
170
|
+
errors.push('Build sass config must be an object');
|
|
207
171
|
}
|
|
208
172
|
|
|
209
173
|
return { valid: errors.length === 0, errors, warnings };
|
|
@@ -242,15 +206,9 @@ function validateIntegrationConfig(integration: any): ConfigValidationResult {
|
|
|
242
206
|
const errors: string[] = [];
|
|
243
207
|
const warnings: string[] = [];
|
|
244
208
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
if (!integration.classNames.theme || typeof integration.classNames.theme !== 'string') {
|
|
249
|
-
errors.push('Integration classNames must have a "theme" string');
|
|
250
|
-
}
|
|
251
|
-
if (!integration.classNames.colorMode || typeof integration.classNames.colorMode !== 'string') {
|
|
252
|
-
errors.push('Integration classNames must have a "colorMode" string');
|
|
253
|
-
}
|
|
209
|
+
// Only validate structure if provided
|
|
210
|
+
if (integration.classNames && typeof integration.classNames !== 'object') {
|
|
211
|
+
errors.push('Integration classNames must be an object');
|
|
254
212
|
}
|
|
255
213
|
|
|
256
214
|
return { valid: errors.length === 0, errors, warnings };
|
|
@@ -290,37 +248,3 @@ function validateDependencies(
|
|
|
290
248
|
return { valid: errors.length === 0, errors, warnings };
|
|
291
249
|
}
|
|
292
250
|
|
|
293
|
-
/**
|
|
294
|
-
* Check if string is valid semver
|
|
295
|
-
*/
|
|
296
|
-
function isValidSemver(version: string): boolean {
|
|
297
|
-
const semverRegex = /^\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/;
|
|
298
|
-
return semverRegex.test(version);
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
/**
|
|
302
|
-
* Check if string is valid color
|
|
303
|
-
*/
|
|
304
|
-
function isValidColor(color: string): boolean {
|
|
305
|
-
// Hex color
|
|
306
|
-
if (/^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$/.test(color)) {
|
|
307
|
-
return true;
|
|
308
|
-
}
|
|
309
|
-
// RGB/RGBA
|
|
310
|
-
if (/^rgba?\(/.test(color)) {
|
|
311
|
-
return true;
|
|
312
|
-
}
|
|
313
|
-
// HSL/HSLA
|
|
314
|
-
if (/^hsla?\(/.test(color)) {
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
317
|
-
// Named colors (basic check)
|
|
318
|
-
const namedColors = [
|
|
319
|
-
'black', 'white', 'red', 'green', 'blue', 'yellow', 'cyan', 'magenta',
|
|
320
|
-
'transparent', 'currentColor',
|
|
321
|
-
];
|
|
322
|
-
if (namedColors.includes(color.toLowerCase())) {
|
|
323
|
-
return true;
|
|
324
|
-
}
|
|
325
|
-
return false;
|
|
326
|
-
}
|
|
@@ -24,14 +24,6 @@ export const DEFAULT_BASE_PATH = '/themes';
|
|
|
24
24
|
*/
|
|
25
25
|
export const DEFAULT_STYLE_ID = 'atomix-js-theme-styles';
|
|
26
26
|
|
|
27
|
-
/**
|
|
28
|
-
* Default cache configuration
|
|
29
|
-
*/
|
|
30
|
-
export const DEFAULT_CACHE_CONFIG = {
|
|
31
|
-
maxSize: 50,
|
|
32
|
-
ttl: 0, // No expiration by default
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
27
|
/**
|
|
36
28
|
* Default engine cache configuration
|
|
37
29
|
*/
|
|
@@ -58,21 +50,11 @@ export const CSS_EXTENSIONS = {
|
|
|
58
50
|
*/
|
|
59
51
|
export const DEFAULT_ATOMIX_CONFIG_PATH = 'atomix.config.ts';
|
|
60
52
|
|
|
61
|
-
/**
|
|
62
|
-
* Default config file path (legacy)
|
|
63
|
-
*/
|
|
64
|
-
export const DEFAULT_CONFIG_PATH = 'theme.config.ts';
|
|
65
|
-
|
|
66
53
|
/**
|
|
67
54
|
* Default config file path (relative)
|
|
68
55
|
*/
|
|
69
56
|
export const DEFAULT_CONFIG_RELATIVE_PATH = '../../../../atomix.config';
|
|
70
57
|
|
|
71
|
-
/**
|
|
72
|
-
* Default legacy config file path (relative)
|
|
73
|
-
*/
|
|
74
|
-
export const DEFAULT_LEGACY_CONFIG_RELATIVE_PATH = '../../../../theme.config';
|
|
75
|
-
|
|
76
58
|
/**
|
|
77
59
|
* Validation thresholds
|
|
78
60
|
*/
|
|
@@ -139,7 +121,7 @@ export const DEFAULT_ANALYTICS_CONFIG = {
|
|
|
139
121
|
* Logger default configuration
|
|
140
122
|
*/
|
|
141
123
|
export const DEFAULT_LOGGER_CONFIG = {
|
|
142
|
-
level: process.env
|
|
124
|
+
level: (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') ? 1 : 2, // WARN in prod, INFO in dev
|
|
143
125
|
enableConsole: true,
|
|
144
126
|
} as const;
|
|
145
127
|
|