@shohojdhara/atomix 0.3.2 → 0.3.4

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.
Files changed (84) hide show
  1. package/README.md +58 -21
  2. package/dist/atomix.css +96 -121
  3. package/dist/atomix.min.css +3 -3
  4. package/dist/index.d.ts +7937 -7765
  5. package/dist/index.esm.js +3677 -4031
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +3648 -3952
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.min.js +1 -1
  10. package/dist/index.min.js.map +1 -1
  11. package/package.json +44 -16
  12. package/scripts/atomix-cli.js +1764 -0
  13. package/scripts/build-themes.js +208 -0
  14. package/scripts/cli/interactive-init.js +520 -0
  15. package/scripts/cli/migration-tools.js +603 -0
  16. package/scripts/cli/theme-bridge.js +129 -0
  17. package/scripts/cli/token-manager.js +519 -0
  18. package/scripts/sync-theme-config.js +309 -0
  19. package/src/components/Button/Button.tsx +36 -1
  20. package/src/components/List/ListGroup.tsx +1 -2
  21. package/src/components/Popover/Popover.tsx +2 -2
  22. package/src/components/Tooltip/Tooltip.stories.tsx +49 -12
  23. package/src/components/Tooltip/Tooltip.tsx +32 -58
  24. package/src/lib/composables/useTooltip.ts +285 -0
  25. package/src/lib/config/index.ts +275 -0
  26. package/src/lib/config/loader.ts +105 -0
  27. package/src/lib/constants/cssVariables.ts +390 -0
  28. package/src/lib/hooks/__tests__/useComponentCustomization.test.ts +151 -0
  29. package/src/lib/hooks/index.ts +19 -0
  30. package/src/lib/hooks/useComponentCustomization.ts +175 -0
  31. package/src/lib/index.ts +14 -1
  32. package/src/lib/patterns/__tests__/slots.test.ts +108 -0
  33. package/src/lib/patterns/index.ts +35 -0
  34. package/src/lib/patterns/slots.tsx +421 -0
  35. package/src/lib/theme/composeTheme.ts +0 -5
  36. package/src/lib/theme/config/index.ts +1 -1
  37. package/src/lib/theme/config/loader.ts +75 -41
  38. package/src/lib/theme/config/types.ts +21 -7
  39. package/src/lib/theme/config/validator.ts +1 -1
  40. package/src/lib/theme/constants.ts +12 -2
  41. package/src/lib/theme/createTheme.ts +2 -135
  42. package/src/lib/theme/createThemeFromConfig.ts +132 -0
  43. package/src/lib/theme/cssVariableMapper.ts +261 -0
  44. package/src/lib/theme/devtools/CLI.ts +161 -76
  45. package/src/lib/theme/devtools/Comparator.tsx +343 -0
  46. package/src/lib/theme/devtools/IMPROVEMENTS.md +429 -0
  47. package/src/lib/theme/devtools/Inspector.tsx +21 -6
  48. package/src/lib/theme/devtools/LiveEditor.tsx +393 -0
  49. package/src/lib/theme/devtools/README.md +433 -0
  50. package/src/lib/theme/devtools/index.ts +12 -11
  51. package/src/lib/theme/generateCSSVariables.ts +79 -38
  52. package/src/lib/theme/index.ts +45 -246
  53. package/src/lib/theme/runtime/ThemeApplicator.ts +252 -0
  54. package/src/lib/theme/runtime/ThemeManager.test.ts +17 -1
  55. package/src/lib/theme/runtime/ThemeManager.ts +7 -7
  56. package/src/lib/theme/themeUtils.ts +27 -5
  57. package/src/lib/theme/types.ts +59 -1
  58. package/src/lib/theme-tools.ts +125 -0
  59. package/src/lib/types/components.ts +260 -72
  60. package/src/lib/types/partProps.ts +426 -0
  61. package/src/lib/utils/__tests__/componentUtils.test.ts +144 -0
  62. package/src/lib/utils/componentUtils.ts +163 -0
  63. package/src/lib/utils/index.ts +17 -57
  64. package/src/styles/01-settings/_settings.colors.scss +10 -10
  65. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  66. package/src/styles/01-settings/_settings.tooltip.scss +1 -1
  67. package/src/styles/03-generic/_generated-root.css +5 -0
  68. package/src/styles/06-components/_components.navbar.scss +12 -5
  69. package/src/styles/06-components/_components.tooltip.scss +31 -81
  70. package/src/themes/README.md +442 -0
  71. package/src/themes/themes.config.js +35 -0
  72. package/src/lib/theme/errors.test.ts +0 -207
  73. package/src/lib/theme/generators/CSSGenerator.ts +0 -311
  74. package/src/lib/theme/generators/ConfigGenerator.ts +0 -287
  75. package/src/lib/theme/generators/TypeGenerator.ts +0 -228
  76. package/src/lib/theme/generators/index.ts +0 -21
  77. package/src/lib/theme/monitoring/ThemeAnalytics.ts +0 -409
  78. package/src/lib/theme/monitoring/index.ts +0 -17
  79. package/src/lib/theme/overrides/ComponentOverrides.ts +0 -243
  80. package/src/lib/theme/overrides/index.ts +0 -15
  81. package/src/lib/theme/studio/ThemeStudio.tsx +0 -312
  82. package/src/lib/theme/studio/index.ts +0 -8
  83. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +0 -364
  84. package/src/lib/theme/whitelabel/index.ts +0 -13
