holygrail5 1.0.21 → 1.0.23

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.
Files changed (42) hide show
  1. package/README.md +72 -0
  2. package/config.json +85 -18
  3. package/dist/assets/fonts/SuisseIntlMono-Bold-WebS.woff +0 -0
  4. package/dist/assets/fonts/SuisseIntlMono-Bold-WebS.woff2 +0 -0
  5. package/dist/assets/fonts/SuisseIntlMono-Regular-WebS.woff +0 -0
  6. package/dist/assets/fonts/SuisseIntlMono-Regular-WebS.woff2 +0 -0
  7. package/dist/assets/fonts/suisse-intl-thin.woff +0 -0
  8. package/dist/assets/fonts/suisse-intl-thin.woff2 +0 -0
  9. package/dist/componentes.html +1 -8
  10. package/dist/developer-guide.md +4 -0
  11. package/dist/guide-styles.css +85 -56
  12. package/dist/index.html +2727 -2690
  13. package/dist/output.css +123 -70
  14. package/dist/skills.html +17 -5
  15. package/dist/themes/dutti-demo.html +76 -39
  16. package/dist/themes/dutti.css +10 -6
  17. package/dist/themes/limited-demo.html +55 -18
  18. package/dist/themes/limited.css +8 -6
  19. package/package.json +2 -2
  20. package/src/.data/.previous-values.json +69 -20
  21. package/src/assets/fonts/SuisseIntlMono-Bold-WebS.woff +0 -0
  22. package/src/assets/fonts/SuisseIntlMono-Bold-WebS.woff2 +0 -0
  23. package/src/assets/fonts/SuisseIntlMono-Regular-WebS.woff +0 -0
  24. package/src/assets/fonts/SuisseIntlMono-Regular-WebS.woff2 +0 -0
  25. package/src/assets/fonts/suisse-intl-thin.woff +0 -0
  26. package/src/assets/fonts/suisse-intl-thin.woff2 +0 -0
  27. package/src/build/asset-manager.js +8 -0
  28. package/src/build/components-generator.js +1 -8
  29. package/src/build/skills-generator.js +12 -4
  30. package/src/build/theme-transformer.js +10 -3
  31. package/src/dev-server.js +28 -13
  32. package/src/docs-generator/guide-styles.css +85 -56
  33. package/src/docs-generator/html-generator.js +188 -183
  34. package/src/docs-generator/sections/colors-section.js +15 -5
  35. package/src/generators/typo-generator.js +1 -2
  36. package/src/generators/utils.js +15 -0
  37. package/themes/_base/_radios.css +7 -6
  38. package/themes/dutti/README.md +17 -0
  39. package/themes/dutti/_variables.css +3 -0
  40. package/themes/dutti/theme.json +2 -1
  41. package/themes/limited/_variables.css +1 -0
  42. package/themes/limited/theme.json +2 -1
@@ -11,6 +11,8 @@
11
11
  // fondos neutros (`bg-light`, `bg-cream`, `orange`, `mustard`)
12
12
  // → primarios. El resto → semánticos.
13
13
 
14
+ const { escapeHtml } = require('../../generators/utils');
15
+
14
16
  const DEFAULT_PRIMARY_KEYS = ['bg-light', 'bg-cream', 'orange', 'mustard'];
15
17
 
16
18
  function isPrimaryColorKey(key) {
@@ -49,15 +51,23 @@ function renderColorCard(key, value, prefix, changedValues) {
49
51
  ? normalizedValue
50
52
  : (normalizedValue.length === 9 ? normalizedValue.substring(0, 7) : normalizedValue);
51
53
 
54
+ // Escapamos cada valor del config antes de interpolarlo. Para valores
55
+ // limpios (claves kebab-case, hex como #ffffff) el escape es idéntico,
56
+ // así que la guía no cambia; sólo blinda valores con caracteres especiales.
57
+ const eKey = escapeHtml(key);
58
+ const eValue = escapeHtml(value);
59
+ const eVarName = escapeHtml(varName);
60
+ const eOpaque = escapeHtml(opaqueValue);
61
+
52
62
  return `
53
- <div class="guide-color-card" data-copy-value="${varName}" title="Click para copiar ${varName}">
54
- <div class="guide-color-preview" style="--color-value: ${opaqueValue};">
63
+ <div class="guide-color-card" data-copy-value="${eVarName}" title="Click para copiar ${eVarName}">
64
+ <div class="guide-color-preview" style="--color-value: ${eOpaque};">
55
65
  ${isLight ? `<div class="guide-color-pattern"></div>` : ''}
56
66
  </div>
57
67
  <div class="guide-color-card-content">
58
- <div class="guide-color-name">${key}</div>
59
- <div class="guide-color-var-name" data-copy-value="${varName}" title="Click para copiar ${varName}">${varName}</div>
60
- <div class="guide-color-value ${isChanged ? 'guide-changed' : ''}" data-copy-value="${value}" title="Click para copiar ${value}">${value}</div>
68
+ <div class="guide-color-name">${eKey}</div>
69
+ <div class="guide-color-var-name" data-copy-value="${eVarName}" title="Click para copiar ${eVarName}">${eVarName}</div>
70
+ <div class="guide-color-value ${isChanged ? 'guide-changed' : ''}" data-copy-value="${eValue}" title="Click para copiar ${eValue}">${eValue}</div>
61
71
  </div>
62
72
  </div>`;
63
73
  }
@@ -198,8 +198,7 @@ function generateClassCSS(className, cls, breakpointName, valueMap, prefix, cate
198
198
  varName = getSharedVarName(prop, props[prop], prefix, category);
199
199
  }
200
200
 
201
- const importantFlag = prop === 'lineHeight' ? ' !important' : '';
202
- cssProps.push(` ${toKebabCase(prop)}: var(${varName})${importantFlag};`);
201
+ cssProps.push(` ${toKebabCase(prop)}: var(${varName});`);
203
202
  });
