@shohojdhara/atomix 0.3.6 → 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 +3 -3
- package/dist/charts.js +50 -142
- package/dist/charts.js.map +1 -1
- package/dist/core.js +179 -274
- package/dist/core.js.map +1 -1
- package/dist/forms.js +50 -142
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +179 -274
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +669 -703
- package/dist/index.esm.js +966 -1649
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1211 -1890
- 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 +163 -334
- package/dist/theme.js +774 -1473
- package/dist/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AtomixGlass/AtomixGlass.tsx +128 -356
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +1 -1
- package/src/components/Button/Button.tsx +85 -167
- package/src/lib/composables/useAtomixGlass.ts +7 -7
- package/src/lib/config/loader.ts +2 -3
- package/src/lib/constants/components.ts +7 -0
- package/src/lib/hooks/usePerformanceMonitor.ts +1 -1
- package/src/lib/hooks/useThemeTokens.ts +105 -0
- package/src/lib/theme/config/configLoader.ts +60 -219
- package/src/lib/theme/config/loader.ts +15 -21
- package/src/lib/theme/constants/constants.ts +1 -1
- package/src/lib/theme/core/ThemeRegistry.ts +75 -279
- package/src/lib/theme/core/composeTheme.ts +14 -64
- package/src/lib/theme/core/createTheme.ts +54 -40
- package/src/lib/theme/core/createThemeObject.ts +2 -2
- package/src/lib/theme/core/index.ts +15 -1
- package/src/lib/theme/errors/errors.ts +1 -1
- package/src/lib/theme/generators/generateCSSNested.ts +130 -0
- package/src/lib/theme/generators/index.ts +6 -0
- package/src/lib/theme/index.ts +35 -10
- package/src/lib/theme/runtime/ThemeApplicator.ts +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +4 -4
- package/src/lib/theme/runtime/ThemeProvider.tsx +261 -554
- package/src/lib/theme/runtime/index.ts +1 -0
- package/src/lib/theme/runtime/useThemeTokens.ts +131 -0
- package/src/lib/theme/utils/componentTheming.ts +132 -0
- package/src/lib/theme/utils/naming.ts +100 -0
- package/src/lib/theme/utils/themeUtils.ts +6 -6
- package/src/lib/utils/componentUtils.ts +1 -1
- package/src/lib/utils/memoryMonitor.ts +3 -3
- package/src/lib/utils/themeNaming.ts +135 -0
|
@@ -1,297 +1,93 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Theme
|
|
3
|
-
*
|
|
4
|
-
* Central registry for all themes with discovery and dependency management
|
|
2
|
+
* Theme Metadata interface
|
|
5
3
|
*/
|
|
4
|
+
export interface ThemeMetadata {
|
|
5
|
+
name: string;
|
|
6
|
+
class: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
version?: string;
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
}
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Theme Registry type - a record of theme IDs to metadata
|
|
14
|
+
*/
|
|
15
|
+
export type ThemeRegistry = Record<string, ThemeMetadata>;
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
|
-
*
|
|
18
|
+
* Create a new theme registry
|
|
13
19
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
id: string;
|
|
17
|
-
/** Theme definition from config */
|
|
18
|
-
definition: ThemeDefinition;
|
|
19
|
-
/** Resolved theme object (for JS themes) */
|
|
20
|
-
theme?: Theme;
|
|
21
|
-
/** Whether theme is loaded */
|
|
22
|
-
loaded: boolean;
|
|
23
|
-
/** Loading promise (if currently loading) */
|
|
24
|
-
loading?: Promise<Theme | void>;
|
|
25
|
-
/** Dependencies */
|
|
26
|
-
dependencies: string[];
|
|
27
|
-
/** Dependent themes (themes that depend on this one) */
|
|
28
|
-
dependents: string[];
|
|
20
|
+
export function createThemeRegistry(): ThemeRegistry {
|
|
21
|
+
return {};
|
|
29
22
|
}
|
|
30
23
|
|
|
31
24
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
25
|
+
* Register a theme
|
|
26
|
+
* @param registry - Theme registry object
|
|
27
|
+
* @param id - Theme identifier
|
|
28
|
+
* @param metadata - Theme metadata
|
|
35
29
|
*/
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
private initialized: boolean = false;
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Initialize registry from config
|
|
43
|
-
*/
|
|
44
|
-
async initialize(config?: LoadedThemeConfig): Promise<void> {
|
|
45
|
-
if (this.initialized) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Load config if not provided
|
|
50
|
-
if (!config) {
|
|
51
|
-
try {
|
|
52
|
-
this.config = loadThemeConfig();
|
|
53
|
-
} catch (error) {
|
|
54
|
-
// In browser environments, config loading will fail
|
|
55
|
-
// Use empty config as fallback
|
|
56
|
-
this.config = {
|
|
57
|
-
themes: {},
|
|
58
|
-
build: {
|
|
59
|
-
output: { directory: 'themes', formats: { expanded: '.css', compressed: '.min.css' } },
|
|
60
|
-
sass: { style: 'expanded', sourceMap: true, loadPaths: ['src'] },
|
|
61
|
-
},
|
|
62
|
-
runtime: {
|
|
63
|
-
basePath: '',
|
|
64
|
-
defaultTheme: undefined, // No default - use built-in styles
|
|
65
|
-
},
|
|
66
|
-
integration: {
|
|
67
|
-
cssVariables: { colorMode: '--color-mode' },
|
|
68
|
-
classNames: { theme: 'data-theme', colorMode: 'data-color-mode' },
|
|
69
|
-
},
|
|
70
|
-
dependencies: {},
|
|
71
|
-
validated: false,
|
|
72
|
-
errors: [],
|
|
73
|
-
warnings: [],
|
|
74
|
-
__tokens: {},
|
|
75
|
-
__extend: {},
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
} else {
|
|
79
|
-
this.config = config;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Register all themes from config
|
|
83
|
-
for (const [themeId, definition] of Object.entries(this.config.themes)) {
|
|
84
|
-
this.register(themeId, definition);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Resolve dependencies
|
|
88
|
-
this.resolveDependencies();
|
|
89
|
-
|
|
90
|
-
this.initialized = true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Register a theme
|
|
95
|
-
*/
|
|
96
|
-
register(themeId: string, definition: ThemeDefinition): void {
|
|
97
|
-
// Get dependencies from config or definition
|
|
98
|
-
const dependencies =
|
|
99
|
-
this.config?.dependencies?.[themeId] ||
|
|
100
|
-
definition.dependencies ||
|
|
101
|
-
[];
|
|
102
|
-
|
|
103
|
-
const entry: RegistryEntry = {
|
|
104
|
-
id: themeId,
|
|
105
|
-
definition,
|
|
106
|
-
loaded: false,
|
|
107
|
-
dependencies: [...dependencies],
|
|
108
|
-
dependents: [],
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
this.entries.set(themeId, entry);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Get theme entry
|
|
116
|
-
*/
|
|
117
|
-
get(themeId: string): RegistryEntry | undefined {
|
|
118
|
-
return this.entries.get(themeId);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Check if theme exists
|
|
123
|
-
*/
|
|
124
|
-
has(themeId: string): boolean {
|
|
125
|
-
return this.entries.has(themeId);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Get all theme IDs
|
|
130
|
-
*/
|
|
131
|
-
getAllIds(): string[] {
|
|
132
|
-
return Array.from(this.entries.keys());
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Get all theme metadata
|
|
137
|
-
*/
|
|
138
|
-
getAllMetadata(): ThemeMetadata[] {
|
|
139
|
-
return Array.from(this.entries.values()).map(entry => ({
|
|
140
|
-
id: entry.id,
|
|
141
|
-
name: entry.definition.name,
|
|
142
|
-
type: entry.definition.type,
|
|
143
|
-
class: entry.definition.class,
|
|
144
|
-
description: entry.definition.description,
|
|
145
|
-
author: entry.definition.author,
|
|
146
|
-
version: entry.definition.version,
|
|
147
|
-
tags: entry.definition.tags,
|
|
148
|
-
supportsDarkMode: entry.definition.supportsDarkMode,
|
|
149
|
-
status: entry.definition.status,
|
|
150
|
-
a11y: entry.definition.a11y,
|
|
151
|
-
color: entry.definition.color,
|
|
152
|
-
features: entry.definition.features,
|
|
153
|
-
dependencies: entry.dependencies,
|
|
154
|
-
}));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Get theme definition
|
|
159
|
-
*/
|
|
160
|
-
getDefinition(themeId: string): ThemeDefinition | undefined {
|
|
161
|
-
return this.entries.get(themeId)?.definition;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Check if a theme is loaded
|
|
166
|
-
*/
|
|
167
|
-
isThemeLoaded(themeId: string): boolean {
|
|
168
|
-
const entry = this.entries.get(themeId);
|
|
169
|
-
return entry ? entry.loaded : false;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Mark a theme as loaded
|
|
174
|
-
*/
|
|
175
|
-
markLoaded(themeId: string, theme?: Theme): void {
|
|
176
|
-
const entry = this.entries.get(themeId);
|
|
177
|
-
if (entry) {
|
|
178
|
-
entry.loaded = true;
|
|
179
|
-
if (theme) {
|
|
180
|
-
entry.theme = theme;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* Get theme object (for JS themes)
|
|
187
|
-
*/
|
|
188
|
-
getTheme(themeId: string): Theme | undefined {
|
|
189
|
-
const entry = this.entries.get(themeId);
|
|
190
|
-
return entry?.loaded ? entry.theme : undefined;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Get dependencies for a theme
|
|
195
|
-
*/
|
|
196
|
-
getDependencies(themeId: string): string[] {
|
|
197
|
-
return this.entries.get(themeId)?.dependencies || [];
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Get dependents for a theme (themes that depend on this one)
|
|
202
|
-
*/
|
|
203
|
-
getDependents(themeId: string): string[] {
|
|
204
|
-
return this.entries.get(themeId)?.dependents || [];
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Resolve all dependencies in correct order
|
|
209
|
-
*/
|
|
210
|
-
resolveDependencyOrder(themeId: string): string[] {
|
|
211
|
-
const resolved: string[] = [];
|
|
212
|
-
const visited = new Set<string>();
|
|
213
|
-
const visiting = new Set<string>();
|
|
214
|
-
|
|
215
|
-
const visit = (id: string): void => {
|
|
216
|
-
if (visiting.has(id)) {
|
|
217
|
-
throw new Error(`Circular dependency detected involving theme: ${id}`);
|
|
218
|
-
}
|
|
219
|
-
if (visited.has(id)) {
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
visiting.add(id);
|
|
224
|
-
const entry = this.entries.get(id);
|
|
225
|
-
if (entry) {
|
|
226
|
-
for (const dep of entry.dependencies) {
|
|
227
|
-
if (!this.has(dep)) {
|
|
228
|
-
throw new Error(`Theme "${id}" depends on non-existent theme: ${dep}`);
|
|
229
|
-
}
|
|
230
|
-
visit(dep);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
visiting.delete(id);
|
|
234
|
-
visited.add(id);
|
|
235
|
-
resolved.push(id);
|
|
236
|
-
};
|
|
30
|
+
export function registerTheme(registry: ThemeRegistry, id: string, metadata: ThemeMetadata): void {
|
|
31
|
+
registry[id] = metadata;
|
|
32
|
+
}
|
|
237
33
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Unregister a theme
|
|
36
|
+
* @param registry - Theme registry object
|
|
37
|
+
* @param id - Theme identifier
|
|
38
|
+
*/
|
|
39
|
+
export function unregisterTheme(registry: ThemeRegistry, id: string): boolean {
|
|
40
|
+
const exists = id in registry;
|
|
41
|
+
delete registry[id];
|
|
42
|
+
return exists;
|
|
43
|
+
}
|
|
241
44
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
if (depEntry) {
|
|
251
|
-
if (!depEntry.dependents.includes(entry.id)) {
|
|
252
|
-
depEntry.dependents.push(entry.id);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a theme is registered
|
|
47
|
+
* @param registry - Theme registry object
|
|
48
|
+
* @param id - Theme identifier
|
|
49
|
+
*/
|
|
50
|
+
export function hasTheme(registry: ThemeRegistry, id: string): boolean {
|
|
51
|
+
return id in registry;
|
|
52
|
+
}
|
|
258
53
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Get theme metadata
|
|
56
|
+
* @param registry - Theme registry object
|
|
57
|
+
* @param id - Theme identifier
|
|
58
|
+
*/
|
|
59
|
+
export function getTheme(registry: ThemeRegistry, id: string): ThemeMetadata | undefined {
|
|
60
|
+
return registry[id];
|
|
61
|
+
}
|
|
264
62
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
63
|
+
/**
|
|
64
|
+
* Get all registered theme metadata
|
|
65
|
+
* @param registry - Theme registry object
|
|
66
|
+
*/
|
|
67
|
+
export function getAllThemes(registry: ThemeRegistry): ThemeMetadata[] {
|
|
68
|
+
return Object.values(registry);
|
|
69
|
+
}
|
|
273
70
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
}
|
|
71
|
+
/**
|
|
72
|
+
* Get all registered theme IDs
|
|
73
|
+
* @param registry - Theme registry object
|
|
74
|
+
*/
|
|
75
|
+
export function getThemeIds(registry: ThemeRegistry): string[] {
|
|
76
|
+
return Object.keys(registry);
|
|
77
|
+
}
|
|
282
78
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Clear all registered themes
|
|
81
|
+
* @param registry - Theme registry object
|
|
82
|
+
*/
|
|
83
|
+
export function clearThemes(registry: ThemeRegistry): void {
|
|
84
|
+
Object.keys(registry).forEach(key => delete registry[key]);
|
|
85
|
+
}
|
|
288
86
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
this.initialized = false;
|
|
296
|
-
}
|
|
87
|
+
/**
|
|
88
|
+
* Get the number of registered themes
|
|
89
|
+
* @param registry - Theme registry object
|
|
90
|
+
*/
|
|
91
|
+
export function getThemeCount(registry: ThemeRegistry): number {
|
|
92
|
+
return Object.keys(registry).length;
|
|
297
93
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Composition Utilities
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Simplified utilities for composing, merging, and extending themes.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { Theme, ThemeOptions } from '../types';
|
|
@@ -22,7 +22,7 @@ function isObject(item: any): item is Record<string, any> {
|
|
|
22
22
|
* Deep merge multiple objects
|
|
23
23
|
* Later objects override earlier ones
|
|
24
24
|
*/
|
|
25
|
-
export function deepMerge<T extends Record<string,
|
|
25
|
+
export function deepMerge<T extends Record<string, unknown>>(...objects: Partial<T>[]): T {
|
|
26
26
|
if (objects.length === 0) return {} as T;
|
|
27
27
|
if (objects.length === 1) return objects[0] as T;
|
|
28
28
|
|
|
@@ -40,10 +40,10 @@ export function deepMerge<T extends Record<string, any>>(...objects: Partial<T>[
|
|
|
40
40
|
|
|
41
41
|
if (isObject(targetValue) && isObject(sourceValue)) {
|
|
42
42
|
// Recursively merge objects
|
|
43
|
-
result[key] = deepMerge(targetValue as
|
|
43
|
+
result[key] = deepMerge(targetValue as Record<string, unknown>, sourceValue as Record<string, unknown>) as T[Extract<keyof T, string>];
|
|
44
44
|
} else {
|
|
45
45
|
// Override with source value
|
|
46
|
-
result[key] = sourceValue as
|
|
46
|
+
result[key] = sourceValue as T[Extract<keyof T, string>];
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
}
|
|
@@ -57,10 +57,10 @@ export function deepMerge<T extends Record<string, any>>(...objects: Partial<T>[
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Merge multiple theme options into a single theme options object
|
|
60
|
-
*
|
|
60
|
+
*
|
|
61
61
|
* @param themes - Theme options to merge
|
|
62
62
|
* @returns Merged theme options
|
|
63
|
-
*
|
|
63
|
+
*
|
|
64
64
|
* @example
|
|
65
65
|
* ```typescript
|
|
66
66
|
* const baseTheme = { palette: { primary: { main: '#000' } } };
|
|
@@ -74,11 +74,11 @@ export function mergeTheme(...themes: ThemeOptions[]): ThemeOptions {
|
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* Extend an existing theme with new options
|
|
77
|
-
*
|
|
77
|
+
*
|
|
78
78
|
* @param baseTheme - Base theme to extend (can be Theme or ThemeOptions)
|
|
79
79
|
* @param extension - Theme options to extend with
|
|
80
80
|
* @returns New theme with extended options
|
|
81
|
-
*
|
|
81
|
+
*
|
|
82
82
|
* @example
|
|
83
83
|
* ```typescript
|
|
84
84
|
* const base = createTheme({ palette: { primary: { main: '#000' } } });
|
|
@@ -88,66 +88,16 @@ export function mergeTheme(...themes: ThemeOptions[]): ThemeOptions {
|
|
|
88
88
|
* ```
|
|
89
89
|
*/
|
|
90
90
|
export function extendTheme(baseTheme: Theme | ThemeOptions, extension: ThemeOptions): Theme {
|
|
91
|
-
//
|
|
92
|
-
const baseOptions: ThemeOptions = (baseTheme as
|
|
93
|
-
?
|
|
94
|
-
:
|
|
91
|
+
// Convert baseTheme to ThemeOptions if it's a complete Theme
|
|
92
|
+
const baseOptions: ThemeOptions = (baseTheme as Theme & { __isJSTheme?: boolean }).__isJSTheme
|
|
93
|
+
? { ...baseTheme } as ThemeOptions
|
|
94
|
+
: baseTheme;
|
|
95
95
|
|
|
96
|
+
// Merge and create new theme
|
|
96
97
|
const merged = mergeTheme(baseOptions, extension);
|
|
97
98
|
return createThemeObject(merged);
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
/**
|
|
101
|
-
* Extract theme options from a complete Theme object
|
|
102
|
-
*/
|
|
103
|
-
function extractThemeOptions(theme: Theme): ThemeOptions {
|
|
104
|
-
return {
|
|
105
|
-
name: theme.name,
|
|
106
|
-
class: theme.class,
|
|
107
|
-
description: theme.description,
|
|
108
|
-
author: theme.author,
|
|
109
|
-
version: theme.version,
|
|
110
|
-
tags: theme.tags,
|
|
111
|
-
supportsDarkMode: theme.supportsDarkMode,
|
|
112
|
-
status: theme.status,
|
|
113
|
-
a11y: theme.a11y,
|
|
114
|
-
color: theme.color,
|
|
115
|
-
features: theme.features,
|
|
116
|
-
dependencies: theme.dependencies,
|
|
117
|
-
palette: {
|
|
118
|
-
primary: theme.palette.primary,
|
|
119
|
-
secondary: theme.palette.secondary,
|
|
120
|
-
error: theme.palette.error,
|
|
121
|
-
warning: theme.palette.warning,
|
|
122
|
-
info: theme.palette.info,
|
|
123
|
-
success: theme.palette.success,
|
|
124
|
-
background: theme.palette.background,
|
|
125
|
-
text: theme.palette.text,
|
|
126
|
-
},
|
|
127
|
-
typography: {
|
|
128
|
-
fontFamily: theme.typography.fontFamily,
|
|
129
|
-
fontSize: theme.typography.fontSize,
|
|
130
|
-
fontWeightLight: theme.typography.fontWeightLight,
|
|
131
|
-
fontWeightRegular: theme.typography.fontWeightRegular,
|
|
132
|
-
fontWeightMedium: theme.typography.fontWeightMedium,
|
|
133
|
-
fontWeightSemiBold: theme.typography.fontWeightSemiBold,
|
|
134
|
-
fontWeightBold: theme.typography.fontWeightBold,
|
|
135
|
-
h1: theme.typography.h1,
|
|
136
|
-
h2: theme.typography.h2,
|
|
137
|
-
h3: theme.typography.h3,
|
|
138
|
-
h4: theme.typography.h4,
|
|
139
|
-
h5: theme.typography.h5,
|
|
140
|
-
h6: theme.typography.h6,
|
|
141
|
-
body1: theme.typography.body1,
|
|
142
|
-
body2: theme.typography.body2,
|
|
143
|
-
},
|
|
144
|
-
shadows: theme.shadows,
|
|
145
|
-
transitions: theme.transitions,
|
|
146
|
-
zIndex: theme.zIndex,
|
|
147
|
-
custom: theme.custom,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
|
|
151
101
|
export default {
|
|
152
102
|
deepMerge,
|
|
153
103
|
mergeTheme,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Core Theme Functions
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Simplified theme system that handles both DesignTokens and Theme objects.
|
|
5
5
|
* Config-first approach: loads from atomix.config.ts when no input is provided.
|
|
6
6
|
* Config file is required for automatic loading.
|
|
7
7
|
*/
|
|
@@ -12,34 +12,33 @@ import type { GenerateCSSVariablesOptions } from '../generators/generateCSS';
|
|
|
12
12
|
import { createTokens } from '../tokens/tokens';
|
|
13
13
|
import { generateCSSVariables } from '../generators/generateCSS';
|
|
14
14
|
import { themeToDesignTokens } from '../adapters/themeAdapter';
|
|
15
|
-
import { loadThemeFromConfigSync } from '../config/configLoader';
|
|
16
15
|
|
|
17
16
|
/**
|
|
18
17
|
* Create theme CSS from tokens or Theme object
|
|
19
|
-
*
|
|
18
|
+
*
|
|
20
19
|
* **Config-First Approach**: If no input is provided, loads from `atomix.config.ts`.
|
|
21
20
|
* Config file is required for automatic loading.
|
|
22
|
-
*
|
|
21
|
+
*
|
|
23
22
|
* @param input - DesignTokens (partial), Theme object, or undefined (loads from config)
|
|
24
23
|
* @param options - CSS generation options (prefix is automatically read from config if not provided)
|
|
25
24
|
* @returns CSS string with custom properties
|
|
26
25
|
* @throws Error if config loading fails when no input is provided
|
|
27
|
-
*
|
|
26
|
+
*
|
|
28
27
|
* @example
|
|
29
28
|
* ```typescript
|
|
30
29
|
* // Loads from atomix.config.ts (config file required)
|
|
31
30
|
* const css = createTheme();
|
|
32
|
-
*
|
|
31
|
+
*
|
|
33
32
|
* // Using DesignTokens
|
|
34
33
|
* const css = createTheme({
|
|
35
34
|
* 'primary': '#7c3aed',
|
|
36
35
|
* 'spacing-4': '1rem',
|
|
37
36
|
* });
|
|
38
|
-
*
|
|
37
|
+
*
|
|
39
38
|
* // Using Theme object
|
|
40
39
|
* const theme = createThemeObject({ palette: { primary: { main: '#7c3aed' } } });
|
|
41
40
|
* const css = createTheme(theme);
|
|
42
|
-
*
|
|
41
|
+
*
|
|
43
42
|
* // With custom options
|
|
44
43
|
* const css = createTheme(undefined, { prefix: 'myapp', selector: ':root' });
|
|
45
44
|
* ```
|
|
@@ -48,47 +47,62 @@ export function createTheme(
|
|
|
48
47
|
input?: Partial<DesignTokens> | Theme,
|
|
49
48
|
options?: GenerateCSSVariablesOptions
|
|
50
49
|
): string {
|
|
50
|
+
// Determine tokens based on input
|
|
51
51
|
let tokens: Partial<DesignTokens>;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// If no input provided, load from config (required)
|
|
52
|
+
|
|
55
53
|
if (!input) {
|
|
56
|
-
|
|
54
|
+
// Check if we're in a browser environment
|
|
55
|
+
if (typeof window !== 'undefined') {
|
|
56
|
+
throw new Error('createTheme: No input provided and config loading is not available in browser environment. Please provide tokens explicitly or use Node.js/SSR environment.');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Load from config when no input provided
|
|
60
|
+
// Using dynamic import in a way that's more compatible with bundlers
|
|
61
|
+
let loadThemeFromConfigSync: any;
|
|
62
|
+
let loadAtomixConfig: any;
|
|
57
63
|
|
|
58
|
-
// Get prefix from config
|
|
59
64
|
try {
|
|
60
|
-
//
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
65
|
+
// Use dynamic require but only in Node.js environments
|
|
66
|
+
// This approach allows bundlers to properly handle external dependencies
|
|
67
|
+
const configLoaderModule = require('../config/configLoader');
|
|
68
|
+
const loaderModule = require('../../config/loader');
|
|
69
|
+
|
|
70
|
+
loadThemeFromConfigSync = configLoaderModule.loadThemeFromConfigSync;
|
|
71
|
+
loadAtomixConfig = loaderModule.loadAtomixConfig;
|
|
72
|
+
|
|
73
|
+
tokens = loadThemeFromConfigSync();
|
|
74
|
+
|
|
75
|
+
// Get prefix from config if needed
|
|
76
|
+
if (!options?.prefix) {
|
|
77
|
+
try {
|
|
78
|
+
const config = loadAtomixConfig({ configPath: 'atomix.config.ts', required: false });
|
|
79
|
+
options = { ...options, prefix: config?.prefix || 'atomix' };
|
|
80
|
+
} catch (error) {
|
|
81
|
+
// If config loading fails, use default prefix
|
|
82
|
+
options = { ...options, prefix: 'atomix' };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
64
85
|
} catch (error) {
|
|
65
|
-
|
|
86
|
+
throw new Error('createTheme: No input provided and config loading is not available in this environment. Please provide tokens explicitly.');
|
|
66
87
|
}
|
|
67
|
-
|
|
68
|
-
|
|
88
|
+
} else if (isThemeObject(input)) {
|
|
89
|
+
// Convert Theme object to DesignTokens
|
|
90
|
+
tokens = themeToDesignTokens(input);
|
|
69
91
|
} else {
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
-
((input as any).palette && (input as any).typography);
|
|
73
|
-
|
|
74
|
-
if (isThemeObject) {
|
|
75
|
-
// Convert Theme to DesignTokens
|
|
76
|
-
tokens = themeToDesignTokens(input as Theme);
|
|
77
|
-
} else {
|
|
78
|
-
// Already DesignTokens
|
|
79
|
-
tokens = input as Partial<DesignTokens>;
|
|
80
|
-
}
|
|
92
|
+
// Use DesignTokens directly
|
|
93
|
+
tokens = input;
|
|
81
94
|
}
|
|
82
95
|
|
|
83
96
|
// Merge with defaults and generate CSS
|
|
84
97
|
const allTokens = createTokens(tokens);
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
return generateCSSVariables(allTokens, finalOptions);
|
|
98
|
+
|
|
99
|
+
// Get prefix from options or use default
|
|
100
|
+
const prefix = options?.prefix ?? 'atomix';
|
|
101
|
+
|
|
102
|
+
return generateCSSVariables(allTokens, { ...options, prefix });
|
|
93
103
|
}
|
|
94
104
|
|
|
105
|
+
// Helper functions to simplify main function
|
|
106
|
+
function isThemeObject(input: any): input is Theme {
|
|
107
|
+
return input?.__isJSTheme === true || (input?.palette && input?.typography);
|
|
108
|
+
}
|
|
@@ -327,8 +327,8 @@ export function createThemeObject(...options: ThemeOptions[]): Theme {
|
|
|
327
327
|
|
|
328
328
|
// Create typography
|
|
329
329
|
const typography: Theme['typography'] = deepMerge(
|
|
330
|
-
{ ...DEFAULT_TYPOGRAPHY } as
|
|
331
|
-
(mergedOptions.typography || {}) as
|
|
330
|
+
{ ...DEFAULT_TYPOGRAPHY } as Partial<Theme['typography']>,
|
|
331
|
+
(mergedOptions.typography || {}) as Partial<Theme['typography']>
|
|
332
332
|
) as Theme['typography'];
|
|
333
333
|
|
|
334
334
|
// Create spacing
|
|
@@ -7,4 +7,18 @@
|
|
|
7
7
|
export { createTheme } from './createTheme';
|
|
8
8
|
export { createThemeObject } from './createThemeObject';
|
|
9
9
|
export { deepMerge, mergeTheme, extendTheme } from './composeTheme';
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
// Simplified Theme Registry API
|
|
12
|
+
export {
|
|
13
|
+
createThemeRegistry,
|
|
14
|
+
registerTheme,
|
|
15
|
+
unregisterTheme,
|
|
16
|
+
hasTheme,
|
|
17
|
+
getTheme,
|
|
18
|
+
getAllThemes,
|
|
19
|
+
getThemeIds,
|
|
20
|
+
clearThemes,
|
|
21
|
+
getThemeCount,
|
|
22
|
+
type ThemeRegistry,
|
|
23
|
+
type ThemeMetadata
|
|
24
|
+
} from './ThemeRegistry';
|
|
@@ -120,7 +120,7 @@ export class ThemeLogger {
|
|
|
120
120
|
|
|
121
121
|
constructor(config: LoggerConfig = {}) {
|
|
122
122
|
this.config = {
|
|
123
|
-
level: config.level ?? (process.env
|
|
123
|
+
level: config.level ?? (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production' ? LogLevel.WARN : LogLevel.INFO),
|
|
124
124
|
enableConsole: config.enableConsole ?? true,
|
|
125
125
|
onError: config.onError,
|
|
126
126
|
onWarn: config.onWarn,
|