@@ -1,311 +0,0 @@
1
- /**
2
- * CSS Generator
3
- *
4
- * Optimized CSS variable generation from theme objects
5
- */
6
-
7
- import type { Theme } from '../types';
8
-
9
- /**
10
- * CSS generation options
11
- */
12
- export interface CSSGeneratorOptions {
13
- /** CSS selector (default: ':root') */
14
- selector?: string;
15
- /** CSS variable prefix (default: 'atomix') */
16
- prefix?: string;
17
- /** Include comments */
18
- includeComments?: boolean;
19
- /** Minify output */
20
- minify?: boolean;
21
- /** Custom property formatter */
22
- formatProperty?: (path: string[], value: any) => string;
23
- }
24
-
25
- /**
26
- * CSS Generator
27
- *
28
- * Generates optimized CSS custom properties from theme objects
29
- */
30
- export class CSSGenerator {
31
- private options: Required<Omit<CSSGeneratorOptions, 'formatProperty'>> & {
32
- formatProperty?: CSSGeneratorOptions['formatProperty'];
33
- };
34
-
35
- constructor(options: CSSGeneratorOptions = {}) {
36
- this.options = {
37
- selector: options.selector || ':root',
38
- prefix: options.prefix || 'atomix',
39
- includeComments: options.includeComments ?? true,
40
- minify: options.minify ?? false,
41
- formatProperty: options.formatProperty,
42
- };
43
- }
44
-
45
- /**
46
- * Generate CSS from theme
47
- */
48
- generate(theme: Theme): string {
49
- const variables = this.extractVariables(theme);
50
- return this.formatCSS(variables);
51
- }
52
-
53
- /**
54
- * Extract CSS variables from theme
55
- */
56
- private extractVariables(theme: Theme): Map<string, string> {
57
- const variables = new Map<string, string>();
58
-
59
- // Palette
60
- this.extractPalette(theme.palette, variables);
61
-
62
- // Typography
63
- this.extractTypography(theme.typography, variables);
64
-
65
- // Spacing (generate common values)
66
- this.extractSpacing(theme.spacing, variables);
67
-
68
- // Breakpoints
69
- this.extractBreakpoints(theme.breakpoints, variables);
70
-
71
- // Shadows
72
- this.extractShadows(theme.shadows, variables);
73
-
74
- // Transitions
75
- this.extractTransitions(theme.transitions, variables);
76
-
77
- // Z-index
78
- this.extractZIndex(theme.zIndex, variables);
79
-
80
- // Border radius
81
- this.extractBorderRadius(theme.borderRadius, variables);
82
-
83
- // Custom properties
84
- this.extractCustom(theme.custom, variables);
85
-
86
- return variables;
87
- }
88
-
89
- /**
90
- * Extract palette variables
91
- */
92
- private extractPalette(palette: Theme['palette'], variables: Map<string, string>): void {
93
- const colors = ['primary', 'secondary', 'error', 'warning', 'info', 'success'] as const;
94
-
95
- for (const color of colors) {
96
- const colorObj = palette[color];
97
- if (colorObj) {
98
- variables.set(`palette-${color}-main`, colorObj.main);
99
- if (colorObj.light) variables.set(`palette-${color}-light`, colorObj.light);
100
- if (colorObj.dark) variables.set(`palette-${color}-dark`, colorObj.dark);
101
- if (colorObj.contrastText) variables.set(`palette-${color}-contrast-text`, colorObj.contrastText);
102
- }
103
- }
104
-
105
- // Background
106
- if (palette.background) {
107
- variables.set('background-default', palette.background.default);
108
- variables.set('background-paper', palette.background.paper);
109
- variables.set('background-subtle', palette.background.subtle);
110
- }
111
-
112
- // Text
113
- if (palette.text) {
114
- variables.set('text-primary', palette.text.primary);
115
- variables.set('text-secondary', palette.text.secondary);
116
- variables.set('text-disabled', palette.text.disabled);
117
- }
118
- }
119
-
120
- /**
121
- * Extract typography variables
122
- */
123
- private extractTypography(typography: Theme['typography'], variables: Map<string, string>): void {
124
- variables.set('font-family', typography.fontFamily);
125
- variables.set('font-size', `${typography.fontSize}px`);
126
-
127
- // Font weights
128
- if (typography.fontWeightLight) variables.set('font-weight-light', String(typography.fontWeightLight));
129
- if (typography.fontWeightRegular) variables.set('font-weight-regular', String(typography.fontWeightRegular));
130
- if (typography.fontWeightMedium) variables.set('font-weight-medium', String(typography.fontWeightMedium));
131
- if (typography.fontWeightSemiBold) variables.set('font-weight-semibold', String(typography.fontWeightSemiBold));
132
- if (typography.fontWeightBold) variables.set('font-weight-bold', String(typography.fontWeightBold));
133
-
134
- // Headings
135
- const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] as const;
136
- for (const heading of headings) {
137
- const h = typography[heading];
138
- if (h) {
139
- if (h.fontSize) variables.set(`typography-${heading}-font-size`, String(h.fontSize));
140
- if (h.fontWeight) variables.set(`typography-${heading}-font-weight`, String(h.fontWeight));
141
- if (h.lineHeight) variables.set(`typography-${heading}-line-height`, String(h.lineHeight));
142
- }
143
- }
144
-
145
- // Body
146
- if (typography.body1) {
147
- if (typography.body1.fontSize) variables.set('typography-body1-font-size', String(typography.body1.fontSize));
148
- if (typography.body1.fontWeight) variables.set('typography-body1-font-weight', String(typography.body1.fontWeight));
149
- if (typography.body1.lineHeight) variables.set('typography-body1-line-height', String(typography.body1.lineHeight));
150
- }
151
-
152
- if (typography.body2) {
153
- if (typography.body2.fontSize) variables.set('typography-body2-font-size', String(typography.body2.fontSize));
154
- if (typography.body2.fontWeight) variables.set('typography-body2-font-weight', String(typography.body2.fontWeight));
155
- if (typography.body2.lineHeight) variables.set('typography-body2-line-height', String(typography.body2.lineHeight));
156
- }
157
- }
158
-
159
- /**
160
- * Extract spacing variables
161
- */
162
- private extractSpacing(spacing: Theme['spacing'], variables: Map<string, string>): void {
163
- // Generate common spacing values
164
- for (let i = 0; i <= 12; i++) {
165
- try {
166
- const value = spacing(i);
167
- variables.set(`spacing-${i}`, value);
168
- } catch {
169
- // Ignore errors
170
- }
171
- }
172
- }
173
-
174
- /**
175
- * Extract breakpoint variables
176
- */
177
- private extractBreakpoints(breakpoints: Theme['breakpoints'], variables: Map<string, string>): void {
178
- const keys = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
179
- for (const key of keys) {
180
- const value = breakpoints.values[key];
181
- if (value !== undefined) {
182
- variables.set(`breakpoint-${key}`, `${value}px`);
183
- }
184
- }
185
- }
186
-
187
- /**
188
- * Extract shadow variables
189
- */
190
- private extractShadows(shadows: Theme['shadows'], variables: Map<string, string>): void {
191
- const keys = ['xs', 'sm', 'md', 'lg', 'xl'] as const;
192
- for (const key of keys) {
193
- const shadow = shadows[key];
194
- if (shadow) {
195
- variables.set(`shadow-${key}`, shadow);
196
- }
197
- }
198
- }
199
-
200
- /**
201
- * Extract transition variables
202
- */
203
- private extractTransitions(transitions: Theme['transitions'], variables: Map<string, string>): void {
204
- if (transitions.duration) {
205
- const durations = ['shortest', 'shorter', 'short', 'standard', 'complex'] as const;
206
- for (const key of durations) {
207
- const value = transitions.duration[key];
208
- if (value !== undefined) {
209
- variables.set(`transition-duration-${key}`, `${value}ms`);
210
- }
211
- }
212
- }
213
-
214
- if (transitions.easing) {
215
- const easings = ['easeInOut', 'easeOut', 'easeIn', 'sharp'] as const;
216
- for (const key of easings) {
217
- const value = transitions.easing[key];
218
- if (value) {
219
- variables.set(`transition-easing-${key}`, value);
220
- }
221
- }
222
- }
223
- }
224
-
225
- /**
226
- * Extract z-index variables
227
- */
228
- private extractZIndex(zIndex: Theme['zIndex'], variables: Map<string, string>): void {
229
- const keys = ['mobileStepper', 'speedDial', 'appBar', 'drawer', 'modal', 'snackbar', 'tooltip'] as const;
230
- for (const key of keys) {
231
- const value = zIndex[key];
232
- if (value !== undefined) {
233
- variables.set(`z-index-${key}`, String(value));
234
- }
235
- }
236
- }
237
-
238
- /**
239
- * Extract border radius variables
240
- */
241
- private extractBorderRadius(borderRadius: Theme['borderRadius'], variables: Map<string, string>): void {
242
- const keys = ['base', 'sm', 'md', 'lg', 'xl', 'xxl', '3xl', '4xl', 'pill'] as const;
243
- for (const key of keys) {
244
- const value = borderRadius[key];
245
- if (value !== undefined) {
246
- variables.set(`border-radius-${key}`, String(value));
247
- }
248
- }
249
- }
250
-
251
- /**
252
- * Extract custom properties
253
- */
254
- private extractCustom(custom: Theme['custom'], variables: Map<string, string>): void {
255
- for (const [key, value] of Object.entries(custom)) {
256
- if (value !== undefined && value !== null) {
257
- variables.set(`custom-${key}`, String(value));
258
- }
259
- }
260
- }
261
-
262
- /**
263
- * Format CSS from variables
264
- */
265
- private formatCSS(variables: Map<string, string>): string {
266
- const { selector, prefix, includeComments, minify } = this.options;
267
- const indent = minify ? '' : ' ';
268
- const newline = minify ? '' : '\n';
269
- const space = minify ? '' : ' ';
270
-
271
- let css = '';
272
-
273
- if (includeComments && !minify) {
274
- css += `/* Atomix Theme CSS Variables */${newline}`;
275
- css += `/* Generated from theme configuration */${newline}${newline}`;
276
- }
277
-
278
- css += `${selector}${space}{${newline}`;
279
-
280
- for (const [key, value] of variables.entries()) {
281
- const property = this.formatPropertyName(key);
282
- css += `${indent}--${prefix}-${property}:${space}${value};${newline}`;
283
- }
284
-
285
- css += `}${newline}`;
286
-
287
- return css;
288
- }
289
-
290
- /**
291
- * Format property name
292
- */
293
- private formatPropertyName(key: string): string {
294
- if (this.options.formatProperty) {
295
- return this.options.formatProperty(key.split('-'), key);
296
- }
297
- return key;
298
- }
299
- }
300
-
301
- /**
302
- * Generate CSS variables from theme
303
- *
304
- * @param theme - Theme object
305
- * @param options - Generation options
306
- * @returns CSS string
307
- */
308
- export function generateCSS(theme: Theme, options: CSSGeneratorOptions = {}): string {
309
- const generator = new CSSGenerator(options);
310
- return generator.generate(theme);
311
- }
@@ -1,287 +0,0 @@
1
- /**
2
- * Configuration Generator
3
- *
4
- * Generates theme configuration templates and scaffolding
5
- */
6
-
7
- import type { ThemeConfig, ThemeDefinition } from '../config/types';
8
-
9
- /**
10
- * Config generation options
11
- */
12
- export interface ConfigGeneratorOptions {
13
- /** Include example themes */
14
- includeExamples?: boolean;
15
- /** Include comments and documentation */
16
- includeComments?: boolean;
17
- /** Output format */
18
- format?: 'typescript' | 'javascript' | 'json';
19
- /** Include build configuration */
20
- includeBuild?: boolean;
21
- /** Include runtime configuration */
22
- includeRuntime?: boolean;
23
- }
24
-
25
- /**
26
- * Configuration Generator
27
- *
28
- * Generates theme configuration files and templates
29
- */
30
- export class ConfigGenerator {
31
- private options: Required<ConfigGeneratorOptions>;
32
-
33
- constructor(options: ConfigGeneratorOptions = {}) {
34
- this.options = {
35
- includeExamples: options.includeExamples ?? true,
36
- includeComments: options.includeComments ?? true,
37
- format: options.format || 'typescript',
38
- includeBuild: options.includeBuild ?? true,
39
- includeRuntime: options.includeRuntime ?? true,
40
- };
41
- }
42
-
43
- /**
44
- * Generate configuration template
45
- */
46
- generate(): string {
47
- let output = '';
48
-
49
- if (this.options.includeComments) {
50
- output += this.generateHeader();
51
- }
52
-
53
- if (this.options.format === 'typescript') {
54
- output += this.generateTypeScriptImports();
55
- }
56
-
57
- output += this.generateConfigObject();
58
-
59
- if (this.options.format === 'typescript') {
60
- output += this.generateTypeScriptExport();
61
- }
62
-
63
- return output;
64
- }
65
-
66
- /**
67
- * Generate file header
68
- */
69
- private generateHeader(): string {
70
- const comment = this.options.format === 'json' ? '' : '//';
71
- return `${this.options.format === 'json' ? '' : '/**\n * Atomix Theme Configuration\n * \n * Configure themes, build settings, and runtime behavior\n */\n\n'}`;
72
- }
73
-
74
- /**
75
- * Generate TypeScript imports
76
- */
77
- private generateTypeScriptImports(): string {
78
- return `import type { ThemeConfig } from '@shohojdhara/atomix/theme/config';
79
- import { createTheme } from '@shohojdhara/atomix/theme';
80
-
81
- `;
82
- }
83
-
84
- /**
85
- * Generate configuration object
86
- */
87
- private generateConfigObject(): string {
88
- const isTS = this.options.format === 'typescript';
89
- const isJSON = this.options.format === 'json';
90
-
91
- let output = '';
92
-
93
- if (isTS) {
94
- output += 'const config: ThemeConfig = {\n';
95
- } else if (!isJSON) {
96
- output += 'const config = {\n';
97
- } else {
98
- output += '{\n';
99
- }
100
-
101
- // Themes
102
- output += ' themes: {\n';
103
-
104
- if (this.options.includeExamples) {
105
- output += this.generateExampleThemes();
106
- } else {
107
- if (this.options.includeComments && !isJSON) {
108
- output += ' // Add your themes here\n';
109
- }
110
- }
111
-
112
- output += ' },\n\n';
113
-
114
- // Build configuration
115
- if (this.options.includeBuild) {
116
- output += this.generateBuildConfig();
117
- }
118
-
119
- // Runtime configuration
120
- if (this.options.includeRuntime) {
121
- output += this.generateRuntimeConfig();
122
- }
123
-
124
- // Integration configuration
125
- output += this.generateIntegrationConfig();
126
-
127
- output += '};\n\n';
128
-
129
- return output;
130
- }
131
-
132
- /**
133
- * Generate example themes
134
- */
135
- private generateExampleThemes(): string {
136
- const isJSON = this.options.format === 'json';
137
- let output = '';
138
-
139
- if (this.options.includeComments && !isJSON) {
140
- output += ' // CSS Theme Example\n';
141
- }
142
-
143
- output += ` 'my-theme': {
144
- type: 'css',
145
- name: 'My Theme',
146
- description: 'A custom theme for my application',
147
- author: 'Your Name',
148
- version: '1.0.0',
149
- tags: ['custom', 'light'],
150
- supportsDarkMode: true,
151
- status: 'stable',
152
- color: '#7AFFD7',
153
- },\n\n`;
154
-
155
- if (this.options.includeComments && !isJSON) {
156
- output += ' // JS Theme Example\n';
157
- }
158
-
159
- if (this.options.format === 'typescript') {
160
- output += ` 'my-js-theme': {
161
- type: 'js',
162
- name: 'My JS Theme',
163
- description: 'A programmatically created theme',
164
- author: 'Your Name',
165
- version: '1.0.0',
166
- tags: ['custom', 'js'],
167
- status: 'experimental',
168
- createTheme: () => createTheme({
169
- name: 'My JS Theme',
170
- palette: {
171
- primary: { main: '#7AFFD7' },
172
- secondary: { main: '#FF5733' },
173
- },
174
- typography: {
175
- fontFamily: 'Inter, sans-serif',
176
- },
177
- }),
178
- },\n\n`;
179
- }
180
-
181
- return output;
182
- }
183
-
184
- /**
185
- * Generate build configuration
186
- */
187
- private generateBuildConfig(): string {
188
- const isJSON = this.options.format === 'json';
189
- let output = '';
190
-
191
- if (this.options.includeComments && !isJSON) {
192
- output += ' // Build configuration\n';
193
- }
194
-
195
- output += ` build: {
196
- output: {
197
- directory: 'themes',
198
- formats: {
199
- expanded: '.css',
200
- compressed: '.min.css',
201
- },
202
- },
203
- sass: {
204
- style: 'expanded',
205
- sourceMap: true,
206
- loadPaths: ['src'],
207
- },
208
- },
209
-
210
- `;
211
-
212
- return output;
213
- }
214
-
215
- /**
216
- * Generate runtime configuration
217
- */
218
- private generateRuntimeConfig(): string {
219
- const isJSON = this.options.format === 'json';
220
- let output = '';
221
-
222
- if (this.options.includeComments && !isJSON) {
223
- output += ' // Runtime configuration\n';
224
- }
225
-
226
- output += ` runtime: {
227
- basePath: '/themes',
228
- cdnPath: null,
229
- preload: ['my-theme'],
230
- lazy: true,
231
- defaultTheme: 'my-theme',
232
- storageKey: 'atomix-theme',
233
- dataAttribute: 'data-theme',
234
- enablePersistence: true,
235
- useMinified: process.env.NODE_ENV === 'production',
236
- },
237
-
238
- `;
239
-
240
- return output;
241
- }
242
-
243
- /**
244
- * Generate integration configuration
245
- */
246
- private generateIntegrationConfig(): string {
247
- const isJSON = this.options.format === 'json';
248
- let output = '';
249
-
250
- if (this.options.includeComments && !isJSON) {
251
- output += ' // Integration configuration\n';
252
- }
253
-
254
- output += ` integration: {
255
- cssVariables: {
256
- colorMode: '--color-mode',
257
- },
258
- classNames: {
259
- theme: 'data-theme',
260
- colorMode: 'data-color-mode',
261
- },
262
- },
263
-
264
- `;
265
-
266
- return output;
267
- }
268
-
269
- /**
270
- * Generate TypeScript export
271
- */
272
- private generateTypeScriptExport(): string {
273
- return `export default config;
274
- `;
275
- }
276
- }
277
-
278
- /**
279
- * Generate configuration template
280
- *
281
- * @param options - Generation options
282
- * @returns Configuration template string
283
- */
284
- export function generateConfigTemplate(options: ConfigGeneratorOptions = {}): string {
285
- const generator = new ConfigGenerator(options);
286
- return generator.generate();
287
- }