@shohojdhara/atomix 0.3.4 → 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 +269 -189
- package/dist/atomix.css.map +1 -0
- package/dist/atomix.min.css +15179 -11
- package/dist/atomix.min.css.map +1 -0
- package/dist/charts.d.ts +1929 -0
- package/dist/charts.js +6477 -0
- package/dist/charts.js.map +1 -0
- package/dist/core.d.ts +1289 -0
- package/dist/core.js +3373 -0
- package/dist/core.js.map +1 -0
- package/dist/forms.d.ts +1085 -0
- package/dist/forms.js +2466 -0
- package/dist/forms.js.map +1 -0
- package/dist/heavy.d.ts +636 -0
- package/dist/heavy.js +4566 -0
- package/dist/heavy.js.map +1 -0
- package/dist/index.d.ts +5171 -4792
- package/dist/index.esm.js +6098 -4563
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +6291 -4747
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/layout.d.ts +300 -0
- package/dist/layout.js +336 -0
- package/dist/layout.js.map +1 -0
- package/dist/theme.d.ts +2122 -0
- package/dist/theme.js +6084 -0
- package/dist/theme.js.map +1 -0
- package/package.json +59 -27
- package/scripts/atomix-cli.js +544 -16
- package/scripts/cli/__tests__/cli-commands.test.js +204 -0
- package/scripts/cli/__tests__/utils.test.js +201 -0
- package/scripts/cli/__tests__/vitest.config.js +26 -0
- package/scripts/cli/interactive-init.js +1 -1
- package/scripts/cli/token-manager.js +32 -7
- package/scripts/cli/utils.js +347 -0
- package/src/components/Accordion/Accordion.stories.tsx +50 -17
- package/src/components/Accordion/Accordion.tsx +5 -54
- package/src/components/Accordion/index.ts +1 -1
- 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/Avatar/Avatar.tsx +3 -3
- package/src/components/Badge/Badge.stories.tsx +91 -13
- package/src/components/Badge/Badge.tsx +3 -3
- package/src/components/Block/Block.stories.tsx +7 -23
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +7 -0
- package/src/components/Breadcrumb/Breadcrumb.tsx +3 -3
- 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/Card/ElevationCard.tsx +1 -1
- package/src/components/Chart/AnimatedChart.tsx +19 -18
- package/src/components/Chart/AreaChart.tsx +5 -2
- package/src/components/Chart/BarChart.tsx +1 -1
- package/src/components/Chart/BubbleChart.tsx +6 -6
- 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/ChartToolbar.tsx +1 -0
- package/src/components/Chart/DonutChart.tsx +0 -1
- package/src/components/Chart/FunnelChart.tsx +1 -2
- 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 +19 -13
- package/src/components/Chart/ScatterChart.tsx +3 -4
- package/src/components/Chart/TreemapChart.tsx +2 -1
- package/src/components/Chart/WaterfallChart.tsx +0 -2
- package/src/components/Chart/types.ts +12 -2
- package/src/components/Chart/utils.ts +4 -3
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +7 -0
- package/src/components/DataTable/DataTable.stories.tsx +23 -16
- package/src/components/DataTable/DataTable.tsx +3 -3
- package/src/components/DatePicker/DatePicker.stories.tsx +27 -19
- package/src/components/Dropdown/Dropdown.stories.tsx +11 -19
- package/src/components/Dropdown/Dropdown.tsx +12 -9
- 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/Footer/FooterSection.tsx +3 -3
- package/src/components/Form/Checkbox.stories.tsx +7 -0
- package/src/components/Form/Checkbox.tsx +3 -3
- 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/Input.tsx +4 -2
- package/src/components/Form/Radio.stories.tsx +9 -1
- package/src/components/Form/Radio.tsx +3 -3
- package/src/components/Form/Select.stories.tsx +9 -1
- package/src/components/Form/Select.tsx +3 -3
- package/src/components/Form/Textarea.stories.tsx +10 -2
- package/src/components/Form/Textarea.tsx +4 -2
- package/src/components/Hero/Hero.stories.tsx +7 -0
- package/src/components/List/List.stories.tsx +10 -3
- package/src/components/List/List.tsx +3 -3
- package/src/components/List/ListGroup.tsx +3 -1
- package/src/components/Messages/Messages.stories.tsx +8 -7
- package/src/components/Modal/Modal.stories.tsx +17 -6
- package/src/components/Modal/Modal.tsx +3 -3
- package/src/components/Navigation/Menu/MegaMenu.tsx +9 -3
- package/src/components/Navigation/Menu/Menu.stories.tsx +7 -0
- package/src/components/Navigation/Menu/Menu.tsx +9 -3
- 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 +88 -7
- package/src/components/PhotoViewer/PhotoViewer.stories.tsx +10 -5
- package/src/components/PhotoViewer/PhotoViewerImage.tsx +2 -2
- package/src/components/Popover/Popover.stories.tsx +191 -115
- package/src/components/Popover/Popover.tsx +4 -4
- package/src/components/ProductReview/ProductReview.stories.tsx +80 -58
- package/src/components/Progress/Progress.stories.tsx +79 -49
- package/src/components/Progress/Progress.tsx +6 -2
- package/src/components/Rating/Rating.stories.tsx +109 -84
- package/src/components/Rating/Rating.tsx +5 -2
- 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/Slider/Slider.tsx +10 -9
- package/src/components/Spinner/Spinner.stories.tsx +15 -11
- package/src/components/Spinner/Spinner.tsx +3 -3
- package/src/components/Steps/Steps.stories.tsx +132 -98
- package/src/components/Tabs/Tabs.stories.tsx +163 -112
- package/src/components/Tabs/Tabs.tsx +3 -3
- 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/Tooltip/Tooltip.tsx +3 -3
- package/src/components/Upload/Upload.stories.tsx +122 -84
- package/src/components/VideoPlayer/VideoPlayer.stories.tsx +7 -24
- package/src/components/index.ts +6 -2
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +2 -2
- package/src/lib/composables/useAtomixGlass.ts +2 -3
- package/src/lib/composables/useChartPerformance.ts +102 -78
- package/src/lib/composables/useChartScale.ts +10 -0
- package/src/lib/composables/useHero.ts +9 -2
- package/src/lib/composables/useHeroBackgroundSlider.ts +5 -3
- package/src/lib/composables/useNavbar.ts +0 -10
- package/src/lib/composables/useSideMenu.ts +1 -0
- package/src/lib/composables/useVideoPlayer.ts +3 -2
- package/src/lib/config/loader.ts +57 -14
- package/src/lib/constants/components.ts +10 -0
- package/src/lib/hooks/index.ts +0 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -15
- package/src/lib/hooks/usePerformanceMonitor.ts +149 -0
- package/src/lib/patterns/index.ts +2 -2
- package/src/lib/patterns/slots.tsx +2 -2
- 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 +489 -112
- package/src/lib/theme/devtools/Preview.tsx +471 -221
- package/src/lib/theme/{core → devtools}/ThemeValidator.ts +6 -3
- 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} +4 -14
- package/src/lib/theme/generators/index.ts +19 -0
- package/src/lib/theme/i18n/rtl.ts +7 -7
- package/src/lib/theme/index.ts +120 -15
- package/src/lib/theme/runtime/ThemeApplicator.ts +53 -95
- package/src/lib/theme/{ThemeContext.tsx → runtime/ThemeContext.tsx} +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +4 -4
- 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 +8 -9
- package/src/lib/types/components.ts +93 -34
- package/src/lib/types/partProps.ts +0 -16
- package/src/lib/utils/componentUtils.ts +1 -1
- package/src/lib/utils/fontPreloader.ts +148 -0
- package/src/lib/utils/index.ts +11 -0
- package/src/lib/utils/memoryMonitor.ts +189 -0
- package/src/styles/01-settings/_settings.design-tokens.scss +4 -1
- package/src/styles/01-settings/_settings.fonts.scss +2 -5
- 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.navbar.scss +0 -6
- package/src/styles/06-components/_components.pagination.scss +88 -0
- package/scripts/build-themes.js +0 -208
- package/scripts/sync-theme-config.js +0 -309
- package/src/components/AtomixGlass/atomixGLass.old.tsx +0 -1263
- 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 -657
- 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 -442
- package/src/styles/03-generic/_generated-root.css +0 -5
- package/src/themes/README.md +0 -442
- package/src/themes/themes.config.js +0 -35
- /package/src/lib/theme/{cssVariableMapper.ts → adapters/cssVariableMapper.ts} +0 -0
- /package/src/lib/theme/{errors.ts → errors/errors.ts} +0 -0
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { Theme, ThemeMetadata } from '../types';
|
|
8
|
-
import { getContrastRatio, getLuminance } from '../themeUtils';
|
|
8
|
+
import { getContrastRatio, getLuminance } from '../utils/themeUtils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Validation result
|
|
@@ -392,8 +392,11 @@ export class ThemeValidator {
|
|
|
392
392
|
|
|
393
393
|
for (let i = 0; i < numericEntries.length; i++) {
|
|
394
394
|
for (let j = i + 1; j < numericEntries.length; j++) {
|
|
395
|
-
const
|
|
396
|
-
const
|
|
395
|
+
const entryA = numericEntries[i];
|
|
396
|
+
const entryB = numericEntries[j];
|
|
397
|
+
if (!entryA || !entryB) continue;
|
|
398
|
+
const [keyA, valueA] = entryA;
|
|
399
|
+
const [keyB, valueB] = entryB;
|
|
397
400
|
const diff = Math.abs(valueA - valueB);
|
|
398
401
|
if (diff < 10 && diff > 0) {
|
|
399
402
|
warnings.push(
|
|
@@ -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
|
+
|
|
@@ -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
|
+
|
|
@@ -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
|
|
@@ -47,7 +47,7 @@ function flattenObject(
|
|
|
47
47
|
result: Record<string, string> = {}
|
|
48
48
|
): Record<string, string> {
|
|
49
49
|
for (const key in obj) {
|
|
50
|
-
if (!
|
|
50
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
|
|
51
51
|
|
|
52
52
|
const value = obj[key];
|
|
53
53
|
const newKey = prefix ? `${prefix}-${key}` : key;
|
|
@@ -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,19 @@
|
|
|
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 { generateCSSVariables as generateCSSVariablesFromTheme } from './generateCSSVariables';
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
saveCSSFile,
|
|
17
|
+
saveCSSFileSync,
|
|
18
|
+
} from './cssFile';
|
|
19
|
+
|
|
@@ -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
|
|
|
@@ -93,7 +92,8 @@ export class RTLManager {
|
|
|
93
92
|
|
|
94
93
|
// Try navigator.language first
|
|
95
94
|
const lang: string = navigator.language || (navigator.languages && navigator.languages[0]) || 'en';
|
|
96
|
-
|
|
95
|
+
const langParts = String(lang).split('-');
|
|
96
|
+
return langParts[0] ? langParts[0].toLowerCase() : 'en';
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
/**
|
package/src/lib/theme/index.ts
CHANGED
|
@@ -1,28 +1,134 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme System Exports
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Unified theme system - handles both DesignTokens and Theme objects.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { createTheme, injectTheme } from '@shohojdhara/atomix/theme';
|
|
9
|
+
*
|
|
10
|
+
* // Using DesignTokens (recommended - flat structure)
|
|
11
|
+
* const css = createTheme({ 'primary': '#7AFFD7', 'spacing-4': '1rem' });
|
|
12
|
+
* injectTheme(css);
|
|
13
|
+
*
|
|
14
|
+
* // Or use with ThemeProvider
|
|
15
|
+
* import { ThemeProvider } from '@shohojdhara/atomix/theme';
|
|
16
|
+
* const tokens = { 'primary': '#7c3aed' };
|
|
17
|
+
* <ThemeProvider defaultTheme={tokens}>...</ThemeProvider>
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Core Theme Functions
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
// Unified createTheme (handles both DesignTokens and Theme objects)
|
|
26
|
+
export { createTheme } from './core';
|
|
27
|
+
|
|
28
|
+
// Theme object creation
|
|
29
|
+
export { createThemeObject } from './core';
|
|
30
|
+
|
|
31
|
+
// Theme composition
|
|
32
|
+
export { deepMerge, mergeTheme, extendTheme } from './core';
|
|
33
|
+
|
|
34
|
+
// Theme registry
|
|
35
|
+
export { ThemeRegistry } from './core';
|
|
36
|
+
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Theme Injection and Management
|
|
39
|
+
// ============================================================================
|
|
40
|
+
|
|
41
|
+
import { injectCSS, removeCSS, isCSSInjected } from './utils/injectCSS';
|
|
42
|
+
import { saveCSSFile, saveCSSFileSync } from './generators/cssFile';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Inject theme CSS into DOM
|
|
46
|
+
*/
|
|
47
|
+
export function injectTheme(css: string, id: string = 'atomix-theme'): void {
|
|
48
|
+
injectCSS(css, id);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Remove theme from DOM
|
|
53
|
+
*/
|
|
54
|
+
export function removeTheme(id: string = 'atomix-theme'): void {
|
|
55
|
+
removeCSS(id);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Save theme to CSS file
|
|
5
60
|
*/
|
|
61
|
+
export async function saveTheme(css: string, filePath: string): Promise<void> {
|
|
62
|
+
await saveCSSFile(css, filePath);
|
|
63
|
+
}
|
|
6
64
|
|
|
7
|
-
//
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Token Utilities
|
|
67
|
+
// ============================================================================
|
|
68
|
+
|
|
69
|
+
export { createTokens, defaultTokens, type DesignTokens } from './tokens';
|
|
70
|
+
|
|
71
|
+
// ============================================================================
|
|
72
|
+
// CSS Generation
|
|
73
|
+
// ============================================================================
|
|
74
|
+
|
|
75
|
+
export {
|
|
76
|
+
generateCSSVariables,
|
|
77
|
+
generateCSSVariablesForSelector,
|
|
78
|
+
type GenerateCSSVariablesOptions,
|
|
79
|
+
} from './generators';
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Injection Utilities
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
export { injectCSS, removeCSS, isCSSInjected } from './utils/injectCSS';
|
|
86
|
+
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// File Utilities
|
|
89
|
+
// ============================================================================
|
|
90
|
+
|
|
91
|
+
export { saveCSSFile, saveCSSFileSync } from './generators/cssFile';
|
|
92
|
+
|
|
93
|
+
// ============================================================================
|
|
94
|
+
// Config Loader
|
|
95
|
+
// ============================================================================
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
loadThemeFromConfig,
|
|
99
|
+
loadThemeFromConfigSync,
|
|
100
|
+
} from './config/configLoader';
|
|
101
|
+
|
|
102
|
+
// ============================================================================
|
|
103
|
+
// React Integration
|
|
104
|
+
// ============================================================================
|
|
105
|
+
|
|
106
|
+
// Core React components and hooks
|
|
8
107
|
export { ThemeProvider } from './runtime/ThemeProvider';
|
|
9
108
|
export { useTheme } from './runtime/useTheme';
|
|
10
|
-
export { ThemeContext } from './ThemeContext';
|
|
11
|
-
export { ThemeManager } from './runtime/ThemeManager';
|
|
109
|
+
export { ThemeContext } from './runtime/ThemeContext';
|
|
12
110
|
export { ThemeErrorBoundary } from './runtime/ThemeErrorBoundary';
|
|
13
111
|
|
|
14
|
-
// Theme
|
|
15
|
-
export {
|
|
16
|
-
export { createThemeFromConfig } from './createThemeFromConfig';
|
|
17
|
-
|
|
18
|
-
// Theme utilities
|
|
19
|
-
export { quickTheme, createDarkVariant, validateTheme, themeToCSS, exportTheme, importTheme } from '../theme-tools';
|
|
112
|
+
// Theme application
|
|
113
|
+
export { ThemeApplicator, getThemeApplicator, applyTheme } from './runtime/ThemeApplicator';
|
|
20
114
|
|
|
21
115
|
// DevTools (for development and debugging)
|
|
22
116
|
export * from './devtools';
|
|
23
117
|
|
|
24
|
-
// Theme
|
|
25
|
-
export {
|
|
118
|
+
// Theme adapter (converts between Theme and DesignTokens)
|
|
119
|
+
export {
|
|
120
|
+
themeToDesignTokens,
|
|
121
|
+
designTokensToCSSVars,
|
|
122
|
+
createDesignTokensFromTheme,
|
|
123
|
+
designTokensToTheme,
|
|
124
|
+
} from './adapters';
|
|
125
|
+
|
|
126
|
+
// Theme helpers (utilities for working with themes and DesignTokens)
|
|
127
|
+
export {
|
|
128
|
+
getDesignTokensFromTheme,
|
|
129
|
+
isDesignTokens,
|
|
130
|
+
isThemeObject,
|
|
131
|
+
} from './utils/themeHelpers';
|
|
26
132
|
|
|
27
133
|
// CSS variable utilities
|
|
28
134
|
export {
|
|
@@ -36,7 +142,7 @@ export {
|
|
|
36
142
|
mergeCSSVars,
|
|
37
143
|
isValidCSSVariableName,
|
|
38
144
|
extractComponentName,
|
|
39
|
-
} from './cssVariableMapper';
|
|
145
|
+
} from './adapters/cssVariableMapper';
|
|
40
146
|
|
|
41
147
|
// RTL Support
|
|
42
148
|
export { RTLManager } from './i18n/rtl';
|
|
@@ -45,7 +151,6 @@ export { RTLManager } from './i18n/rtl';
|
|
|
45
151
|
export type {
|
|
46
152
|
Theme,
|
|
47
153
|
ThemeMetadata,
|
|
48
|
-
ThemeManagerConfig,
|
|
49
154
|
ThemeChangeEvent,
|
|
50
155
|
ThemeLoadOptions,
|
|
51
156
|
ThemeValidationResult,
|
|
@@ -61,6 +166,6 @@ export type { ThemeErrorBoundaryProps } from './runtime/ThemeErrorBoundary';
|
|
|
61
166
|
export type {
|
|
62
167
|
CSSVariableConfig,
|
|
63
168
|
CSSVariableNamingOptions,
|
|
64
|
-
} from './cssVariableMapper';
|
|
169
|
+
} from './adapters/cssVariableMapper';
|
|
65
170
|
|
|
66
171
|
export type { RTLConfig } from './i18n/rtl';
|