eva-css-fluid 1.0.4 ā 2.0.5
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/MIGRATION.md +337 -0
- package/README.md +441 -3
- package/cli.cjs +73 -0
- package/dist/eva.css +2133 -2093
- package/dist/eva.css.map +1 -1
- package/dist/eva.min.css +1 -1
- package/dist/eva.min.css.map +1 -1
- package/dist/test.css +5689 -0
- package/dist/test.css.map +1 -0
- package/eva.config.template.js +216 -0
- package/index.scss +9 -0
- package/package.json +85 -52
- package/scripts/build-with-config.cjs +169 -0
- package/src/_colors.scss +41 -6
- package/src/_config.scss +55 -0
- package/src/_eva.scss +84 -0
- package/src/cli-commands.cjs +539 -0
- package/src/colors-only.scss +16 -0
- package/src/config-loader.cjs +319 -0
- package/src/config-schema.cjs +455 -0
- package/src/core.scss +43 -0
- package/src/index.scss +5 -1
- package/src/variables.scss +33 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// ===========================================
|
|
2
|
+
// EVA CSS - Colors Only Entry Point
|
|
3
|
+
// ===========================================
|
|
4
|
+
// Use this when you only want the OKLCH
|
|
5
|
+
// color system without any other features
|
|
6
|
+
// ===========================================
|
|
7
|
+
|
|
8
|
+
// Import only the color system
|
|
9
|
+
@use '_colors';
|
|
10
|
+
|
|
11
|
+
// Import theme for dark/light mode support
|
|
12
|
+
@use '_theme';
|
|
13
|
+
|
|
14
|
+
// Result: Only color variables
|
|
15
|
+
// var(--brand), var(--accent), var(--light), var(--dark), etc.
|
|
16
|
+
// Perfect for integrating EVA colors into existing projects!
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EVA CSS Configuration Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration from eva.config.js or package.json
|
|
5
|
+
* Supports both CommonJS and ES Modules
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const {
|
|
11
|
+
validateConfig,
|
|
12
|
+
mergeWithDefaults,
|
|
13
|
+
normalizeConfig,
|
|
14
|
+
toScssVariables
|
|
15
|
+
} = require('./config-schema.cjs');
|
|
16
|
+
|
|
17
|
+
// Import eva-colors for HEX to OKLCH conversion
|
|
18
|
+
let hexToOklch;
|
|
19
|
+
try {
|
|
20
|
+
const evaColors = require('eva-colors');
|
|
21
|
+
hexToOklch = evaColors.hexToOklch;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
// Fallback if eva-colors is not installed
|
|
24
|
+
hexToOklch = null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Find configuration file in the current working directory
|
|
29
|
+
*
|
|
30
|
+
* Priority:
|
|
31
|
+
* 1. eva.config.js
|
|
32
|
+
* 2. eva.config.cjs
|
|
33
|
+
* 3. eva.config.mjs
|
|
34
|
+
* 4. package.json (under "eva" key)
|
|
35
|
+
*
|
|
36
|
+
* @param {string} cwd - Current working directory
|
|
37
|
+
* @returns {Object|null} { path: string, source: string, type: string } or null
|
|
38
|
+
*/
|
|
39
|
+
function findConfigFile(cwd = process.cwd()) {
|
|
40
|
+
const configFiles = [
|
|
41
|
+
{ name: 'eva.config.js', type: 'module' },
|
|
42
|
+
{ name: 'eva.config.cjs', type: 'commonjs' },
|
|
43
|
+
{ name: 'eva.config.mjs', type: 'module' },
|
|
44
|
+
{ name: 'package.json', type: 'package' }
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
for (const { name, type } of configFiles) {
|
|
48
|
+
const filePath = path.join(cwd, name);
|
|
49
|
+
if (fs.existsSync(filePath)) {
|
|
50
|
+
return {
|
|
51
|
+
path: filePath,
|
|
52
|
+
source: name,
|
|
53
|
+
type
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Load configuration from a file (CommonJS)
|
|
63
|
+
*
|
|
64
|
+
* @param {string} filePath - Path to config file
|
|
65
|
+
* @param {string} source - Source file name
|
|
66
|
+
* @returns {Object} Configuration object
|
|
67
|
+
*/
|
|
68
|
+
function loadConfigFromFile(filePath, source) {
|
|
69
|
+
try {
|
|
70
|
+
// Clear require cache to ensure fresh load
|
|
71
|
+
delete require.cache[require.resolve(filePath)];
|
|
72
|
+
|
|
73
|
+
if (source === 'package.json') {
|
|
74
|
+
const packageJson = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
75
|
+
if (!packageJson.eva) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return normalizeConfig(packageJson.eva);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// For .js, .cjs, .mjs files
|
|
82
|
+
const config = require(filePath);
|
|
83
|
+
|
|
84
|
+
// Handle ES module default export
|
|
85
|
+
const rawConfig = config.default || config;
|
|
86
|
+
|
|
87
|
+
return normalizeConfig(rawConfig);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error.code === 'MODULE_NOT_FOUND') {
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Failed to load config from ${source}: Missing dependencies. ` +
|
|
92
|
+
`Run 'npm install' to install required packages.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (error instanceof SyntaxError) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`Failed to parse config from ${source}: ${error.message}\n` +
|
|
99
|
+
`Check for syntax errors in your configuration file.`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
throw new Error(`Failed to load config from ${source}: ${error.message}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Normalize theme colors - Convert HEX to OKLCH if needed
|
|
109
|
+
*
|
|
110
|
+
* @param {Object} theme - Theme configuration
|
|
111
|
+
* @returns {Object} Theme with normalized colors
|
|
112
|
+
*/
|
|
113
|
+
function normalizeThemeColors(theme) {
|
|
114
|
+
if (!theme || !theme.colors) return theme;
|
|
115
|
+
|
|
116
|
+
const normalized = { ...theme };
|
|
117
|
+
normalized.colors = {};
|
|
118
|
+
|
|
119
|
+
for (const [colorName, colorValue] of Object.entries(theme.colors)) {
|
|
120
|
+
if (typeof colorValue === 'string') {
|
|
121
|
+
// HEX color - convert to OKLCH
|
|
122
|
+
if (!hexToOklch) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
'eva-colors package is required to convert HEX colors to OKLCH. ' +
|
|
125
|
+
'Run: npm install eva-colors'
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const oklch = hexToOklch(colorValue);
|
|
130
|
+
if (!oklch) {
|
|
131
|
+
throw new Error(`Invalid HEX color "${colorValue}" for theme.colors.${colorName}`);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
normalized.colors[colorName] = {
|
|
135
|
+
lightness: oklch.l,
|
|
136
|
+
chroma: oklch.c,
|
|
137
|
+
hue: oklch.h
|
|
138
|
+
};
|
|
139
|
+
} else if (typeof colorValue === 'object') {
|
|
140
|
+
// Already in OKLCH format
|
|
141
|
+
normalized.colors[colorName] = colorValue;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return normalized;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Load and validate EVA CSS configuration
|
|
150
|
+
*
|
|
151
|
+
* @param {Object} options - Options
|
|
152
|
+
* @param {string} options.cwd - Current working directory
|
|
153
|
+
* @param {boolean} options.silent - Suppress console output
|
|
154
|
+
* @returns {Object|null} Validated and merged configuration, or null if no config found
|
|
155
|
+
*/
|
|
156
|
+
function loadConfig(options = {}) {
|
|
157
|
+
const { cwd = process.cwd(), silent = false } = options;
|
|
158
|
+
|
|
159
|
+
// Find config file
|
|
160
|
+
const configFile = findConfigFile(cwd);
|
|
161
|
+
|
|
162
|
+
if (!configFile) {
|
|
163
|
+
if (!silent) {
|
|
164
|
+
console.log('ā¹ļø No EVA CSS config file found, using SCSS variables');
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!silent) {
|
|
170
|
+
console.log(`š Loading EVA CSS config from ${configFile.source}...`);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Load config
|
|
174
|
+
const userConfig = loadConfigFromFile(configFile.path, configFile.source);
|
|
175
|
+
|
|
176
|
+
if (!userConfig) {
|
|
177
|
+
if (!silent) {
|
|
178
|
+
console.log('ā¹ļø No EVA CSS config found in package.json');
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Normalize theme colors (HEX ā OKLCH)
|
|
184
|
+
if (userConfig.theme && userConfig.theme.colors) {
|
|
185
|
+
try {
|
|
186
|
+
userConfig.theme = normalizeThemeColors(userConfig.theme);
|
|
187
|
+
if (!silent) {
|
|
188
|
+
const hexColors = Object.entries(userConfig.theme.colors).filter(([_, v]) =>
|
|
189
|
+
typeof v === 'object' && v.lightness !== undefined
|
|
190
|
+
);
|
|
191
|
+
if (hexColors.length > 0) {
|
|
192
|
+
console.log(`šØ Converted ${hexColors.length} HEX colors to OKLCH`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} catch (error) {
|
|
196
|
+
throw new Error(`Theme color conversion failed: ${error.message}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Validate config
|
|
201
|
+
const validatedConfig = validateConfig(userConfig, configFile.source);
|
|
202
|
+
|
|
203
|
+
// Merge with defaults
|
|
204
|
+
const finalConfig = mergeWithDefaults(validatedConfig);
|
|
205
|
+
|
|
206
|
+
if (!silent) {
|
|
207
|
+
console.log('ā
Configuration loaded and validated successfully');
|
|
208
|
+
if (finalConfig.debug) {
|
|
209
|
+
console.log('\nš Configuration:');
|
|
210
|
+
console.log(` Sizes: ${finalConfig.sizes.join(', ')}`);
|
|
211
|
+
console.log(` Font sizes: ${finalConfig.fontSizes.join(', ')}`);
|
|
212
|
+
console.log(` Build classes: ${finalConfig.buildClass}`);
|
|
213
|
+
console.log(` Custom class mode: ${finalConfig.customClass}`);
|
|
214
|
+
console.log('');
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
config: finalConfig,
|
|
220
|
+
source: configFile.source,
|
|
221
|
+
path: configFile.path
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Generate SCSS file from config
|
|
227
|
+
*
|
|
228
|
+
* @param {Object} config - Configuration object
|
|
229
|
+
* @param {string} outputPath - Path to output SCSS file
|
|
230
|
+
*/
|
|
231
|
+
function generateScssConfig(config, outputPath) {
|
|
232
|
+
const scssContent = [
|
|
233
|
+
'// AUTO-GENERATED FROM eva.config.js or package.json',
|
|
234
|
+
'// Do not edit this file directly - it will be overwritten',
|
|
235
|
+
'// Edit your eva.config.js or package.json instead',
|
|
236
|
+
'',
|
|
237
|
+
toScssVariables(config),
|
|
238
|
+
''
|
|
239
|
+
].join('\n');
|
|
240
|
+
|
|
241
|
+
fs.writeFileSync(outputPath, scssContent, 'utf8');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* CLI command to validate configuration
|
|
246
|
+
*/
|
|
247
|
+
function validateConfigCommand() {
|
|
248
|
+
try {
|
|
249
|
+
console.log('š Validating EVA CSS configuration...\n');
|
|
250
|
+
|
|
251
|
+
const result = loadConfig({ silent: false });
|
|
252
|
+
|
|
253
|
+
if (!result) {
|
|
254
|
+
console.log('\nā ļø No configuration file found');
|
|
255
|
+
console.log(' Create eva.config.js or add "eva" key to package.json');
|
|
256
|
+
console.log(' See: https://eva-css.xyz/configuration\n');
|
|
257
|
+
process.exit(0);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log('\nā
Configuration is valid!\n');
|
|
261
|
+
console.log('Configuration summary:');
|
|
262
|
+
console.log(` Source: ${result.source}`);
|
|
263
|
+
console.log(` Sizes: ${result.config.sizes.length} values`);
|
|
264
|
+
console.log(` Font sizes: ${result.config.fontSizes.length} values`);
|
|
265
|
+
console.log(` Build mode: ${result.config.buildClass ? 'utility classes' : 'variables only'}`);
|
|
266
|
+
|
|
267
|
+
if (result.config.customClass && Object.keys(result.config.classConfig).length > 0) {
|
|
268
|
+
console.log(` Custom classes: ${Object.keys(result.config.classConfig).length} properties configured`);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (result.config.purge && result.config.purge.enabled) {
|
|
272
|
+
console.log(` Purge: enabled`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
console.log('');
|
|
276
|
+
process.exit(0);
|
|
277
|
+
} catch (error) {
|
|
278
|
+
console.error(`\nā ${error.message}\n`);
|
|
279
|
+
process.exit(1);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* CLI command to generate SCSS from config
|
|
285
|
+
*/
|
|
286
|
+
function generateScssCommand(outputPath = 'src/_config-generated.scss') {
|
|
287
|
+
try {
|
|
288
|
+
console.log('š§ Generating SCSS configuration...\n');
|
|
289
|
+
|
|
290
|
+
const result = loadConfig({ silent: false });
|
|
291
|
+
|
|
292
|
+
if (!result) {
|
|
293
|
+
console.log('\nā ļø No configuration file found');
|
|
294
|
+
console.log(' Using default SCSS variables instead\n');
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const fullOutputPath = path.resolve(process.cwd(), outputPath);
|
|
299
|
+
generateScssConfig(result.config, fullOutputPath);
|
|
300
|
+
|
|
301
|
+
console.log(`\nā
SCSS configuration generated: ${fullOutputPath}\n`);
|
|
302
|
+
console.log('You can now import this in your SCSS:');
|
|
303
|
+
console.log(` @use '${outputPath}';`);
|
|
304
|
+
console.log('');
|
|
305
|
+
|
|
306
|
+
process.exit(0);
|
|
307
|
+
} catch (error) {
|
|
308
|
+
console.error(`\nā ${error.message}\n`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
module.exports = {
|
|
314
|
+
findConfigFile,
|
|
315
|
+
loadConfig,
|
|
316
|
+
generateScssConfig,
|
|
317
|
+
validateConfigCommand,
|
|
318
|
+
generateScssCommand
|
|
319
|
+
};
|