emily-css 1.0.18 → 1.0.20

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 CHANGED
@@ -4,6 +4,19 @@ All notable changes to `emily-css` are documented here.
4
4
 
5
5
  ---
6
6
 
7
+ ## v1.0.20 — May 2026
8
+
9
+ **replace folder structure template to tempalates**
10
+
11
+ ### Fixed
12
+ - replace folder structure template to tempalates
13
+
14
+ ---
15
+ ## v1.0.19 — May 2026
16
+
17
+ **Add framework-aware output paths and bundled showcase template**
18
+
19
+ ---
7
20
  ## v1.0.18 — May 2026
8
21
 
9
22
  ****
package/bin/emilyui.js CHANGED
@@ -7,8 +7,6 @@ if (command === "init") {
7
7
  } else if (command === "build") {
8
8
  const { build } = require("../src/index.js");
9
9
  build({ keepFull: process.argv.includes("--keep-full") });
10
- } else if (command === "purge") {
11
- require("../src/purge-cmd.js");
12
10
  } else if (command === "watch") {
13
11
  require("../src/watch.js");
14
12
  } else if (command === "showcase") {
@@ -19,9 +17,8 @@ if (command === "init") {
19
17
 
20
18
  Commands:
21
19
  emily-css init Set up a new project (interactive wizard)
22
- emily-css build Generate production CSS to dist/emily.min.css
23
- emily-css watch Dev mode: watch for config changes and rebuild
24
- emily-css purge Scan project files and remove unused utilities
20
+ emily-css build Generate production CSS to the configured output path
21
+ emily-css watch Dev mode: watch for changes and rebuild
25
22
  emily-css showcase Launch the component showcase in your browser
26
23
  emily-css help Show this help text
27
24
 
@@ -39,12 +36,11 @@ if (command === "init") {
39
36
 
40
37
  Usage:
41
38
  emily-css init Set up a new project
42
- emily-css build Generate production CSS
39
+ emily-css build Generate production CSS to the configured output path
43
40
  emily-css watch Dev mode: rebuild on changes
44
- emily-css purge Remove unused utilities
45
41
  emily-css showcase Browse components in your browser
46
42
  emily-css help Full command reference
47
43
 
48
44
  Run emily-css help for more detail.
49
45
  `);
50
- }
46
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emily-css",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "A config-driven utility CSS framework. Define your brand once, generate the CSS.",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -9,6 +9,7 @@
9
9
  "files": [
10
10
  "bin/",
11
11
  "src/",
12
+ "templates/",
12
13
  "README.md",
13
14
  "LICENSE",
14
15
  "CHANGELOG.md"
@@ -22,7 +23,10 @@
22
23
  "emily:showcase": "node src/showcase.js",
23
24
  "commit": "node scripts/commit.js",
24
25
  "release": "node scripts/release.js",
25
- "ship": "node scripts/ship.js"
26
+ "ship": "node scripts/ship.js",
27
+ "emily:build": "emily-css build",
28
+ "emily:watch": "emily-css watch",
29
+ "emily:help": "emily-css help"
26
30
  },
27
31
  "keywords": [
28
32
  "css",
@@ -50,6 +54,7 @@
50
54
  "cross-spawn": "^7.0.6",
51
55
  "emily-css": "^1.0.8",
52
56
  "enquirer": "^2.4.1",
57
+ "fast-glob": "^3.3.3",
53
58
  "ora": "^5.4.1"
54
59
  }
55
60
  }
package/src/index.js CHANGED
@@ -867,28 +867,54 @@ function generatePatternComponents() {
867
867
  // BUILD FUNCTION
868
868
  // ============================================================================
869
869
 
870
- function buildFullFramework() {
871
- const configPath = path.join(process.cwd(), 'emily.config.json');
870
+ function getConfigPath() {
871
+ return path.join(process.cwd(), 'emily.config.json');
872
+ }
873
+
874
+ function getConfig() {
875
+ const configPath = getConfigPath();
876
+
872
877
  if (!fs.existsSync(configPath)) {
873
- console.error(`\n emily-css: No config found.\n Expected: ${configPath}\n Run "emily-css init" to create one.\n`);
878
+ console.error('\n emily-css: No config found. Run "emily-css init" first.\n');
874
879
  process.exit(1);
875
880
  }
876
- const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
881
+
882
+ return JSON.parse(fs.readFileSync(configPath, 'utf8'));
883
+ }
884
+
885
+ function getFullCssPath(config) {
886
+ return path.join(process.cwd(), config.output?.fullCss || 'dist/emily.css');
887
+ }
888
+
889
+ function getProductionCssPath(config) {
890
+ return path.join(process.cwd(), config.output?.css || 'dist/emily.min.css');
891
+ }
892
+
893
+ function ensureDirectoryForFile(filePath) {
894
+ const dir = path.dirname(filePath);
895
+
896
+ if (!fs.existsSync(dir)) {
897
+ fs.mkdirSync(dir, { recursive: true });
898
+ }
899
+ }
900
+
901
+ function getSourceDir(config) {
902
+ return config.purge?.sourceDir || '.';
903
+ }
904
+
905
+ function buildFullFramework() {
906
+ const config = getConfig();
877
907
 
878
908
  console.log('Building EmilyCSS full framework...');
879
909
 
880
- // Generate colours
881
910
  const colours = generateAllColours(config.colours);
882
911
  console.log(`✓ Generated ${Object.keys(colours).length} colour scales`);
883
912
 
884
- // Generate spacing
885
913
  const spacing = generateSpacing(config.baseUnit, config.spacing.scale);
886
914
  console.log(`✓ Generated ${Object.keys(spacing).length} spacing values`);
887
915
 
888
- // 1. Generate Variables (Theme Layer)
889
916
  const variablesCss = generateCSSVariables(colours, spacing, config);
890
917
 
891
- // 2. Generate Utilities (Utilities Layer)
892
918
  let utilityCss = '';
893
919
  utilityCss += displayUtilities();
894
920
  utilityCss += generateSpacingUtilities(spacing);
@@ -923,21 +949,16 @@ function buildFullFramework() {
923
949
  utilityCss += backgroundUtilities();
924
950
  utilityCss += filterUtilities();
925
951
 
926
- // Add state, dark mode, and responsive variants to utilities
927
952
  utilityCss = addStateVariants(utilityCss);
928
953
  utilityCss = addDarkModeVariants(utilityCss);
929
954
  utilityCss = addResponsiveVariants(utilityCss, config);
930
955
 
931
- // 3. Assemble Final CSS with Layers
932
- // Layer order matters: later layers win over earlier ones.
933
- // theme → CSS custom properties / design tokens
934
- // base → box-sizing reset, font-face, body defaults
935
- // components → reserved for future component styles
936
- // utilities → generated utility classes (highest priority)
937
956
  const { fontFace, bodyFont } = generateFontCSS(config);
957
+
938
958
  const fontLabel = typeof config.fontFamily === 'object'
939
959
  ? 'heading: ' + (config.fontFamily.heading || 'system') + ', body: ' + (config.fontFamily.body || 'system')
940
960
  : (config.fontFamily || 'system');
961
+
941
962
  console.log('✓ Font: ' + fontLabel);
942
963
 
943
964
  const baseCss = `
@@ -946,7 +967,6 @@ function buildFullFramework() {
946
967
  box-sizing: border-box;
947
968
  }
948
969
 
949
- /* Remove default margin/padding on common elements */
950
970
  body, h1, h2, h3, h4, h5, h6, p,
951
971
  ul, ol, dl, dd, figure, blockquote,
952
972
  fieldset, textarea, pre {
@@ -954,23 +974,19 @@ function buildFullFramework() {
954
974
  padding: 0;
955
975
  }
956
976
 
957
- /* Lists: remove bullets/numbers when unstyled */
958
977
  ul, ol {
959
978
  list-style: none;
960
979
  }
961
980
 
962
- /* Inherit fonts for form elements */
963
981
  input, button, textarea, select {
964
982
  font: inherit;
965
983
  }
966
984
 
967
- /* Sensible media defaults */
968
985
  img, picture, video, canvas, svg {
969
986
  display: block;
970
987
  max-width: 100%;
971
988
  }
972
989
 
973
- /* Remove default button styles */
974
990
  button {
975
991
  background: none;
976
992
  border: none;
@@ -978,12 +994,10 @@ function buildFullFramework() {
978
994
  padding: 0;
979
995
  }
980
996
 
981
- /* Avoid overflow on long words */
982
997
  p, h1, h2, h3, h4, h5, h6 {
983
998
  overflow-wrap: break-word;
984
999
  }
985
1000
 
986
- /* Code — terminal style by default */
987
1001
  code {
988
1002
  font-family: "Menlo", "Monaco", "Courier New", monospace;
989
1003
  font-size: 0.875em;
@@ -994,7 +1008,6 @@ function buildFullFramework() {
994
1008
  display: inline;
995
1009
  }
996
1010
 
997
- /* Block code — terminal command style, no extra classes needed */
998
1011
  code.block {
999
1012
  display: block;
1000
1013
  padding: 0.625rem 1rem;
@@ -1003,7 +1016,6 @@ function buildFullFramework() {
1003
1016
  line-height: 1.6;
1004
1017
  }
1005
1018
 
1006
- /* Pre — wraps multi-line code, consistent terminal look */
1007
1019
  pre {
1008
1020
  background-color: #0d0c0b;
1009
1021
  color: #e4e0db;
@@ -1016,7 +1028,6 @@ function buildFullFramework() {
1016
1028
  border: 1px solid #2a2520;
1017
1029
  }
1018
1030
 
1019
- /* Reset code inside pre — inherits pre's colours */
1020
1031
  pre code {
1021
1032
  background: none;
1022
1033
  padding: 0;
@@ -1028,25 +1039,21 @@ function buildFullFramework() {
1028
1039
  }
1029
1040
  ${bodyFont}`;
1030
1041
 
1031
- // @font-face must sit outside @layer for broadest browser compatibility
1032
1042
  let css = fontFace ? `${fontFace}\n` : '';
1033
1043
  css += `@layer theme, base, components, utilities;\n\n`;
1034
1044
  css += `@layer theme {\n${variablesCss}}\n\n`;
1045
+
1035
1046
  const baseStylesCss = generateBaseStyles(config);
1036
1047
  css += `@layer base {${baseCss}${baseStylesCss}}\n\n`;
1037
1048
  css += `@layer components {\n${generatePatternComponents()}}\n\n`;
1038
1049
  css += `@layer utilities {\n${utilityCss}}\n`;
1039
1050
 
1040
- // Write output
1041
- const outputPath = path.join(process.cwd(), 'dist/emily.css');
1042
- const outputDir = path.dirname(outputPath);
1051
+ const fullCssPath = getFullCssPath(config);
1043
1052
 
1044
- if (!fs.existsSync(outputDir)) {
1045
- fs.mkdirSync(outputDir, { recursive: true });
1046
- }
1053
+ ensureDirectoryForFile(fullCssPath);
1054
+ fs.writeFileSync(fullCssPath, css);
1047
1055
 
1048
- fs.writeFileSync(outputPath, css);
1049
- console.log(`✓ Generated CSS: ${outputPath}`);
1056
+ console.log(`✓ Generated CSS: ${fullCssPath}`);
1050
1057
  console.log(`✓ File size: ${(css.length / 1024).toFixed(2)} KB (unminified)`);
1051
1058
  console.log('Full framework build complete');
1052
1059
  }
@@ -1061,55 +1068,44 @@ function minify(css) {
1061
1068
  .trim();
1062
1069
  }
1063
1070
 
1064
- function getConfig() {
1065
- const configPath = path.join(process.cwd(), 'emily.config.json');
1066
-
1067
- if (!fs.existsSync(configPath)) {
1068
- console.error('\n emily-css: No config found. Run "emily-css init" first.\n');
1069
- process.exit(1);
1070
- }
1071
-
1072
- return JSON.parse(fs.readFileSync(configPath, 'utf8'));
1073
- }
1074
-
1075
- function getSourceDir(config) {
1076
- return config.purge && config.purge.sourceDir ? config.purge.sourceDir : '.';
1077
- }
1078
-
1079
1071
  function buildProductionCss() {
1080
1072
  const config = getConfig();
1081
1073
  const sourceDir = getSourceDir(config);
1082
- const cssPath = path.join(process.cwd(), 'dist/emily.css');
1083
- const minPath = path.join(process.cwd(), 'dist/emily.min.css');
1074
+ const fullCssPath = getFullCssPath(config);
1075
+ const productionCssPath = getProductionCssPath(config);
1084
1076
 
1085
- if (!fs.existsSync(cssPath)) {
1077
+ if (!fs.existsSync(fullCssPath)) {
1086
1078
  buildFullFramework();
1087
1079
  }
1088
1080
 
1089
1081
  const { purgeCSS } = require('./purge.js');
1090
- const css = fs.readFileSync(cssPath, 'utf8');
1082
+ const css = fs.readFileSync(fullCssPath, 'utf8');
1091
1083
  const purged = purgeCSS(css, sourceDir, config);
1092
1084
  const minified = minify(purged);
1093
1085
 
1094
- fs.writeFileSync(minPath, minified);
1086
+ ensureDirectoryForFile(productionCssPath);
1087
+ fs.writeFileSync(productionCssPath, minified);
1095
1088
 
1096
1089
  return {
1097
1090
  css,
1098
1091
  purged,
1099
1092
  minified,
1100
1093
  originalSize: Buffer.byteLength(css, 'utf8'),
1101
- outputSize: Buffer.byteLength(minified, 'utf8')
1094
+ outputSize: Buffer.byteLength(minified, 'utf8'),
1095
+ outputPath: productionCssPath,
1096
+ fullCssPath,
1102
1097
  };
1103
1098
  }
1104
1099
 
1105
1100
  function isFrameworkStale() {
1106
- const configPath = path.join(process.cwd(), 'emily.config.json');
1107
- const cssPath = path.join(process.cwd(), 'dist/emily.css');
1101
+ const config = getConfig();
1102
+ const configPath = getConfigPath();
1103
+ const fullCssPath = getFullCssPath(config);
1108
1104
 
1109
- if (!fs.existsSync(cssPath)) return true;
1105
+ if (!fs.existsSync(fullCssPath)) return true;
1110
1106
  if (!fs.existsSync(configPath)) return true;
1111
1107
 
1112
- return fs.statSync(configPath).mtimeMs > fs.statSync(cssPath).mtimeMs;
1108
+ return fs.statSync(configPath).mtimeMs > fs.statSync(fullCssPath).mtimeMs;
1113
1109
  }
1114
1110
 
1115
1111
  function ensureFullFramework() {
@@ -1121,18 +1117,19 @@ function ensureFullFramework() {
1121
1117
  function build(options = {}) {
1122
1118
  ensureFullFramework();
1123
1119
 
1120
+ const config = getConfig();
1121
+ const fullCssPath = getFullCssPath(config);
1124
1122
  const result = buildProductionCss();
1125
- const cssPath = path.join(process.cwd(), 'dist/emily.css');
1126
1123
 
1127
- console.log('✓ Generated production CSS: dist/emily.min.css');
1124
+ console.log('✓ Generated production CSS: ' + path.relative(process.cwd(), result.outputPath));
1128
1125
  console.log('✓ File size: ' + (result.outputSize / 1024).toFixed(2) + ' KB');
1129
1126
 
1130
- if (!options.keepFull && fs.existsSync(cssPath)) {
1127
+ if (!options.keepFull && fs.existsSync(fullCssPath)) {
1131
1128
  try {
1132
- fs.unlinkSync(cssPath);
1133
- console.log('Removed dist/emily.css for production build.');
1134
- } catch (e) {
1135
- // Windows FUSE: can't delete, non-fatal
1129
+ fs.unlinkSync(fullCssPath);
1130
+ console.log('Removed ' + path.relative(process.cwd(), fullCssPath) + ' for production build.');
1131
+ } catch (error) {
1132
+ // Windows FUSE: cannot always delete files cleanly, non-fatal.
1136
1133
  }
1137
1134
  }
1138
1135
 
@@ -1162,4 +1159,4 @@ module.exports = {
1162
1159
  addResponsiveVariants,
1163
1160
  generateFontCSS,
1164
1161
  codeUtilities,
1165
- };
1162
+ };