emily-css 1.0.9 → 1.0.15
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/CHANGELOG.md +159 -0
- package/README.md +64 -222
- package/bin/emilyui.js +32 -6
- package/package.json +55 -49
- package/src/generators.js +34 -1
- package/src/index.js +64 -23
- package/src/init.js +240 -198
- package/src/showcase.js +90 -0
package/src/init.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
const crossSpawn = require("cross-spawn");
|
|
4
|
-
const {
|
|
4
|
+
const { Select, Input, Confirm } = require("enquirer");
|
|
5
5
|
const chalk = require("chalk");
|
|
6
6
|
const ora = require("ora");
|
|
7
7
|
const boxen = require("boxen");
|
|
@@ -23,62 +23,50 @@ const DEFAULT_PURGE_IGNORE = [
|
|
|
23
23
|
".vite",
|
|
24
24
|
];
|
|
25
25
|
|
|
26
|
-
const DEFAULT_COLOURS = {
|
|
27
|
-
primary: "#DB2777",
|
|
28
|
-
secondary: "#2563EB",
|
|
29
|
-
success: "#017F65",
|
|
30
|
-
warning: "#FFC107",
|
|
31
|
-
error: "#B20000",
|
|
32
|
-
neutral: "#57534E",
|
|
33
|
-
};
|
|
34
|
-
|
|
35
26
|
const COLOUR_PRESETS = {
|
|
36
27
|
primary: [
|
|
28
|
+
{ value: "custom", label: "Enter your own hex" },
|
|
37
29
|
{ value: "#DB2777", label: "Emily Pink" },
|
|
38
|
-
{ value: "#114B5F", label: "Deep Teal" },
|
|
39
30
|
{ value: "#2563EB", label: "Blue" },
|
|
40
|
-
{ value: "#
|
|
41
|
-
{ value: "
|
|
31
|
+
{ value: "#028090", label: "Teal" },
|
|
32
|
+
{ value: "#114B5F", label: "Deep Teal" },
|
|
33
|
+
{ value: "#15803D", label: "Green" },
|
|
34
|
+
{ value: "#7C3AED", label: "Purple" },
|
|
35
|
+
{ value: "#E05C00", label: "Burnt Orange" },
|
|
42
36
|
],
|
|
43
37
|
secondary: [
|
|
38
|
+
{ value: "custom", label: "Enter your own hex" },
|
|
44
39
|
{ value: "#2563EB", label: "Blue" },
|
|
45
40
|
{ value: "#028090", label: "Teal" },
|
|
46
41
|
{ value: "#7C3AED", label: "Purple" },
|
|
47
42
|
{ value: "#DB2777", label: "Emily Pink" },
|
|
48
|
-
{ value: "
|
|
43
|
+
{ value: "#F59E0B", label: "Amber" },
|
|
44
|
+
{ value: "#57534E", label: "Warm Grey" },
|
|
49
45
|
],
|
|
50
46
|
success: [
|
|
51
|
-
{ value: "#017F65", label: "Accessible Green" },
|
|
47
|
+
{ value: "#017F65", label: "Accessible Green (recommended)" },
|
|
52
48
|
{ value: "#15803D", label: "Forest Green" },
|
|
53
|
-
{ value: "
|
|
54
|
-
{ value: "custom", label: "Custom hex" },
|
|
49
|
+
{ value: "custom", label: "Enter your own hex" },
|
|
55
50
|
],
|
|
56
51
|
warning: [
|
|
57
|
-
{ value: "#FFC107", label: "Amber" },
|
|
58
|
-
{ value: "#F59E0B", label: "Orange" },
|
|
59
|
-
{ value: "
|
|
60
|
-
{ value: "custom", label: "Custom hex" },
|
|
52
|
+
{ value: "#FFC107", label: "Amber (recommended)" },
|
|
53
|
+
{ value: "#F59E0B", label: "Orange Amber" },
|
|
54
|
+
{ value: "custom", label: "Enter your own hex" },
|
|
61
55
|
],
|
|
62
56
|
error: [
|
|
63
|
-
{ value: "#B20000", label: "Accessible Red" },
|
|
57
|
+
{ value: "#B20000", label: "Accessible Red (recommended)" },
|
|
64
58
|
{ value: "#DC2626", label: "Red" },
|
|
65
|
-
{ value: "
|
|
66
|
-
{ value: "custom", label: "Custom hex" },
|
|
67
|
-
],
|
|
68
|
-
neutral: [
|
|
69
|
-
{ value: "#57534E", label: "Warm Grey" },
|
|
70
|
-
{ value: "#334155", label: "Slate" },
|
|
71
|
-
{ value: "#111827", label: "Near Black" },
|
|
72
|
-
{ value: "custom", label: "Custom hex" },
|
|
59
|
+
{ value: "custom", label: "Enter your own hex" },
|
|
73
60
|
],
|
|
74
61
|
};
|
|
75
62
|
|
|
76
63
|
const FONT_OPTIONS = [
|
|
77
|
-
{ name: "lexend", message: "Lexend" },
|
|
78
|
-
{ name: "inter", message: "Inter" },
|
|
79
|
-
{ name: "
|
|
80
|
-
{ name: "
|
|
81
|
-
{ name: "
|
|
64
|
+
{ name: "lexend", message: "Lexend (clear, accessible - recommended)" },
|
|
65
|
+
{ name: "inter", message: "Inter (clean, widely used)" },
|
|
66
|
+
{ name: "dm-sans", message: "DM Sans (modern, geometric)" },
|
|
67
|
+
{ name: "nunito", message: "Nunito (friendly, rounded)" },
|
|
68
|
+
{ name: "atkinson", message: "Atkinson Hyperlegible (maximum legibility)" },
|
|
69
|
+
{ name: "system", message: "System sans-serif (no download required)" },
|
|
82
70
|
];
|
|
83
71
|
|
|
84
72
|
const PURGE_EXTENSIONS = [
|
|
@@ -109,47 +97,69 @@ function isValidHex(hex) {
|
|
|
109
97
|
return /^#[0-9A-F]{6}$/i.test(hex);
|
|
110
98
|
}
|
|
111
99
|
|
|
112
|
-
function
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
name: "custom",
|
|
116
|
-
message: "Custom hex",
|
|
117
|
-
};
|
|
118
|
-
}
|
|
100
|
+
function colourSwatch(hex) {
|
|
101
|
+
return chalk.hex(hex)("■");
|
|
102
|
+
}
|
|
119
103
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
104
|
+
async function askHex(promptName, message, initial) {
|
|
105
|
+
const value = await new Input({
|
|
106
|
+
name: promptName,
|
|
107
|
+
message,
|
|
108
|
+
initial: initial || "#000000",
|
|
109
|
+
validate(value) {
|
|
110
|
+
return isValidHex(value) ? true : "Enter a valid hex colour, e.g. #0077B6";
|
|
111
|
+
},
|
|
112
|
+
}).run();
|
|
113
|
+
return value.toUpperCase();
|
|
124
114
|
}
|
|
125
115
|
|
|
126
|
-
async function
|
|
127
|
-
const choices =
|
|
128
|
-
|
|
129
|
-
|
|
116
|
+
async function askColourFromPresets(label, presets, defaultHex) {
|
|
117
|
+
const choices = presets.map(function(opt) {
|
|
118
|
+
if (opt.value === "custom") {
|
|
119
|
+
return { name: "custom", message: "Enter your own hex" };
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
name: opt.value,
|
|
123
|
+
message: colourSwatch(opt.value) + " " + opt.label + " " + chalk.gray(opt.value),
|
|
124
|
+
};
|
|
125
|
+
});
|
|
130
126
|
|
|
131
127
|
const selected = await new Select({
|
|
132
|
-
name:
|
|
133
|
-
message:
|
|
134
|
-
choices,
|
|
128
|
+
name: label,
|
|
129
|
+
message: label + " colour",
|
|
130
|
+
choices: choices,
|
|
135
131
|
}).run();
|
|
136
132
|
|
|
137
|
-
if (selected !== "custom")
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
if (selected !== "custom") return selected.toUpperCase();
|
|
134
|
+
return askHex(label + "Custom", "Enter " + label + " hex", defaultHex);
|
|
135
|
+
}
|
|
140
136
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
137
|
+
async function askBtnColour(label, matchLabel, matchHex, presets) {
|
|
138
|
+
const sameChoice = {
|
|
139
|
+
name: matchHex,
|
|
140
|
+
message: colourSwatch(matchHex) + " Same as " + matchLabel + " " + chalk.gray(matchHex),
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const otherChoices = presets
|
|
144
|
+
.filter(function(opt) { return opt.value !== matchHex; })
|
|
145
|
+
.map(function(opt) {
|
|
146
|
+
if (opt.value === "custom") {
|
|
147
|
+
return { name: "custom", message: "Enter your own hex" };
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
name: opt.value,
|
|
151
|
+
message: colourSwatch(opt.value) + " " + opt.label + " " + chalk.gray(opt.value),
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const selected = await new Select({
|
|
156
|
+
name: label,
|
|
157
|
+
message: label + " colour",
|
|
158
|
+
choices: [sameChoice].concat(otherChoices),
|
|
150
159
|
}).run();
|
|
151
160
|
|
|
152
|
-
return
|
|
161
|
+
if (selected !== "custom") return selected.toUpperCase();
|
|
162
|
+
return askHex(label + "Custom", "Enter " + label + " hex", matchHex);
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
function hasFile(fileName) {
|
|
@@ -158,11 +168,7 @@ function hasFile(fileName) {
|
|
|
158
168
|
|
|
159
169
|
function readPackageJson() {
|
|
160
170
|
const packagePath = path.join(process.cwd(), "package.json");
|
|
161
|
-
|
|
162
|
-
if (!fs.existsSync(packagePath)) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
|
|
171
|
+
if (!fs.existsSync(packagePath)) return null;
|
|
166
172
|
try {
|
|
167
173
|
return JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
168
174
|
} catch {
|
|
@@ -172,7 +178,6 @@ function readPackageJson() {
|
|
|
172
178
|
|
|
173
179
|
function hasDependency(packageJson, dependencyName) {
|
|
174
180
|
if (!packageJson) return false;
|
|
175
|
-
|
|
176
181
|
return Boolean(
|
|
177
182
|
packageJson.dependencies?.[dependencyName] ||
|
|
178
183
|
packageJson.devDependencies?.[dependencyName],
|
|
@@ -181,35 +186,26 @@ function hasDependency(packageJson, dependencyName) {
|
|
|
181
186
|
|
|
182
187
|
function addEmilyScriptsToPackageJson() {
|
|
183
188
|
const packagePath = path.join(process.cwd(), "package.json");
|
|
184
|
-
|
|
185
|
-
if (!fs.existsSync(packagePath)) {
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
+
if (!fs.existsSync(packagePath)) return false;
|
|
189
190
|
try {
|
|
190
191
|
const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
191
|
-
|
|
192
192
|
packageJson.scripts = packageJson.scripts || {};
|
|
193
|
-
|
|
194
193
|
let changed = false;
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
packageJson.scripts[
|
|
203
|
-
|
|
194
|
+
const scripts = {
|
|
195
|
+
"emily:build": "emily-css build",
|
|
196
|
+
"emily:watch": "emily-css watch",
|
|
197
|
+
"emily:help": "emily-css help",
|
|
198
|
+
"emily:showcase": "emily-css showcase",
|
|
199
|
+
};
|
|
200
|
+
for (const [key, val] of Object.entries(scripts)) {
|
|
201
|
+
if (!packageJson.scripts[key]) {
|
|
202
|
+
packageJson.scripts[key] = val;
|
|
203
|
+
changed = true;
|
|
204
|
+
}
|
|
204
205
|
}
|
|
205
|
-
|
|
206
206
|
if (changed) {
|
|
207
|
-
fs.writeFileSync(
|
|
208
|
-
packagePath,
|
|
209
|
-
JSON.stringify(packageJson, null, 2) + "\n",
|
|
210
|
-
);
|
|
207
|
+
fs.writeFileSync(packagePath, JSON.stringify(packageJson, null, 2) + "\n");
|
|
211
208
|
}
|
|
212
|
-
|
|
213
209
|
return true;
|
|
214
210
|
} catch {
|
|
215
211
|
return false;
|
|
@@ -323,22 +319,20 @@ function createDefaultConfig({
|
|
|
323
319
|
colours,
|
|
324
320
|
headingFont,
|
|
325
321
|
bodyFont,
|
|
326
|
-
monoFont,
|
|
327
322
|
baseUnit,
|
|
328
323
|
detectedProject,
|
|
329
324
|
sourceDir,
|
|
330
325
|
}) {
|
|
331
326
|
return {
|
|
332
327
|
name,
|
|
333
|
-
description:
|
|
328
|
+
description: name + " design system",
|
|
334
329
|
|
|
335
|
-
baseUnit:
|
|
330
|
+
baseUnit: baseUnit + "px",
|
|
336
331
|
baseFontSize: "16px",
|
|
337
332
|
|
|
338
333
|
fontFamily: {
|
|
339
334
|
heading: headingFont,
|
|
340
335
|
body: bodyFont,
|
|
341
|
-
mono: monoFont,
|
|
342
336
|
},
|
|
343
337
|
|
|
344
338
|
customFonts: [],
|
|
@@ -475,29 +469,26 @@ function createDefaultConfig({
|
|
|
475
469
|
// ============================================================================
|
|
476
470
|
|
|
477
471
|
async function init() {
|
|
478
|
-
console.log(
|
|
479
|
-
chalk.bold.magenta("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"),
|
|
480
|
-
);
|
|
472
|
+
console.log(chalk.bold.magenta("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"));
|
|
481
473
|
console.log(chalk.bold.magenta(" EmilyUI Setup"));
|
|
482
|
-
console.log(
|
|
483
|
-
chalk.bold.magenta("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"),
|
|
484
|
-
);
|
|
474
|
+
console.log(chalk.bold.magenta("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n"));
|
|
485
475
|
|
|
486
476
|
try {
|
|
487
477
|
const spinner = ora("Analysing project structure...").start();
|
|
488
478
|
const detectedProject = detectProject();
|
|
489
|
-
spinner.succeed(
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
479
|
+
spinner.succeed("Detected project: " + chalk.cyan(detectedProject.name));
|
|
480
|
+
|
|
481
|
+
// Derive a sensible default name from package.json if available
|
|
482
|
+
const packageJsonData = readPackageJson();
|
|
483
|
+
const pkgName = packageJsonData && packageJsonData.name
|
|
484
|
+
? packageJsonData.name.replace(/-/g, " ").replace(/\b\w/g, function(c) { return c.toUpperCase(); })
|
|
485
|
+
: "My Design System";
|
|
486
|
+
|
|
487
|
+
const projectName = await new Input({
|
|
488
|
+
name: "projectName",
|
|
489
|
+
message: "Project name",
|
|
490
|
+
initial: pkgName,
|
|
491
|
+
validate: function(v) { return v.trim() ? true : "Project name is required"; },
|
|
501
492
|
}).run();
|
|
502
493
|
|
|
503
494
|
if (!projectName || !projectName.trim()) {
|
|
@@ -505,15 +496,69 @@ async function init() {
|
|
|
505
496
|
process.exit(1);
|
|
506
497
|
}
|
|
507
498
|
|
|
508
|
-
|
|
499
|
+
// =========================================================================
|
|
500
|
+
// COLOURS
|
|
501
|
+
// =========================================================================
|
|
502
|
+
|
|
503
|
+
console.log(chalk.bold("\n" + chalk.magenta("→") + " Brand colours"));
|
|
504
|
+
|
|
505
|
+
const primary = await askColourFromPresets("primary", COLOUR_PRESETS.primary, "#DB2777");
|
|
506
|
+
const secondary = await askColourFromPresets("secondary", COLOUR_PRESETS.secondary, "#2563EB");
|
|
507
|
+
const btnPrimary = await askBtnColour("btn-primary", "primary", primary, COLOUR_PRESETS.primary);
|
|
508
|
+
const btnSecondary = await askBtnColour("btn-secondary", "secondary", secondary, COLOUR_PRESETS.secondary);
|
|
509
|
+
|
|
510
|
+
console.log(chalk.bold("\n" + chalk.magenta("→") + " Utility colours"));
|
|
511
|
+
console.log(chalk.gray(" Defaults shown. Press enter to accept or pick an alternative.\n"));
|
|
512
|
+
|
|
513
|
+
const success = await askColourFromPresets("success", COLOUR_PRESETS.success, "#017F65");
|
|
514
|
+
const warning = await askColourFromPresets("warning", COLOUR_PRESETS.warning, "#FFC107");
|
|
515
|
+
const error = await askColourFromPresets("error", COLOUR_PRESETS.error, "#B20000");
|
|
516
|
+
|
|
517
|
+
const colours = {
|
|
518
|
+
primary: primary,
|
|
519
|
+
secondary: secondary,
|
|
520
|
+
"btn-primary": btnPrimary,
|
|
521
|
+
"btn-secondary": btnSecondary,
|
|
522
|
+
success: success,
|
|
523
|
+
warning: warning,
|
|
524
|
+
error: error,
|
|
525
|
+
neutral: "#57534E",
|
|
526
|
+
};
|
|
509
527
|
|
|
510
|
-
|
|
528
|
+
// Additional utility colours
|
|
529
|
+
let addingMore = true;
|
|
530
|
+
while (addingMore) {
|
|
531
|
+
const wantsMore = await new Confirm({
|
|
532
|
+
name: "addMore",
|
|
533
|
+
message: "Add another utility colour?",
|
|
534
|
+
initial: false,
|
|
535
|
+
}).run();
|
|
536
|
+
|
|
537
|
+
if (!wantsMore) {
|
|
538
|
+
addingMore = false;
|
|
539
|
+
break;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const customName = await new Input({
|
|
543
|
+
name: "customName",
|
|
544
|
+
message: "Colour name (e.g. accent, highlight, brand-dark)",
|
|
545
|
+
validate: function(value) {
|
|
546
|
+
const trimmed = value.trim();
|
|
547
|
+
if (!trimmed) return "Name is required";
|
|
548
|
+
if (!/^[a-z][a-z0-9-]*$/.test(trimmed)) return "Use lowercase letters, numbers, and hyphens only";
|
|
549
|
+
if (colours[trimmed]) return '"' + trimmed + '" is already defined';
|
|
550
|
+
return true;
|
|
551
|
+
},
|
|
552
|
+
}).run();
|
|
511
553
|
|
|
512
|
-
|
|
513
|
-
normalisedColours[colourName] = await askColour(colourName);
|
|
554
|
+
colours[customName.trim()] = await askHex("hex-" + customName, "Hex for " + customName, "#000000");
|
|
514
555
|
}
|
|
515
556
|
|
|
516
|
-
|
|
557
|
+
// =========================================================================
|
|
558
|
+
// TYPOGRAPHY
|
|
559
|
+
// =========================================================================
|
|
560
|
+
|
|
561
|
+
console.log(chalk.bold("\n" + chalk.magenta("→") + " Typography"));
|
|
517
562
|
|
|
518
563
|
const headingFont = await new Select({
|
|
519
564
|
name: "headingFont",
|
|
@@ -529,59 +574,47 @@ async function init() {
|
|
|
529
574
|
initial: 1,
|
|
530
575
|
}).run();
|
|
531
576
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
{
|
|
544
|
-
name: "baseUnitInput",
|
|
545
|
-
message: "Base spacing unit in px",
|
|
546
|
-
initial: "8",
|
|
547
|
-
},
|
|
548
|
-
],
|
|
549
|
-
validate(values) {
|
|
550
|
-
const parsed = Number.parseInt(values.baseUnitInput, 10);
|
|
551
|
-
|
|
552
|
-
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
553
|
-
return "Base spacing unit must be a positive number.";
|
|
554
|
-
}
|
|
555
|
-
|
|
577
|
+
// =========================================================================
|
|
578
|
+
// SPACING
|
|
579
|
+
// =========================================================================
|
|
580
|
+
|
|
581
|
+
const baseUnitRaw = await new Input({
|
|
582
|
+
name: "baseUnit",
|
|
583
|
+
message: "Base spacing unit in px (18px = 1.125rem)",
|
|
584
|
+
initial: "18",
|
|
585
|
+
validate: function(value) {
|
|
586
|
+
const parsed = Number.parseInt(value, 10);
|
|
587
|
+
if (Number.isNaN(parsed) || parsed <= 0) return "Must be a positive number.";
|
|
556
588
|
return true;
|
|
557
589
|
},
|
|
558
590
|
}).run();
|
|
559
591
|
|
|
560
|
-
const baseUnit = Number.parseInt(
|
|
592
|
+
const baseUnit = Number.parseInt(baseUnitRaw, 10);
|
|
561
593
|
|
|
562
|
-
|
|
594
|
+
// =========================================================================
|
|
595
|
+
// PURGE
|
|
596
|
+
// =========================================================================
|
|
563
597
|
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
message: "Scan directory",
|
|
571
|
-
initial: detectedProject.sourceDir,
|
|
572
|
-
},
|
|
573
|
-
],
|
|
598
|
+
console.log(chalk.bold("\n" + chalk.magenta("→") + " Purge settings"));
|
|
599
|
+
|
|
600
|
+
const sourceDirRaw = await new Input({
|
|
601
|
+
name: "sourceDir",
|
|
602
|
+
message: "Detected " + detectedProject.name + " — scan directory",
|
|
603
|
+
initial: detectedProject.sourceDir,
|
|
574
604
|
}).run();
|
|
575
605
|
|
|
606
|
+
// =========================================================================
|
|
607
|
+
// BUILD
|
|
608
|
+
// =========================================================================
|
|
609
|
+
|
|
576
610
|
const config = createDefaultConfig({
|
|
577
611
|
name: projectName.trim(),
|
|
578
|
-
colours:
|
|
579
|
-
headingFont,
|
|
580
|
-
bodyFont,
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
detectedProject,
|
|
584
|
-
sourceDir: sourceDir.trim() || detectedProject.sourceDir,
|
|
612
|
+
colours: colours,
|
|
613
|
+
headingFont: headingFont,
|
|
614
|
+
bodyFont: bodyFont,
|
|
615
|
+
baseUnit: baseUnit,
|
|
616
|
+
detectedProject: detectedProject,
|
|
617
|
+
sourceDir: sourceDirRaw.trim() || detectedProject.sourceDir,
|
|
585
618
|
});
|
|
586
619
|
|
|
587
620
|
const configPath = path.join(process.cwd(), "emily.config.json");
|
|
@@ -597,12 +630,9 @@ async function init() {
|
|
|
597
630
|
});
|
|
598
631
|
|
|
599
632
|
let stderr = "";
|
|
633
|
+
build.stderr.on("data", function(data) { stderr += data.toString(); });
|
|
600
634
|
|
|
601
|
-
build.
|
|
602
|
-
stderr += data.toString();
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
build.on("close", (code) => {
|
|
635
|
+
build.on("close", async function(code) {
|
|
606
636
|
if (code === 0) {
|
|
607
637
|
buildSpinner.succeed("EmilyUI CSS built successfully.");
|
|
608
638
|
|
|
@@ -610,57 +640,69 @@ async function init() {
|
|
|
610
640
|
|
|
611
641
|
console.log(
|
|
612
642
|
"\n" +
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
),
|
|
643
|
+
boxen(
|
|
644
|
+
chalk.green.bold("Setup complete") +
|
|
645
|
+
"\n\nConfig: " + chalk.cyan("emily.config.json") +
|
|
646
|
+
"\nOutput: " + chalk.cyan("dist/emily.min.css") +
|
|
647
|
+
"\nProject: " + chalk.cyan(detectedProject.name) +
|
|
648
|
+
"\nScan: " + chalk.cyan(config.purge.sourceDir) +
|
|
649
|
+
"\n\nNext: link " + chalk.yellow("dist/emily.min.css") + " in your project." +
|
|
650
|
+
(scriptsAdded
|
|
651
|
+
? "\n\nScripts added:\n" +
|
|
652
|
+
chalk.cyan(" npm run emily:build\n") +
|
|
653
|
+
chalk.cyan(" npm run emily:watch\n") +
|
|
654
|
+
chalk.cyan(" npm run emily:showcase\n") +
|
|
655
|
+
chalk.cyan(" npm run emily:help")
|
|
656
|
+
: ""),
|
|
657
|
+
{ padding: 1, margin: 1, borderStyle: "round", borderColor: "magenta" },
|
|
658
|
+
),
|
|
630
659
|
);
|
|
660
|
+
|
|
661
|
+
const startWatch = await new Confirm({
|
|
662
|
+
name: "startWatch",
|
|
663
|
+
message: "Start the file watcher now?",
|
|
664
|
+
initial: true,
|
|
665
|
+
}).run();
|
|
666
|
+
|
|
667
|
+
if (startWatch) {
|
|
668
|
+
console.log(chalk.cyan("\nStarting watcher — press Ctrl+C to stop.\n"));
|
|
669
|
+
const watcher = crossSpawn("npx", ["emily-css", "watch"], {
|
|
670
|
+
cwd: process.cwd(),
|
|
671
|
+
stdio: "inherit",
|
|
672
|
+
shell: process.platform === "win32",
|
|
673
|
+
});
|
|
674
|
+
watcher.on("close", function(c) { process.exit(c || 0); });
|
|
675
|
+
} else {
|
|
676
|
+
console.log(chalk.gray("\nRun the watcher any time with: npm run emily:watch\n"));
|
|
677
|
+
process.exit(0);
|
|
678
|
+
}
|
|
631
679
|
} else {
|
|
632
680
|
buildSpinner.fail("Automatic build failed.");
|
|
633
|
-
|
|
634
681
|
console.log("\nYour config was created, but CSS was not built.");
|
|
635
|
-
console.log("\nRun
|
|
682
|
+
console.log("\nRun manually:\n");
|
|
636
683
|
console.log(chalk.cyan(" npx emily-css build"));
|
|
637
|
-
|
|
638
684
|
if (stderr.trim()) {
|
|
639
685
|
console.log(chalk.gray("\nBuild error:\n"));
|
|
640
686
|
console.log(stderr.trim());
|
|
641
687
|
}
|
|
688
|
+
process.exit(1);
|
|
642
689
|
}
|
|
643
|
-
|
|
644
|
-
process.exit(code === 0 ? 0 : 1);
|
|
645
690
|
});
|
|
646
691
|
|
|
647
|
-
build.on("error", (error)
|
|
692
|
+
build.on("error", function(error) {
|
|
648
693
|
buildSpinner.fail("Automatic build failed.");
|
|
649
|
-
|
|
650
694
|
console.log("\nYour config was created, but CSS was not built.");
|
|
651
|
-
console.log(
|
|
652
|
-
console.log("\nRun
|
|
695
|
+
console.log("Reason: " + error.message);
|
|
696
|
+
console.log("\nRun manually:\n");
|
|
653
697
|
console.log(chalk.cyan(" npx emily-css build\n"));
|
|
654
|
-
|
|
655
698
|
process.exit(1);
|
|
656
699
|
});
|
|
700
|
+
|
|
657
701
|
} catch (error) {
|
|
658
702
|
console.log(chalk.red("\nSetup cancelled or failed."));
|
|
659
|
-
|
|
660
703
|
if (error && error.message) {
|
|
661
704
|
console.log(chalk.gray(error.message));
|
|
662
705
|
}
|
|
663
|
-
|
|
664
706
|
process.exit(1);
|
|
665
707
|
}
|
|
666
708
|
}
|