@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
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
* Developer tools for theme management and debugging
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
// CLI Tools
|
|
8
|
-
export { ThemeCLI, createCLI, runCLI } from './CLI';
|
|
9
|
-
export type { CLICommand } from './CLI';
|
|
10
|
-
|
|
11
7
|
// React Components
|
|
12
8
|
export { ThemePreview } from './Preview';
|
|
13
9
|
export type { ThemePreviewProps } from './Preview';
|
|
@@ -20,3 +16,17 @@ export type { ThemeComparatorProps } from './Comparator';
|
|
|
20
16
|
|
|
21
17
|
export { ThemeLiveEditor } from './LiveEditor';
|
|
22
18
|
export type { ThemeLiveEditorProps } from './LiveEditor';
|
|
19
|
+
|
|
20
|
+
// Validator (devtools only)
|
|
21
|
+
export { ThemeValidator } from './ThemeValidator';
|
|
22
|
+
export type {
|
|
23
|
+
ValidationResult,
|
|
24
|
+
A11yIssue,
|
|
25
|
+
} from './ThemeValidator';
|
|
26
|
+
|
|
27
|
+
// Hooks
|
|
28
|
+
export { useHistory } from './useHistory';
|
|
29
|
+
export type {
|
|
30
|
+
UseHistoryOptions,
|
|
31
|
+
UseHistoryReturn,
|
|
32
|
+
} from './useHistory';
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useHistory Hook
|
|
3
|
+
*
|
|
4
|
+
* React hook for managing undo/redo history
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
8
|
+
|
|
9
|
+
export interface UseHistoryOptions {
|
|
10
|
+
/** Maximum number of history entries (default: 50) */
|
|
11
|
+
maxHistorySize?: number;
|
|
12
|
+
/** Initial state */
|
|
13
|
+
initialState?: any;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UseHistoryReturn<T> {
|
|
17
|
+
/** Current state */
|
|
18
|
+
state: T;
|
|
19
|
+
/** Update state and add to history */
|
|
20
|
+
setState: (newState: T) => void;
|
|
21
|
+
/** Undo last change */
|
|
22
|
+
undo: () => void;
|
|
23
|
+
/** Redo last undone change */
|
|
24
|
+
redo: () => void;
|
|
25
|
+
/** Check if undo is available */
|
|
26
|
+
canUndo: boolean;
|
|
27
|
+
/** Check if redo is available */
|
|
28
|
+
canRedo: boolean;
|
|
29
|
+
/** Clear history */
|
|
30
|
+
clearHistory: () => void;
|
|
31
|
+
/** Get history statistics */
|
|
32
|
+
getHistoryStats: () => { currentIndex: number; totalEntries: number };
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* useHistory hook
|
|
37
|
+
*
|
|
38
|
+
* Provides undo/redo functionality for state management
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* const { state, setState, undo, redo, canUndo, canRedo } = useHistory({
|
|
43
|
+
* initialState: theme,
|
|
44
|
+
* maxHistorySize: 50
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function useHistory<T>(options: UseHistoryOptions = {}): UseHistoryReturn<T> {
|
|
49
|
+
const { maxHistorySize = 50, initialState } = options;
|
|
50
|
+
|
|
51
|
+
const [state, setStateInternal] = useState<T>(initialState as T);
|
|
52
|
+
const historyRef = useRef<T[]>([initialState as T]);
|
|
53
|
+
const currentIndexRef = useRef<number>(0);
|
|
54
|
+
const [canUndo, setCanUndo] = useState(false);
|
|
55
|
+
const [canRedo, setCanRedo] = useState(false);
|
|
56
|
+
|
|
57
|
+
const updateHistoryState = useCallback(() => {
|
|
58
|
+
setCanUndo(currentIndexRef.current > 0);
|
|
59
|
+
setCanRedo(currentIndexRef.current < historyRef.current.length - 1);
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
const setState = useCallback((newState: T) => {
|
|
63
|
+
// Remove any future history if we're not at the end
|
|
64
|
+
if (currentIndexRef.current < historyRef.current.length - 1) {
|
|
65
|
+
historyRef.current = historyRef.current.slice(0, currentIndexRef.current + 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Add new state to history
|
|
69
|
+
historyRef.current.push(newState);
|
|
70
|
+
currentIndexRef.current = historyRef.current.length - 1;
|
|
71
|
+
|
|
72
|
+
// Limit history size
|
|
73
|
+
if (historyRef.current.length > maxHistorySize) {
|
|
74
|
+
historyRef.current.shift();
|
|
75
|
+
currentIndexRef.current--;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
setStateInternal(newState);
|
|
79
|
+
updateHistoryState();
|
|
80
|
+
}, [maxHistorySize, updateHistoryState]);
|
|
81
|
+
|
|
82
|
+
const undo = useCallback(() => {
|
|
83
|
+
if (currentIndexRef.current > 0) {
|
|
84
|
+
currentIndexRef.current--;
|
|
85
|
+
const previousState = historyRef.current[currentIndexRef.current];
|
|
86
|
+
setStateInternal(previousState as T);
|
|
87
|
+
updateHistoryState();
|
|
88
|
+
}
|
|
89
|
+
}, [updateHistoryState]);
|
|
90
|
+
|
|
91
|
+
const redo = useCallback(() => {
|
|
92
|
+
if (currentIndexRef.current < historyRef.current.length - 1) {
|
|
93
|
+
currentIndexRef.current++;
|
|
94
|
+
const nextState = historyRef.current[currentIndexRef.current];
|
|
95
|
+
setStateInternal(nextState as T);
|
|
96
|
+
updateHistoryState();
|
|
97
|
+
}
|
|
98
|
+
}, [updateHistoryState]);
|
|
99
|
+
|
|
100
|
+
const clearHistory = useCallback(() => {
|
|
101
|
+
const currentState = historyRef.current[currentIndexRef.current];
|
|
102
|
+
historyRef.current = [currentState as T];
|
|
103
|
+
currentIndexRef.current = 0;
|
|
104
|
+
updateHistoryState();
|
|
105
|
+
}, [updateHistoryState]);
|
|
106
|
+
|
|
107
|
+
const getHistoryStats = useCallback(() => {
|
|
108
|
+
return {
|
|
109
|
+
currentIndex: currentIndexRef.current,
|
|
110
|
+
totalEntries: historyRef.current.length,
|
|
111
|
+
};
|
|
112
|
+
}, []);
|
|
113
|
+
|
|
114
|
+
// Initialize undo/redo state
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
updateHistoryState();
|
|
117
|
+
}, [updateHistoryState]);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
state,
|
|
121
|
+
setState,
|
|
122
|
+
undo,
|
|
123
|
+
redo,
|
|
124
|
+
canUndo,
|
|
125
|
+
canRedo,
|
|
126
|
+
clearHistory,
|
|
127
|
+
getHistoryStats,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
@@ -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,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS File Utilities
|
|
3
|
+
*
|
|
4
|
+
* Save CSS to file system (Node.js only).
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Save CSS to file
|
|
9
|
+
*
|
|
10
|
+
* Writes CSS string to a file. Only works in Node.js environment.
|
|
11
|
+
*
|
|
12
|
+
* @param css - CSS string to save
|
|
13
|
+
* @param filePath - Output file path
|
|
14
|
+
* @throws Error if called in browser environment
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const css = ':root { --atomix-color-primary: #7AFFD7; }';
|
|
19
|
+
* await saveCSSFile(css, './themes/custom.css');
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export async function saveCSSFile(
|
|
23
|
+
css: string,
|
|
24
|
+
filePath: string
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
// Check if in browser environment
|
|
27
|
+
if (typeof window !== 'undefined') {
|
|
28
|
+
throw new Error(
|
|
29
|
+
'saveCSSFile can only be used in Node.js environment. ' +
|
|
30
|
+
'Use injectCSS() for browser environments.'
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Dynamic import to avoid bundling Node.js modules in browser builds
|
|
35
|
+
const fs = await import('fs/promises');
|
|
36
|
+
const path = await import('path');
|
|
37
|
+
|
|
38
|
+
// Ensure directory exists
|
|
39
|
+
const dir = path.dirname(filePath);
|
|
40
|
+
await fs.mkdir(dir, { recursive: true });
|
|
41
|
+
|
|
42
|
+
// Write file
|
|
43
|
+
await fs.writeFile(filePath, css, 'utf8');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Save CSS to file (synchronous version)
|
|
48
|
+
*
|
|
49
|
+
* Synchronous version of saveCSSFile. Only works in Node.js environment.
|
|
50
|
+
*
|
|
51
|
+
* @param css - CSS string to save
|
|
52
|
+
* @param filePath - Output file path
|
|
53
|
+
* @throws Error if called in browser environment
|
|
54
|
+
*/
|
|
55
|
+
export function saveCSSFileSync(css: string, filePath: string): void {
|
|
56
|
+
// Check if in browser environment
|
|
57
|
+
if (typeof window !== 'undefined') {
|
|
58
|
+
throw new Error(
|
|
59
|
+
'saveCSSFileSync can only be used in Node.js environment. ' +
|
|
60
|
+
'Use injectCSS() for browser environments.'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Use require for synchronous file operations
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
66
|
+
const fs = require('fs');
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
68
|
+
const path = require('path');
|
|
69
|
+
|
|
70
|
+
// Ensure directory exists
|
|
71
|
+
const dir = path.dirname(filePath);
|
|
72
|
+
if (!fs.existsSync(dir)) {
|
|
73
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Write file
|
|
77
|
+
fs.writeFileSync(filePath, css, 'utf8');
|
|
78
|
+
}
|
|
79
|
+
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Variable Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates CSS custom properties from design tokens.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DesignTokens } from '../tokens/tokens';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Options for CSS variable generation
|
|
11
|
+
*/
|
|
12
|
+
export interface GenerateCSSVariablesOptions {
|
|
13
|
+
/** CSS selector for the variables (default: ':root') */
|
|
14
|
+
selector?: string;
|
|
15
|
+
/** Prefix for CSS variables (default: 'atomix') */
|
|
16
|
+
prefix?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generate CSS variables from tokens
|
|
21
|
+
*
|
|
22
|
+
* Converts flat token object to CSS custom properties.
|
|
23
|
+
*
|
|
24
|
+
* @param tokens - Design tokens object
|
|
25
|
+
* @param options - Generation options
|
|
26
|
+
* @returns CSS string with custom properties
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const tokens = {
|
|
31
|
+
* 'primary': '#7c3aed',
|
|
32
|
+
* 'spacing-4': '1rem',
|
|
33
|
+
* };
|
|
34
|
+
*
|
|
35
|
+
* const css = generateCSSVariables(tokens);
|
|
36
|
+
* // Returns: ":root {\n --atomix-primary: #7c3aed;\n --atomix-spacing-4: 1rem;\n}"
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function generateCSSVariables(
|
|
40
|
+
tokens: DesignTokens,
|
|
41
|
+
options: GenerateCSSVariablesOptions = {}
|
|
42
|
+
): string {
|
|
43
|
+
const {
|
|
44
|
+
selector = ':root',
|
|
45
|
+
prefix = 'atomix',
|
|
46
|
+
} = options;
|
|
47
|
+
|
|
48
|
+
// Filter out undefined values and generate CSS variables
|
|
49
|
+
const variables = Object.entries(tokens)
|
|
50
|
+
.filter(([, value]) => value !== undefined)
|
|
51
|
+
.map(([key, value]) => {
|
|
52
|
+
// Convert token key to CSS variable name
|
|
53
|
+
// 'color-primary' -> '--atomix-color-primary'
|
|
54
|
+
const varName = `--${prefix}-${key}`;
|
|
55
|
+
return ` ${varName}: ${value};`;
|
|
56
|
+
})
|
|
57
|
+
.join('\n');
|
|
58
|
+
|
|
59
|
+
// Return formatted CSS
|
|
60
|
+
return `${selector} {\n${variables}\n}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Generate CSS variables with custom selector
|
|
65
|
+
*
|
|
66
|
+
* Useful for theme-specific selectors like `[data-theme="dark"]`
|
|
67
|
+
*
|
|
68
|
+
* @param tokens - Design tokens object
|
|
69
|
+
* @param selector - CSS selector (e.g., '[data-theme="dark"]')
|
|
70
|
+
* @param prefix - CSS variable prefix
|
|
71
|
+
* @returns CSS string
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const css = generateCSSVariablesForSelector(
|
|
76
|
+
* tokens,
|
|
77
|
+
* '[data-theme="dark"]',
|
|
78
|
+
* 'atomix'
|
|
79
|
+
* );
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function generateCSSVariablesForSelector(
|
|
83
|
+
tokens: DesignTokens,
|
|
84
|
+
selector: string,
|
|
85
|
+
prefix: string = 'atomix'
|
|
86
|
+
): string {
|
|
87
|
+
return generateCSSVariables(tokens, { selector, prefix });
|
|
88
|
+
}
|
|
89
|
+
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Variable Generator for Nested Tokens
|
|
3
|
+
*
|
|
4
|
+
* Generates CSS custom properties from nested token structures.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { DesignTokens } from '../tokens/tokens';
|
|
8
|
+
import { generateCSSVariables } from './generateCSS';
|
|
9
|
+
import { ThemeNaming } from '../../utils/themeNaming';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Options for CSS variable generation with nested support
|
|
13
|
+
*/
|
|
14
|
+
export interface GenerateNestedCSSVariablesOptions {
|
|
15
|
+
/** CSS selector for the variables (default: ':root') */
|
|
16
|
+
selector?: string;
|
|
17
|
+
/** Prefix for CSS variables (default: 'atomix') */
|
|
18
|
+
prefix?: string;
|
|
19
|
+
/** Separator for nested tokens (default: '-') */
|
|
20
|
+
separator?: string;
|
|
21
|
+
/** Whether to flatten nested objects (default: true) */
|
|
22
|
+
flatten?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generate CSS variables from nested token structure
|
|
27
|
+
*
|
|
28
|
+
* Converts nested token object to CSS custom properties.
|
|
29
|
+
* Supports both nested objects and flat token structures.
|
|
30
|
+
*
|
|
31
|
+
* @param tokens - Design tokens object (can be nested)
|
|
32
|
+
* @param options - Generation options
|
|
33
|
+
* @returns CSS string with custom properties
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* const tokens = {
|
|
38
|
+
* color: {
|
|
39
|
+
* primary: '#7c3aed',
|
|
40
|
+
* secondary: '#10b981',
|
|
41
|
+
* },
|
|
42
|
+
* spacing: {
|
|
43
|
+
* small: '0.5rem',
|
|
44
|
+
* medium: '1rem',
|
|
45
|
+
* },
|
|
46
|
+
* };
|
|
47
|
+
*
|
|
48
|
+
* const css = generateNestedCSSVariables(tokens);
|
|
49
|
+
* // Returns: ":root {
|
|
50
|
+
--atomix-color-primary: #7c3aed;
|
|
51
|
+
--atomix-color-secondary: #10b981;
|
|
52
|
+
--atomix-spacing-small: 0.5rem;
|
|
53
|
+
--atomix-spacing-medium: 1rem;
|
|
54
|
+
}"
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function generateNestedCSSVariables(
|
|
58
|
+
tokens: DesignTokens,
|
|
59
|
+
options: GenerateNestedCSSVariablesOptions = {}
|
|
60
|
+
): string {
|
|
61
|
+
const {
|
|
62
|
+
selector = ':root',
|
|
63
|
+
prefix = 'atomix',
|
|
64
|
+
separator = '-',
|
|
65
|
+
flatten = true,
|
|
66
|
+
} = options;
|
|
67
|
+
|
|
68
|
+
// Flatten nested token structure
|
|
69
|
+
const flattened = flatten ? flattenTokens(tokens, separator) : tokens;
|
|
70
|
+
|
|
71
|
+
// Generate CSS variables using the original function
|
|
72
|
+
return generateCSSVariables(flattened, { selector, prefix });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Flatten nested token structure
|
|
77
|
+
*
|
|
78
|
+
* @param tokens - Token object (can be nested)
|
|
79
|
+
* @param separator - Separator for nested keys
|
|
80
|
+
* @returns Flattened token object
|
|
81
|
+
*/
|
|
82
|
+
function flattenTokens(tokens: DesignTokens, separator: string): DesignTokens {
|
|
83
|
+
const result: DesignTokens = {};
|
|
84
|
+
|
|
85
|
+
for (const [key, value] of Object.entries(tokens)) {
|
|
86
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
87
|
+
// Recursively flatten nested objects
|
|
88
|
+
const flattened = flattenTokens(value, separator);
|
|
89
|
+
|
|
90
|
+
// Combine keys with separator
|
|
91
|
+
for (const [nestedKey, nestedValue] of Object.entries(flattened)) {
|
|
92
|
+
const newKey = `${key}${separator}${nestedKey}`;
|
|
93
|
+
result[newKey] = nestedValue;
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
// Direct value
|
|
97
|
+
result[key] = value;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Generate CSS variables with custom selector for nested tokens
|
|
106
|
+
*
|
|
107
|
+
* @param tokens - Design tokens object
|
|
108
|
+
* @param selector - CSS selector (e.g., '[data-theme="dark"]')
|
|
109
|
+
* @param prefix - CSS variable prefix
|
|
110
|
+
* @param separator - Separator for nested keys
|
|
111
|
+
* @returns CSS string
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const css = generateNestedCSSVariablesForSelector(
|
|
116
|
+
* tokens,
|
|
117
|
+
* '[data-theme="dark"]',
|
|
118
|
+
* 'atomix',
|
|
119
|
+
* '-'
|
|
120
|
+
* );
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export function generateNestedCSSVariablesForSelector(
|
|
124
|
+
tokens: DesignTokens,
|
|
125
|
+
selector: string,
|
|
126
|
+
prefix: string = 'atomix',
|
|
127
|
+
separator: string = '-'
|
|
128
|
+
): string {
|
|
129
|
+
return generateNestedCSSVariables(tokens, { selector, prefix, separator });
|
|
130
|
+
}
|
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
* @see src/styles/03-generic/_generic.root.scss for SCSS token definitions
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type { Theme } from '
|
|
20
|
-
import { isBrowser } from '
|
|
21
|
-
import { hexToRgb, alpha, lighten, darken, emphasize } from '
|
|
19
|
+
import type { Theme } from '../types';
|
|
20
|
+
import { isBrowser } from '../utils/domUtils';
|
|
21
|
+
import { hexToRgb, alpha, lighten, darken, emphasize } from '../utils/themeUtils';
|
|
22
22
|
|
|
23
23
|
// ============================================================================
|
|
24
24
|
// CSS Variable Generation
|
|
@@ -133,14 +133,6 @@ function generatePaletteVariables(palette: Theme['palette'], prefix: string): Re
|
|
|
133
133
|
if (key !== 'light' && key !== 'dark') {
|
|
134
134
|
const colorScale = generateColorScale(color.main, prefix, key);
|
|
135
135
|
Object.assign(vars, colorScale);
|
|
136
|
-
|
|
137
|
-
// Add semantic aliases that map to scale steps (for backward compatibility)
|
|
138
|
-
// primary-main → primary-6 (main color)
|
|
139
|
-
vars[`${prefix}-${key}-main`] = colorScale[`${prefix}-${key}-6`] || color.main;
|
|
140
|
-
// primary-light → primary-3 (light variant)
|
|
141
|
-
vars[`${prefix}-${key}-light`] = colorScale[`${prefix}-${key}-3`] || color.light || color.main;
|
|
142
|
-
// primary-dark → primary-9 (dark variant)
|
|
143
|
-
vars[`${prefix}-${key}-dark`] = colorScale[`${prefix}-${key}-9`] || color.dark || color.main;
|
|
144
136
|
} else {
|
|
145
137
|
// For light/dark, use the provided values directly
|
|
146
138
|
vars[`${prefix}-${key}-main`] = color.main;
|
|
@@ -658,8 +650,6 @@ function generateBorderRadiusVariables(
|
|
|
658
650
|
|
|
659
651
|
// 2X large border radius (maps to spacing-4 = 16px)
|
|
660
652
|
vars[`${prefix}-border-radius-xxl`] = formatValue(borderRadius.xxl, '1rem');
|
|
661
|
-
// Also add deprecated 2xl alias for consistency
|
|
662
|
-
vars[`${prefix}-border-radius-2xl`] = formatValue(borderRadius.xxl, '1rem');
|
|
663
653
|
|
|
664
654
|
// 3X large border radius (maps to spacing-6 = 24px)
|
|
665
655
|
vars[`${prefix}-border-radius-3xl`] = formatValue(borderRadius['3xl'], '1.5rem');
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSS Generators
|
|
3
|
+
*
|
|
4
|
+
* Generators for creating CSS from themes and tokens
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
generateCSSVariables,
|
|
9
|
+
generateCSSVariablesForSelector,
|
|
10
|
+
type GenerateCSSVariablesOptions,
|
|
11
|
+
} from './generateCSS';
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
generateNestedCSSVariables,
|
|
15
|
+
generateNestedCSSVariablesForSelector,
|
|
16
|
+
type GenerateNestedCSSVariablesOptions,
|
|
17
|
+
} from './generateCSSNested';
|
|
18
|
+
|
|
19
|
+
export { generateCSSVariables as generateCSSVariablesFromTheme } from './generateCSSVariables';
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
saveCSSFile,
|
|
23
|
+
saveCSSFileSync,
|
|
24
|
+
} from './cssFile';
|
|
25
|
+
|
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* Provides utilities for managing RTL text direction in themes
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { getLogger } from '../errors';
|
|
7
|
+
import { getLogger } from '../errors/errors';
|
|
8
|
+
import { DEFAULT_RTL_CONFIG as BASE_RTL_CONFIG } from '../constants/constants';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* RTL configuration options
|
|
@@ -38,14 +39,12 @@ const RTL_LOCALES = new Set([
|
|
|
38
39
|
'sd', // Sindhi
|
|
39
40
|
]);
|
|
40
41
|
|
|
42
|
+
|
|
41
43
|
/**
|
|
42
|
-
* Default RTL configuration
|
|
44
|
+
* Default RTL configuration (extends base config with locale)
|
|
43
45
|
*/
|
|
44
46
|
const DEFAULT_RTL_CONFIG: Required<Omit<RTLConfig, 'locale'>> & { locale?: string } = {
|
|
45
|
-
|
|
46
|
-
direction: 'ltr',
|
|
47
|
-
dataAttribute: 'data-direction',
|
|
48
|
-
autoDetect: false,
|
|
47
|
+
...BASE_RTL_CONFIG,
|
|
49
48
|
locale: undefined,
|
|
50
49
|
};
|
|
51
50
|
|