eva-css-fluid 2.0.0 ā 2.0.6
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 +442 -27
- package/cli.cjs +22 -6
- package/package.json +85 -85
- package/src/cli-commands.cjs +539 -0
package/README.md
CHANGED
|
@@ -64,6 +64,38 @@ yarn add eva-css-fluid
|
|
|
64
64
|
|
|
65
65
|
**Migrating from another framework?** See the [Migration Guide](./MIGRATION.md) for detailed instructions.
|
|
66
66
|
|
|
67
|
+
## š¦ Which Configuration Method Should I Use?
|
|
68
|
+
|
|
69
|
+
EVA CSS can be configured in two ways. **Choose based on your project needs:**
|
|
70
|
+
|
|
71
|
+
### For Quick Start / Learning
|
|
72
|
+
š **Use SCSS Variables** - Everything in one file, works immediately
|
|
73
|
+
|
|
74
|
+
### For Production Projects
|
|
75
|
+
Choose based on your needs:
|
|
76
|
+
|
|
77
|
+
| You want... | Use... |
|
|
78
|
+
|-------------|--------|
|
|
79
|
+
| Simplicity, no build scripts | **SCSS Variables** (`@use ... with ()`) |
|
|
80
|
+
| Centralized config, multiple SCSS files | **JSON Config** (requires custom build script) |
|
|
81
|
+
| Watch mode without complexity | **SCSS Variables** |
|
|
82
|
+
| Config validation, better DX | **JSON Config** (requires custom build script) |
|
|
83
|
+
|
|
84
|
+
š” **You can start with SCSS variables and migrate to JSON later - the generated CSS is identical!**
|
|
85
|
+
|
|
86
|
+
### Option Comparison
|
|
87
|
+
|
|
88
|
+
| Feature | SCSS Variables | JSON Config |
|
|
89
|
+
|---------|----------------|-------------|
|
|
90
|
+
| **Setup complexity** | ā Simple | āāā Requires script |
|
|
91
|
+
| **Works with `npx sass`** | ā
Yes, immediately | ā ļø No, needs custom script |
|
|
92
|
+
| **Config location** | Inside SCSS file | Separate `eva.config.cjs` |
|
|
93
|
+
| **Multiple SCSS files** | ā ļø Config duplicated | ā
Shared config |
|
|
94
|
+
| **Validation** | ā No | ā
`npx eva-css validate` |
|
|
95
|
+
| **Generated CSS** | ā
Identical output | ā
Identical output |
|
|
96
|
+
|
|
97
|
+
**See detailed workflows below** for implementation examples.
|
|
98
|
+
|
|
67
99
|
## š Quick Start
|
|
68
100
|
|
|
69
101
|
### New Project (Recommended)
|
|
@@ -120,9 +152,39 @@ npx sass --load-path=node_modules styles/main.scss:styles/main.css
|
|
|
120
152
|
|
|
121
153
|
### Using SCSS with Custom Configuration
|
|
122
154
|
|
|
123
|
-
**This is the main feature of EVA CSS!**
|
|
155
|
+
**This is the main feature of EVA CSS!** Extract sizes from your design and configure EVA to generate only what you need.
|
|
156
|
+
|
|
157
|
+
#### Option 1: SCSS Variables (Recommended for Beginners)
|
|
158
|
+
|
|
159
|
+
**Direct configuration in your SCSS file** - Works immediately with `npx sass`:
|
|
160
|
+
|
|
161
|
+
```scss
|
|
162
|
+
// Example: Sizes extracted from Figma design
|
|
163
|
+
@use 'eva-css-fluid' with (
|
|
164
|
+
$sizes: 4, 8, 16, 32, 64, 128, // š Change these to YOUR design sizes!
|
|
165
|
+
$font-sizes: 14, 16, 20, 24, 32, // š Change these to YOUR font sizes!
|
|
166
|
+
$build-class: true,
|
|
167
|
+
$px-rem-suffix: false
|
|
168
|
+
);
|
|
169
|
+
```
|
|
124
170
|
|
|
125
|
-
|
|
171
|
+
**Compile immediately:**
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
npx sass --load-path=node_modules styles/main.scss:styles/main.css
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
ā
**Advantages:**
|
|
178
|
+
- Works immediately with standard Sass compilation
|
|
179
|
+
- No additional build scripts needed
|
|
180
|
+
- Perfect for watch mode: `npx sass --watch ...`
|
|
181
|
+
- Great for learning and simple projects
|
|
182
|
+
|
|
183
|
+
ā ļø **Note:** If you import EVA in multiple SCSS files, you'll need to duplicate the configuration.
|
|
184
|
+
|
|
185
|
+
#### Option 2: JSON Configuration (Advanced - Requires Build Script)
|
|
186
|
+
|
|
187
|
+
**Centralized configuration file** - Better for complex projects with multiple SCSS files:
|
|
126
188
|
|
|
127
189
|
Create `eva.config.cjs` in your project root:
|
|
128
190
|
|
|
@@ -136,42 +198,72 @@ module.exports = {
|
|
|
136
198
|
};
|
|
137
199
|
```
|
|
138
200
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
```json
|
|
142
|
-
{
|
|
143
|
-
"eva": {
|
|
144
|
-
"sizes": [4, 8, 16, 32, 64, 128],
|
|
145
|
-
"fontSizes": [14, 16, 20, 24, 32],
|
|
146
|
-
"buildClass": true
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Then simply import EVA CSS:
|
|
201
|
+
Then in your SCSS:
|
|
152
202
|
|
|
153
203
|
```scss
|
|
154
204
|
@use 'eva-css-fluid';
|
|
155
205
|
```
|
|
156
206
|
|
|
157
|
-
|
|
207
|
+
ā ļø **IMPORTANT:** JSON configuration requires a **custom build script** to work. SCSS cannot execute JavaScript directly.
|
|
158
208
|
|
|
209
|
+
**You have two choices:**
|
|
210
|
+
|
|
211
|
+
**A) Use the EVA package's build script** (for building EVA itself):
|
|
159
212
|
```bash
|
|
213
|
+
# This is only for building the EVA CSS package itself, NOT for your project
|
|
214
|
+
cd node_modules/eva-css-fluid
|
|
160
215
|
npm run build
|
|
161
|
-
# Configuration is automatically loaded from eva.config.cjs or package.json
|
|
162
216
|
```
|
|
163
217
|
|
|
164
|
-
|
|
218
|
+
**B) Create your own build script** (recommended for user projects):
|
|
165
219
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
220
|
+
1. Copy the build script template:
|
|
221
|
+
```bash
|
|
222
|
+
# Create scripts directory if needed
|
|
223
|
+
mkdir -p scripts
|
|
224
|
+
|
|
225
|
+
# Copy the ready-to-use script from the monorepo examples
|
|
226
|
+
cp node_modules/eva-css-fluid/../../examples/user-scripts/build-with-config.js scripts/build-eva.js
|
|
227
|
+
|
|
228
|
+
# Or download directly from GitHub
|
|
229
|
+
curl -o scripts/build-eva.js https://raw.githubusercontent.com/nkdeus/eva-framework/main/examples/user-scripts/build-with-config.js
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
2. Add npm script to your `package.json`:
|
|
233
|
+
```json
|
|
234
|
+
{
|
|
235
|
+
"scripts": {
|
|
236
|
+
"build:css": "node scripts/build-eva.js styles/main.scss dist/main.css",
|
|
237
|
+
"watch:css": "nodemon --watch eva.config.cjs --watch styles/ --exec 'npm run build:css'"
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
3. Build your CSS:
|
|
243
|
+
```bash
|
|
244
|
+
npm run build:css
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**What the script does:**
|
|
248
|
+
- Reads your `eva.config.cjs` configuration
|
|
249
|
+
- Converts JSON config ā SCSS variables
|
|
250
|
+
- Compiles SCSS with the injected config
|
|
251
|
+
- Handles HEX ā OKLCH color conversion automatically
|
|
252
|
+
|
|
253
|
+
š **See [examples/user-scripts/README.md](../../examples/user-scripts/README.md) for detailed documentation**
|
|
254
|
+
|
|
255
|
+
ā
**Advantages:**
|
|
256
|
+
- Single config file shared across multiple SCSS files
|
|
257
|
+
- Config validation with `npx eva-css validate`
|
|
258
|
+
- Cleaner SCSS files
|
|
259
|
+
- Better for large projects
|
|
260
|
+
|
|
261
|
+
ā ļø **Disadvantages:**
|
|
262
|
+
- Requires custom build script setup
|
|
263
|
+
- More complex workflow
|
|
264
|
+
- Not compatible with standard `npx sass` command
|
|
265
|
+
|
|
266
|
+
š” **New to EVA CSS?** Start with **Option 1 (SCSS Variables)** and migrate to JSON config later if needed!
|
|
175
267
|
|
|
176
268
|
**Real example from a Figma project:**
|
|
177
269
|
|
|
@@ -189,6 +281,60 @@ npm run build
|
|
|
189
281
|
// var(--4), var(--8), var(--16), var(--32), var(--64), var(--120), var(--141)
|
|
190
282
|
```
|
|
191
283
|
|
|
284
|
+
## ā FAQ - Configuration
|
|
285
|
+
|
|
286
|
+
### Q: Why doesn't `@use 'eva-css-fluid'` automatically load `eva.config.cjs`?
|
|
287
|
+
|
|
288
|
+
**A:** SCSS cannot execute JavaScript during compilation. The `eva.config.cjs` file must be read **before** SCSS compilation and transformed into SCSS variables.
|
|
289
|
+
|
|
290
|
+
**Solutions:**
|
|
291
|
+
- **Simple:** Use `@use ... with ()` directly in your SCSS (no script needed)
|
|
292
|
+
- **Advanced:** Create a build script that reads the config and injects it into SCSS (see Option 2 above)
|
|
293
|
+
|
|
294
|
+
### Q: What's the difference between "JSON config" and "SCSS variables"?
|
|
295
|
+
|
|
296
|
+
**A:** The generated CSS is **100% identical**. It's only a matter of workflow organization:
|
|
297
|
+
|
|
298
|
+
| Method | Configuration Location | Compilation Command |
|
|
299
|
+
|--------|----------------------|---------------------|
|
|
300
|
+
| SCSS Variables | Inside SCSS file with `@use ... with ()` | `npx sass styles.scss` |
|
|
301
|
+
| JSON Config | Separate `eva.config.cjs` file | Custom script required |
|
|
302
|
+
|
|
303
|
+
**Choose based on your workflow:**
|
|
304
|
+
- **Simple projects:** SCSS variables (quick and easy)
|
|
305
|
+
- **Complex projects with multiple SCSS files:** JSON config (shared configuration)
|
|
306
|
+
|
|
307
|
+
### Q: Can I use the `scripts/build-with-config.cjs` from the eva-css package?
|
|
308
|
+
|
|
309
|
+
**A:** That script is designed to **build EVA CSS itself** (the framework), not your project.
|
|
310
|
+
|
|
311
|
+
For your project, you need to:
|
|
312
|
+
1. Create your own build script (see template in `examples/user-scripts/`)
|
|
313
|
+
2. Or use SCSS variables with `@use ... with ()` instead
|
|
314
|
+
|
|
315
|
+
### Q: Which option should I use for my project?
|
|
316
|
+
|
|
317
|
+
**A:** Follow this decision tree:
|
|
318
|
+
|
|
319
|
+
```
|
|
320
|
+
Do you have multiple SCSS files that need the same EVA config?
|
|
321
|
+
āā NO ā Use SCSS Variables (simpler)
|
|
322
|
+
āā YES ā Do you want config validation and centralized settings?
|
|
323
|
+
āā YES ā Use JSON Config (requires build script setup)
|
|
324
|
+
āā NO ā Use SCSS Variables (simpler, just duplicate config)
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Q: Can I migrate from SCSS variables to JSON config later?
|
|
328
|
+
|
|
329
|
+
**A:** Yes! Since both methods generate identical CSS, you can switch at any time:
|
|
330
|
+
|
|
331
|
+
1. Create `eva.config.cjs` with your settings
|
|
332
|
+
2. Set up a build script (see examples/)
|
|
333
|
+
3. Update your SCSS from `@use ... with ()` to `@use 'eva-css-fluid'`
|
|
334
|
+
4. Update your build command
|
|
335
|
+
|
|
336
|
+
No CSS changes needed!
|
|
337
|
+
|
|
192
338
|
## šØ Configuration Options
|
|
193
339
|
|
|
194
340
|
### JSON Configuration (eva.config.cjs or package.json)
|
|
@@ -246,6 +392,30 @@ module.exports = {
|
|
|
246
392
|
};
|
|
247
393
|
```
|
|
248
394
|
|
|
395
|
+
**Real-world example** (Tailwind colors to EVA theme):
|
|
396
|
+
|
|
397
|
+
```javascript
|
|
398
|
+
// Extract colors from your design system
|
|
399
|
+
module.exports = {
|
|
400
|
+
theme: {
|
|
401
|
+
name: 'myproject',
|
|
402
|
+
colors: {
|
|
403
|
+
brand: '#3b82f6', // Tailwind blue-500
|
|
404
|
+
accent: '#22c55e', // Tailwind green-500
|
|
405
|
+
extra: '#a855f7' // Tailwind purple-500
|
|
406
|
+
},
|
|
407
|
+
lightMode: { lightness: 98, darkness: 10 },
|
|
408
|
+
darkMode: { lightness: 8, darkness: 95 },
|
|
409
|
+
autoSwitch: true // Auto dark mode with prefers-color-scheme
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**These HEX colors are automatically converted to:**
|
|
415
|
+
- `#3b82f6` ā `oklch(57.4% 0.213 263.8)` (perceptually uniform blue)
|
|
416
|
+
- `#22c55e` ā `oklch(72.6% 0.200 147.6)` (perceptually uniform green)
|
|
417
|
+
- `#a855f7` ā `oklch(60.8% 0.248 302.7)` (perceptually uniform purple)
|
|
418
|
+
|
|
249
419
|
**Available colors:** `brand`, `accent`, `extra`, `dark`, `light`
|
|
250
420
|
|
|
251
421
|
**Color formats:**
|
|
@@ -481,6 +651,251 @@ var(--brand-b_) // More brighter
|
|
|
481
651
|
}
|
|
482
652
|
```
|
|
483
653
|
|
|
654
|
+
## ā Troubleshooting
|
|
655
|
+
|
|
656
|
+
### Common Issues and Solutions
|
|
657
|
+
|
|
658
|
+
#### "The target selector was not found" with @extend
|
|
659
|
+
|
|
660
|
+
**Error:**
|
|
661
|
+
```
|
|
662
|
+
Error: The target selector was not found.
|
|
663
|
+
Use "@extend .w-64 !optional" to avoid this error.
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
**Cause:** You're using `@use` instead of `@forward` when trying to extend EVA classes.
|
|
667
|
+
|
|
668
|
+
**Solution:** Use `@forward` to expose EVA classes in your module:
|
|
669
|
+
|
|
670
|
+
```scss
|
|
671
|
+
// ā Wrong - @use doesn't expose classes for @extend
|
|
672
|
+
@use 'eva-css-fluid';
|
|
673
|
+
|
|
674
|
+
.my-class {
|
|
675
|
+
@extend .w-64; // Error!
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// ā
Correct - @forward exposes classes
|
|
679
|
+
@forward 'eva-css-fluid';
|
|
680
|
+
|
|
681
|
+
.my-class {
|
|
682
|
+
@extend .w-64; // Works!
|
|
683
|
+
}
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
#### Theme colors not appearing in compiled CSS
|
|
687
|
+
|
|
688
|
+
**Problem:** You defined colors in `eva.config.cjs` but they don't show up in the output CSS.
|
|
689
|
+
|
|
690
|
+
**Solutions:**
|
|
691
|
+
|
|
692
|
+
1. **Using JSON config?** Make sure you're using the build script:
|
|
693
|
+
```bash
|
|
694
|
+
# Won't work - SCSS can't read .cjs files
|
|
695
|
+
npx sass styles/main.scss dist/main.css
|
|
696
|
+
|
|
697
|
+
# Use this instead
|
|
698
|
+
node scripts/build-eva.js styles/main.scss dist/main.css
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
2. **Import colors module** if using SCSS variables:
|
|
702
|
+
```scss
|
|
703
|
+
@use 'eva-css-fluid/src/colors' with (
|
|
704
|
+
$theme-name: 'myapp',
|
|
705
|
+
$theme-colors: (
|
|
706
|
+
brand: (lightness: 62.8, chroma: 0.258, hue: 29.23),
|
|
707
|
+
// ... more colors
|
|
708
|
+
)
|
|
709
|
+
);
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
3. **Apply theme class in HTML:**
|
|
713
|
+
```html
|
|
714
|
+
<!-- Without this class, theme colors won't be active -->
|
|
715
|
+
<body class="current-theme theme-myapp">
|
|
716
|
+
<h1 class="_c-brand">Now this works!</h1>
|
|
717
|
+
</body>
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
#### HEX colors not converting to OKLCH
|
|
721
|
+
|
|
722
|
+
**Problem:** You put HEX colors in `eva.config.cjs` but get an error or they don't work.
|
|
723
|
+
|
|
724
|
+
**Cause:** The build script needs `eva-colors` to convert HEX ā OKLCH automatically.
|
|
725
|
+
|
|
726
|
+
**Solution:**
|
|
727
|
+
|
|
728
|
+
1. Install `eva-colors` as a dependency:
|
|
729
|
+
```bash
|
|
730
|
+
npm install eva-colors
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
2. Or convert colors manually:
|
|
734
|
+
```bash
|
|
735
|
+
npx eva-color convert "#ff5733"
|
|
736
|
+
# Output: oklch(62.8% 0.258 29.23)
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
3. Then use OKLCH format in config:
|
|
740
|
+
```javascript
|
|
741
|
+
// eva.config.cjs
|
|
742
|
+
module.exports = {
|
|
743
|
+
theme: {
|
|
744
|
+
colors: {
|
|
745
|
+
brand: { lightness: 62.8, chroma: 0.258, hue: 29.23 }
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
#### Configuration not loading / "Invalid configuration" error
|
|
752
|
+
|
|
753
|
+
**Problem:** Your `eva.config.cjs` isn't being read or validation fails.
|
|
754
|
+
|
|
755
|
+
**Checklist:**
|
|
756
|
+
|
|
757
|
+
1. **File location:** Must be in project root (same level as `package.json`)
|
|
758
|
+
2. **File name:** Must be exactly `eva.config.cjs` or `eva.config.js`
|
|
759
|
+
3. **Syntax:** Must use `module.exports`, not ESM `export`
|
|
760
|
+
4. **Validate config:**
|
|
761
|
+
```bash
|
|
762
|
+
npx eva-css validate
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
**Common mistakes:**
|
|
766
|
+
|
|
767
|
+
```javascript
|
|
768
|
+
// ā Wrong - ESM syntax
|
|
769
|
+
export default {
|
|
770
|
+
sizes: [16, 24]
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// ā
Correct - CommonJS
|
|
774
|
+
module.exports = {
|
|
775
|
+
sizes: [16, 24]
|
|
776
|
+
};
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
#### Dark mode toggle not working
|
|
780
|
+
|
|
781
|
+
**Problem:** Clicking toggle button doesn't switch themes.
|
|
782
|
+
|
|
783
|
+
**Required setup:**
|
|
784
|
+
|
|
785
|
+
1. **HTML structure:**
|
|
786
|
+
```html
|
|
787
|
+
<body class="current-theme theme-myapp">
|
|
788
|
+
<!-- Both classes required ^^ -->
|
|
789
|
+
<button onclick="document.body.classList.toggle('toggle-theme')">
|
|
790
|
+
Toggle Dark Mode
|
|
791
|
+
</button>
|
|
792
|
+
</body>
|
|
793
|
+
```
|
|
794
|
+
|
|
795
|
+
2. **Theme configuration:**
|
|
796
|
+
```javascript
|
|
797
|
+
// eva.config.cjs
|
|
798
|
+
module.exports = {
|
|
799
|
+
theme: {
|
|
800
|
+
name: 'myapp', // Must match class: .theme-myapp
|
|
801
|
+
lightMode: { lightness: 96.4, darkness: 6.4 },
|
|
802
|
+
darkMode: { lightness: 5, darkness: 95 },
|
|
803
|
+
autoSwitch: false // Set true for auto prefers-color-scheme
|
|
804
|
+
}
|
|
805
|
+
};
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
3. **Toggle class:** The `.toggle-theme` class triggers dark mode when present.
|
|
809
|
+
|
|
810
|
+
#### CSS file size is huge (100KB+)
|
|
811
|
+
|
|
812
|
+
**Problem:** Generated CSS file is very large.
|
|
813
|
+
|
|
814
|
+
**Solutions:**
|
|
815
|
+
|
|
816
|
+
1. **Enable custom class mode** to generate only needed classes:
|
|
817
|
+
```scss
|
|
818
|
+
@use 'eva-css-fluid' with (
|
|
819
|
+
$sizes: (16, 24, 32, 64),
|
|
820
|
+
$custom-class: true,
|
|
821
|
+
$class-config: (
|
|
822
|
+
w: (64,), // Only .w-64
|
|
823
|
+
p: (16, 24), // Only .p-16 and .p-24
|
|
824
|
+
fs: (16, 24) // Only .fs-16 and .fs-24
|
|
825
|
+
)
|
|
826
|
+
);
|
|
827
|
+
```
|
|
828
|
+
**Result:** Reduces output by ~85%
|
|
829
|
+
|
|
830
|
+
2. **Use CSS purging** to remove unused classes:
|
|
831
|
+
```bash
|
|
832
|
+
npm install --save-dev eva-css-purge
|
|
833
|
+
npx eva-purge --css dist/eva.css --content "src/**/*.html"
|
|
834
|
+
```
|
|
835
|
+
**Result:** Typically 60-90% size reduction
|
|
836
|
+
|
|
837
|
+
3. **Use variables mode** instead of utility classes:
|
|
838
|
+
```scss
|
|
839
|
+
@use 'eva-css-fluid' with (
|
|
840
|
+
$build-class: false // No utility classes, only variables
|
|
841
|
+
);
|
|
842
|
+
```
|
|
843
|
+
**Result:** Much smaller CSS (only variables, no classes)
|
|
844
|
+
|
|
845
|
+
#### Sass compilation error: "Cannot find module"
|
|
846
|
+
|
|
847
|
+
**Error:**
|
|
848
|
+
```
|
|
849
|
+
Error: Can't find stylesheet to import.
|
|
850
|
+
ā·
|
|
851
|
+
1 ā @use 'eva-css-fluid';
|
|
852
|
+
ā ^^^^^^^^^^^^^^^^^^^^^
|
|
853
|
+
```
|
|
854
|
+
|
|
855
|
+
**Solutions:**
|
|
856
|
+
|
|
857
|
+
1. **Add load-path** if using older Sass:
|
|
858
|
+
```bash
|
|
859
|
+
npx sass --load-path=node_modules styles/main.scss dist/main.css
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
2. **Check package is installed:**
|
|
863
|
+
```bash
|
|
864
|
+
npm ls eva-css-fluid
|
|
865
|
+
# Should show: eva-css-fluid@x.x.x
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
3. **Try explicit path:**
|
|
869
|
+
```scss
|
|
870
|
+
@use '../node_modules/eva-css-fluid/src';
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
#### Watch mode not detecting config changes
|
|
874
|
+
|
|
875
|
+
**Problem:** Changing `eva.config.cjs` doesn't trigger rebuild.
|
|
876
|
+
|
|
877
|
+
**Solution:** Use `nodemon` to watch config file:
|
|
878
|
+
|
|
879
|
+
```json
|
|
880
|
+
{
|
|
881
|
+
"scripts": {
|
|
882
|
+
"watch:css": "nodemon --watch eva.config.cjs --watch styles/ --exec 'node scripts/build-eva.js styles/main.scss dist/main.css'"
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
Install nodemon:
|
|
888
|
+
```bash
|
|
889
|
+
npm install --save-dev nodemon
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
#### Need help?
|
|
893
|
+
|
|
894
|
+
- š [Full Documentation](https://eva-css.xyz/)
|
|
895
|
+
- š¬ [GitHub Issues](https://github.com/nkdeus/eva/issues)
|
|
896
|
+
- š¦ [NPM Package](https://www.npmjs.com/package/eva-css-fluid)
|
|
897
|
+
- šÆ [Working Examples](../../examples/)
|
|
898
|
+
|
|
484
899
|
## š Documentation
|
|
485
900
|
|
|
486
901
|
- [Full Documentation](https://eva-css.xyz/)
|
package/cli.cjs
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* EVA CSS CLI
|
|
5
|
-
* Commands for configuration validation and
|
|
5
|
+
* Commands for configuration validation and project setup
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
const { validateConfigCommand, generateScssCommand } = require('./src/config-loader.cjs');
|
|
9
|
+
const { initCommand, setupCommand } = require('./src/cli-commands.cjs');
|
|
9
10
|
|
|
10
11
|
const args = process.argv.slice(2);
|
|
11
12
|
const command = args[0];
|
|
@@ -18,21 +19,36 @@ Usage:
|
|
|
18
19
|
eva-css <command> [options]
|
|
19
20
|
|
|
20
21
|
Commands:
|
|
22
|
+
init Initialize EVA CSS in existing project (creates eva.config.cjs)
|
|
23
|
+
setup Complete project setup with workflow choice (SCSS vs JSON)
|
|
21
24
|
validate Validate eva.config.js or package.json configuration
|
|
22
25
|
generate Generate SCSS variables from config file
|
|
23
26
|
help Show this help message
|
|
24
27
|
|
|
25
28
|
Examples:
|
|
26
|
-
eva-css
|
|
27
|
-
eva-css
|
|
29
|
+
eva-css init # Initialize eva.config.cjs interactively
|
|
30
|
+
eva-css setup # Complete setup with file generation
|
|
31
|
+
eva-css validate # Validate configuration
|
|
32
|
+
eva-css generate output.scss
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
Getting Started:
|
|
35
|
+
For new projects: eva-css setup
|
|
36
|
+
For existing projects: eva-css init
|
|
37
|
+
|
|
38
|
+
Documentation:
|
|
39
|
+
https://github.com/nkdeus/eva/blob/main/packages/eva-css/README.md
|
|
32
40
|
`);
|
|
33
41
|
}
|
|
34
42
|
|
|
35
43
|
switch (command) {
|
|
44
|
+
case 'init':
|
|
45
|
+
initCommand();
|
|
46
|
+
break;
|
|
47
|
+
|
|
48
|
+
case 'setup':
|
|
49
|
+
setupCommand();
|
|
50
|
+
break;
|
|
51
|
+
|
|
36
52
|
case 'validate':
|
|
37
53
|
validateConfigCommand();
|
|
38
54
|
break;
|
package/package.json
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
2
|
+
"name": "eva-css-fluid",
|
|
3
|
+
"version": "2.0.6",
|
|
4
|
+
"description": "Fluid design framework with OKLCH colors - Transform static designs into responsive fluid systems",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.scss",
|
|
7
|
+
"sass": "src/index.scss",
|
|
8
|
+
"style": "dist/eva.css",
|
|
9
|
+
"bin": {
|
|
10
|
+
"eva-css": "./cli.cjs"
|
|
11
|
+
},
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"sass": "./index.scss",
|
|
15
|
+
"style": "./dist/eva.css",
|
|
16
|
+
"default": "./dist/eva.css"
|
|
17
|
+
},
|
|
18
|
+
"./src": {
|
|
19
|
+
"sass": "./src/index.scss",
|
|
20
|
+
"default": "./src/index.scss"
|
|
21
|
+
},
|
|
22
|
+
"./variables": {
|
|
23
|
+
"sass": "./src/variables.scss",
|
|
24
|
+
"default": "./src/variables.scss"
|
|
25
|
+
},
|
|
26
|
+
"./core": {
|
|
27
|
+
"sass": "./src/core.scss",
|
|
28
|
+
"default": "./src/core.scss"
|
|
29
|
+
},
|
|
30
|
+
"./colors": {
|
|
31
|
+
"sass": "./src/colors-only.scss",
|
|
32
|
+
"default": "./src/colors-only.scss"
|
|
33
|
+
},
|
|
34
|
+
"./src/*": "./src/*.scss",
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"src/",
|
|
39
|
+
"dist/",
|
|
40
|
+
"index.scss",
|
|
41
|
+
"cli.cjs",
|
|
42
|
+
"scripts/",
|
|
43
|
+
"eva.config.template.js",
|
|
44
|
+
"README.md",
|
|
45
|
+
"MIGRATION.md"
|
|
46
|
+
],
|
|
47
|
+
"keywords": [
|
|
48
|
+
"css",
|
|
49
|
+
"scss",
|
|
50
|
+
"sass",
|
|
51
|
+
"framework",
|
|
52
|
+
"fluid-design",
|
|
53
|
+
"oklch",
|
|
54
|
+
"utility-css",
|
|
55
|
+
"design-system",
|
|
56
|
+
"responsive",
|
|
57
|
+
"eva"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "node scripts/build-with-config.cjs",
|
|
61
|
+
"build:min": "node scripts/build-with-config.cjs --min",
|
|
62
|
+
"build:purge": "node scripts/build-with-config.cjs --purge",
|
|
63
|
+
"build:sass": "sass src/index.scss dist/eva.css --style=expanded",
|
|
64
|
+
"build:sass:min": "sass src/index.scss dist/eva.min.css --style=compressed",
|
|
65
|
+
"watch": "sass --watch src/index.scss dist/eva.css",
|
|
66
|
+
"dev": "npm run watch",
|
|
67
|
+
"validate:config": "node cli.cjs validate",
|
|
68
|
+
"generate:config": "node cli.cjs generate"
|
|
69
|
+
},
|
|
70
|
+
"dependencies": {
|
|
71
|
+
"eva-colors": "^2.0.6"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"sass": "^1.94.1"
|
|
75
|
+
},
|
|
76
|
+
"repository": {
|
|
77
|
+
"type": "git",
|
|
78
|
+
"url": "https://github.com/nkdeus/eva.git",
|
|
79
|
+
"directory": "packages/eva-css"
|
|
80
|
+
},
|
|
81
|
+
"author": {
|
|
82
|
+
"name": "Michaƫl Tati",
|
|
83
|
+
"url": "https://ulysse-2029.com/"
|
|
84
|
+
},
|
|
85
|
+
"homepage": "https://eva-css.xyz/",
|
|
86
|
+
"license": "MIT"
|
|
87
87
|
}
|
|
@@ -0,0 +1,539 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EVA CSS CLI Interactive Commands
|
|
3
|
+
*
|
|
4
|
+
* Commands: init, setup
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const readline = require('readline');
|
|
10
|
+
|
|
11
|
+
// CLI colors
|
|
12
|
+
const colors = {
|
|
13
|
+
reset: '\x1b[0m',
|
|
14
|
+
bright: '\x1b[1m',
|
|
15
|
+
dim: '\x1b[2m',
|
|
16
|
+
green: '\x1b[32m',
|
|
17
|
+
blue: '\x1b[34m',
|
|
18
|
+
cyan: '\x1b[36m',
|
|
19
|
+
yellow: '\x1b[33m',
|
|
20
|
+
red: '\x1b[31m'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function log(msg) {
|
|
24
|
+
console.log(msg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function success(msg) {
|
|
28
|
+
log(`${colors.green}ā
${colors.reset} ${msg}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function info(msg) {
|
|
32
|
+
log(`${colors.blue}ā¹${colors.reset} ${msg}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function error(msg) {
|
|
36
|
+
log(`${colors.red}ā${colors.reset} ${msg}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function title(msg) {
|
|
40
|
+
log(`\n${colors.bright}${colors.cyan}${msg}${colors.reset}\n`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Readline interface for prompts
|
|
44
|
+
function prompt(question) {
|
|
45
|
+
const rl = readline.createInterface({
|
|
46
|
+
input: process.stdin,
|
|
47
|
+
output: process.stdout
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return new Promise(resolve => {
|
|
51
|
+
rl.question(`${colors.cyan}?${colors.reset} ${question} `, answer => {
|
|
52
|
+
rl.close();
|
|
53
|
+
resolve(answer.trim());
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function select(question, options) {
|
|
59
|
+
log(`${colors.cyan}?${colors.reset} ${question}`);
|
|
60
|
+
options.forEach((opt, i) => {
|
|
61
|
+
const description = opt.description ? ` ${colors.dim}- ${opt.description}${colors.reset}` : '';
|
|
62
|
+
log(` ${colors.dim}${i + 1}.${colors.reset} ${opt.label}${description}`);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const answer = await prompt(` Select (1-${options.length}):`);
|
|
66
|
+
const index = parseInt(answer) - 1;
|
|
67
|
+
|
|
68
|
+
if (index >= 0 && index < options.length) {
|
|
69
|
+
return options[index].value;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
error('Invalid selection, using default');
|
|
73
|
+
return options[0].value;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function confirm(question, defaultValue = true) {
|
|
77
|
+
const defaultText = defaultValue ? 'Y/n' : 'y/N';
|
|
78
|
+
const answer = await prompt(`${question} (${defaultText})`);
|
|
79
|
+
|
|
80
|
+
if (!answer) return defaultValue;
|
|
81
|
+
return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Generate eva.config.cjs template
|
|
86
|
+
*/
|
|
87
|
+
function generateEvaConfig(options) {
|
|
88
|
+
const { sizes, fontSizes, buildClass, debug, workflow } = options;
|
|
89
|
+
|
|
90
|
+
return `/**
|
|
91
|
+
* EVA CSS Configuration
|
|
92
|
+
*
|
|
93
|
+
* This configuration file defines your design tokens.
|
|
94
|
+
* Customize sizes, font sizes, and build options.
|
|
95
|
+
*
|
|
96
|
+
* Documentation: https://github.com/nkdeus/eva/blob/main/packages/eva-css/docs/JSON-CONFIG.md
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
// Design sizes - extracted from your design system
|
|
101
|
+
// These become CSS variables: var(--4), var(--8), var(--16), etc.
|
|
102
|
+
sizes: [${sizes.join(', ')}],
|
|
103
|
+
|
|
104
|
+
// Font sizes for typography
|
|
105
|
+
// These become CSS variables: var(--14), var(--16), var(--20), etc.
|
|
106
|
+
fontSizes: [${fontSizes.join(', ')}],
|
|
107
|
+
|
|
108
|
+
// Generate utility classes (.w-64, .p-16, .fs-24, etc.)
|
|
109
|
+
buildClass: ${buildClass},
|
|
110
|
+
|
|
111
|
+
// Show configuration during build (useful for debugging)
|
|
112
|
+
debug: ${debug},
|
|
113
|
+
|
|
114
|
+
// Theme configuration
|
|
115
|
+
theme: {
|
|
116
|
+
name: 'eva',
|
|
117
|
+
colors: {
|
|
118
|
+
// Using EVA default colors
|
|
119
|
+
// You can customize: brand, accent, extra
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
lightMode: {
|
|
123
|
+
lightness: 96.4, // Light background
|
|
124
|
+
darkness: 6.4 // Dark text
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
darkMode: {
|
|
128
|
+
lightness: 5, // Dark background
|
|
129
|
+
darkness: 95 // Light text
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// Auto-switch based on system preference
|
|
133
|
+
autoSwitch: false
|
|
134
|
+
}${workflow === 'json' ? `,
|
|
135
|
+
|
|
136
|
+
// Optional: CSS purging for production
|
|
137
|
+
// Uncomment to reduce file size by 60-90%
|
|
138
|
+
/*
|
|
139
|
+
purge: {
|
|
140
|
+
enabled: true,
|
|
141
|
+
content: ['*.html', 'src/**/*.{js,jsx,tsx,vue}'],
|
|
142
|
+
css: 'dist/main.css',
|
|
143
|
+
output: 'dist/main-purged.css',
|
|
144
|
+
safelist: ['theme-', 'current-', 'toggle-']
|
|
145
|
+
}
|
|
146
|
+
*/` : ''}
|
|
147
|
+
};
|
|
148
|
+
`;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Generate build script for JSON config workflow
|
|
153
|
+
*/
|
|
154
|
+
function generateBuildScript() {
|
|
155
|
+
return `#!/usr/bin/env node
|
|
156
|
+
/**
|
|
157
|
+
* EVA CSS Build Script
|
|
158
|
+
*
|
|
159
|
+
* This script loads eva.config.cjs and injects it into SCSS compilation.
|
|
160
|
+
*
|
|
161
|
+
* USAGE:
|
|
162
|
+
* node scripts/build.js <input.scss> <output.css>
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
const fs = require('fs');
|
|
166
|
+
const path = require('path');
|
|
167
|
+
const { execSync } = require('child_process');
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Load EVA configuration from eva.config.cjs
|
|
171
|
+
*/
|
|
172
|
+
function loadConfig() {
|
|
173
|
+
const configPath = path.join(process.cwd(), 'eva.config.cjs');
|
|
174
|
+
|
|
175
|
+
if (!fs.existsSync(configPath)) {
|
|
176
|
+
console.log('ā ļø No eva.config.cjs found');
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
delete require.cache[require.resolve(configPath)];
|
|
181
|
+
return require(configPath);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Convert configuration to SCSS variables
|
|
186
|
+
*/
|
|
187
|
+
function generateScssWithParams(config) {
|
|
188
|
+
const params = [];
|
|
189
|
+
|
|
190
|
+
if (config.sizes) {
|
|
191
|
+
params.push(\`$sizes: (\${config.sizes.join(', ')})\`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (config.fontSizes) {
|
|
195
|
+
params.push(\`$font-sizes: (\${config.fontSizes.join(', ')})\`);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (typeof config.buildClass === 'boolean') {
|
|
199
|
+
params.push(\`$build-class: \${config.buildClass}\`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (typeof config.debug === 'boolean') {
|
|
203
|
+
params.push(\`$debug: \${config.debug}\`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return params.join(',\\n ');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Build CSS from SCSS with configuration injection
|
|
211
|
+
*/
|
|
212
|
+
function buildCss(inputScss, outputCss, config) {
|
|
213
|
+
if (!fs.existsSync(inputScss)) {
|
|
214
|
+
console.error(\`ā Input file not found: \${inputScss}\`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const outputDir = path.dirname(outputCss);
|
|
219
|
+
if (!fs.existsSync(outputDir)) {
|
|
220
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const inputDir = path.dirname(inputScss);
|
|
224
|
+
const inputBase = path.basename(inputScss, '.scss');
|
|
225
|
+
const tempPath = path.join(inputDir, \`.\${inputBase}-temp.scss\`);
|
|
226
|
+
|
|
227
|
+
try {
|
|
228
|
+
const content = fs.readFileSync(inputScss, 'utf8');
|
|
229
|
+
let output = content;
|
|
230
|
+
|
|
231
|
+
if (config) {
|
|
232
|
+
const params = generateScssWithParams(config);
|
|
233
|
+
|
|
234
|
+
if (params) {
|
|
235
|
+
output = content.replace(
|
|
236
|
+
/@use\\s+['"]eva-css\\/index['"];?/g,
|
|
237
|
+
\`@use 'eva-css/index' with (\\n \${params}\\n);\`
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
console.log('ā
Config injected into SCSS');
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
fs.writeFileSync(tempPath, output);
|
|
245
|
+
|
|
246
|
+
console.log('šØ Compiling SCSS...');
|
|
247
|
+
execSync(
|
|
248
|
+
\`npx sass --load-path=node_modules \${tempPath}:\${outputCss}\`,
|
|
249
|
+
{ stdio: 'inherit' }
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
if (fs.existsSync(outputCss)) {
|
|
253
|
+
const stats = fs.statSync(outputCss);
|
|
254
|
+
const sizeKB = (stats.size / 1024).toFixed(2);
|
|
255
|
+
console.log(\`ā
CSS compiled: \${outputCss} (\${sizeKB} KB)\`);
|
|
256
|
+
}
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error('ā Build failed:', error.message);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
} finally {
|
|
261
|
+
if (fs.existsSync(tempPath)) {
|
|
262
|
+
fs.unlinkSync(tempPath);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Main execution
|
|
269
|
+
*/
|
|
270
|
+
function main() {
|
|
271
|
+
const [,, input, output] = process.argv;
|
|
272
|
+
|
|
273
|
+
if (!input || !output) {
|
|
274
|
+
console.log('Usage: node scripts/build.js <input.scss> <output.css>');
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
console.log('š EVA CSS Build\\n');
|
|
279
|
+
console.log(\`š„ Input: \${input}\`);
|
|
280
|
+
console.log(\`š¤ Output: \${output}\\n\`);
|
|
281
|
+
|
|
282
|
+
const config = loadConfig();
|
|
283
|
+
buildCss(input, output, config);
|
|
284
|
+
|
|
285
|
+
console.log('\\n⨠Build complete!\\n');
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (require.main === module) {
|
|
289
|
+
main();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
module.exports = { loadConfig, generateScssWithParams, buildCss };
|
|
293
|
+
`;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* eva-css init command
|
|
298
|
+
* Initialize EVA CSS in existing project
|
|
299
|
+
*/
|
|
300
|
+
async function initCommand() {
|
|
301
|
+
try {
|
|
302
|
+
title('šØ EVA CSS Initialization');
|
|
303
|
+
|
|
304
|
+
// Check if eva.config.cjs already exists
|
|
305
|
+
const configPath = path.join(process.cwd(), 'eva.config.cjs');
|
|
306
|
+
if (fs.existsSync(configPath)) {
|
|
307
|
+
error('eva.config.cjs already exists!');
|
|
308
|
+
const overwrite = await confirm('Overwrite?', false);
|
|
309
|
+
if (!overwrite) {
|
|
310
|
+
log('\nAborted.');
|
|
311
|
+
process.exit(0);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Get configuration from user
|
|
316
|
+
log('');
|
|
317
|
+
info('Configure your design system:\n');
|
|
318
|
+
|
|
319
|
+
const sizesInput = await prompt('Design sizes (comma-separated) [4, 8, 16, 32, 64, 128]:');
|
|
320
|
+
const sizes = sizesInput ? sizesInput.split(',').map(s => parseInt(s.trim())) : [4, 8, 16, 32, 64, 128];
|
|
321
|
+
|
|
322
|
+
const fontSizesInput = await prompt('Font sizes (comma-separated) [14, 16, 20, 24, 32, 48]:');
|
|
323
|
+
const fontSizes = fontSizesInput ? fontSizesInput.split(',').map(s => parseInt(s.trim())) : [14, 16, 20, 24, 32, 48];
|
|
324
|
+
|
|
325
|
+
const buildClass = await confirm('Generate utility classes?', true);
|
|
326
|
+
const debug = await confirm('Enable debug mode?', false);
|
|
327
|
+
|
|
328
|
+
// Generate config file
|
|
329
|
+
const configContent = generateEvaConfig({
|
|
330
|
+
sizes,
|
|
331
|
+
fontSizes,
|
|
332
|
+
buildClass,
|
|
333
|
+
debug,
|
|
334
|
+
workflow: 'json'
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
fs.writeFileSync(configPath, configContent);
|
|
338
|
+
success('Created eva.config.cjs');
|
|
339
|
+
|
|
340
|
+
// Success message
|
|
341
|
+
title('ā
EVA CSS Initialized!');
|
|
342
|
+
|
|
343
|
+
log(`${colors.bright}Next steps:${colors.reset}\n`);
|
|
344
|
+
log(` ${colors.dim}1.${colors.reset} Run ${colors.cyan}npx eva-css validate${colors.reset} to verify configuration`);
|
|
345
|
+
log(` ${colors.dim}2.${colors.reset} Import EVA CSS in your SCSS: ${colors.dim}@use 'eva-css/index';${colors.reset}`);
|
|
346
|
+
log(` ${colors.dim}3.${colors.reset} Use ${colors.cyan}eva-css setup${colors.reset} for full project setup with build scripts\n`);
|
|
347
|
+
|
|
348
|
+
log(`${colors.dim}Documentation: https://github.com/nkdeus/eva/blob/main/packages/eva-css/README.md${colors.reset}\n`);
|
|
349
|
+
|
|
350
|
+
} catch (err) {
|
|
351
|
+
error(`Failed to initialize: ${err.message}`);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* eva-css setup command
|
|
358
|
+
* Complete project setup with workflow choice
|
|
359
|
+
*/
|
|
360
|
+
async function setupCommand() {
|
|
361
|
+
try {
|
|
362
|
+
title('š EVA CSS Project Setup');
|
|
363
|
+
|
|
364
|
+
// Choose workflow
|
|
365
|
+
log('');
|
|
366
|
+
const workflow = await select('Choose your workflow:', [
|
|
367
|
+
{
|
|
368
|
+
label: 'SCSS Variables',
|
|
369
|
+
value: 'scss',
|
|
370
|
+
description: 'Simple, works with npx sass directly'
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
label: 'JSON Config',
|
|
374
|
+
value: 'json',
|
|
375
|
+
description: 'Centralized config, requires build script'
|
|
376
|
+
}
|
|
377
|
+
]);
|
|
378
|
+
|
|
379
|
+
log('');
|
|
380
|
+
info('Configure your design system:\n');
|
|
381
|
+
|
|
382
|
+
const sizesInput = await prompt('Design sizes (comma-separated) [4, 8, 16, 32, 64, 128]:');
|
|
383
|
+
const sizes = sizesInput ? sizesInput.split(',').map(s => parseInt(s.trim())) : [4, 8, 16, 32, 64, 128];
|
|
384
|
+
|
|
385
|
+
const fontSizesInput = await prompt('Font sizes (comma-separated) [14, 16, 20, 24, 32, 48]:');
|
|
386
|
+
const fontSizes = fontSizesInput ? fontSizesInput.split(',').map(s => parseInt(s.trim())) : [14, 16, 20, 24, 32, 48];
|
|
387
|
+
|
|
388
|
+
const buildClass = await confirm('Generate utility classes?', true);
|
|
389
|
+
const debug = await confirm('Enable debug mode?', false);
|
|
390
|
+
|
|
391
|
+
log('\nš Setting up project files...\n');
|
|
392
|
+
|
|
393
|
+
// Create directories
|
|
394
|
+
if (!fs.existsSync('styles')) {
|
|
395
|
+
fs.mkdirSync('styles', { recursive: true });
|
|
396
|
+
success('Created styles/');
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (!fs.existsSync('dist')) {
|
|
400
|
+
fs.mkdirSync('dist', { recursive: true });
|
|
401
|
+
success('Created dist/');
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (workflow === 'json') {
|
|
405
|
+
// JSON Config workflow
|
|
406
|
+
|
|
407
|
+
// 1. Create eva.config.cjs
|
|
408
|
+
const configContent = generateEvaConfig({ sizes, fontSizes, buildClass, debug, workflow });
|
|
409
|
+
fs.writeFileSync('eva.config.cjs', configContent);
|
|
410
|
+
success('Created eva.config.cjs');
|
|
411
|
+
|
|
412
|
+
// 2. Create build script
|
|
413
|
+
if (!fs.existsSync('scripts')) {
|
|
414
|
+
fs.mkdirSync('scripts', { recursive: true });
|
|
415
|
+
}
|
|
416
|
+
fs.writeFileSync('scripts/build.js', generateBuildScript());
|
|
417
|
+
success('Created scripts/build.js');
|
|
418
|
+
|
|
419
|
+
// 3. Create clean SCSS (no config inline)
|
|
420
|
+
const scssContent = `// EVA CSS
|
|
421
|
+
// Configuration is loaded from eva.config.cjs
|
|
422
|
+
|
|
423
|
+
@use 'eva-css/index';
|
|
424
|
+
|
|
425
|
+
// Your custom styles here
|
|
426
|
+
|
|
427
|
+
body {
|
|
428
|
+
margin: 0;
|
|
429
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
430
|
+
transition: background 0.3s, color 0.3s;
|
|
431
|
+
}
|
|
432
|
+
`;
|
|
433
|
+
fs.writeFileSync('styles/main.scss', scssContent);
|
|
434
|
+
success('Created styles/main.scss');
|
|
435
|
+
|
|
436
|
+
// 4. Update or create package.json scripts
|
|
437
|
+
const packageJsonPath = 'package.json';
|
|
438
|
+
let packageJson = {};
|
|
439
|
+
|
|
440
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
441
|
+
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
442
|
+
} else {
|
|
443
|
+
packageJson = {
|
|
444
|
+
name: path.basename(process.cwd()),
|
|
445
|
+
version: '1.0.0',
|
|
446
|
+
private: true
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
packageJson.scripts = packageJson.scripts || {};
|
|
451
|
+
packageJson.scripts.build = 'node scripts/build.js styles/main.scss dist/main.css';
|
|
452
|
+
packageJson.scripts.watch = 'nodemon --watch styles --watch eva.config.cjs --ext scss,cjs --exec "npm run build"';
|
|
453
|
+
packageJson.scripts.validate = 'eva-css validate';
|
|
454
|
+
|
|
455
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
456
|
+
success('Updated package.json scripts');
|
|
457
|
+
|
|
458
|
+
// Success message
|
|
459
|
+
title('ā
JSON Config Workflow Setup Complete!');
|
|
460
|
+
|
|
461
|
+
log(`${colors.bright}Next steps:${colors.reset}\n`);
|
|
462
|
+
log(` ${colors.dim}1.${colors.reset} Install dependencies: ${colors.cyan}npm install --save-dev sass nodemon${colors.reset}`);
|
|
463
|
+
log(` ${colors.dim}2.${colors.reset} Validate config: ${colors.cyan}npm run validate${colors.reset}`);
|
|
464
|
+
log(` ${colors.dim}3.${colors.reset} Build CSS: ${colors.cyan}npm run build${colors.reset}`);
|
|
465
|
+
log(` ${colors.dim}4.${colors.reset} Watch mode: ${colors.cyan}npm run watch${colors.reset}\n`);
|
|
466
|
+
|
|
467
|
+
} else {
|
|
468
|
+
// SCSS Variables workflow
|
|
469
|
+
|
|
470
|
+
// Create SCSS with inline config
|
|
471
|
+
const scssContent = `// EVA CSS - SCSS Variables Configuration
|
|
472
|
+
|
|
473
|
+
@use 'eva-css/index' with (
|
|
474
|
+
// Design sizes from your design system
|
|
475
|
+
$sizes: (${sizes.join(', ')}),
|
|
476
|
+
|
|
477
|
+
// Font sizes for typography
|
|
478
|
+
$font-sizes: (${fontSizes.join(', ')}),
|
|
479
|
+
|
|
480
|
+
// Generate utility classes
|
|
481
|
+
$build-class: ${buildClass},
|
|
482
|
+
|
|
483
|
+
// Show debug info during build
|
|
484
|
+
$debug: ${debug}
|
|
485
|
+
);
|
|
486
|
+
|
|
487
|
+
// Your custom styles here
|
|
488
|
+
|
|
489
|
+
body {
|
|
490
|
+
margin: 0;
|
|
491
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
492
|
+
transition: background 0.3s, color 0.3s;
|
|
493
|
+
}
|
|
494
|
+
`;
|
|
495
|
+
fs.writeFileSync('styles/main.scss', scssContent);
|
|
496
|
+
success('Created styles/main.scss');
|
|
497
|
+
|
|
498
|
+
// Update or create package.json scripts
|
|
499
|
+
const packageJsonPath = 'package.json';
|
|
500
|
+
let packageJson = {};
|
|
501
|
+
|
|
502
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
503
|
+
packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
504
|
+
} else {
|
|
505
|
+
packageJson = {
|
|
506
|
+
name: path.basename(process.cwd()),
|
|
507
|
+
version: '1.0.0',
|
|
508
|
+
private: true
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
packageJson.scripts = packageJson.scripts || {};
|
|
513
|
+
packageJson.scripts.build = 'sass --load-path=node_modules styles/main.scss:dist/main.css';
|
|
514
|
+
packageJson.scripts.watch = 'sass --watch --load-path=node_modules styles/main.scss:dist/main.css';
|
|
515
|
+
|
|
516
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
517
|
+
success('Updated package.json scripts');
|
|
518
|
+
|
|
519
|
+
// Success message
|
|
520
|
+
title('ā
SCSS Variables Workflow Setup Complete!');
|
|
521
|
+
|
|
522
|
+
log(`${colors.bright}Next steps:${colors.reset}\n`);
|
|
523
|
+
log(` ${colors.dim}1.${colors.reset} Install Sass: ${colors.cyan}npm install --save-dev sass${colors.reset}`);
|
|
524
|
+
log(` ${colors.dim}2.${colors.reset} Build CSS: ${colors.cyan}npm run build${colors.reset}`);
|
|
525
|
+
log(` ${colors.dim}3.${colors.reset} Watch mode: ${colors.cyan}npm run watch${colors.reset}\n`);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
log(`${colors.dim}Documentation: https://github.com/nkdeus/eva/blob/main/packages/eva-css/README.md${colors.reset}\n`);
|
|
529
|
+
|
|
530
|
+
} catch (err) {
|
|
531
|
+
error(`Setup failed: ${err.message}`);
|
|
532
|
+
process.exit(1);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
module.exports = {
|
|
537
|
+
initCommand,
|
|
538
|
+
setupCommand
|
|
539
|
+
};
|