omgkit 2.30.0 → 2.32.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/README.md +60 -9
- package/lib/generators/css.generator.js +151 -0
- package/lib/generators/figma.generator.js +311 -0
- package/lib/generators/index.js +135 -0
- package/lib/generators/scss.generator.js +249 -0
- package/lib/generators/style-dictionary.generator.js +456 -0
- package/lib/generators/tailwind.generator.js +251 -0
- package/lib/theme-v2.js +755 -0
- package/lib/theme.js +97 -4
- package/package.json +2 -2
- package/plugin/commands/design/export.md +232 -0
- package/plugin/commands/design/rebuild.md +46 -0
- package/plugin/commands/design/validate.md +223 -0
- package/plugin/registry.yaml +2 -2
- package/templates/design/schema/theme-v2.schema.json +384 -0
- package/templates/design/themes/corporate-enterprise/consulting.json +457 -1
- package/templates/design/themes/corporate-enterprise/corporate-indigo.json +457 -1
- package/templates/design/themes/corporate-enterprise/finance.json +457 -1
- package/templates/design/themes/corporate-enterprise/healthcare.json +457 -1
- package/templates/design/themes/corporate-enterprise/legal.json +457 -1
- package/templates/design/themes/corporate-enterprise/ocean-blue.json +457 -1
- package/templates/design/themes/creative-bold/candy.json +457 -1
- package/templates/design/themes/creative-bold/coral-sunset.json +457 -1
- package/templates/design/themes/creative-bold/gradient-dream.json +457 -1
- package/templates/design/themes/creative-bold/neon.json +457 -1
- package/templates/design/themes/creative-bold/retro.json +457 -1
- package/templates/design/themes/creative-bold/studio.json +457 -1
- package/templates/design/themes/minimal-clean/minimal-slate.json +457 -1
- package/templates/design/themes/minimal-clean/mono.json +457 -1
- package/templates/design/themes/minimal-clean/nordic.json +457 -1
- package/templates/design/themes/minimal-clean/paper.json +457 -1
- package/templates/design/themes/minimal-clean/swiss.json +457 -1
- package/templates/design/themes/minimal-clean/zen.json +457 -1
- package/templates/design/themes/nature-organic/arctic.json +457 -1
- package/templates/design/themes/nature-organic/autumn.json +457 -1
- package/templates/design/themes/nature-organic/desert.json +457 -1
- package/templates/design/themes/nature-organic/forest.json +457 -1
- package/templates/design/themes/nature-organic/lavender.json +457 -1
- package/templates/design/themes/nature-organic/ocean.json +457 -1
- package/templates/design/themes/tech-ai/electric-cyan.json +459 -29
- package/templates/design/themes/tech-ai/hologram.json +457 -1
- package/templates/design/themes/tech-ai/matrix-green.json +457 -1
- package/templates/design/themes/tech-ai/neo-tokyo.json +457 -1
- package/templates/design/themes/tech-ai/neural-dark.json +457 -1
- package/templates/design/themes/tech-ai/quantum-purple.json +457 -1
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OMGKIT Theme Generator Factory
|
|
3
|
+
* Unified export interface for all theme formats
|
|
4
|
+
*
|
|
5
|
+
* @module lib/generators
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { generateCSS } from './css.generator.js';
|
|
9
|
+
import { generateSCSS } from './scss.generator.js';
|
|
10
|
+
import { generateTailwindV2 } from './tailwind.generator.js';
|
|
11
|
+
import { generateFigmaTokens } from './figma.generator.js';
|
|
12
|
+
import { generateStyleDictionary } from './style-dictionary.generator.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Available generator definitions
|
|
16
|
+
*/
|
|
17
|
+
export const GENERATORS = {
|
|
18
|
+
css: {
|
|
19
|
+
name: 'CSS',
|
|
20
|
+
description: 'CSS variables with @layer base',
|
|
21
|
+
fn: generateCSS,
|
|
22
|
+
ext: '.css',
|
|
23
|
+
mimeType: 'text/css'
|
|
24
|
+
},
|
|
25
|
+
scss: {
|
|
26
|
+
name: 'SCSS',
|
|
27
|
+
description: 'Sass variables and mixins',
|
|
28
|
+
fn: generateSCSS,
|
|
29
|
+
ext: '.scss',
|
|
30
|
+
mimeType: 'text/x-scss'
|
|
31
|
+
},
|
|
32
|
+
tailwind: {
|
|
33
|
+
name: 'Tailwind',
|
|
34
|
+
description: 'Tailwind CSS configuration',
|
|
35
|
+
fn: generateTailwindV2,
|
|
36
|
+
ext: '.js',
|
|
37
|
+
mimeType: 'application/javascript'
|
|
38
|
+
},
|
|
39
|
+
figma: {
|
|
40
|
+
name: 'Figma',
|
|
41
|
+
description: 'Figma design tokens',
|
|
42
|
+
fn: generateFigmaTokens,
|
|
43
|
+
ext: '.json',
|
|
44
|
+
mimeType: 'application/json'
|
|
45
|
+
},
|
|
46
|
+
'style-dictionary': {
|
|
47
|
+
name: 'Style Dictionary',
|
|
48
|
+
description: 'Style Dictionary design tokens',
|
|
49
|
+
fn: generateStyleDictionary,
|
|
50
|
+
ext: '.json',
|
|
51
|
+
mimeType: 'application/json'
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get list of available generator formats
|
|
57
|
+
* @returns {string[]} Array of format names
|
|
58
|
+
*/
|
|
59
|
+
export function getAvailableFormats() {
|
|
60
|
+
return Object.keys(GENERATORS);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get generator info by format
|
|
65
|
+
* @param {string} format - Generator format name
|
|
66
|
+
* @returns {Object|null} Generator info or null
|
|
67
|
+
*/
|
|
68
|
+
export function getGeneratorInfo(format) {
|
|
69
|
+
return GENERATORS[format] || null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Generate theme output in specified format
|
|
74
|
+
* @param {Object} theme - Theme object (v1 or v2)
|
|
75
|
+
* @param {string} format - Output format
|
|
76
|
+
* @param {Object} options - Generator-specific options
|
|
77
|
+
* @returns {string|Object} Generated output
|
|
78
|
+
* @throws {Error} If format is not supported
|
|
79
|
+
*/
|
|
80
|
+
export function generateTheme(theme, format, options = {}) {
|
|
81
|
+
const generator = GENERATORS[format];
|
|
82
|
+
|
|
83
|
+
if (!generator) {
|
|
84
|
+
const available = getAvailableFormats().join(', ');
|
|
85
|
+
throw new Error(`Unknown format: ${format}. Available: ${available}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return generator.fn(theme, options);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Generate theme in all available formats
|
|
93
|
+
* @param {Object} theme - Theme object (v1 or v2)
|
|
94
|
+
* @param {Object} options - Generator options
|
|
95
|
+
* @returns {Object} Map of format -> output
|
|
96
|
+
*/
|
|
97
|
+
export function generateAllFormats(theme, options = {}) {
|
|
98
|
+
const results = {};
|
|
99
|
+
|
|
100
|
+
for (const [format, generator] of Object.entries(GENERATORS)) {
|
|
101
|
+
try {
|
|
102
|
+
results[format] = {
|
|
103
|
+
content: generator.fn(theme, options),
|
|
104
|
+
ext: generator.ext,
|
|
105
|
+
mimeType: generator.mimeType,
|
|
106
|
+
success: true
|
|
107
|
+
};
|
|
108
|
+
} catch (error) {
|
|
109
|
+
results[format] = {
|
|
110
|
+
content: null,
|
|
111
|
+
ext: generator.ext,
|
|
112
|
+
error: error.message,
|
|
113
|
+
success: false
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return results;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Get file extension for format
|
|
123
|
+
* @param {string} format - Generator format
|
|
124
|
+
* @returns {string} File extension (with dot)
|
|
125
|
+
*/
|
|
126
|
+
export function getFormatExtension(format) {
|
|
127
|
+
return GENERATORS[format]?.ext || '.txt';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Re-export individual generators
|
|
131
|
+
export { generateCSS } from './css.generator.js';
|
|
132
|
+
export { generateSCSS } from './scss.generator.js';
|
|
133
|
+
export { generateTailwindV2 } from './tailwind.generator.js';
|
|
134
|
+
export { generateFigmaTokens } from './figma.generator.js';
|
|
135
|
+
export { generateStyleDictionary } from './style-dictionary.generator.js';
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SCSS Generator
|
|
3
|
+
* Generates Sass variables and mixins from theme
|
|
4
|
+
*
|
|
5
|
+
* @module lib/generators/scss
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { detectThemeVersion } from '../theme.js';
|
|
9
|
+
import { processTheme, processAnimations } from '../theme-v2.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Convert kebab-case to camelCase
|
|
13
|
+
* @param {string} str - Kebab-case string
|
|
14
|
+
* @returns {string} camelCase string
|
|
15
|
+
*/
|
|
16
|
+
function toCamelCase(str) {
|
|
17
|
+
return str.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Generate SCSS from theme
|
|
22
|
+
* @param {Object} theme - Theme object (v1 or v2)
|
|
23
|
+
* @param {Object} options - Generation options
|
|
24
|
+
* @param {boolean} options.useVariables - Use $variables (default: true)
|
|
25
|
+
* @param {boolean} options.useMaps - Generate Sass maps (default: true)
|
|
26
|
+
* @param {boolean} options.useMixins - Generate mixins (default: true)
|
|
27
|
+
* @param {string} options.prefix - Variable prefix (default: 'theme')
|
|
28
|
+
* @returns {string} SCSS content
|
|
29
|
+
*/
|
|
30
|
+
export function generateSCSS(theme, options = {}) {
|
|
31
|
+
const {
|
|
32
|
+
useVariables = true,
|
|
33
|
+
useMaps = true,
|
|
34
|
+
useMixins = true,
|
|
35
|
+
prefix = 'theme'
|
|
36
|
+
} = options;
|
|
37
|
+
|
|
38
|
+
const version = detectThemeVersion(theme);
|
|
39
|
+
const result = processTheme(theme);
|
|
40
|
+
const { light: lightVars, dark: darkVars } = result.variables;
|
|
41
|
+
|
|
42
|
+
let scss = `// OMGKIT Theme: ${theme.name}
|
|
43
|
+
// Theme ID: ${theme.id}
|
|
44
|
+
// Category: ${theme.category}
|
|
45
|
+
// Version: ${version}
|
|
46
|
+
// Generated by OMGKIT Design System
|
|
47
|
+
|
|
48
|
+
`;
|
|
49
|
+
|
|
50
|
+
// Font variables
|
|
51
|
+
const fontSans = theme.typography?.fontFamily?.sans ||
|
|
52
|
+
theme.fontFamily?.sans ||
|
|
53
|
+
'Inter, system-ui, sans-serif';
|
|
54
|
+
const fontMono = theme.typography?.fontFamily?.mono ||
|
|
55
|
+
theme.fontFamily?.mono ||
|
|
56
|
+
'JetBrains Mono, monospace';
|
|
57
|
+
const radius = theme.spacing?.radius || theme.radius || '0.5rem';
|
|
58
|
+
|
|
59
|
+
// Generate Sass variables
|
|
60
|
+
if (useVariables) {
|
|
61
|
+
scss += `// ============================================
|
|
62
|
+
// Sass Variables
|
|
63
|
+
// ============================================
|
|
64
|
+
|
|
65
|
+
// Typography
|
|
66
|
+
$${prefix}-font-sans: ${fontSans};
|
|
67
|
+
$${prefix}-font-mono: ${fontMono};
|
|
68
|
+
$${prefix}-radius: ${radius};
|
|
69
|
+
|
|
70
|
+
// Light Theme Variables
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
for (const [key, value] of Object.entries(lightVars)) {
|
|
74
|
+
const varName = toCamelCase(key);
|
|
75
|
+
scss += `$${prefix}-light-${varName}: ${value};\n`;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
scss += `
|
|
79
|
+
// Dark Theme Variables
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
for (const [key, value] of Object.entries(darkVars)) {
|
|
83
|
+
const varName = toCamelCase(key);
|
|
84
|
+
scss += `$${prefix}-dark-${varName}: ${value};\n`;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Generate Sass maps
|
|
89
|
+
if (useMaps) {
|
|
90
|
+
scss += `
|
|
91
|
+
// ============================================
|
|
92
|
+
// Sass Maps
|
|
93
|
+
// ============================================
|
|
94
|
+
|
|
95
|
+
$${prefix}-colors-light: (
|
|
96
|
+
`;
|
|
97
|
+
for (const [key, value] of Object.entries(lightVars)) {
|
|
98
|
+
scss += ` '${key}': ${value},\n`;
|
|
99
|
+
}
|
|
100
|
+
scss += `);\n`;
|
|
101
|
+
|
|
102
|
+
scss += `
|
|
103
|
+
$${prefix}-colors-dark: (
|
|
104
|
+
`;
|
|
105
|
+
for (const [key, value] of Object.entries(darkVars)) {
|
|
106
|
+
scss += ` '${key}': ${value},\n`;
|
|
107
|
+
}
|
|
108
|
+
scss += `);\n`;
|
|
109
|
+
|
|
110
|
+
// Semantic color map
|
|
111
|
+
scss += `
|
|
112
|
+
// Semantic tokens map (for programmatic access)
|
|
113
|
+
$${prefix}-semantic: (
|
|
114
|
+
'background': 'background',
|
|
115
|
+
'foreground': 'foreground',
|
|
116
|
+
'primary': 'primary',
|
|
117
|
+
'primary-foreground': 'primary-foreground',
|
|
118
|
+
'secondary': 'secondary',
|
|
119
|
+
'secondary-foreground': 'secondary-foreground',
|
|
120
|
+
'muted': 'muted',
|
|
121
|
+
'muted-foreground': 'muted-foreground',
|
|
122
|
+
'accent': 'accent',
|
|
123
|
+
'accent-foreground': 'accent-foreground',
|
|
124
|
+
'destructive': 'destructive',
|
|
125
|
+
'destructive-foreground': 'destructive-foreground',
|
|
126
|
+
'border': 'border',
|
|
127
|
+
'input': 'input',
|
|
128
|
+
'ring': 'ring',
|
|
129
|
+
'card': 'card',
|
|
130
|
+
'card-foreground': 'card-foreground',
|
|
131
|
+
'popover': 'popover',
|
|
132
|
+
'popover-foreground': 'popover-foreground',
|
|
133
|
+
);
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Generate mixins
|
|
138
|
+
if (useMixins) {
|
|
139
|
+
scss += `
|
|
140
|
+
// ============================================
|
|
141
|
+
// Mixins
|
|
142
|
+
// ============================================
|
|
143
|
+
|
|
144
|
+
/// Get a theme color value
|
|
145
|
+
/// @param {String} $color - Color name
|
|
146
|
+
/// @param {String} $mode - 'light' or 'dark'
|
|
147
|
+
/// @return {String} HSL value
|
|
148
|
+
@function ${prefix}-color($color, $mode: 'light') {
|
|
149
|
+
@if $mode == 'dark' {
|
|
150
|
+
@return map-get($${prefix}-colors-dark, $color);
|
|
151
|
+
}
|
|
152
|
+
@return map-get($${prefix}-colors-light, $color);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// Apply HSL color as CSS value
|
|
156
|
+
/// @param {String} $color - Color name
|
|
157
|
+
/// @return {Color} HSL color
|
|
158
|
+
@function ${prefix}-hsl($color) {
|
|
159
|
+
@return hsl(var(--#{$color}));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/// Apply theme-aware background color
|
|
163
|
+
@mixin ${prefix}-bg($color) {
|
|
164
|
+
background-color: hsl(var(--#{$color}));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/// Apply theme-aware text color
|
|
168
|
+
@mixin ${prefix}-text($color) {
|
|
169
|
+
color: hsl(var(--#{$color}));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// Apply theme-aware border color
|
|
173
|
+
@mixin ${prefix}-border($color: 'border') {
|
|
174
|
+
border-color: hsl(var(--#{$color}));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// Apply all CSS variables for light mode
|
|
178
|
+
@mixin ${prefix}-light-mode {
|
|
179
|
+
@each $name, $value in $${prefix}-colors-light {
|
|
180
|
+
--#{$name}: #{$value};
|
|
181
|
+
}
|
|
182
|
+
--radius: #{$${prefix}-radius};
|
|
183
|
+
--font-sans: #{$${prefix}-font-sans};
|
|
184
|
+
--font-mono: #{$${prefix}-font-mono};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/// Apply all CSS variables for dark mode
|
|
188
|
+
@mixin ${prefix}-dark-mode {
|
|
189
|
+
@each $name, $value in $${prefix}-colors-dark {
|
|
190
|
+
--#{$name}: #{$value};
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/// Root setup with CSS variables
|
|
195
|
+
@mixin ${prefix}-root {
|
|
196
|
+
:root {
|
|
197
|
+
@include ${prefix}-light-mode;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.dark {
|
|
201
|
+
@include ${prefix}-dark-mode;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/// Base styles
|
|
206
|
+
@mixin ${prefix}-base {
|
|
207
|
+
* {
|
|
208
|
+
border-color: hsl(var(--border));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
body {
|
|
212
|
+
background-color: hsl(var(--background));
|
|
213
|
+
color: hsl(var(--foreground));
|
|
214
|
+
font-family: var(--font-sans);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Add animation variables if present
|
|
221
|
+
if (theme.animations) {
|
|
222
|
+
const { animations } = processAnimations(theme.animations);
|
|
223
|
+
|
|
224
|
+
scss += `
|
|
225
|
+
// ============================================
|
|
226
|
+
// Animations
|
|
227
|
+
// ============================================
|
|
228
|
+
|
|
229
|
+
`;
|
|
230
|
+
for (const [name, value] of Object.entries(animations)) {
|
|
231
|
+
scss += `$${prefix}-animation-${name}: ${value};\n`;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return scss;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Generate SCSS partial (variables only, for @use)
|
|
240
|
+
* @param {Object} theme - Theme object
|
|
241
|
+
* @param {Object} options - Options
|
|
242
|
+
* @returns {string} SCSS partial content
|
|
243
|
+
*/
|
|
244
|
+
export function generateSCSSPartial(theme, options = {}) {
|
|
245
|
+
return generateSCSS(theme, {
|
|
246
|
+
...options,
|
|
247
|
+
useMixins: false
|
|
248
|
+
});
|
|
249
|
+
}
|