@hiscovega/grisso 1.0.4 → 1.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 +135 -70
- package/dist/grisso.css +1 -1
- package/lib/build.d.ts +2 -0
- package/lib/build.js +15 -2
- package/lib/cli.d.ts +2 -0
- package/lib/cli.js +197 -0
- package/lib/defaults.js +1 -0
- package/lib/generators.d.ts +0 -4
- package/lib/generators.js +13 -6
- package/lib/partials/borders.js +7 -0
- package/lib/partials/layout.js +13 -9
- package/lib/partials/sizing.js +33 -5
- package/lib/partials/typography.js +10 -3
- package/lib/purge.js +3 -3
- package/lib/resolve-config.d.ts +0 -1
- package/lib/resolve-config.js +5 -2
- package/lib/tokens.d.ts +14 -0
- package/lib/tokens.js +132 -0
- package/lib/types.d.ts +2 -0
- package/package.json +7 -17
- package/plugin.cjs +0 -5
- package/plugin.js +0 -43
package/lib/tokens.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { resolveConfig } from "./resolve-config.js";
|
|
2
|
+
/** Orden fijo de secciones — matchea defaults.ts y tokens-example.css */
|
|
3
|
+
const TOKEN_MAP_KEYS = [
|
|
4
|
+
"spacing",
|
|
5
|
+
"brandColors",
|
|
6
|
+
"foregroundColors",
|
|
7
|
+
"iconColors",
|
|
8
|
+
"supportColors",
|
|
9
|
+
"backgroundColors",
|
|
10
|
+
"overlayColors",
|
|
11
|
+
"borderWidth",
|
|
12
|
+
"opacity",
|
|
13
|
+
"shadows",
|
|
14
|
+
"borderColors",
|
|
15
|
+
];
|
|
16
|
+
/** Labels para los headers CSS de cada sección */
|
|
17
|
+
const SECTION_LABELS = {
|
|
18
|
+
spacing: "Spacing",
|
|
19
|
+
brandColors: "Colors: marca",
|
|
20
|
+
foregroundColors: "Colors: texto",
|
|
21
|
+
iconColors: "Colors: iconos",
|
|
22
|
+
supportColors: "Colors: soporte",
|
|
23
|
+
backgroundColors: "Colors: fondo",
|
|
24
|
+
overlayColors: "Colors: overlays",
|
|
25
|
+
borderWidth: "Border widths",
|
|
26
|
+
opacity: "Opacidad",
|
|
27
|
+
shadows: "Sombras",
|
|
28
|
+
borderColors: "Colors: bordes",
|
|
29
|
+
};
|
|
30
|
+
/** Keys que NO son token maps */
|
|
31
|
+
const NON_TOKEN_KEYS = new Set([
|
|
32
|
+
"columns",
|
|
33
|
+
"breakpoints",
|
|
34
|
+
"safelist",
|
|
35
|
+
"extend",
|
|
36
|
+
]);
|
|
37
|
+
const VAR_RE = /var\(--([\w-]+)\)/g;
|
|
38
|
+
/** Extrae nombres de custom properties de un token map, deduplicados y en orden */
|
|
39
|
+
function extractVarNames(tokenMap) {
|
|
40
|
+
const seen = new Set();
|
|
41
|
+
const result = [];
|
|
42
|
+
for (const value of Object.values(tokenMap)) {
|
|
43
|
+
for (const match of value.matchAll(VAR_RE)) {
|
|
44
|
+
const name = match[1];
|
|
45
|
+
if (!seen.has(name)) {
|
|
46
|
+
seen.add(name);
|
|
47
|
+
result.push(name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
/** Genera scaffold CSS con todas las custom properties */
|
|
54
|
+
function formatCSS(config) {
|
|
55
|
+
const lines = [];
|
|
56
|
+
lines.push("/* @hiscovega/grisso — tokens scaffold", " Define estas variables en :root o en el scope que prefieras.", " Generado desde la config resuelta de Grisso.", "*/", "", ":root {");
|
|
57
|
+
let hasSections = false;
|
|
58
|
+
// Secciones conocidas en orden fijo
|
|
59
|
+
for (const key of TOKEN_MAP_KEYS) {
|
|
60
|
+
const map = config[key];
|
|
61
|
+
if (!map || typeof map !== "object")
|
|
62
|
+
continue;
|
|
63
|
+
const vars = extractVarNames(map);
|
|
64
|
+
if (vars.length === 0)
|
|
65
|
+
continue;
|
|
66
|
+
const label = SECTION_LABELS[key] || key;
|
|
67
|
+
if (hasSections)
|
|
68
|
+
lines.push("");
|
|
69
|
+
lines.push(`\t/* ─── ${label} ${"─".repeat(Math.max(1, 55 - label.length))} */`);
|
|
70
|
+
for (const name of vars) {
|
|
71
|
+
lines.push(`\t--${name}: ;`);
|
|
72
|
+
}
|
|
73
|
+
hasSections = true;
|
|
74
|
+
}
|
|
75
|
+
// Secciones custom del consumidor (keys desconocidas que sean objetos)
|
|
76
|
+
for (const [key, value] of Object.entries(config)) {
|
|
77
|
+
if (NON_TOKEN_KEYS.has(key))
|
|
78
|
+
continue;
|
|
79
|
+
if (TOKEN_MAP_KEYS.includes(key))
|
|
80
|
+
continue;
|
|
81
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
82
|
+
continue;
|
|
83
|
+
const vars = extractVarNames(value);
|
|
84
|
+
if (vars.length === 0)
|
|
85
|
+
continue;
|
|
86
|
+
if (hasSections)
|
|
87
|
+
lines.push("");
|
|
88
|
+
lines.push(`\t/* ─── ${key} ${"─".repeat(Math.max(1, 55 - key.length))} */`);
|
|
89
|
+
for (const name of vars) {
|
|
90
|
+
lines.push(`\t--${name}: ;`);
|
|
91
|
+
}
|
|
92
|
+
hasSections = true;
|
|
93
|
+
}
|
|
94
|
+
lines.push("}", "");
|
|
95
|
+
return lines.join("\n");
|
|
96
|
+
}
|
|
97
|
+
/** Genera JSON con los token maps de la config resuelta */
|
|
98
|
+
function formatJSON(config) {
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const key of TOKEN_MAP_KEYS) {
|
|
101
|
+
const map = config[key];
|
|
102
|
+
if (map && typeof map === "object") {
|
|
103
|
+
result[key] = map;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Incluir token maps custom del consumidor
|
|
107
|
+
for (const [key, value] of Object.entries(config)) {
|
|
108
|
+
if (NON_TOKEN_KEYS.has(key))
|
|
109
|
+
continue;
|
|
110
|
+
if (TOKEN_MAP_KEYS.includes(key))
|
|
111
|
+
continue;
|
|
112
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
113
|
+
continue;
|
|
114
|
+
result[key] = value;
|
|
115
|
+
}
|
|
116
|
+
return JSON.stringify(result, null, "\t");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Extrae tokens de la config resuelta y genera un scaffold CSS o JSON.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* const css = await extractTokens();
|
|
123
|
+
* const json = await extractTokens({ format: "json" });
|
|
124
|
+
*/
|
|
125
|
+
export async function extractTokens(options = {}) {
|
|
126
|
+
const { config: configPath, format = "css" } = options;
|
|
127
|
+
const config = await resolveConfig(configPath);
|
|
128
|
+
if (format === "json") {
|
|
129
|
+
return formatJSON(config);
|
|
130
|
+
}
|
|
131
|
+
return formatCSS(config);
|
|
132
|
+
}
|
package/lib/types.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export interface GrissoConfig {
|
|
|
19
19
|
opacity: TokenMap;
|
|
20
20
|
shadows: TokenMap;
|
|
21
21
|
borderColors: TokenMap;
|
|
22
|
+
/** Patrones de clases protegidas del tree-shaking */
|
|
23
|
+
safelist: (string | RegExp)[];
|
|
22
24
|
[key: string]: unknown;
|
|
23
25
|
}
|
|
24
26
|
/** Función parcial que genera CSS a partir de la config */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hiscovega/grisso",
|
|
3
3
|
"description": "Griddo CSS utility class library",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.6",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
7
7
|
"type": "module",
|
|
@@ -9,31 +9,29 @@
|
|
|
9
9
|
".": {
|
|
10
10
|
"style": "./dist/grisso.css"
|
|
11
11
|
},
|
|
12
|
-
"./plugin": {
|
|
13
|
-
"import": "./plugin.js",
|
|
14
|
-
"require": "./plugin.cjs"
|
|
15
|
-
},
|
|
16
12
|
"./build": "./lib/build.js",
|
|
13
|
+
"./tokens": "./lib/tokens.js",
|
|
17
14
|
"./config": "./lib/defaults.js",
|
|
18
15
|
"./tokens-example.css": "./tokens-example.css"
|
|
19
16
|
},
|
|
20
17
|
"engines": {
|
|
21
18
|
"node": ">=24"
|
|
22
19
|
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"grisso": "lib/cli.js"
|
|
22
|
+
},
|
|
23
23
|
"files": [
|
|
24
24
|
"dist/",
|
|
25
25
|
"lib/",
|
|
26
|
-
"plugin.js",
|
|
27
|
-
"plugin.cjs",
|
|
28
26
|
"tokens-example.css",
|
|
29
27
|
"README.md"
|
|
30
28
|
],
|
|
31
29
|
"scripts": {
|
|
32
|
-
"build": "tsc && node
|
|
30
|
+
"build": "tsc && node lib/cli.js build --output dist/grisso.css",
|
|
33
31
|
"typecheck": "tsc --noEmit",
|
|
34
32
|
"lint": "biome check .",
|
|
35
33
|
"lint:fix": "biome check --write .",
|
|
36
|
-
"playground": "npm run build && node
|
|
34
|
+
"playground": "npm run build && node lib/cli.js build --config playground/grisso.config.mjs --content playground/index.html --content playground/example.module.css --output playground/grisso.css && open playground/index.html",
|
|
37
35
|
"test": "vitest run",
|
|
38
36
|
"test:watch": "vitest",
|
|
39
37
|
"prepublishOnly": "npm run build",
|
|
@@ -50,13 +48,5 @@
|
|
|
50
48
|
"release-it": "^19.2.4",
|
|
51
49
|
"typescript": "^5.9.3",
|
|
52
50
|
"vitest": "^4.0.18"
|
|
53
|
-
},
|
|
54
|
-
"peerDependencies": {
|
|
55
|
-
"postcss": "^8.0.0"
|
|
56
|
-
},
|
|
57
|
-
"peerDependenciesMeta": {
|
|
58
|
-
"postcss": {
|
|
59
|
-
"optional": true
|
|
60
|
-
}
|
|
61
51
|
}
|
|
62
52
|
}
|
package/plugin.cjs
DELETED
package/plugin.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { generateCSS } from "./lib/index.js";
|
|
2
|
-
import { purgeCSS } from "./lib/purge.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* PostCSS plugin de Grisso.
|
|
6
|
-
* Genera CSS desde JS y aplica tree-shaking usando PurgeCSS
|
|
7
|
-
* si se pasan rutas de contenido.
|
|
8
|
-
*
|
|
9
|
-
* No aplica optimización (el consumidor tiene su propio pipeline PostCSS).
|
|
10
|
-
*
|
|
11
|
-
* @param {Object} options
|
|
12
|
-
* @param {string[]} [options.content] - Rutas glob de archivos a escanear para tree-shaking.
|
|
13
|
-
* Si se omite, se incluye todo el CSS de Grisso (útil en desarrollo).
|
|
14
|
-
* @param {string} [options.config] - Ruta a grisso.config.mjs del consumidor.
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* // postcss.config.js del proyecto consumidor
|
|
18
|
-
* import grisso from "@hiscovega/grisso/plugin";
|
|
19
|
-
* export default {
|
|
20
|
-
* plugins: [
|
|
21
|
-
* grisso({ content: ["./src/**\/*.{js,ts,jsx,tsx,css}"] })
|
|
22
|
-
* ]
|
|
23
|
-
* }
|
|
24
|
-
*/
|
|
25
|
-
export default function grissoPlugin(options = {}) {
|
|
26
|
-
const { content, config: configPath } = options;
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
postcssPlugin: "postcss-grisso",
|
|
30
|
-
async Once(root, { parse }) {
|
|
31
|
-
let css = await generateCSS(configPath);
|
|
32
|
-
|
|
33
|
-
if (content && content.length > 0) {
|
|
34
|
-
css = await purgeCSS(css, { content });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const grissoRoot = parse(css);
|
|
38
|
-
grissoRoot.each((node) => root.prepend(node.clone()));
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
grissoPlugin.postcss = true;
|