yummacss 3.0.0 → 3.0.2

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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2022-present Yumma CSS maintained by Renildo Pereira.
1
+ Copyright (c) 2023-present Yumma CSS maintained by Renildo Pereira.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -1,33 +1,66 @@
1
- <div align="center">
2
- <a href="https://yummacss.com" target="_blank" target="_blank" rel="noopener noreferrer">
3
- <picture>
4
- <source media="(prefers-color-scheme: dark)" srcset="https://www.yummacss.com/trademark/logo-dark.png">
5
- <source media="(prefers-color-scheme: light)" srcset="https://www.yummacss.com/trademark/logo-light.png">
6
- <img alt="Yumma CSS" src="https://www.yummacss.com/trademark/logo-light.png" width="220" style="max-width: 100%;">
7
- </picture>
8
- </a>
9
- </div>
10
-
11
- <p align="center">
12
- The CSS framework with abbreviated styles for modern design systems — no bloat!
13
- <br>
14
- <a href="https://yummacss.com"><strong>Read the documentation ↝</strong></a>
15
- </p>
16
-
17
- ## Community
18
-
19
- Join the Yumma CSS community! Share your experiences and help Yumma CSS grow and be the best it can be.
20
-
21
- - Follow [@yummacss on X (Twitter)](https://x.com/yummacss)
22
- - Subscribe to [@yummacss on YouTube](https://www.youtube.com/@yummacss)
23
- - Join discussions on [`#yummacss` Discord](https://discord.gg/Zd2y6yVqgK)
1
+ # [@yummacss](https://www.npmjs.com/package/yummacss)
2
+
3
+ A CSS framework for the web with abbreviated styles.
4
+
5
+ [![NPM Version](https://img.shields.io/npm/v/yummacss?style=plastic&label=yummacss&labelColor=eaedfc&color=413cb8)](https://www.npmjs.com/package/yummacss)
6
+ [![NPM Downloads](https://img.shields.io/npm/d18m/yummacss?style=plastic&label=downloads&labelColor=eaedfc&color=413cb8)](https://www.npmjs.com/package/yummacss)
7
+
8
+ ## Getting started
9
+
10
+ Yumma CSS is a CSS framework packed with a set of abbreviated utility classes for building faster and more maintainable UIs.
11
+
12
+ ### Installing
13
+
14
+ A step by step series of examples that tell you how to get a development
15
+ environment running
16
+
17
+ Install Yumma CSS
18
+
19
+ ```
20
+ npm i yummacss -D
21
+ ```
22
+
23
+ Initialize configuration
24
+
25
+ ```
26
+ npx yummacss init
27
+ ```
28
+
29
+ Our [framework guides](https://www.yummacss.com/docs/installation#framework-guides) will teach you how to set up your configuration file.
30
+
31
+ ## Development setup
32
+
33
+ The Yumma CSS CLI provides several commands to help you work with your Yumma CSS files.
34
+
35
+ > [!IMPORTANT]
36
+ > Make sure you have a `yumma.config.js` file set up before running these commands. If you haven’t, run `npx yummacss init` first.
37
+
38
+ ### Building styles
39
+
40
+ The `build` command will compile your Yumma CSS files once.
41
+
42
+ ```bash
43
+ npx yummacss build
44
+ ```
45
+
46
+ ### Watching changes
47
+
48
+ The `watch` command will watch for changes in your Yumma CSS files and recompile them automatically.
49
+
50
+ ```bash
51
+ npx yummacss watch
52
+ ```
53
+
54
+ ## Documentation
55
+
56
+ Head over to [yummacss.com](https://www.yummacss.com) for the full documentation.
24
57
 
25
58
  ## Built with
26
59
 
27
- - [Gulp](https://gulpjs.com/) A toolkit to automate & enhance your workflow.
28
- - [SCSS](https://sass-lang.com/documentation/syntax/) CSS with superpowers.
29
- - [Typescript](https://www.typescriptlang.org/) A superset of JavaScript.
60
+ - [gulp](https://www.npmjs.com/package/gulp) - The streaming build system.
61
+ - [sass](https://www.npmjs.com/package/sass) - CSS with superpowers.
62
+ - [typescript](https://www.npmjs.com/package/typescript) - A language for application-scale JavaScript.
30
63
 
31
- ## Licensing
64
+ ## License
32
65
 
33
- MIT Copyright (c) 2022–present
66
+ This project is licensed under the [MIT License](LICENSE)
@@ -1,12 +1,13 @@
1
1
  import { writeFileSync } from "fs";
2
- import { compileSCSS } from "../services/scssCompiler.js";
3
- import { purgeCSS } from "../services/purgeService.js";
4
- import { minifyCSS } from "../services/minifyService.js";
2
+ import { messages } from "../lib/cli-lang.js";
3
+ import { cli } from "../lib/cli-ui.js";
5
4
  import { loadConfig } from "../services/configLoader.js";
6
- import { cli } from "../utils/cli-ui.js";
5
+ import { minifyCSS } from "../services/minifyService.js";
6
+ import { purgeCSS } from "../services/purgeService.js";
7
+ import { compileSCSS } from "../services/scssCompiler.js";
7
8
  let cache = {};
8
9
  export async function build(existingConfig, forceRebuild = false) {
9
- const buildSpinner = cli.startSpinner("Starting build process...");
10
+ const buildSpinner = cli.startSpinner(messages.build.start);
10
11
  const startTime = Date.now();
11
12
  try {
12
13
  const config = existingConfig || (await loadConfig());
@@ -14,7 +15,7 @@ export async function build(existingConfig, forceRebuild = false) {
14
15
  const configChanged = cache.configHash !== configHash;
15
16
  let css;
16
17
  if (forceRebuild || configChanged || !cache.css) {
17
- buildSpinner.text = "Compiling SCSS...";
18
+ buildSpinner.text = messages.build.compiling;
18
19
  const result = await compileSCSS(config);
19
20
  css = result.css;
20
21
  cache = {
@@ -25,20 +26,18 @@ export async function build(existingConfig, forceRebuild = false) {
25
26
  }
26
27
  else {
27
28
  css = cache.css;
28
- buildSpinner.text = "Using cached SCSS...";
29
+ buildSpinner.text = messages.build.usingCache;
29
30
  }
30
- buildSpinner.text = "Purging unused styles...";
31
+ buildSpinner.text = messages.build.purging;
31
32
  const purgedCSS = await purgeCSS(css, config);
32
- buildSpinner.text = "Minifying CSS...";
33
+ buildSpinner.text = messages.build.minifying;
33
34
  const finalCSS = minifyCSS(purgedCSS, config);
34
35
  writeFileSync(config.output, finalCSS);
35
- buildSpinner.succeed("Build completed successfully!");
36
- cli.success(`Styles written to: ${config.output}`);
37
- cli.info(`Total time: ${Date.now() - startTime}ms`);
36
+ buildSpinner.succeed(messages.build.success(Date.now() - startTime, config.output));
38
37
  }
39
38
  catch (error) {
40
- buildSpinner.fail("Build failed!");
41
- cli.error(error instanceof Error ? error.message : "Unknown error occurred");
39
+ buildSpinner.fail(messages.build.fail);
40
+ cli.error(error instanceof Error ? error.message : messages.common.unknownError);
42
41
  process.exit(1);
43
42
  }
44
43
  }
@@ -1,17 +1,19 @@
1
1
  import { writeFileSync } from "fs";
2
- import { defaultConfig } from "../config/defaultConfig.js";
3
- import { cli } from "../utils/cli-ui.js";
2
+ import { generateConfigFile } from "../config/templates.js";
3
+ import { messages } from "../lib/cli-lang.js";
4
+ import { cli } from "../lib/cli-ui.js";
5
+ const DEFAULT_CONFIG_EXTENSION = ".js";
4
6
  export function init() {
5
- const initSpinner = cli.startSpinner("Creating config file...");
7
+ const init = cli.startSpinner(messages.init.start);
6
8
  try {
7
- const configContent = `export default ${JSON.stringify(defaultConfig, null, 2)}`;
8
- writeFileSync("yumma.config.js", configContent);
9
- initSpinner.succeed("Config file created!");
10
- cli.success("yumma.config.js successfully created");
9
+ const configContent = generateConfigFile(DEFAULT_CONFIG_EXTENSION);
10
+ const configFileName = `yumma.config${DEFAULT_CONFIG_EXTENSION}`;
11
+ writeFileSync(configFileName, configContent);
12
+ init.succeed(messages.init.success);
11
13
  }
12
14
  catch (error) {
13
- initSpinner.fail("Failed to create config file!");
14
- cli.error(error instanceof Error ? error.message : "Unknown error occurred");
15
+ init.fail(messages.init.fail);
16
+ cli.error(error instanceof Error ? error.message : messages.common.unknownError);
15
17
  process.exit(1);
16
18
  }
17
19
  }
@@ -1,14 +1,16 @@
1
1
  import chok from "chokidar";
2
- import { build } from "./build.js";
3
- import { loadConfig } from "../services/configLoader.js";
4
- import { cli } from "../utils/cli-ui.js";
5
2
  import { globby } from "globby";
3
+ import { messages } from "../lib/cli-lang.js";
4
+ import { cli } from "../lib/cli-ui.js";
5
+ import { loadConfig } from "../services/configLoader.js";
6
+ import { build } from "./build.js";
6
7
  let currentConfig;
8
+ let buildTimeout = null;
9
+ let changedFiles = new Set();
7
10
  export async function watch() {
8
- const watchSpinner = cli.startSpinner("Initializing watch mode...");
11
+ const watchSpinner = cli.startSpinner(messages.watch.start);
9
12
  try {
10
13
  currentConfig = await loadConfig();
11
- watchSpinner.start("Watching for changes...");
12
14
  await build(currentConfig, true);
13
15
  const files = await globby(currentConfig.source);
14
16
  const watcher = chok.watch(files, {
@@ -24,13 +26,23 @@ export async function watch() {
24
26
  .on("add", (path) => handleChange(path, "added"))
25
27
  .on("change", (path) => handleChange(path, "changed"))
26
28
  .on("unlink", (path) => handleChange(path, "removed"));
27
- async function handleChange(path, event) {
28
- await build(currentConfig, true);
29
+ function handleChange(path, event) {
30
+ changedFiles.add(path);
31
+ if (buildTimeout) {
32
+ clearTimeout(buildTimeout);
33
+ }
34
+ buildTimeout = setTimeout(async () => {
35
+ if (changedFiles.size > 0) {
36
+ await build(currentConfig, true);
37
+ changedFiles.clear();
38
+ }
39
+ buildTimeout = null;
40
+ }, 500); // 500ms
29
41
  }
30
42
  }
31
43
  catch (error) {
32
- watchSpinner.fail("Watch failed!");
33
- cli.error(error instanceof Error ? error.message : "Unknown error occurred");
44
+ watchSpinner.fail(messages.watch.fail);
45
+ cli.error(error instanceof Error ? error.message : messages.common.unknownError);
34
46
  process.exit(1);
35
47
  }
36
48
  }
@@ -1,4 +1,4 @@
1
- export const defaultConfig = {
1
+ const defaultConfig = {
2
2
  source: [""],
3
3
  output: "",
4
4
  buildOptions: {
@@ -6,3 +6,4 @@ export const defaultConfig = {
6
6
  minify: false,
7
7
  },
8
8
  };
9
+ export { defaultConfig };
@@ -0,0 +1,33 @@
1
+ import { readFileSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ import { defaultConfig } from "./defaultConfig.js";
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const TEMPLATES_DIR = join(__dirname, "templates");
8
+ const CONFIG_PLACEHOLDER = "{{CONFIG}}";
9
+ const SUPPORTED_TEMPLATES = [
10
+ { extension: ".js", templateFile: "yumma.config.js.template" },
11
+ ];
12
+ function loadTemplate(templateFile) {
13
+ const templatePath = join(TEMPLATES_DIR, templateFile);
14
+ return readFileSync(templatePath, "utf-8");
15
+ }
16
+ function generateConfigContent(template, config) {
17
+ const configString = JSON.stringify(config, null, 2);
18
+ return template.replace(CONFIG_PLACEHOLDER, configString);
19
+ }
20
+ export function generateConfigFile(extension) {
21
+ const templateInfo = SUPPORTED_TEMPLATES.find(t => t.extension === extension);
22
+ if (!templateInfo) {
23
+ throw new Error(`Unsupported config extension: ${extension}`);
24
+ }
25
+ const template = loadTemplate(templateInfo.templateFile);
26
+ return generateConfigContent(template, defaultConfig);
27
+ }
28
+ export function getSupportedExtensions() {
29
+ return SUPPORTED_TEMPLATES.map(t => t.extension);
30
+ }
31
+ export function isSupportedExtension(extension) {
32
+ return SUPPORTED_TEMPLATES.some(t => t.extension === extension);
33
+ }
@@ -0,0 +1,23 @@
1
+ export const messages = {
2
+ build: {
3
+ start: "Building...",
4
+ compiling: "Compiling...",
5
+ usingCache: "Using cache...",
6
+ purging: "Purging...",
7
+ minifying: "Minifying...",
8
+ success: (ms, output) => `Build done in ${ms}ms. (${output})`,
9
+ fail: "Build failed.",
10
+ },
11
+ init: {
12
+ start: "Creating config...",
13
+ success: "Config created.",
14
+ fail: "Config failed.",
15
+ },
16
+ watch: {
17
+ start: "Watching...",
18
+ fail: "Watch failed.",
19
+ },
20
+ common: {
21
+ unknownError: "Unknown error.",
22
+ },
23
+ };
@@ -1,8 +1,8 @@
1
1
  import ora from "ora";
2
- export const spinner = ora({
2
+ const spinner = ora({
3
3
  spinner: "sand",
4
4
  });
5
- export const cli = {
5
+ const cli = {
6
6
  success: (msg) => console.log(`✔ ${msg}`),
7
7
  info: (msg) => console.log(`ℹ ${msg}`),
8
8
  error: (msg) => console.log(`✗ ${msg}`),
@@ -11,3 +11,4 @@ export const cli = {
11
11
  return spinner;
12
12
  },
13
13
  };
14
+ export { spinner, cli };
@@ -1,10 +1,36 @@
1
- import { join } from "path";
1
+ import { join, extname } from "path";
2
2
  import { pathToFileURL } from "url";
3
+ import { existsSync } from "fs";
3
4
  import { defaultConfig } from "../config/defaultConfig.js";
5
+ import { getSupportedExtensions } from "../config/templates.js";
6
+ const CONFIG_BASE = "yumma.config";
7
+ const SUPPORTED_EXTENSIONS = getSupportedExtensions();
8
+ const EXTENSION_LOADERS = {
9
+ ".js": async (path) => {
10
+ const configUrl = pathToFileURL(path).href;
11
+ return (await import(configUrl)).default;
12
+ },
13
+ };
14
+ function findConfigFile(cwd) {
15
+ for (const ext of SUPPORTED_EXTENSIONS) {
16
+ const file = join(cwd, `${CONFIG_BASE}${ext}`);
17
+ if (existsSync(file))
18
+ return file;
19
+ }
20
+ return null;
21
+ }
4
22
  export async function loadConfig() {
5
- const configPath = join(process.cwd(), "yumma.config.js");
6
- const configUrl = pathToFileURL(configPath).href;
7
- const { default: userConfig } = (await import(configUrl));
23
+ const cwd = process.cwd();
24
+ const configPath = findConfigFile(cwd);
25
+ if (!configPath) {
26
+ throw new Error(`No config file found. Supported: ${CONFIG_BASE}${SUPPORTED_EXTENSIONS.join(", ")}`);
27
+ }
28
+ const ext = extname(configPath);
29
+ const loader = EXTENSION_LOADERS[ext];
30
+ if (!loader) {
31
+ throw new Error(`Unsupported config file extension: ${ext}`);
32
+ }
33
+ const userConfig = await loader(configPath);
8
34
  return {
9
35
  ...defaultConfig,
10
36
  ...userConfig,
@@ -1,5 +1,5 @@
1
- import { PurgeCSS } from "purgecss";
2
1
  import { globby } from "globby";
2
+ import { PurgeCSS } from "purgecss";
3
3
  export async function purgeCSS(css, config) {
4
4
  const purgeCSSResult = await new PurgeCSS().purge({
5
5
  content: await globby(config.source),
@@ -1,6 +1,6 @@
1
- import * as sass from "sass-embedded";
2
- import { fileURLToPath } from "url";
3
1
  import { dirname, join } from "path";
2
+ import { fileURLToPath } from "url";
3
+ import * as sass from "sass-embedded";
4
4
  const __filename = fileURLToPath(import.meta.url);
5
5
  const __dirname = dirname(__filename);
6
6
  const packageRoot = join(__dirname, "../../..");
@@ -1,19 +1,16 @@
1
1
  import { Command } from "commander";
2
- import { init } from "../commands/init.js";
3
2
  import { build } from "../commands/build.js";
3
+ import { init } from "../commands/init.js";
4
4
  import { watch } from "../commands/watch.js";
5
5
  const program = new Command();
6
- program.name("yummacss").description("Yumma CSS CLI").version("3.0.0");
7
- program
8
- .command("init")
9
- .description("Create a default config file")
10
- .action(init);
6
+ program.name("yummacss").description("Yumma CSS CLI");
7
+ program.command("init").description("Create config file.").action(init);
11
8
  program
12
9
  .command("build")
13
- .description("Compile CSS with optional minification")
10
+ .description("Build styles.")
14
11
  .action(() => build().catch(() => process.exit(1)));
15
12
  program
16
13
  .command("watch")
17
- .description("Watch files and rebuild on changes")
14
+ .description("Build styles automatically.")
18
15
  .action(() => watch().catch(() => process.exit(1)));
19
16
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,50 +1,65 @@
1
- {
2
- "author": "Renildo Pereira",
3
- "description": "The CSS framework with abbreviated styles.",
4
- "license": "MIT",
5
- "main": "./dist/cli/index.js",
6
- "name": "yummacss",
7
- "type": "module",
8
- "version": "3.0.0",
9
- "bin": {
10
- "yummacss": "./dist/cli/src/cli.js",
11
- "yumma": "./dist/cli/src/cli.js"
12
- },
13
- "exports": {
14
- ".": "./dist/cli/src/cli.js"
15
- },
16
- "files": [
17
- "dist",
18
- "src"
19
- ],
20
- "scripts": {
21
- "build": "gulp build",
22
- "build:css": "gulp build",
23
- "build:cli": "tsc -p tsconfig.cli.json",
24
- "dev": "tsc -p tsconfig.cli.json --watch",
25
- "prepublishOnly": "pnpm build:cli"
26
- },
27
- "keywords": [
28
- "utility-first",
29
- "framework"
30
- ],
31
- "dependencies": {
32
- "chokidar": "^4.0.3",
33
- "commander": "^13.1.0",
34
- "globby": "^14.1.0",
35
- "lightningcss": "^1.29.3",
36
- "ora": "^8.2.0",
37
- "purgecss": "^7.0.2",
38
- "sass-embedded": "^1.85.1"
39
- },
40
- "devDependencies": {
41
- "@types/node": "^22.13.10",
42
- "gulp": "^5.0.0",
43
- "gulp-clean-css": "^4.3.0",
44
- "gulp-debug": "^5.0.1",
45
- "gulp-rename": "^2.0.0",
46
- "gulp-sass": "^6.0.0",
47
- "sass": "^1.85.1",
48
- "typescript": "^5.8.2"
49
- }
1
+ {
2
+ "name": "yummacss",
3
+ "version": "3.0.2",
4
+ "description": "A CSS framework for the web with abbreviated styles.",
5
+ "keywords": [
6
+ "css-framework",
7
+ "css",
8
+ "design-system",
9
+ "framework",
10
+ "gulp",
11
+ "lightningcss",
12
+ "responsive-design",
13
+ "responsive",
14
+ "scss",
15
+ "yummacss"
16
+ ],
17
+ "homepage": "https://yummacss.com",
18
+ "license": "MIT",
19
+ "author": "Renildo Pereira",
20
+ "files": [
21
+ "dist/cli",
22
+ "src"
23
+ ],
24
+ "main": "./dist/cli/index.js",
25
+ "type": "module",
26
+ "exports": {
27
+ ".": "./dist/cli/src/cli.js"
28
+ },
29
+ "bin": {
30
+ "yummacss": "./dist/cli/src/cli.js",
31
+ "yumma": "./dist/cli/src/cli.js"
32
+ },
33
+ "repository": {
34
+ "type": "git",
35
+ "url": "git+https://github.com/yumma-lib/yumma-css.git"
36
+ },
37
+ "scripts": {
38
+ "build:cli": "tsc -p tsconfig.cli.json",
39
+ "build:css": "gulp build",
40
+ "build": "pnpm build:css && pnpm build:cli",
41
+ "dev": "tsc -p tsconfig.cli.json --watch",
42
+ "format:cli": "pnpx prettier --write cli",
43
+ "prepublishOnly": "pnpm build:cli"
44
+ },
45
+ "dependencies": {
46
+ "chokidar": "^4.0.3",
47
+ "commander": "^13.1.0",
48
+ "globby": "^14.1.0",
49
+ "lightningcss": "^1.29.3",
50
+ "ora": "^8.2.0",
51
+ "purgecss": "^7.0.2",
52
+ "sass-embedded": "^1.85.1"
53
+ },
54
+ "devDependencies": {
55
+ "@ianvs/prettier-plugin-sort-imports": "^4.5.1",
56
+ "@types/node": "^22.13.10",
57
+ "gulp-clean-css": "^4.3.0",
58
+ "gulp-debug": "^5.0.1",
59
+ "gulp-rename": "^2.0.0",
60
+ "gulp-sass": "^6.0.0",
61
+ "gulp": "^5.0.0",
62
+ "sass": "^1.85.1",
63
+ "typescript": "^5.8.2"
64
+ }
50
65
  }
@@ -57,9 +57,10 @@ $yma-outline-width: 1px !default;
57
57
  // positioning
58
58
  $yma-bottom-left-top-right: 0.25rem !default;
59
59
 
60
- // typography
60
+ // text
61
61
  $yma-decoration-thickness: 1px !default;
62
62
 
63
+ // font
63
64
  $yma-font-size-xs: 0.75rem !default;
64
65
  $yma-font-size-sm: 0.875rem !default;
65
66
  $yma-font-size-md: 1rem !default;
@@ -1,9 +1,5 @@
1
1
  @use "../abstracts/variables" as vars;
2
2
 
3
- /**
4
- * Yumma CSS v3.0.0 by Renildo Pereira | https://www.yummacss.com/
5
- */
6
-
7
3
  /** -- Box sizing --
8
4
  * 1. Use a more intuitive box-sizing model to make the design consistent.
9
5
  * 2. Remove default margin and padding.