@shohojdhara/atomix 0.3.5 → 0.3.6
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 +61 -66
- package/dist/charts.js.map +1 -1
- package/dist/core.js +47 -31
- package/dist/core.js.map +1 -1
- package/dist/forms.js +47 -31
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js +47 -31
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +1841 -1633
- package/dist/index.esm.js +4975 -4113
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +5151 -4290
- 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 +1572 -1442
- package/dist/theme.js +4816 -4080
- 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 +65 -31
- package/src/components/AtomixGlass/AtomixGlassContainer.tsx +11 -4
- 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/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 +2 -3
- package/src/lib/composables/useNavbar.ts +0 -10
- package/src/lib/config/loader.ts +2 -1
- package/src/lib/constants/components.ts +10 -0
- package/src/lib/hooks/useComponentCustomization.ts +1 -1
- 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 +254 -0
- package/src/lib/theme/config/loader.ts +37 -48
- 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} +0 -18
- package/src/lib/theme/constants/index.ts +8 -0
- package/src/lib/theme/core/ThemeRegistry.ts +19 -6
- package/src/lib/theme/core/__tests__/createTheme.test.ts +132 -0
- package/src/lib/theme/core/composeTheme.ts +155 -0
- package/src/lib/theme/core/createTheme.ts +94 -0
- package/src/lib/theme/{createTheme.ts → core/createThemeObject.ts} +10 -6
- package/src/lib/theme/core/index.ts +5 -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/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/{generateCSSVariables.ts → generators/generateCSSVariables.ts} +3 -13
- package/src/lib/theme/generators/index.ts +19 -0
- package/src/lib/theme/i18n/rtl.ts +5 -6
- package/src/lib/theme/index.ts +120 -15
- package/src/lib/theme/runtime/ThemeApplicator.ts +52 -111
- package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +1 -1
- package/src/lib/theme/runtime/ThemeProvider.tsx +456 -179
- package/src/lib/theme/runtime/index.ts +1 -2
- package/src/lib/theme/runtime/useTheme.ts +1 -2
- 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.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/themeHelpers.ts +78 -0
- package/src/lib/theme/{themeUtils.ts → utils/themeUtils.ts} +1 -1
- package/src/lib/theme-tools.ts +7 -8
- package/src/lib/types/components.ts +40 -130
- package/src/lib/utils/componentUtils.ts +1 -1
- 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
- /package/src/lib/theme/{errors.ts → errors/errors.ts} +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* createTheme Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests for createTheme function including automatic config loading
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
8
|
+
import { createTheme } from '../createTheme';
|
|
9
|
+
import type { DesignTokens } from '../../tokens/tokens';
|
|
10
|
+
import type { Theme } from '../../types';
|
|
11
|
+
|
|
12
|
+
describe('createTheme', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.clearAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe('Automatic Config Loading', () => {
|
|
18
|
+
it('should work without input (uses defaults or config)', () => {
|
|
19
|
+
// createTheme() should work even if config is not available
|
|
20
|
+
// It will fall back to default tokens
|
|
21
|
+
const css = createTheme();
|
|
22
|
+
|
|
23
|
+
expect(typeof css).toBe('string');
|
|
24
|
+
expect(css.length).toBeGreaterThan(0);
|
|
25
|
+
expect(css).toContain(':root');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should generate valid CSS with default tokens', () => {
|
|
29
|
+
const css = createTheme();
|
|
30
|
+
|
|
31
|
+
// Should contain CSS variable declarations
|
|
32
|
+
expect(css).toMatch(/--atomix-[a-z-]+:\s*[^;]+;/);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('DesignTokens Input', () => {
|
|
37
|
+
it('should accept DesignTokens and generate CSS', () => {
|
|
38
|
+
const tokens: Partial<DesignTokens> = {
|
|
39
|
+
'primary': '#7AFFD7',
|
|
40
|
+
'secondary': '#FF5733',
|
|
41
|
+
'spacing-4': '1rem',
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const css = createTheme(tokens);
|
|
45
|
+
|
|
46
|
+
expect(css).toContain('--atomix-primary');
|
|
47
|
+
expect(css).toContain('#7AFFD7');
|
|
48
|
+
expect(css).toContain('--atomix-secondary');
|
|
49
|
+
expect(css).toContain('#FF5733');
|
|
50
|
+
expect(css).toContain('--atomix-spacing-4');
|
|
51
|
+
expect(css).toContain('1rem');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should merge with default tokens', () => {
|
|
55
|
+
const tokens: Partial<DesignTokens> = {
|
|
56
|
+
'primary': '#CUSTOM',
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const css = createTheme(tokens);
|
|
60
|
+
|
|
61
|
+
// Should contain custom primary
|
|
62
|
+
expect(css).toContain('--atomix-primary');
|
|
63
|
+
expect(css).toContain('#CUSTOM');
|
|
64
|
+
|
|
65
|
+
// Should also contain default tokens
|
|
66
|
+
expect(css).toContain('--atomix-secondary');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('Options', () => {
|
|
71
|
+
it('should respect prefix option', () => {
|
|
72
|
+
const tokens: Partial<DesignTokens> = {
|
|
73
|
+
'primary': '#7AFFD7',
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const css = createTheme(tokens, { prefix: 'myapp' });
|
|
77
|
+
|
|
78
|
+
expect(css).toContain('--myapp-primary');
|
|
79
|
+
expect(css).not.toContain('--atomix-primary');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should respect selector option', () => {
|
|
83
|
+
const tokens: Partial<DesignTokens> = {
|
|
84
|
+
'primary': '#7AFFD7',
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const css = createTheme(tokens, { selector: '[data-theme="dark"]' });
|
|
88
|
+
|
|
89
|
+
expect(css).toContain('[data-theme="dark"]');
|
|
90
|
+
expect(css).not.toContain(':root');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should use default prefix when not provided', () => {
|
|
94
|
+
const tokens: Partial<DesignTokens> = {
|
|
95
|
+
'primary': '#7AFFD7',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const css = createTheme(tokens);
|
|
99
|
+
|
|
100
|
+
expect(css).toContain('--atomix-primary');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('CSS Output Format', () => {
|
|
105
|
+
it('should generate valid CSS syntax', () => {
|
|
106
|
+
const tokens: Partial<DesignTokens> = {
|
|
107
|
+
'primary': '#7AFFD7',
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const css = createTheme(tokens);
|
|
111
|
+
|
|
112
|
+
// Should be valid CSS
|
|
113
|
+
expect(css).toMatch(/^[^{]*\{[^}]*\}/s);
|
|
114
|
+
expect(css).toContain(':');
|
|
115
|
+
expect(css).toContain(';');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should format CSS with proper indentation', () => {
|
|
119
|
+
const tokens: Partial<DesignTokens> = {
|
|
120
|
+
'primary': '#7AFFD7',
|
|
121
|
+
'secondary': '#FF5733',
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const css = createTheme(tokens);
|
|
125
|
+
|
|
126
|
+
// Should have proper formatting
|
|
127
|
+
expect(css).toContain('\n');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Composition Utilities
|
|
3
|
+
*
|
|
4
|
+
* Utilities for composing, merging, and extending themes.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { Theme, ThemeOptions } from '../types';
|
|
8
|
+
import { createThemeObject } from './createThemeObject';
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Deep Merge Utility
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if value is an object
|
|
16
|
+
*/
|
|
17
|
+
function isObject(item: any): item is Record<string, any> {
|
|
18
|
+
return item && typeof item === 'object' && !Array.isArray(item) && typeof item !== 'function';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Deep merge multiple objects
|
|
23
|
+
* Later objects override earlier ones
|
|
24
|
+
*/
|
|
25
|
+
export function deepMerge<T extends Record<string, any>>(...objects: Partial<T>[]): T {
|
|
26
|
+
if (objects.length === 0) return {} as T;
|
|
27
|
+
if (objects.length === 1) return objects[0] as T;
|
|
28
|
+
|
|
29
|
+
const [target, ...sources] = objects;
|
|
30
|
+
const result = { ...target } as T;
|
|
31
|
+
|
|
32
|
+
for (const source of sources) {
|
|
33
|
+
if (!source) continue;
|
|
34
|
+
|
|
35
|
+
for (const key in source) {
|
|
36
|
+
if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
|
|
37
|
+
|
|
38
|
+
const targetValue = result[key];
|
|
39
|
+
const sourceValue = source[key];
|
|
40
|
+
|
|
41
|
+
if (isObject(targetValue) && isObject(sourceValue)) {
|
|
42
|
+
// Recursively merge objects
|
|
43
|
+
result[key] = deepMerge(targetValue as any, sourceValue as any) as any;
|
|
44
|
+
} else {
|
|
45
|
+
// Override with source value
|
|
46
|
+
result[key] = sourceValue as any;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// Theme Merging
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Merge multiple theme options into a single theme options object
|
|
60
|
+
*
|
|
61
|
+
* @param themes - Theme options to merge
|
|
62
|
+
* @returns Merged theme options
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const baseTheme = { palette: { primary: { main: '#000' } } };
|
|
67
|
+
* const customTheme = { palette: { secondary: { main: '#fff' } } };
|
|
68
|
+
* const merged = mergeTheme(baseTheme, customTheme);
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
export function mergeTheme(...themes: ThemeOptions[]): ThemeOptions {
|
|
72
|
+
return deepMerge({}, ...themes);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Extend an existing theme with new options
|
|
77
|
+
*
|
|
78
|
+
* @param baseTheme - Base theme to extend (can be Theme or ThemeOptions)
|
|
79
|
+
* @param extension - Theme options to extend with
|
|
80
|
+
* @returns New theme with extended options
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const base = createTheme({ palette: { primary: { main: '#000' } } });
|
|
85
|
+
* const extended = extendTheme(base, {
|
|
86
|
+
* palette: { secondary: { main: '#fff' } }
|
|
87
|
+
* });
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
export function extendTheme(baseTheme: Theme | ThemeOptions, extension: ThemeOptions): Theme {
|
|
91
|
+
// If baseTheme is a complete Theme, extract the options
|
|
92
|
+
const baseOptions: ThemeOptions = (baseTheme as any).__isJSTheme
|
|
93
|
+
? extractThemeOptions(baseTheme as Theme)
|
|
94
|
+
: (baseTheme as ThemeOptions);
|
|
95
|
+
|
|
96
|
+
const merged = mergeTheme(baseOptions, extension);
|
|
97
|
+
return createThemeObject(merged);
|
|
98
|
+
}
|
|
99
|
+
|
|
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
|
+
export default {
|
|
152
|
+
deepMerge,
|
|
153
|
+
mergeTheme,
|
|
154
|
+
extendTheme,
|
|
155
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core Theme Functions
|
|
3
|
+
*
|
|
4
|
+
* Unified theme system that handles both DesignTokens and Theme objects.
|
|
5
|
+
* Config-first approach: loads from atomix.config.ts when no input is provided.
|
|
6
|
+
* Config file is required for automatic loading.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { DesignTokens } from '../tokens/tokens';
|
|
10
|
+
import type { Theme } from '../types';
|
|
11
|
+
import type { GenerateCSSVariablesOptions } from '../generators/generateCSS';
|
|
12
|
+
import { createTokens } from '../tokens/tokens';
|
|
13
|
+
import { generateCSSVariables } from '../generators/generateCSS';
|
|
14
|
+
import { themeToDesignTokens } from '../adapters/themeAdapter';
|
|
15
|
+
import { loadThemeFromConfigSync } from '../config/configLoader';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create theme CSS from tokens or Theme object
|
|
19
|
+
*
|
|
20
|
+
* **Config-First Approach**: If no input is provided, loads from `atomix.config.ts`.
|
|
21
|
+
* Config file is required for automatic loading.
|
|
22
|
+
*
|
|
23
|
+
* @param input - DesignTokens (partial), Theme object, or undefined (loads from config)
|
|
24
|
+
* @param options - CSS generation options (prefix is automatically read from config if not provided)
|
|
25
|
+
* @returns CSS string with custom properties
|
|
26
|
+
* @throws Error if config loading fails when no input is provided
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Loads from atomix.config.ts (config file required)
|
|
31
|
+
* const css = createTheme();
|
|
32
|
+
*
|
|
33
|
+
* // Using DesignTokens
|
|
34
|
+
* const css = createTheme({
|
|
35
|
+
* 'primary': '#7c3aed',
|
|
36
|
+
* 'spacing-4': '1rem',
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Using Theme object
|
|
40
|
+
* const theme = createThemeObject({ palette: { primary: { main: '#7c3aed' } } });
|
|
41
|
+
* const css = createTheme(theme);
|
|
42
|
+
*
|
|
43
|
+
* // With custom options
|
|
44
|
+
* const css = createTheme(undefined, { prefix: 'myapp', selector: ':root' });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export function createTheme(
|
|
48
|
+
input?: Partial<DesignTokens> | Theme,
|
|
49
|
+
options?: GenerateCSSVariablesOptions
|
|
50
|
+
): string {
|
|
51
|
+
let tokens: Partial<DesignTokens>;
|
|
52
|
+
let configPrefix: string | undefined;
|
|
53
|
+
|
|
54
|
+
// If no input provided, load from config (required)
|
|
55
|
+
if (!input) {
|
|
56
|
+
const configTokens = loadThemeFromConfigSync();
|
|
57
|
+
|
|
58
|
+
// Get prefix from config
|
|
59
|
+
try {
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
61
|
+
const { loadAtomixConfig } = require('../../config/loader');
|
|
62
|
+
const config = loadAtomixConfig({ configPath: 'atomix.config.ts', required: true });
|
|
63
|
+
configPrefix = config?.prefix;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
// Prefix loading failed, but tokens were loaded, so continue
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
tokens = configTokens;
|
|
69
|
+
} else {
|
|
70
|
+
// Check if it's a Theme object
|
|
71
|
+
const isThemeObject = (input as any).__isJSTheme === true ||
|
|
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
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Merge with defaults and generate CSS
|
|
84
|
+
const allTokens = createTokens(tokens);
|
|
85
|
+
|
|
86
|
+
// Use prefix from config if not provided in options
|
|
87
|
+
const finalOptions: GenerateCSSVariablesOptions = {
|
|
88
|
+
...options,
|
|
89
|
+
prefix: options?.prefix ?? configPrefix ?? 'atomix',
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
return generateCSSVariables(allTokens, finalOptions);
|
|
93
|
+
}
|
|
94
|
+
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* createThemeObject - Create a theme object with computed values
|
|
3
3
|
*
|
|
4
4
|
* Similar to Material-UI's createTheme, this function accepts theme configuration
|
|
5
5
|
* options and returns a complete theme object with computed values.
|
|
6
6
|
*
|
|
7
|
+
* NOTE: For most use cases, use the simple theme system's `createTheme` instead,
|
|
8
|
+
* which generates CSS from DesignTokens. This function is for advanced use cases
|
|
9
|
+
* that need the full Theme object structure.
|
|
10
|
+
*
|
|
7
11
|
* @example
|
|
8
12
|
* ```typescript
|
|
9
|
-
* const theme =
|
|
13
|
+
* const theme = createThemeObject({
|
|
10
14
|
* palette: {
|
|
11
15
|
* primary: { main: '#7AFFD7' },
|
|
12
16
|
* secondary: { main: '#FF5733' },
|
|
@@ -31,8 +35,8 @@ import type {
|
|
|
31
35
|
TransitionOptions,
|
|
32
36
|
ZIndexOptions,
|
|
33
37
|
BorderRadiusOptions,
|
|
34
|
-
} from '
|
|
35
|
-
import { hexToRgb, getLuminance, getContrastText, lighten, darken, createSpacing } from '
|
|
38
|
+
} from '../types';
|
|
39
|
+
import { hexToRgb, getLuminance, getContrastText, lighten, darken, createSpacing } from '../utils/themeUtils';
|
|
36
40
|
import { deepMerge } from './composeTheme';
|
|
37
41
|
|
|
38
42
|
// ============================================================================
|
|
@@ -291,7 +295,7 @@ function createBreakpoints(breakpointsInput?: BreakpointsOptions): Theme['breakp
|
|
|
291
295
|
* @param options - Theme configuration options
|
|
292
296
|
* @returns Complete theme object
|
|
293
297
|
*/
|
|
294
|
-
export function
|
|
298
|
+
export function createThemeObject(...options: ThemeOptions[]): Theme {
|
|
295
299
|
// Merge all options
|
|
296
300
|
const mergedOptions = options.reduce((acc, option) => deepMerge(acc, option), {} as ThemeOptions);
|
|
297
301
|
|
|
@@ -385,4 +389,4 @@ export function createTheme(...options: ThemeOptions[]): Theme {
|
|
|
385
389
|
return theme;
|
|
386
390
|
}
|
|
387
391
|
|
|
388
|
-
export default
|
|
392
|
+
export default createThemeObject;
|
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Theme
|
|
2
|
+
* Core Theme Engine
|
|
3
3
|
*
|
|
4
|
-
* Core
|
|
4
|
+
* Core theme creation, composition, and registry functionality
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
export {
|
|
7
|
+
export { createTheme } from './createTheme';
|
|
8
|
+
export { createThemeObject } from './createThemeObject';
|
|
9
|
+
export { deepMerge, mergeTheme, extendTheme } from './composeTheme';
|
|
8
10
|
export { ThemeRegistry } from './ThemeRegistry';
|
|
9
|
-
export { ThemeCache } from './ThemeCache';
|
|
10
|
-
export { ThemeValidator } from './ThemeValidator';
|
|
11
|
-
|
|
12
|
-
export type {
|
|
13
|
-
ThemeChangeEvent,
|
|
14
|
-
ThemeLoadOptions,
|
|
15
|
-
ThemeChangeListener,
|
|
16
|
-
ThemeLoadListener,
|
|
17
|
-
ThemeErrorListener,
|
|
18
|
-
ThemeEngineConfig,
|
|
19
|
-
} from './ThemeEngine';
|
|
20
|
-
|
|
21
|
-
export type {
|
|
22
|
-
ValidationResult,
|
|
23
|
-
A11yIssue,
|
|
24
|
-
} from './ThemeValidator';
|