@shohojdhara/atomix 0.3.15 → 0.4.0
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/build-tools/index.d.ts +31 -30
- package/build-tools/package.json +4 -21
- package/dist/atomix.css +20924 -2611
- package/dist/atomix.css.map +1 -1
- package/dist/atomix.min.css +76 -2
- package/dist/atomix.min.css.map +1 -1
- package/dist/build-tools/index.d.ts +31 -30
- package/dist/build-tools/package.json +4 -21
- package/dist/charts.js.map +1 -1
- package/dist/core.js.map +1 -1
- package/dist/forms.js.map +1 -1
- package/dist/heavy.js.map +1 -1
- package/dist/index.d.ts +144 -18
- package/dist/index.esm.js +110 -55
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +110 -55
- 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.js.map +1 -1
- package/dist/theme.d.ts +9 -9
- package/dist/theme.js.map +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.stories.tsx +32 -23
- package/src/components/Accordion/Accordion.test.tsx +70 -50
- package/src/components/Accordion/Accordion.tsx +99 -94
- package/src/components/AtomixGlass/AtomixGlass.test.tsx +1 -1
- package/src/components/AtomixGlass/GlassFilter.tsx +9 -16
- package/src/components/AtomixGlass/glass-utils.ts +4 -3
- package/src/components/AtomixGlass/shader-utils.ts +128 -52
- package/src/components/AtomixGlass/stories/Playground.stories.tsx +1 -1
- package/src/components/AtomixGlass/stories/Shaders.stories.tsx +1 -1
- package/src/components/Avatar/Avatar.stories.tsx +45 -62
- package/src/components/Avatar/Avatar.tsx +58 -56
- package/src/components/Badge/Badge.stories.tsx +20 -9
- package/src/components/Badge/Badge.test.tsx +41 -41
- package/src/components/Badge/Badge.tsx +64 -62
- package/src/components/Block/Block.stories.tsx +14 -4
- package/src/components/Breadcrumb/Breadcrumb.stories.tsx +9 -8
- package/src/components/Breadcrumb/Breadcrumb.tsx +62 -60
- package/src/components/Button/Button.stories.tsx +13 -22
- package/src/components/Button/Button.test.tsx +97 -81
- package/src/components/Button/Button.tsx +46 -14
- package/src/components/Button/ButtonGroup.stories.tsx +37 -32
- package/src/components/Button/ButtonGroup.tsx +4 -15
- package/src/components/Callout/Callout.stories.tsx +109 -16
- package/src/components/Card/Card.stories.tsx +67 -36
- package/src/components/Card/Card.tsx +30 -14
- package/src/components/Chart/AreaChart.tsx +1 -1
- package/src/components/Chart/CandlestickChart.tsx +23 -16
- package/src/components/Chart/Chart.stories.tsx +4 -9
- package/src/components/Chart/Chart.tsx +40 -44
- package/src/components/Chart/ChartRenderer.tsx +39 -12
- package/src/components/Chart/ChartToolbar.tsx +21 -5
- package/src/components/Chart/DonutChart.tsx +1 -1
- package/src/components/Chart/FunnelChart.tsx +4 -1
- package/src/components/Chart/GaugeChart.tsx +3 -1
- package/src/components/Chart/HeatmapChart.tsx +50 -37
- package/src/components/Chart/LineChart.tsx +3 -2
- package/src/components/Chart/MultiAxisChart.tsx +24 -16
- package/src/components/Chart/RadarChart.tsx +19 -17
- package/src/components/Chart/ScatterChart.tsx +29 -21
- package/src/components/ColorModeToggle/ColorModeToggle.stories.tsx +6 -2
- package/src/components/ColorModeToggle/ColorModeToggle.tsx +15 -3
- package/src/components/Countdown/Countdown.stories.tsx +7 -7
- package/src/components/DataTable/DataTable.stories.tsx +43 -38
- package/src/components/DataTable/DataTable.test.tsx +26 -148
- package/src/components/DataTable/DataTable.tsx +485 -456
- package/src/components/DatePicker/DatePicker.stories.tsx +32 -47
- package/src/components/DatePicker/DatePicker.tsx +31 -26
- package/src/components/Dropdown/Dropdown.stories.tsx +2 -5
- package/src/components/Dropdown/Dropdown.tsx +313 -299
- package/src/components/EdgePanel/EdgePanel.stories.tsx +6 -19
- package/src/components/EdgePanel/EdgePanel.tsx +1 -3
- package/src/components/Footer/Footer.stories.tsx +21 -16
- package/src/components/Footer/Footer.tsx +130 -128
- package/src/components/Footer/FooterLink.tsx +2 -2
- package/src/components/Form/Checkbox.test.tsx +49 -49
- package/src/components/Form/Checkbox.tsx +108 -100
- package/src/components/Form/Form.stories.tsx +2 -10
- package/src/components/Form/Input.stories.tsx +22 -39
- package/src/components/Form/Input.test.tsx +38 -44
- package/src/components/Form/Radio.stories.tsx +6 -12
- package/src/components/Form/Radio.tsx +68 -66
- package/src/components/Form/Select.tsx +184 -182
- package/src/components/Form/Textarea.test.tsx +27 -32
- package/src/components/Hero/Hero.stories.tsx +56 -23
- package/src/components/Hero/Hero.tsx +201 -55
- package/src/components/Icon/index.ts +7 -1
- package/src/components/List/List.tsx +19 -23
- package/src/components/Modal/Modal.stories.tsx +2 -1
- package/src/components/Modal/Modal.tsx +130 -127
- package/src/components/Navigation/Menu/MegaMenu.tsx +70 -70
- package/src/components/Navigation/Nav/NavDropdown.tsx +1 -5
- package/src/components/Navigation/SideMenu/SideMenu.stories.tsx +128 -28
- package/src/components/Navigation/SideMenu/SideMenu.tsx +5 -7
- package/src/components/Navigation/SideMenu/SideMenuItem.tsx +4 -5
- package/src/components/Pagination/Pagination.stories.tsx +7 -4
- package/src/components/Pagination/Pagination.tsx +199 -202
- package/src/components/PhotoViewer/PhotoViewer.tsx +4 -1
- package/src/components/Popover/Popover.stories.tsx +99 -192
- package/src/components/Popover/Popover.tsx +41 -37
- package/src/components/Progress/Progress.stories.tsx +35 -44
- package/src/components/River/River.stories.tsx +2 -1
- package/src/components/SectionIntro/SectionIntro.stories.tsx +71 -71
- package/src/components/Slider/Slider.stories.tsx +12 -4
- package/src/components/Spinner/Spinner.stories.tsx +3 -1
- package/src/components/Spinner/Spinner.test.tsx +23 -23
- package/src/components/Spinner/Spinner.tsx +43 -46
- package/src/components/Steps/Steps.stories.tsx +8 -6
- package/src/components/Tabs/Tabs.stories.tsx +12 -9
- package/src/components/Tabs/Tabs.tsx +74 -72
- package/src/components/Toggle/Toggle.stories.tsx +27 -13
- package/src/components/Toggle/Toggle.test.tsx +65 -70
- package/src/components/Toggle/Toggle.tsx +4 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +24 -20
- package/src/components/Tooltip/Tooltip.tsx +104 -106
- package/src/components/Upload/Upload.stories.tsx +129 -127
- package/src/components/Upload/Upload.tsx +287 -283
- package/src/components/VideoPlayer/VideoPlayer.tsx +6 -1
- package/src/components/index.ts +13 -2
- package/src/layouts/Grid/Grid.stories.tsx +9 -3
- package/src/layouts/MasonryGrid/MasonryGrid.tsx +5 -1
- package/src/lib/__tests__/theme-tools.test.ts +32 -6
- package/src/lib/composables/shared-mouse-tracker.ts +13 -14
- package/src/lib/composables/useAtomixGlass.ts +106 -49
- package/src/lib/composables/useChartExport.ts +1 -1
- package/src/lib/composables/useDataTable.ts +29 -17
- package/src/lib/composables/useHero.ts +58 -14
- package/src/lib/composables/useHeroBackgroundSlider.ts +2 -9
- package/src/lib/composables/useInput.ts +10 -8
- package/src/lib/composables/useSideMenu.ts +6 -5
- package/src/lib/composables/useTooltip.ts +1 -2
- package/src/lib/composables/useVideoPlayer.ts +44 -35
- package/src/lib/config/index.ts +154 -154
- package/src/lib/constants/cssVariables.ts +29 -29
- package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +2 -6
- package/src/lib/hooks/index.ts +1 -1
- package/src/lib/hooks/useComponentCustomization.ts +11 -17
- package/src/lib/hooks/usePerformanceMonitor.ts +6 -7
- package/src/lib/patterns/__tests__/slots.test.ts +1 -1
- package/src/lib/patterns/index.ts +1 -1
- package/src/lib/patterns/slots.tsx +8 -13
- package/src/lib/storybook/InteractiveDemo.tsx +13 -18
- package/src/lib/storybook/PreviewContainer.tsx +1 -1
- package/src/lib/storybook/VariantsGrid.tsx +3 -7
- package/src/lib/storybook/index.ts +1 -1
- package/src/lib/theme/adapters/cssVariableMapper.ts +47 -74
- package/src/lib/theme/adapters/index.ts +3 -9
- package/src/lib/theme/adapters/themeAdapter.ts +41 -26
- package/src/lib/theme/config/index.ts +1 -1
- package/src/lib/theme/config/types.ts +2 -2
- package/src/lib/theme/config/validator.ts +10 -5
- package/src/lib/theme/constants/constants.ts +2 -2
- package/src/lib/theme/constants/index.ts +1 -2
- package/src/lib/theme/core/__tests__/createTheme.test.ts +20 -22
- package/src/lib/theme/core/composeTheme.ts +32 -26
- package/src/lib/theme/core/createTheme.ts +1 -1
- package/src/lib/theme/core/createThemeObject.ts +308 -301
- package/src/lib/theme/core/index.ts +3 -3
- package/src/lib/theme/devtools/CLI.ts +106 -104
- package/src/lib/theme/devtools/Comparator.tsx +50 -32
- package/src/lib/theme/devtools/DesignTokensCustomizer.stories.tsx +50 -48
- package/src/lib/theme/devtools/DesignTokensCustomizer.tsx +257 -63
- package/src/lib/theme/devtools/Inspector.tsx +75 -60
- package/src/lib/theme/devtools/LiveEditor.tsx +97 -76
- package/src/lib/theme/devtools/Preview.tsx +150 -106
- package/src/lib/theme/devtools/ThemeValidator.ts +29 -21
- package/src/lib/theme/devtools/index.ts +3 -9
- package/src/lib/theme/devtools/useHistory.ts +23 -21
- package/src/lib/theme/errors/errors.ts +12 -11
- package/src/lib/theme/errors/index.ts +2 -7
- package/src/lib/theme/generators/generateCSS.ts +9 -13
- package/src/lib/theme/generators/generateCSSNested.ts +1 -6
- package/src/lib/theme/generators/generateCSSVariables.ts +673 -630
- package/src/lib/theme/generators/index.ts +1 -4
- package/src/lib/theme/i18n/index.ts +1 -1
- package/src/lib/theme/i18n/rtl.ts +13 -13
- package/src/lib/theme/index.ts +7 -16
- package/src/lib/theme/runtime/ThemeApplicator.ts +4 -4
- package/src/lib/theme/runtime/ThemeContext.tsx +1 -1
- package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +19 -23
- package/src/lib/theme/runtime/ThemeProvider.tsx +230 -239
- package/src/lib/theme/runtime/__tests__/ThemeProvider.integration.test.tsx +1 -1
- package/src/lib/theme/runtime/__tests__/ThemeProvider.test.tsx +24 -29
- package/src/lib/theme/runtime/index.ts +2 -5
- package/src/lib/theme/runtime/useTheme.ts +18 -18
- package/src/lib/theme/runtime/useThemeTokens.ts +22 -22
- package/src/lib/theme/test/testTheme.ts +15 -16
- package/src/lib/theme/tokens/index.ts +2 -7
- package/src/lib/theme/tokens/tokens.ts +25 -24
- package/src/lib/theme/types.ts +428 -411
- package/src/lib/theme/utils/__tests__/themeValidation.test.ts +3 -3
- package/src/lib/theme/utils/componentTheming.ts +18 -18
- package/src/lib/theme/utils/domUtils.ts +277 -289
- package/src/lib/theme/utils/index.ts +1 -2
- package/src/lib/theme/utils/injectCSS.ts +10 -14
- package/src/lib/theme/utils/naming.ts +20 -16
- package/src/lib/theme/utils/themeHelpers.ts +10 -12
- package/src/lib/theme/utils/themeUtils.ts +85 -86
- package/src/lib/theme/utils/themeValidation.ts +82 -33
- package/src/lib/theme-tools.ts +8 -6
- package/src/lib/types/components.ts +172 -71
- package/src/lib/types/partProps.ts +1 -1
- package/src/lib/utils/__tests__/csv.test.ts +1 -1
- package/src/lib/utils/componentUtils.ts +8 -12
- package/src/lib/utils/csv.ts +3 -1
- package/src/lib/utils/dataTableExport.ts +1 -5
- package/src/lib/utils/fontPreloader.ts +10 -19
- package/src/lib/utils/icons.ts +4 -1
- package/src/lib/utils/index.ts +2 -6
- package/src/lib/utils/memoryMonitor.ts +10 -8
- package/src/lib/utils/themeNaming.ts +2 -2
- package/src/styles/01-settings/_index.scss +0 -1
- package/src/styles/01-settings/_settings.colors.scss +8 -8
- package/src/styles/01-settings/_settings.design-tokens.scss +61 -50
- package/src/styles/01-settings/_settings.navbar.scss +1 -1
- package/src/styles/01-settings/_settings.spacing.scss +3 -4
- package/src/styles/01-settings/_settings.tooltip.scss +1 -1
- package/src/styles/01-settings/_settings.typography.scss +1 -1
- package/src/styles/02-tools/_tools.button.scss +51 -21
- package/src/styles/02-tools/_tools.utility-api.scss +30 -18
- package/src/styles/03-generic/_generic.root.scss +4 -3
- package/src/styles/06-components/_components.atomix-glass.scss +13 -9
- package/src/styles/06-components/_components.button.scss +16 -4
- package/src/styles/06-components/_components.callout.scss +27 -21
- package/src/styles/06-components/_components.card.scss +5 -14
- package/src/styles/06-components/_components.chart.scss +22 -19
- package/src/styles/06-components/_components.checkbox.scss +3 -1
- package/src/styles/06-components/_components.color-mode-toggle.scss +3 -1
- package/src/styles/06-components/_components.edge-panel.scss +9 -2
- package/src/styles/06-components/_components.footer.scss +1 -1
- package/src/styles/06-components/_components.side-menu.scss +5 -5
- package/src/styles/06-components/_components.toggle.scss +18 -0
- package/src/styles/06-components/_index.scss +1 -1
- package/src/styles/06-components/old.chart.styles.scss +0 -2
- package/src/styles/99-utilities/_utilities.border.scss +69 -27
- package/src/styles/99-utilities/_utilities.display.scss +1 -1
- package/src/styles/99-utilities/_utilities.opacity.scss +10 -0
- package/src/styles/99-utilities/_utilities.position.scss +16 -9
- package/src/styles/99-utilities/_utilities.scss +1 -1
- package/src/styles/99-utilities/_utilities.sizes.scss +47 -18
- package/src/styles/99-utilities/_utilities.spacing.scss +118 -66
- package/src/styles/99-utilities/_utilities.text-gradient.scss +30 -30
- package/src/styles/99-utilities/_utilities.text.scss +67 -46
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Live Editor Component
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* React component for live editing themes in development
|
|
5
5
|
* Enhanced with undo/redo, keyboard shortcuts, resizable layout, and better color pickers
|
|
6
6
|
*/
|
|
@@ -36,7 +36,7 @@ type ColorFormat = 'hex' | 'rgb' | 'rgba' | 'hsl' | 'hsla';
|
|
|
36
36
|
function convertColorFormat(color: string, format: ColorFormat): string {
|
|
37
37
|
// Remove whitespace
|
|
38
38
|
color = color.trim();
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
// If already in target format, return as is
|
|
41
41
|
if (format === 'hex' && color.startsWith('#')) return color;
|
|
42
42
|
if (format === 'rgb' && color.startsWith('rgb(')) return color;
|
|
@@ -71,7 +71,7 @@ function convertColorFormat(color: string, format: ColorFormat): string {
|
|
|
71
71
|
case 'hsla': {
|
|
72
72
|
// Convert RGB to HSL (simplified)
|
|
73
73
|
const hsl = rgbToHsl(r, g, b);
|
|
74
|
-
return format === 'hsl'
|
|
74
|
+
return format === 'hsl'
|
|
75
75
|
? `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)`
|
|
76
76
|
: `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${a})`;
|
|
77
77
|
}
|
|
@@ -97,11 +97,17 @@ function rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: n
|
|
|
97
97
|
if (max !== min) {
|
|
98
98
|
const d = max - min;
|
|
99
99
|
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
100
|
-
|
|
100
|
+
|
|
101
101
|
switch (max) {
|
|
102
|
-
case r:
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
case r:
|
|
103
|
+
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
|
|
104
|
+
break;
|
|
105
|
+
case g:
|
|
106
|
+
h = ((b - r) / d + 2) / 6;
|
|
107
|
+
break;
|
|
108
|
+
case b:
|
|
109
|
+
h = ((r - g) / d + 4) / 6;
|
|
110
|
+
break;
|
|
105
111
|
}
|
|
106
112
|
}
|
|
107
113
|
|
|
@@ -114,7 +120,7 @@ function rgbToHsl(r: number, g: number, b: number): { h: number; s: number; l: n
|
|
|
114
120
|
|
|
115
121
|
/**
|
|
116
122
|
* Theme Live Editor Component
|
|
117
|
-
*
|
|
123
|
+
*
|
|
118
124
|
* Allows live editing of theme properties with instant preview
|
|
119
125
|
*/
|
|
120
126
|
export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
@@ -160,47 +166,53 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
160
166
|
localStorage.setItem('atomix-editor-layout', resizerPosition.toString());
|
|
161
167
|
}, [resizerPosition]);
|
|
162
168
|
|
|
163
|
-
const updateTheme = useCallback(
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
169
|
+
const updateTheme = useCallback(
|
|
170
|
+
(newTheme: Theme, addToHistory = true) => {
|
|
171
|
+
if (addToHistory) {
|
|
172
|
+
setThemeHistory(newTheme);
|
|
173
|
+
} else {
|
|
174
|
+
// Direct update without history (for JSON editor typing)
|
|
175
|
+
setJsonInput(JSON.stringify(newTheme, null, 2));
|
|
176
|
+
}
|
|
177
|
+
onChange?.(newTheme);
|
|
178
|
+
setError(null);
|
|
179
|
+
},
|
|
180
|
+
[onChange, setThemeHistory]
|
|
181
|
+
);
|
|
173
182
|
|
|
174
183
|
// Sync JSON input with theme history
|
|
175
184
|
useEffect(() => {
|
|
176
185
|
setJsonInput(JSON.stringify(theme, null, 2));
|
|
177
186
|
}, [theme]);
|
|
178
187
|
|
|
179
|
-
const handleJsonChange = useCallback(
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
const handleJsonChange = useCallback(
|
|
189
|
+
(value: string) => {
|
|
190
|
+
setJsonInput(value);
|
|
191
|
+
try {
|
|
192
|
+
const parsed = JSON.parse(value);
|
|
193
|
+
const newTheme = createThemeObject(parsed);
|
|
194
|
+
updateTheme(newTheme, false); // Don't add to history on every keystroke
|
|
195
|
+
} catch (err) {
|
|
196
|
+
setError(err instanceof Error ? err.message : 'Invalid JSON');
|
|
197
|
+
}
|
|
198
|
+
},
|
|
199
|
+
[updateTheme]
|
|
200
|
+
);
|
|
189
201
|
|
|
190
202
|
// Debounced JSON update to history
|
|
191
203
|
const jsonUpdateTimeoutRef = useRef<NodeJS.Timeout>();
|
|
192
204
|
useEffect(() => {
|
|
193
205
|
if (error) return;
|
|
194
|
-
|
|
206
|
+
|
|
195
207
|
try {
|
|
196
208
|
const parsed = JSON.parse(jsonInput);
|
|
197
209
|
const newTheme = createThemeObject(parsed);
|
|
198
|
-
|
|
210
|
+
|
|
199
211
|
// Clear existing timeout
|
|
200
212
|
if (jsonUpdateTimeoutRef.current) {
|
|
201
213
|
clearTimeout(jsonUpdateTimeoutRef.current);
|
|
202
214
|
}
|
|
203
|
-
|
|
215
|
+
|
|
204
216
|
// Add to history after 1 second of no typing
|
|
205
217
|
jsonUpdateTimeoutRef.current = setTimeout(() => {
|
|
206
218
|
setThemeHistory(newTheme);
|
|
@@ -216,27 +228,30 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
216
228
|
};
|
|
217
229
|
}, [jsonInput, error, setThemeHistory]);
|
|
218
230
|
|
|
219
|
-
const handleColorChange = useCallback(
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
current[key]
|
|
231
|
+
const handleColorChange = useCallback(
|
|
232
|
+
(path: string, value: string | number) => {
|
|
233
|
+
const newTheme = { ...theme };
|
|
234
|
+
const keys = path.split('.');
|
|
235
|
+
let current: any = newTheme;
|
|
236
|
+
|
|
237
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
238
|
+
const key = keys[i];
|
|
239
|
+
if (key && !current[key]) {
|
|
240
|
+
current[key] = {};
|
|
241
|
+
}
|
|
242
|
+
if (key) {
|
|
243
|
+
current = current[key];
|
|
244
|
+
}
|
|
228
245
|
}
|
|
229
|
-
|
|
230
|
-
|
|
246
|
+
|
|
247
|
+
const lastKey = keys[keys.length - 1];
|
|
248
|
+
if (lastKey) {
|
|
249
|
+
current[lastKey] = value;
|
|
231
250
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
current[lastKey] = value;
|
|
237
|
-
}
|
|
238
|
-
updateTheme(createThemeObject(newTheme));
|
|
239
|
-
}, [theme, updateTheme]);
|
|
251
|
+
updateTheme(createThemeObject(newTheme));
|
|
252
|
+
},
|
|
253
|
+
[theme, updateTheme]
|
|
254
|
+
);
|
|
240
255
|
|
|
241
256
|
const exportTheme = useCallback(() => {
|
|
242
257
|
const dataStr = JSON.stringify(theme, null, 2);
|
|
@@ -270,7 +285,7 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
270
285
|
exportTheme();
|
|
271
286
|
} else if (ctrlKey && e.key === '/') {
|
|
272
287
|
e.preventDefault();
|
|
273
|
-
setEditMode(prev => prev === 'visual' ? 'json' : 'visual');
|
|
288
|
+
setEditMode(prev => (prev === 'visual' ? 'json' : 'visual'));
|
|
274
289
|
} else if (e.key === 'Escape') {
|
|
275
290
|
setError(null);
|
|
276
291
|
}
|
|
@@ -291,13 +306,13 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
291
306
|
|
|
292
307
|
const handleMouseMove = (e: MouseEvent) => {
|
|
293
308
|
if (!editorRef.current || !previewRef.current) return;
|
|
294
|
-
|
|
309
|
+
|
|
295
310
|
const container = editorRef.current.parentElement;
|
|
296
311
|
if (!container) return;
|
|
297
312
|
|
|
298
313
|
const containerRect = container.getBoundingClientRect();
|
|
299
314
|
const newPosition = ((e.clientX - containerRect.left) / containerRect.width) * 100;
|
|
300
|
-
|
|
315
|
+
|
|
301
316
|
// Constrain between 20% and 80%
|
|
302
317
|
const constrainedPosition = Math.max(20, Math.min(80, newPosition));
|
|
303
318
|
setResizerPosition(constrainedPosition);
|
|
@@ -316,9 +331,12 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
316
331
|
};
|
|
317
332
|
}, [isResizing]);
|
|
318
333
|
|
|
319
|
-
const getColorValue = useCallback(
|
|
320
|
-
|
|
321
|
-
|
|
334
|
+
const getColorValue = useCallback(
|
|
335
|
+
(color: string): string => {
|
|
336
|
+
return convertColorFormat(color, colorFormat);
|
|
337
|
+
},
|
|
338
|
+
[colorFormat]
|
|
339
|
+
);
|
|
322
340
|
|
|
323
341
|
return (
|
|
324
342
|
<div className={`atomix-theme-live-editor ${className || ''}`} style={style}>
|
|
@@ -371,19 +389,16 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
371
389
|
</div>
|
|
372
390
|
|
|
373
391
|
<div className="editor-content" ref={editorRef}>
|
|
374
|
-
<div
|
|
375
|
-
className="editor-panel"
|
|
376
|
-
style={{ width: `${resizerPosition}%` }}
|
|
377
|
-
>
|
|
392
|
+
<div className="editor-panel" style={{ width: `${resizerPosition}%` }}>
|
|
378
393
|
{editMode === 'visual' ? (
|
|
379
394
|
<div className="visual-editor">
|
|
380
395
|
<div className="editor-section">
|
|
381
396
|
<h3>Colors</h3>
|
|
382
397
|
<div className="color-format-selector">
|
|
383
398
|
<label>Color Format:</label>
|
|
384
|
-
<select
|
|
385
|
-
value={colorFormat}
|
|
386
|
-
onChange={
|
|
399
|
+
<select
|
|
400
|
+
value={colorFormat}
|
|
401
|
+
onChange={e => setColorFormat(e.target.value as ColorFormat)}
|
|
387
402
|
>
|
|
388
403
|
<option value="hex">HEX</option>
|
|
389
404
|
<option value="rgb">RGB</option>
|
|
@@ -392,7 +407,7 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
392
407
|
<option value="hsla">HSLA</option>
|
|
393
408
|
</select>
|
|
394
409
|
</div>
|
|
395
|
-
|
|
410
|
+
|
|
396
411
|
{/* Primary Color */}
|
|
397
412
|
<div className="editor-field">
|
|
398
413
|
<label>Primary Color</label>
|
|
@@ -400,12 +415,12 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
400
415
|
<input
|
|
401
416
|
type="color"
|
|
402
417
|
value={theme.palette.primary.main}
|
|
403
|
-
onChange={
|
|
418
|
+
onChange={e => handleColorChange('palette.primary.main', e.target.value)}
|
|
404
419
|
/>
|
|
405
420
|
<input
|
|
406
421
|
type="text"
|
|
407
422
|
value={getColorValue(theme.palette.primary.main)}
|
|
408
|
-
onChange={
|
|
423
|
+
onChange={e => {
|
|
409
424
|
const converted = convertColorFormat(e.target.value, 'hex');
|
|
410
425
|
handleColorChange('palette.primary.main', converted);
|
|
411
426
|
}}
|
|
@@ -421,12 +436,12 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
421
436
|
<input
|
|
422
437
|
type="color"
|
|
423
438
|
value={theme.palette.secondary.main}
|
|
424
|
-
onChange={
|
|
439
|
+
onChange={e => handleColorChange('palette.secondary.main', e.target.value)}
|
|
425
440
|
/>
|
|
426
441
|
<input
|
|
427
442
|
type="text"
|
|
428
443
|
value={getColorValue(theme.palette.secondary.main)}
|
|
429
|
-
onChange={
|
|
444
|
+
onChange={e => {
|
|
430
445
|
const converted = convertColorFormat(e.target.value, 'hex');
|
|
431
446
|
handleColorChange('palette.secondary.main', converted);
|
|
432
447
|
}}
|
|
@@ -443,12 +458,14 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
443
458
|
<input
|
|
444
459
|
type="color"
|
|
445
460
|
value={theme.palette.background.default}
|
|
446
|
-
onChange={
|
|
461
|
+
onChange={e =>
|
|
462
|
+
handleColorChange('palette.background.default', e.target.value)
|
|
463
|
+
}
|
|
447
464
|
/>
|
|
448
465
|
<input
|
|
449
466
|
type="text"
|
|
450
467
|
value={getColorValue(theme.palette.background.default)}
|
|
451
|
-
onChange={
|
|
468
|
+
onChange={e => {
|
|
452
469
|
const converted = convertColorFormat(e.target.value, 'hex');
|
|
453
470
|
handleColorChange('palette.background.default', converted);
|
|
454
471
|
}}
|
|
@@ -465,7 +482,7 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
465
482
|
<input
|
|
466
483
|
type="text"
|
|
467
484
|
value={theme.typography.fontFamily}
|
|
468
|
-
onChange={
|
|
485
|
+
onChange={e => handleColorChange('typography.fontFamily', e.target.value)}
|
|
469
486
|
placeholder="Inter, sans-serif"
|
|
470
487
|
/>
|
|
471
488
|
</div>
|
|
@@ -475,7 +492,9 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
475
492
|
<input
|
|
476
493
|
type="number"
|
|
477
494
|
value={theme.typography.fontSize}
|
|
478
|
-
onChange={
|
|
495
|
+
onChange={e =>
|
|
496
|
+
handleColorChange('typography.fontSize', parseInt(e.target.value))
|
|
497
|
+
}
|
|
479
498
|
min="10"
|
|
480
499
|
max="24"
|
|
481
500
|
/>
|
|
@@ -486,25 +505,27 @@ export const ThemeLiveEditor: React.FC<ThemeLiveEditorProps> = ({
|
|
|
486
505
|
<div className="json-editor">
|
|
487
506
|
<textarea
|
|
488
507
|
value={jsonInput}
|
|
489
|
-
onChange={
|
|
508
|
+
onChange={e => handleJsonChange(e.target.value)}
|
|
490
509
|
spellCheck={false}
|
|
491
510
|
/>
|
|
492
511
|
{error && (
|
|
493
512
|
<div className="error-message">
|
|
494
513
|
❌ {error}
|
|
495
|
-
<button className="error-dismiss" onClick={() => setError(null)}
|
|
514
|
+
<button className="error-dismiss" onClick={() => setError(null)}>
|
|
515
|
+
×
|
|
516
|
+
</button>
|
|
496
517
|
</div>
|
|
497
518
|
)}
|
|
498
519
|
</div>
|
|
499
520
|
)}
|
|
500
521
|
</div>
|
|
501
522
|
|
|
502
|
-
<div
|
|
523
|
+
<div
|
|
503
524
|
className={`resizer ${isResizing ? 'resizing' : ''}`}
|
|
504
525
|
onMouseDown={handleResizeStart}
|
|
505
526
|
/>
|
|
506
527
|
|
|
507
|
-
<div
|
|
528
|
+
<div
|
|
508
529
|
className="preview-panel"
|
|
509
530
|
ref={previewRef}
|
|
510
531
|
style={{ width: `${100 - resizerPosition}%` }}
|