@shohojdhara/atomix 0.3.1 → 0.3.2

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 (90) hide show
  1. package/CHANGELOG.md +0 -1
  2. package/README.md +3 -5
  3. package/dist/atomix.css +458 -552
  4. package/dist/atomix.min.css +3 -3
  5. package/dist/index.d.ts +2435 -358
  6. package/dist/index.esm.js +5758 -1901
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +5768 -1933
  9. package/dist/index.js.map +1 -1
  10. package/dist/index.min.js +1 -1
  11. package/dist/index.min.js.map +1 -1
  12. package/package.json +1 -11
  13. package/src/lib/composables/useAtomixGlass.ts +46 -46
  14. package/src/lib/index.ts +1 -4
  15. package/src/lib/theme/config/index.ts +21 -0
  16. package/src/lib/theme/config/loader.ts +276 -0
  17. package/src/lib/theme/config/types.ts +98 -0
  18. package/src/lib/theme/config/validator.ts +326 -0
  19. package/src/lib/theme/constants.ts +183 -0
  20. package/src/lib/theme/core/ThemeCache.ts +283 -0
  21. package/src/lib/theme/core/ThemeEngine.test.ts +146 -0
  22. package/src/lib/theme/core/ThemeEngine.ts +657 -0
  23. package/src/lib/theme/core/ThemeRegistry.ts +284 -0
  24. package/src/lib/theme/core/ThemeValidator.ts +530 -0
  25. package/src/lib/theme/core/index.ts +24 -0
  26. package/src/lib/theme/createTheme.ts +81 -70
  27. package/src/lib/theme/devtools/CLI.ts +279 -0
  28. package/src/lib/theme/devtools/Inspector.tsx +594 -0
  29. package/src/lib/theme/devtools/Preview.tsx +392 -0
  30. package/src/lib/theme/devtools/index.ts +21 -0
  31. package/src/lib/theme/errors.test.ts +207 -0
  32. package/src/lib/theme/errors.ts +233 -0
  33. package/src/lib/theme/generateCSSVariables.ts +93 -9
  34. package/src/lib/theme/generators/CSSGenerator.ts +311 -0
  35. package/src/lib/theme/generators/ConfigGenerator.ts +287 -0
  36. package/src/lib/theme/generators/TypeGenerator.ts +228 -0
  37. package/src/lib/theme/generators/index.ts +21 -0
  38. package/src/lib/theme/i18n/index.ts +9 -0
  39. package/src/lib/theme/i18n/rtl.ts +325 -0
  40. package/src/lib/theme/index.ts +155 -11
  41. package/src/lib/theme/monitoring/ThemeAnalytics.ts +409 -0
  42. package/src/lib/theme/monitoring/index.ts +17 -0
  43. package/src/lib/theme/overrides/ComponentOverrides.ts +243 -0
  44. package/src/lib/theme/overrides/index.ts +15 -0
  45. package/src/lib/theme/runtime/ThemeErrorBoundary.tsx +233 -0
  46. package/src/lib/theme/runtime/ThemeManager.test.ts +176 -0
  47. package/src/lib/theme/runtime/ThemeManager.ts +442 -0
  48. package/src/lib/theme/runtime/ThemeProvider.tsx +318 -0
  49. package/src/lib/theme/runtime/index.ts +17 -0
  50. package/src/lib/theme/runtime/useTheme.ts +52 -0
  51. package/src/lib/theme/studio/ThemeStudio.tsx +312 -0
  52. package/src/lib/theme/studio/index.ts +8 -0
  53. package/src/lib/theme/types.ts +3 -1
  54. package/src/lib/theme/utils.ts +23 -22
  55. package/src/lib/theme/whitelabel/WhiteLabelManager.ts +364 -0
  56. package/src/lib/theme/whitelabel/index.ts +13 -0
  57. package/src/styles/01-settings/_settings.badge.scss +1 -1
  58. package/src/styles/01-settings/_settings.callout.scss +1 -1
  59. package/src/styles/01-settings/_settings.card.scss +1 -1
  60. package/src/styles/01-settings/_settings.input.scss +1 -1
  61. package/src/styles/01-settings/_settings.navbar.scss +1 -1
  62. package/src/styles/01-settings/_settings.upload.scss +1 -1
  63. package/src/styles/06-components/_components.chart.scss +2 -2
  64. package/src/styles/99-utilities/_utilities.border.scss +27 -58
  65. package/src/styles/99-utilities/_utilities.gradient.scss +12 -0
  66. package/src/styles/99-utilities/_utilities.position.scss +8 -15
  67. package/src/styles/99-utilities/_utilities.scss +2 -0
  68. package/src/styles/99-utilities/_utilities.spacing.scss +76 -121
  69. package/src/styles/99-utilities/_utilities.text.scss +30 -49
  70. package/dist/themes/applemix.css +0 -15615
  71. package/dist/themes/applemix.min.css +0 -70
  72. package/dist/themes/boomdevs.css +0 -15193
  73. package/dist/themes/boomdevs.min.css +0 -403
  74. package/dist/themes/esrar.css +0 -17399
  75. package/dist/themes/esrar.min.css +0 -187
  76. package/dist/themes/flashtrade.css +0 -16613
  77. package/dist/themes/flashtrade.min.css +0 -190
  78. package/dist/themes/mashroom.css +0 -30104
  79. package/dist/themes/mashroom.min.css +0 -401
  80. package/dist/themes/shaj-default.css +0 -16228
  81. package/dist/themes/shaj-default.min.css +0 -498
  82. package/src/lib/theme/ThemeManager.integration.test.ts +0 -124
  83. package/src/lib/theme/ThemeManager.stories.tsx +0 -472
  84. package/src/lib/theme/ThemeManager.test.ts +0 -190
  85. package/src/lib/theme/ThemeManager.ts +0 -645
  86. package/src/lib/theme/ThemeProvider.tsx +0 -377
  87. package/src/lib/theme/createTheme.test.ts +0 -475
  88. package/src/lib/theme/useTheme.test.tsx +0 -67
  89. package/src/lib/theme/useTheme.ts +0 -64
  90. package/src/lib/theme/utils.test.ts +0 -140