204
203
 
205
204
  return cssProps.length ? ` .${className} {\n${cssProps.join('\n')}\n }` : '';
@@ -4,6 +4,20 @@
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
6
 
7
+ // Escapa caracteres especiales de HTML para evitar inyección al volcar
8
+ // valores del config en la guía y las demos. Escapa también comillas
9
+ // (" y ') porque muchos valores se interpolan dentro de atributos
10
+ // (title="...", style="...", data-copy-value="..."): sin escapar las
11
+ // comillas, un valor podría romper el atributo y reabrir el contexto.
12
+ function escapeHtml(str) {
13
+ return String(str)
14
+ .replace(/&/g, '&amp;')
15
+ .replace(/</g, '&lt;')
16
+ .replace(/>/g, '&gt;')
17
+ .replace(/"/g, '&quot;')
18
+ .replace(/'/g, '&#39;');
19
+ }
20
+
7
21
  // Convierte nombres de propiedades de JavaScript (camelCase) a formato CSS (kebab-case)
8
22
  // Por ejemplo, "fontSize" se convierte en "font-size" para usarlo en CSS
9
23
  function toKebabCase(str) {
@@ -200,6 +214,7 @@ function applyThemeTypographyOverrides(config, themeData) {
200
214
  }
201
215
 
202
216
  module.exports = {
217
+ escapeHtml,
203
218
  toKebabCase,
204
219
  pxToRem,
205
220
  remToPx,
@@ -33,7 +33,7 @@
33
33
  padding-bottom: 0;
34
34
  cursor: pointer;
35
35
  font-weight: normal;
36
- font-size: var(--hg-typo-font-size-xs, 12px);
36
+ font-size: var(--hg-typo-font-size-12);
37
37
  text-align: initial;
38
38
  display: flex;
39
39
  flex-direction: column;
@@ -52,7 +52,8 @@
52
52
  outline: 0;
53
53
  display: inline-block;
54
54
  vertical-align: top;
55
- margin: 0 var(--hg-spacing-10, 10px) 0 0;
55
+ /* Geometría del componente (círculo 14px + hueco): valor propio, no de la escala de spacing */
56
+ margin: 0 10px 0 0;
56
57
  border-radius: 0;
57
58
  }
58
59
 
@@ -61,7 +62,7 @@
61
62
  display: inline-block;
62
63
  vertical-align: top;
63
64
  margin: 0;
64
- line-height: var(--hg-typo-line-height-sm, 16px);
65
+ line-height: 16px;
65
66
  padding-left: var(--hg-spacing-24);
66
67
  min-height: 20px;
67
68
  }
@@ -127,7 +128,7 @@
127
128
  }
128
129
 
129
130
  .check-center .box3-content {
130
- padding-left: var(--hg-spacing-30, 30px);
131
+ padding-left: 30px; /* geometría: círculo + hueco, no escala de spacing */
131
132
  }
132
133
 
133
134
  .check-center.checkbox-radio [type=radio]:checked + label .border-1,
@@ -171,7 +172,7 @@
171
172
  }
172
173
 
173
174
  .check-top .box3-content {
174
- padding-left: var(--hg-spacing-30, 30px);
175
+ padding-left: 30px; /* geometría: círculo + hueco, no escala de spacing */
175
176
  }
176
177
 
