@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 Adapter
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Converts between Theme objects and DesignTokens.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -11,12 +11,12 @@ import { hexToRgb } from '../utils/themeUtils';
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Convert Theme object to DesignTokens
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* Extracts values from a Theme object and converts them to flat DesignTokens format.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* @param theme - Theme object to convert
|
|
18
18
|
* @returns Partial DesignTokens object
|
|
19
|
-
*
|
|
19
|
+
*
|
|
20
20
|
* @example
|
|
21
21
|
* ```typescript
|
|
22
22
|
* const theme = createTheme({ palette: { primary: { main: '#7c3aed' } } });
|
|
@@ -150,14 +150,14 @@ export function themeToDesignTokens(theme: Theme): Partial<DesignTokens> {
|
|
|
150
150
|
tokens['font-sans-serif'] = theme.typography.fontFamily;
|
|
151
151
|
tokens['body-font-size'] = `${theme.typography.fontSize}px`;
|
|
152
152
|
tokens['body-font-weight'] = String(theme.typography.fontWeightRegular);
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
// Font weights
|
|
155
155
|
tokens['font-weight-light'] = String(theme.typography.fontWeightLight);
|
|
156
156
|
tokens['font-weight-normal'] = String(theme.typography.fontWeightRegular);
|
|
157
157
|
tokens['font-weight-medium'] = String(theme.typography.fontWeightMedium);
|
|
158
158
|
tokens['font-weight-semibold'] = String(theme.typography.fontWeightSemiBold);
|
|
159
159
|
tokens['font-weight-bold'] = String(theme.typography.fontWeightBold);
|
|
160
|
-
|
|
160
|
+
|
|
161
161
|
// Line heights
|
|
162
162
|
if (theme.typography.h1?.lineHeight) {
|
|
163
163
|
tokens['line-height-base'] = String(theme.typography.h1.lineHeight);
|
|
@@ -165,7 +165,11 @@ export function themeToDesignTokens(theme: Theme): Partial<DesignTokens> {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
// Convert spacing (if available as object)
|
|
168
|
-
if (
|
|
168
|
+
if (
|
|
169
|
+
theme.spacing &&
|
|
170
|
+
typeof theme.spacing === 'object' &&
|
|
171
|
+
!('__isSpacingFunction' in theme.spacing)
|
|
172
|
+
) {
|
|
169
173
|
const spacing = theme.spacing as Record<string, string | number>;
|
|
170
174
|
Object.entries(spacing).forEach(([key, value]) => {
|
|
171
175
|
tokens[`spacing-${key}` as keyof DesignTokens] = String(value);
|
|
@@ -175,12 +179,18 @@ export function themeToDesignTokens(theme: Theme): Partial<DesignTokens> {
|
|
|
175
179
|
// Convert border radius
|
|
176
180
|
if (theme.borderRadius) {
|
|
177
181
|
Object.entries(theme.borderRadius).forEach(([key, value]) => {
|
|
178
|
-
const tokenKey =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
182
|
+
const tokenKey =
|
|
183
|
+
key === 'sm'
|
|
184
|
+
? 'border-radius-sm'
|
|
185
|
+
: key === 'md'
|
|
186
|
+
? 'border-radius'
|
|
187
|
+
: key === 'lg'
|
|
188
|
+
? 'border-radius-lg'
|
|
189
|
+
: key === 'xl'
|
|
190
|
+
? 'border-radius-xl'
|
|
191
|
+
: key === 'xxl'
|
|
192
|
+
? 'border-radius-xxl'
|
|
193
|
+
: `border-radius-${key}`;
|
|
184
194
|
tokens[tokenKey as keyof DesignTokens] = String(value);
|
|
185
195
|
});
|
|
186
196
|
}
|
|
@@ -188,12 +198,18 @@ export function themeToDesignTokens(theme: Theme): Partial<DesignTokens> {
|
|
|
188
198
|
// Convert shadows
|
|
189
199
|
if (theme.shadows) {
|
|
190
200
|
Object.entries(theme.shadows).forEach(([key, value]) => {
|
|
191
|
-
const tokenKey =
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
201
|
+
const tokenKey =
|
|
202
|
+
key === 'xs'
|
|
203
|
+
? 'box-shadow-xs'
|
|
204
|
+
: key === 'sm'
|
|
205
|
+
? 'box-shadow-sm'
|
|
206
|
+
: key === 'md'
|
|
207
|
+
? 'box-shadow'
|
|
208
|
+
: key === 'lg'
|
|
209
|
+
? 'box-shadow-lg'
|
|
210
|
+
: key === 'xl'
|
|
211
|
+
? 'box-shadow-xl'
|
|
212
|
+
: `box-shadow-${key}`;
|
|
197
213
|
tokens[tokenKey as keyof DesignTokens] = String(value);
|
|
198
214
|
});
|
|
199
215
|
}
|
|
@@ -240,13 +256,13 @@ export function themeToDesignTokens(theme: Theme): Partial<DesignTokens> {
|
|
|
240
256
|
|
|
241
257
|
/**
|
|
242
258
|
* Convert DesignTokens to Theme-compatible CSS variables
|
|
243
|
-
*
|
|
259
|
+
*
|
|
244
260
|
* @param tokens - DesignTokens object
|
|
245
261
|
* @returns CSS variables object compatible with Theme.cssVars
|
|
246
262
|
*/
|
|
247
263
|
export function designTokensToCSSVars(tokens: Partial<DesignTokens>): Record<string, string> {
|
|
248
264
|
const cssVars: Record<string, string> = {};
|
|
249
|
-
|
|
265
|
+
|
|
250
266
|
Object.entries(tokens).forEach(([key, value]) => {
|
|
251
267
|
if (value !== undefined) {
|
|
252
268
|
cssVars[`--atomix-${key}`] = String(value);
|
|
@@ -258,9 +274,9 @@ export function designTokensToCSSVars(tokens: Partial<DesignTokens>): Record<str
|
|
|
258
274
|
|
|
259
275
|
/**
|
|
260
276
|
* Create DesignTokens from Theme with defaults
|
|
261
|
-
*
|
|
277
|
+
*
|
|
262
278
|
* Converts a Theme to DesignTokens and merges with default tokens.
|
|
263
|
-
*
|
|
279
|
+
*
|
|
264
280
|
* @param theme - Theme object to convert
|
|
265
281
|
* @returns Complete DesignTokens object
|
|
266
282
|
*/
|
|
@@ -271,17 +287,16 @@ export function createDesignTokensFromTheme(theme: Theme): DesignTokens {
|
|
|
271
287
|
|
|
272
288
|
/**
|
|
273
289
|
* Create a minimal Theme object from DesignTokens
|
|
274
|
-
*
|
|
290
|
+
*
|
|
275
291
|
* @param tokens - DesignTokens to convert
|
|
276
292
|
* @returns Minimal Theme object with cssVars populated
|
|
277
293
|
*/
|
|
278
294
|
export function designTokensToTheme(tokens: Partial<DesignTokens>): Partial<Theme> {
|
|
279
295
|
const cssVars = designTokensToCSSVars(tokens);
|
|
280
|
-
|
|
296
|
+
|
|
281
297
|
return {
|
|
282
298
|
name: 'Design Tokens Theme',
|
|
283
299
|
cssVars,
|
|
284
300
|
__isJSTheme: true,
|
|
285
301
|
} as Partial<Theme>;
|
|
286
302
|
}
|
|
287
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme Configuration Validator
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Validates theme configuration structure and values
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ import type { ConfigValidationResult } from './types';
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Validate theme configuration
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
12
|
* @param config - Configuration to validate
|
|
13
13
|
* @returns Validation result with errors and warnings
|
|
14
14
|
*/
|
|
@@ -117,8 +117,14 @@ function validateThemes(themes: Record<string, any>): ConfigValidationResult {
|
|
|
117
117
|
|
|
118
118
|
// Validate accessibility (only critical checks)
|
|
119
119
|
if (theme.a11y?.contrastTarget) {
|
|
120
|
-
if (
|
|
121
|
-
|
|
120
|
+
if (
|
|
121
|
+
typeof theme.a11y.contrastTarget !== 'number' ||
|
|
122
|
+
theme.a11y.contrastTarget < 1 ||
|
|
123
|
+
theme.a11y.contrastTarget > 21
|
|
124
|
+
) {
|
|
125
|
+
warnings.push(
|
|
126
|
+
`Theme "${themeId}" has invalid contrast target: ${theme.a11y.contrastTarget}`
|
|
127
|
+
);
|
|
122
128
|
}
|
|
123
129
|
}
|
|
124
130
|
}
|
|
@@ -247,4 +253,3 @@ function validateDependencies(
|
|
|
247
253
|
|
|
248
254
|
return { valid: errors.length === 0, errors, warnings };
|
|
249
255
|
}
|
|
250
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Theme System Constants
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Centralized constants for the theme system to avoid magic numbers and strings.
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -121,7 +121,7 @@ export const DEFAULT_ANALYTICS_CONFIG = {
|
|
|
121
121
|
* Logger default configuration
|
|
122
122
|
*/
|
|
123
123
|
export const DEFAULT_LOGGER_CONFIG = {
|
|
124
|
-
level:
|
|
124
|
+
level: typeof process !== 'undefined' && process.env?.NODE_ENV === 'production' ? 1 : 2, // WARN in prod, INFO in dev
|
|
125
125
|
enableConsole: true,
|
|
126
126
|
} as const;
|
|
127
127
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* createTheme Tests
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Tests for createTheme function including automatic config loading
|
|
5
5
|
*/
|
|
6
6
|
|
|
@@ -19,7 +19,7 @@ describe('createTheme', () => {
|
|
|
19
19
|
// createTheme() should work even if config is not available
|
|
20
20
|
// It will fall back to default tokens
|
|
21
21
|
const css = createTheme();
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
expect(typeof css).toBe('string');
|
|
24
24
|
expect(css.length).toBeGreaterThan(0);
|
|
25
25
|
expect(css).toContain(':root');
|
|
@@ -27,7 +27,7 @@ describe('createTheme', () => {
|
|
|
27
27
|
|
|
28
28
|
it('should generate valid CSS with default tokens', () => {
|
|
29
29
|
const css = createTheme();
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
// Should contain CSS variable declarations
|
|
32
32
|
expect(css).toMatch(/--atomix-[a-z-]+:\s*[^;]+;/);
|
|
33
33
|
});
|
|
@@ -36,13 +36,13 @@ describe('createTheme', () => {
|
|
|
36
36
|
describe('DesignTokens Input', () => {
|
|
37
37
|
it('should accept DesignTokens and generate CSS', () => {
|
|
38
38
|
const tokens: Partial<DesignTokens> = {
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
primary: '#7AFFD7',
|
|
40
|
+
secondary: '#FF5733',
|
|
41
41
|
'spacing-4': '1rem',
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const css = createTheme(tokens);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
expect(css).toContain('--atomix-primary');
|
|
47
47
|
expect(css).toContain('#7AFFD7');
|
|
48
48
|
expect(css).toContain('--atomix-secondary');
|
|
@@ -53,15 +53,15 @@ describe('createTheme', () => {
|
|
|
53
53
|
|
|
54
54
|
it('should merge with default tokens', () => {
|
|
55
55
|
const tokens: Partial<DesignTokens> = {
|
|
56
|
-
|
|
56
|
+
primary: '#CUSTOM',
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
const css = createTheme(tokens);
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
// Should contain custom primary
|
|
62
62
|
expect(css).toContain('--atomix-primary');
|
|
63
63
|
expect(css).toContain('#CUSTOM');
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
// Should also contain default tokens
|
|
66
66
|
expect(css).toContain('--atomix-secondary');
|
|
67
67
|
});
|
|
@@ -70,33 +70,33 @@ describe('createTheme', () => {
|
|
|
70
70
|
describe('Options', () => {
|
|
71
71
|
it('should respect prefix option', () => {
|
|
72
72
|
const tokens: Partial<DesignTokens> = {
|
|
73
|
-
|
|
73
|
+
primary: '#7AFFD7',
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
const css = createTheme(tokens, { prefix: 'myapp' });
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
expect(css).toContain('--myapp-primary');
|
|
79
79
|
expect(css).not.toContain('--atomix-primary');
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it('should respect selector option', () => {
|
|
83
83
|
const tokens: Partial<DesignTokens> = {
|
|
84
|
-
|
|
84
|
+
primary: '#7AFFD7',
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
const css = createTheme(tokens, { selector: '[data-theme="dark"]' });
|
|
88
|
-
|
|
88
|
+
|
|
89
89
|
expect(css).toContain('[data-theme="dark"]');
|
|
90
90
|
expect(css).not.toContain(':root');
|
|
91
91
|
});
|
|
92
92
|
|
|
93
93
|
it('should use default prefix when not provided', () => {
|
|
94
94
|
const tokens: Partial<DesignTokens> = {
|
|
95
|
-
|
|
95
|
+
primary: '#7AFFD7',
|
|
96
96
|
};
|
|
97
97
|
|
|
98
98
|
const css = createTheme(tokens);
|
|
99
|
-
|
|
99
|
+
|
|
100
100
|
expect(css).toContain('--atomix-primary');
|
|
101
101
|
});
|
|
102
102
|
});
|
|
@@ -104,11 +104,11 @@ describe('createTheme', () => {
|
|
|
104
104
|
describe('CSS Output Format', () => {
|
|
105
105
|
it('should generate valid CSS syntax', () => {
|
|
106
106
|
const tokens: Partial<DesignTokens> = {
|
|
107
|
-
|
|
107
|
+
primary: '#7AFFD7',
|
|
108
108
|
};
|
|
109
109
|
|
|
110
110
|
const css = createTheme(tokens);
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
// Should be valid CSS
|
|
113
113
|
expect(css).toMatch(/^[^{]*\{[^}]*\}/s);
|
|
114
114
|
expect(css).toContain(':');
|
|
@@ -117,16 +117,14 @@ describe('createTheme', () => {
|
|
|
117
117
|
|
|
118
118
|
it('should format CSS with proper indentation', () => {
|
|
119
119
|
const tokens: Partial<DesignTokens> = {
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
primary: '#7AFFD7',
|
|
121
|
+
secondary: '#FF5733',
|
|
122
122
|
};
|
|
123
123
|
|
|
124
124
|
const css = createTheme(tokens);
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
// Should have proper formatting
|
|
127
127
|
expect(css).toContain('\n');
|
|
128
128
|
});
|
|
129
129
|
});
|
|
130
130
|
});
|
|
131
|
-
|
|
132
|
-
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Check if value is an object
|
|
13
13
|
*/
|
|
14
14
|
function isObject(item: any): item is Record<string, any> {
|
|
15
|
-
|
|
15
|
+
return item && typeof item === 'object' && !Array.isArray(item) && typeof item !== 'function';
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
/**
|
|
@@ -20,32 +20,35 @@ function isObject(item: any): item is Record<string, any> {
|
|
|
20
20
|
* Later objects override earlier ones
|
|
21
21
|
*/
|
|
22
22
|
export function deepMerge<T extends Record<string, unknown>>(...objects: Partial<T>[]): T {
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
if (objects.length === 0) return {} as T;
|
|
24
|
+
if (objects.length === 1) return objects[0] as T;
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
const [target, ...sources] = objects;
|
|
27
|
+
const result = { ...target } as T;
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
for (const source of sources) {
|
|
30
|
+
if (!source) continue;
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
for (const key in source) {
|
|
33
|
+
if (!Object.prototype.hasOwnProperty.call(source, key)) continue;
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const targetValue = result[key];
|
|
36
|
+
const sourceValue = source[key];
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
if (isObject(targetValue) && isObject(sourceValue)) {
|
|
39
|
+
// Recursively merge objects
|
|
40
|
+
result[key] = deepMerge(
|
|
41
|
+
targetValue as Record<string, unknown>,
|
|
42
|
+
sourceValue as Record<string, unknown>
|
|
43
|
+
) as T[Extract<keyof T, string>];
|
|
44
|
+
} else {
|
|
45
|
+
// Override with source value
|
|
46
|
+
result[key] = sourceValue as T[Extract<keyof T, string>];
|
|
47
|
+
}
|
|
46
48
|
}
|
|
49
|
+
}
|
|
47
50
|
|
|
48
|
-
|
|
51
|
+
return result;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
// ============================================================================
|
|
@@ -69,7 +72,7 @@ import type { DesignTokens } from '../tokens/tokens';
|
|
|
69
72
|
* ```
|
|
70
73
|
*/
|
|
71
74
|
export function mergeTheme(...tokens: Partial<DesignTokens>[]): Partial<DesignTokens> {
|
|
72
|
-
|
|
75
|
+
return deepMerge({}, ...tokens);
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
/**
|
|
@@ -86,12 +89,15 @@ export function mergeTheme(...tokens: Partial<DesignTokens>[]): Partial<DesignTo
|
|
|
86
89
|
* // Returns: { 'primary': '#000', 'secondary': '#fff' }
|
|
87
90
|
* ```
|
|
88
91
|
*/
|
|
89
|
-
export function extendTheme(
|
|
90
|
-
|
|
92
|
+
export function extendTheme(
|
|
93
|
+
baseTokens: Partial<DesignTokens>,
|
|
94
|
+
extension: Partial<DesignTokens>
|
|
95
|
+
): Partial<DesignTokens> {
|
|
96
|
+
return mergeTheme(baseTokens, extension);
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
export default {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
100
|
+
deepMerge,
|
|
101
|
+
mergeTheme,
|
|
102
|
+
extendTheme,
|
|
97
103
|
};
|