@@ -39,116 +39,119 @@ import type {
39
39
 
40
40
  const DEFAULT_PALETTE: Theme['palette'] = {
41
41
  primary: {
42
- main: '#7AFFD7',
43
- light: '#A3FFE5',
44
- dark: '#00E6C3',
45
- contrastText: '#000000',
42
+ main: '#7c3aed', // Primary-6
43
+ light: '#d0b2f5', // Primary-3
44
+ dark: '#3c1583', // Primary-9
45
+ contrastText: '#ffffff',
46
46
  },
47
47
  secondary: {
48
- main: '#FF5733',
49
- light: '#FF8A65',
50
- dark: '#C62828',
51
- contrastText: '#FFFFFF',
48
+ main: '#f3f4f6', // Gray-2
49
+ light: '#ffffff', // Gray-1
50
+ dark: '#e5e7eb', // Gray-3
51
+ contrastText: '#1f2937', // Gray-9
52
52
  },
53
53
  error: {
54
- main: '#F44336',
55
- light: '#E57373',
56
- dark: '#D32F2F',
57
- contrastText: '#FFFFFF',
54
+ main: '#ef4444', // Red-6
55
+ light: '#fca5a5', // Red-4
56
+ dark: '#991b1b', // Red-9
57
+ contrastText: '#ffffff',
58
58
  },
59
59
  warning: {
60
- main: '#FF9800',
61
- light: '#FFB74D',
62
- dark: '#F57C00',
60
+ main: '#eab308', // Yellow-6
61
+ light: '#fde047', // Yellow-4
62
+ dark: '#854d0e', // Yellow-9
63
63
  contrastText: '#000000',
64
64
  },
65
65
  info: {
66
- main: '#2196F3',
67
- light: '#64B5F6',
68
- dark: '#1976D2',
69
- contrastText: '#FFFFFF',
66
+ main: '#3b82f6', // Blue-6
67
+ light: '#93c5fd', // Blue-4
68
+ dark: '#1e40af', // Blue-9
69
+ contrastText: '#ffffff',
70
70
  },
71
71
  success: {
72
- main: '#4CAF50',
73
- light: '#81C784',
74
- dark: '#388E3C',
75
- contrastText: '#FFFFFF',
72
+ main: '#22c55e', // Green-6
73
+ light: '#86efac', // Green-4
74
+ dark: '#166534', // Green-9
75
+ contrastText: '#ffffff',
76
76
  },
77
77
  background: {
78
- default: '#FFFFFF',
79
- paper: '#F5F5F5',
80
- subtle: '#FAFAFA',
78
+ default: '#ffffff', // Primary-bg
79
+ paper: '#f3f4f6', // Secondary-bg
80
+ subtle: '#d1d5db', // Gray-4 (Tertiary-bg)
81
81
  },
82
82
  text: {
83
- primary: 'rgba(0, 0, 0, 0.87)',
84
- secondary: 'rgba(0, 0, 0, 0.6)',
85
- disabled: 'rgba(0, 0, 0, 0.38)',
83
+ primary: '#111827', // Gray-10
84
+ secondary: '#374151', // Gray-8
85
+ disabled: '#9ca3af', // Gray-5
86
86
  },
87
87
  };
88
88
 
89
89
  const DEFAULT_TYPOGRAPHY: Theme['typography'] = {
90
- fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
91
- fontSize: 14,
90
+ fontFamily: '"Roboto", "Helvetica Neue", "Helvetica", "Arial", sans-serif',
91
+ fontSize: 16, // 1rem
92
92
  fontWeightLight: 300,
93
93
  fontWeightRegular: 400,
94
94
  fontWeightMedium: 500,
95
95
  fontWeightSemiBold: 600,
96
96
  fontWeightBold: 700,
97
+ fontWeightHeavy: 800,
98
+ fontWeightBlack: 900,
97
99
  h1: {
98
- fontSize: '2.5rem',
100
+ fontSize: '2.5rem', // 40px
99
101
  fontWeight: 700,
100
- lineHeight: 1.2,
101
- letterSpacing: '-0.01562em',
102
+ lineHeight: 1.3,
103
+ letterSpacing: '-1px',
102
104
  },
103
105
  h2: {
104
- fontSize: '2rem',
106
+ fontSize: '2rem', // 32px
105
107
  fontWeight: 700,
106
108
  lineHeight: 1.3,
107
- letterSpacing: '-0.00833em',
109
+ letterSpacing: '-1px',
108
110
  },
109
111
  h3: {
110
- fontSize: '1.75rem',
111
- fontWeight: 600,
112
- lineHeight: 1.4,
113
- letterSpacing: '0em',
112
+ fontSize: '1.5rem', // 24px
113
+ fontWeight: 700,
114
+ lineHeight: 1.3,
115
+ letterSpacing: '-1px',
114
116
  },
115
117
  h4: {
116
- fontSize: '1.5rem',
117
- fontWeight: 600,
118
- lineHeight: 1.4,
119
- letterSpacing: '0.00735em',
118
+ fontSize: '1.25rem', // 20px
119
+ fontWeight: 700,
120
+ lineHeight: 1.3,
121
+ letterSpacing: '-0.5px',
120
122
  },
121
123
  h5: {
122
- fontSize: '1.25rem',
123
- fontWeight: 600,
124
- lineHeight: 1.5,
125
- letterSpacing: '0em',
124
+ fontSize: '1.125rem', // 18px
125
+ fontWeight: 700,
126
+ lineHeight: 1.3,
127
+ letterSpacing: '-0.5px',
126
128
  },
127
129
  h6: {
128
- fontSize: '1rem',
129
- fontWeight: 600,
130
- lineHeight: 1.6,
131
- letterSpacing: '0.0075em',
130
+ fontSize: '1rem', // 16px
131
+ fontWeight: 700,
132
+ lineHeight: 1.3,
133
+ letterSpacing: '-0.5px',
132
134
  },
133
135
  body1: {
134
- fontSize: '1rem',
136
+ fontSize: '1rem', // 16px
135
137
  fontWeight: 400,
136
- lineHeight: 1.5,
138
+ lineHeight: 1.2,
137
139
  },
138
140
  body2: {
139
- fontSize: '0.875rem',
141
+ fontSize: '0.875rem', // 14px
140
142
  fontWeight: 400,
141
- lineHeight: 1.43,
143
+ lineHeight: 1.2,
142
144
  },
143
145
  };
144
146
 
145
147
  const DEFAULT_BREAKPOINTS: Theme['breakpoints'] = {
146
148
  values: {
147
149
  xs: 0,
148
- sm: 600,
149
- md: 960,
150
- lg: 1280,
151
- xl: 1920,
150
+ sm: 576,
151
+ md: 768,
152
+ lg: 992,
153
+ xl: 1200,
154
+ xxl: 1440,
152
155
  },
153
156
  unit: 'px',
154
157
  up: (key) => {
@@ -167,12 +170,12 @@ const DEFAULT_BREAKPOINTS: Theme['breakpoints'] = {
167
170
  };
168
171
 
169
172
  const DEFAULT_SHADOWS: Theme['shadows'] = {
170
- xs: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
171
- sm: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
172
- md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
173
- lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)',
174
- xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)',
175
- inset: 'inset 0 1px 3px 0 rgba(0, 0, 0, 0.1), inset 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
173
+ xs: '0px 1px 2px 0px rgba(45, 54, 67, 0.04), 0px 2px 4px 0px rgba(45, 54, 67, 0.08)',
174
+ sm: '0 2px 4px rgba(0, 0, 0, 0.075)',
175
+ md: '0 4px 8px rgba(0, 0, 0, 0.1)',
176
+ lg: '0 16px 48px rgba(0, 0, 0, 0.175)',
177
+ xl: '0px 16px 64px -8px rgba(45, 54, 67, 0.14)',
178
+ inset: 'inset 0 1px 2px rgba(0, 0, 0, 0.075)',
176
179
  };
177
180
 
178
181
  const DEFAULT_TRANSITIONS: Theme['transitions'] = {
@@ -381,10 +384,11 @@ function createSpacing(spacingInput: SpacingOptions = 4): SpacingFunction {
381
384
  function createBreakpoints(breakpointsInput?: BreakpointsOptions): Theme['breakpoints'] {
382
385
  const values = {
383
386
  xs: 0,
384
- sm: 600,
385
- md: 960,
386
- lg: 1280,
387
- xl: 1920,
387
+ sm: 576,
388
+ md: 768,
389
+ lg: 992,
390
+ xl: 1200,
391
+ xxl: 1440,
388
392
  ...breakpointsInput?.values,
389
393
  };
390
394
 
@@ -431,6 +435,13 @@ export function createTheme(...options: ThemeOptions[]): Theme {
431
435
  warning: createPaletteColor(mergedOptions.palette?.warning || DEFAULT_PALETTE.warning),
432
436
  info: createPaletteColor(mergedOptions.palette?.info || DEFAULT_PALETTE.info),
433
437
  success: createPaletteColor(mergedOptions.palette?.success || DEFAULT_PALETTE.success),
438
+ // Handle light and dark colors if provided
439
+ ...(mergedOptions.palette?.light && {
440
+ light: createPaletteColor(mergedOptions.palette.light),
441
+ }),
442
+ ...(mergedOptions.palette?.dark && {
443
+ dark: createPaletteColor(mergedOptions.palette.dark),
444
+ }),
434
445
  background: {
435
446
  default: mergedOptions.palette?.background?.default || DEFAULT_PALETTE.background.default,
436
447
  paper: mergedOptions.palette?.background?.paper || DEFAULT_PALETTE.background.paper,
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Theme CLI
3
+ *
4
+ * Command-line interface for theme management
5
+ */
6
+
7
+ import { generateConfigTemplate } from '../generators/ConfigGenerator';
8
+ import { generateCSS } from '../generators/CSSGenerator';
9
+ import { generateTypes } from '../generators/TypeGenerator';
10
+ import { loadThemeConfig } from '../config/loader';
11
+ import { validateConfig } from '../config/validator';
12
+
13
+ /**
14
+ * CLI command interface
15
+ */
16
+ export interface CLICommand {
17
+ name: string;
18
+ description: string;
19
+ options?: Record<string, string>;
20
+ handler: (args: string[], options: Record<string, any>) => Promise<void> | void;
21
+ }
22
+
23
+ /**
24
+ * Theme CLI
25
+ *
26
+ * Command-line interface for theme operations
27
+ */
28
+ export class ThemeCLI {
29
+ private commands: Map<string, CLICommand> = new Map();
30
+
31
+ constructor() {
32
+ this.registerDefaultCommands();
33
+ }
34
+
35
+ /**
36
+ * Register default commands
37
+ */
38
+ private registerDefaultCommands(): void {
39
+ this.register({
40
+ name: 'init',
41
+ description: 'Initialize theme configuration',
42
+ options: {
43
+ '--format': 'Output format (typescript, javascript, json)',
44
+ '--examples': 'Include example themes',
45
+ },
46
+ handler: this.handleInit.bind(this),
47
+ });
48
+
49
+ this.register({
50
+ name: 'validate',
51
+ description: 'Validate theme configuration',
52
+ handler: this.handleValidate.bind(this),
53
+ });
54
+
55
+ this.register({
56
+ name: 'build',
57
+ description: 'Build theme CSS files',
58
+ options: {
59
+ '--output': 'Output directory',
60
+ '--minify': 'Minify output',
61
+ },
62
+ handler: this.handleBuild.bind(this),
63
+ });
64
+
65
+ this.register({
66
+ name: 'types',
67
+ description: 'Generate TypeScript types',
68
+ options: {
69
+ '--output': 'Output file',
70
+ '--module': 'Module name',
71
+ },
72
+ handler: this.handleTypes.bind(this),
73
+ });
74
+
75
+ this.register({
76
+ name: 'help',
77
+ description: 'Show help information',
78
+ handler: this.handleHelp.bind(this),
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Register a command
84
+ */
85
+ register(command: CLICommand): void {
86
+ this.commands.set(command.name, command);
87
+ }
88
+
89
+ /**
90
+ * Run CLI with arguments
91
+ */
92
+ async run(args: string[]): Promise<void> {
93
+ const [commandName, ...commandArgs] = args;
94
+
95
+ if (!commandName) {
96
+ this.handleHelp([], {});
97
+ return;
98
+ }
99
+
100
+ const command = this.commands.get(commandName);
101
+ if (!command) {
102
+ console.error(`Unknown command: ${commandName}`);
103
+ console.error('Run "atomix-theme help" for available commands');
104
+ process.exit(1);
105
+ }
106
+
107
+ try {
108
+ const { args: parsedArgs, options } = this.parseArgs(commandArgs);
109
+ await command.handler(parsedArgs, options);
110
+ } catch (error) {
111
+ console.error(`Error running command "${commandName}":`, error);
112
+ process.exit(1);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Parse command arguments
118
+ */
119
+ private parseArgs(args: string[]): { args: string[]; options: Record<string, any> } {
120
+ const parsedArgs: string[] = [];
121
+ const options: Record<string, any> = {};
122
+
123
+ for (let i = 0; i < args.length; i++) {
124
+ const arg = args[i];
125
+ if (arg?.startsWith('--')) {
126
+ const key = arg.slice(2);
127
+ const nextArg = args[i + 1];
128
+ if (nextArg && !nextArg.startsWith('--')) {
129
+ options[key] = nextArg;
130
+ i++; // Skip next argument
131
+ } else {
132
+ options[key] = true;
133
+ }
134
+ } else if (arg) {
135
+ parsedArgs.push(arg);
136
+ }
137
+ }
138
+
139
+ return { args: parsedArgs, options };
140
+ }
141
+
142
+ /**
143
+ * Handle init command
144
+ */
145
+ private handleInit(args: string[], options: Record<string, any>): void {
146
+ const format = options.format || 'typescript';
147
+ const includeExamples = options.examples !== false;
148
+
149
+ const config = generateConfigTemplate({
150
+ format: format as any,
151
+ includeExamples,
152
+ includeComments: true,
153
+ });
154
+
155
+ const filename = format === 'json' ? 'theme.config.json' :
156
+ format === 'javascript' ? 'theme.config.js' :
157
+ 'theme.config.ts';
158
+
159
+ console.log(`Generating ${filename}...`);
160
+ console.log(config);
161
+ console.log(`\\nTheme configuration template generated!`);
162
+ console.log(`Save this content to ${filename} in your project root.`);
163
+ }
164
+
165
+ /**
166
+ * Handle validate command
167
+ */
168
+ private handleValidate(args: string[], options: Record<string, any>): void {
169
+ try {
170
+ const config = loadThemeConfig();
171
+ const result = validateConfig(config);
172
+
173
+ if (result.valid) {
174
+ console.log('✅ Theme configuration is valid');
175
+ if (result.warnings.length > 0) {
176
+ console.log('\\n⚠️ Warnings:');
177
+ result.warnings.forEach(warning => console.log(` - ${warning}`));
178
+ }
179
+ } else {
180
+ console.log('❌ Theme configuration is invalid');
181
+ console.log('\\nErrors:');
182
+ result.errors.forEach(error => console.log(` - ${error}`));
183
+
184
+ if (result.warnings.length > 0) {
185
+ console.log('\\nWarnings:');
186
+ result.warnings.forEach(warning => console.log(` - ${warning}`));
187
+ }
188
+ process.exit(1);
189
+ }
190
+ } catch (error) {
191
+ console.error('Failed to load theme configuration:', error);
192
+ process.exit(1);
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Handle build command
198
+ */
199
+ private handleBuild(args: string[], options: Record<string, any>): void {
200
+ console.log('Building themes...');
201
+ console.log('Note: This is a placeholder. Implement actual build logic based on your needs.');
202
+
203
+ try {
204
+ const config = loadThemeConfig();
205
+ console.log(`Found ${Object.keys(config.themes).length} themes to build`);
206
+
207
+ // This would typically:
208
+ // 1. Load each theme
209
+ // 2. Generate CSS for CSS themes
210
+ // 3. Execute createTheme for JS themes and generate CSS
211
+ // 4. Write files to output directory
212
+
213
+ console.log('✅ Build completed');
214
+ } catch (error) {
215
+ console.error('Build failed:', error);
216
+ process.exit(1);
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Handle types command
222
+ */
223
+ private handleTypes(args: string[], options: Record<string, any>): void {
224
+ console.log('Generating TypeScript types...');
225
+ console.log('Note: This is a placeholder. Implement actual type generation logic.');
226
+
227
+ try {
228
+ const config = loadThemeConfig();
229
+ const moduleName = options.module || 'CustomTheme';
230
+
231
+ // This would typically:
232
+ // 1. Load themes
233
+ // 2. Generate TypeScript definitions
234
+ // 3. Write to output file
235
+
236
+ console.log(`Generated types for module: ${moduleName}`);
237
+ console.log('✅ Type generation completed');
238
+ } catch (error) {
239
+ console.error('Type generation failed:', error);
240
+ process.exit(1);
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Handle help command
246
+ */
247
+ private handleHelp(args: string[], options: Record<string, any>): void {
248
+ console.log('Atomix Theme CLI\\n');
249
+ console.log('Usage: atomix-theme <command> [options]\\n');
250
+ console.log('Commands:');
251
+
252
+ for (const [name, command] of this.commands.entries()) {
253
+ console.log(` ${name.padEnd(12)} ${command.description}`);
254
+
255
+ if (command.options) {
256
+ for (const [option, description] of Object.entries(command.options)) {
257
+ console.log(` ${option.padEnd(16)} ${description}`);
258
+ }
259
+ }
260
+ console.log();
261
+ }
262
+ }
263
+ }
264
+
265
+ /**
266
+ * Create CLI instance
267
+ */
268
+ export function createCLI(): ThemeCLI {
269
+ return new ThemeCLI();
270
+ }
271
+
272
+ /**
273
+ * Run CLI with process arguments
274
+ */
275
+ export function runCLI(): void {
276
+ const cli = createCLI();
277
+ const args = process.argv.slice(2);
278
+ cli.run(args);
279
+ }