177
178
  .check-top.checkbox-radio [type=radio]:checked + label .border-1,
@@ -192,7 +193,7 @@
192
193
  }
193
194
 
194
195
  .check-clear .box3-content {
195
- padding-left: var(--hg-spacing-30, 30px);
196
+ padding-left: 30px; /* geometría: círculo + hueco, no escala de spacing */
196
197
  }
197
198
 
198
199
  .check-clear.checkbox-radio [type=radio]:checked + label .border-1,
@@ -397,6 +397,23 @@ Todos los componentes son responsive por defecto. Puedes usar las clases respons
397
397
  </html>
398
398
  ```
399
399
 
400
+ ## 🔤 Tipografías HolyGrail5 (labels mono)
401
+
402
+ Además de los componentes del tema, puedes usar las clases tipográficas generadas desde `config.json` (prefijo `hg-`):
403
+
404
+ | Clase | Variante | Fuente | Mobile | Desktop |
405
+ |-------|----------|--------|--------|---------|
406
+ | `.label-mono` | Regular | `suisse-mono-regular` | 10px / 120% | 10px / 120% |
407
+ | `.label-mono-b` | Bold | `suisse-mono-bold` | 10px / 120% | 10px / 120% |
408
+
409
+ Comportamiento alineado con `.label-s` / `.label-s-b` (uppercase, `letter-spacing: 0.06em`). Variables CSS: `--hg-typo-font-family-mono-regular`, `--hg-typo-font-family-mono-bold`.
410
+
411
+ ```html
412
+ <span class="label-mono">Referencia SKU</span>
413
+ <span class="label-mono-b">Nuevo</span>
414
+
415
+ La tabla completa de tipografías del tema se genera en el build (`HG_TYPO_TABLE` en `demo.html` → `dist/themes/dutti-demo.html`).
416
+
400
417
  ## 📄 Ver Demo
401
418
 
402
419
  Abre `demo.html` en tu navegador para ver todos los componentes en acción:
@@ -42,6 +42,7 @@
42
42
  --checkbox-border: var(--hg-color-middle-grey);
43
43
  --checkbox-checked-bg: var(--hg-color-primary);
44
44
  --checkbox-checked-border: var(--hg-color-primary);
45
+ --checkbox-check-color: var(--hg-color-white);
45
46
 
46
47
  --radio-bg: var(--hg-color-white);
47
48
  --radio-border: var(--hg-color-middle-grey);
@@ -73,6 +74,8 @@
73
74
  --hg-typo-font-family-primary-regular: "suisse-regular", Arial, Helvetica, sans-serif;
74
75
  --hg-typo-font-family-primary-bold: "suisse-semibold", Arial, Helvetica, sans-serif;
75
76
  --hg-typo-font-family-secondary: "suisse-medium", Arial, Helvetica, sans-serif;
77
+ --hg-typo-font-family-mono-regular: "suisse-mono-regular", Arial, Helvetica, sans-serif;
78
+ --hg-typo-font-family-mono-bold: "suisse-mono-bold", Arial, Helvetica, sans-serif;
76
79
 
77
80
  /* Bordes y radios */
78
81
  --border-radius: 0;
@@ -60,7 +60,8 @@
60
60
  "bg": "var(--hg-color-white)",
61
61
  "border": "var(--hg-color-middle-grey)",
62
62
  "checked-bg": "var(--hg-color-primary)",
63
- "checked-border": "var(--hg-color-primary)"
63
+ "checked-border": "var(--hg-color-primary)",
64
+ "check-color": "var(--hg-color-white)"
64
65
  },
65
66
  "radio": {
66
67
  "bg": "var(--hg-color-white)",
@@ -77,6 +77,7 @@
77
77
  --checkbox-border: var(--hg-color-middle-grey);
78
78
  --checkbox-checked-bg: var(--hg-color-feel-dark);
79
79
  --checkbox-checked-border: var(--hg-color-feel-dark);
80
+ --checkbox-check-color: var(--hg-color-white);
80
81
 
81
82
  --radio-bg: var(--hg-color-white);
82
83
  --radio-border: var(--hg-color-middle-grey);
@@ -79,7 +79,8 @@
79
79
  "bg": "var(--hg-color-white)",
80
80
  "border": "var(--hg-color-middle-grey)",
81
81
  "checked-bg": "var(--hg-color-feel-dark)",
82
- "checked-border": "var(--hg-color-feel-dark)"
82
+ "checked-border": "var(--hg-color-feel-dark)",
83
+ "check-color": "var(--hg-color-white)"
83
84
  },
84
85
  "radio": {
85
86
  "bg": "var(--hg-color-white)",