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.
- package/README.md +72 -0
- package/config.json +85 -18
- package/dist/assets/fonts/SuisseIntlMono-Bold-WebS.woff +0 -0
- package/dist/assets/fonts/SuisseIntlMono-Bold-WebS.woff2 +0 -0
- package/dist/assets/fonts/SuisseIntlMono-Regular-WebS.woff +0 -0
- package/dist/assets/fonts/SuisseIntlMono-Regular-WebS.woff2 +0 -0
- package/dist/assets/fonts/suisse-intl-thin.woff +0 -0
- package/dist/assets/fonts/suisse-intl-thin.woff2 +0 -0
- package/dist/componentes.html +1 -8
- package/dist/developer-guide.md +4 -0
- package/dist/guide-styles.css +85 -56
- package/dist/index.html +2727 -2690
- package/dist/output.css +123 -70
- package/dist/skills.html +17 -5
- package/dist/themes/dutti-demo.html +76 -39
- package/dist/themes/dutti.css +10 -6
- package/dist/themes/limited-demo.html +55 -18
- package/dist/themes/limited.css +8 -6
- package/package.json +2 -2
- package/src/.data/.previous-values.json +69 -20
- package/src/assets/fonts/SuisseIntlMono-Bold-WebS.woff +0 -0
- package/src/assets/fonts/SuisseIntlMono-Bold-WebS.woff2 +0 -0
- package/src/assets/fonts/SuisseIntlMono-Regular-WebS.woff +0 -0
- package/src/assets/fonts/SuisseIntlMono-Regular-WebS.woff2 +0 -0
- package/src/assets/fonts/suisse-intl-thin.woff +0 -0
- package/src/assets/fonts/suisse-intl-thin.woff2 +0 -0
- package/src/build/asset-manager.js +8 -0
- package/src/build/components-generator.js +1 -8
- package/src/build/skills-generator.js +12 -4
- package/src/build/theme-transformer.js +10 -3
- package/src/dev-server.js +28 -13
- package/src/docs-generator/guide-styles.css +85 -56
- package/src/docs-generator/html-generator.js +188 -183
- package/src/docs-generator/sections/colors-section.js +15 -5
- package/src/generators/typo-generator.js +1 -2
- package/src/generators/utils.js +15 -0
- package/themes/_base/_radios.css +7 -6
- package/themes/dutti/README.md +17 -0
- package/themes/dutti/_variables.css +3 -0
- package/themes/dutti/theme.json +2 -1
- package/themes/limited/_variables.css +1 -0
- package/themes/limited/theme.json +2 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
|
-
const { pxToRem, remToPx, getFontFamilyName, resolveActiveThemes } = require('../generators/utils');
|
|
5
|
+
const { pxToRem, remToPx, getFontFamilyName, resolveActiveThemes, escapeHtml } = require('../generators/utils');
|
|
6
6
|
const { buildValueMap } = require('../css-generator');
|
|
7
7
|
const { generateTypographyHTML } = require('../build/typo-table-generator');
|
|
8
8
|
const {
|
|
@@ -28,7 +28,7 @@ function getLastCommitAuthor() {
|
|
|
28
28
|
// Obtiene la versión del package.json
|
|
29
29
|
function getPackageVersion() {
|
|
30
30
|
try {
|
|
31
|
-
const packagePath = path.join(__dirname, '..', 'package.json');
|
|
31
|
+
const packagePath = path.join(__dirname, '..', '..', 'package.json');
|
|
32
32
|
if (fs.existsSync(packagePath)) {
|
|
33
33
|
const packageData = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
34
34
|
return packageData.version || null;
|
|
@@ -38,6 +38,38 @@ function getPackageVersion() {
|
|
|
38
38
|
}
|
|
39
39
|
return null;
|
|
40
40
|
}
|
|
41
|
+
// Resuelve el grosor (font-weight) que DEBERÍA tener un cut a partir de su
|
|
42
|
+
// nombre/valor. Orden de comprobación importante: los compuestos
|
|
43
|
+
// (semibold, extralight…) se evalúan antes que los simples (bold, light)
|
|
44
|
+
// para no caer en el match equivocado.
|
|
45
|
+
function inferFontWeight(str) {
|
|
46
|
+
const t = String(str).toLowerCase();
|
|
47
|
+
if (/thin|hairline/.test(t)) return 100;
|
|
48
|
+
if (/extra[-\s]?light|ultra[-\s]?light/.test(t)) return 200;
|
|
49
|
+
if (/semi[-\s]?bold|demi[-\s]?bold/.test(t)) return 600;
|
|
50
|
+
if (/extra[-\s]?bold|ultra[-\s]?bold/.test(t)) return 800;
|
|
51
|
+
if (/black|heavy/.test(t)) return 900;
|
|
52
|
+
if (/bold/.test(t)) return 700;
|
|
53
|
+
if (/medium/.test(t)) return 500;
|
|
54
|
+
if (/light/.test(t)) return 300;
|
|
55
|
+
if (/regular|normal|book/.test(t)) return 400;
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Devuelve el grosor que DEBERÍA tener una entrada de fontFamilyMap. Prioriza
|
|
60
|
+
// el override explícito en `config.fontWeightMap[name]` (misma clave que
|
|
61
|
+
// fontFamilyMap); si no existe, lo infiere del VALOR (que nombra el cut real,
|
|
62
|
+
// p. ej. "suisse-semibold" → 600) y, como último recurso, de la clave. Se
|
|
63
|
+
// infiere del valor antes que de la clave a propósito: la clave puede mentir
|
|
64
|
+
// (`primary-bold` apunta en realidad a un SemiBold = 600, no a un Bold = 700).
|
|
65
|
+
// Devuelve null si no hay forma de determinarlo.
|
|
66
|
+
function resolveFontWeight(name, value, fontWeightMap) {
|
|
67
|
+
if (fontWeightMap && fontWeightMap[name] != null && fontWeightMap[name] !== '') {
|
|
68
|
+
return fontWeightMap[name];
|
|
69
|
+
}
|
|
70
|
+
return inferFontWeight(value) ?? inferFontWeight(name);
|
|
71
|
+
}
|
|
72
|
+
|
|
41
73
|
function generateHTML(configData, previousValuesPath = null) {
|
|
42
74
|
const classNames = Object.keys(configData.typo);
|
|
43
75
|
const prefix = configData.prefix || 'hg';
|
|
@@ -142,16 +174,16 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
142
174
|
<td class="guide-preview-cell">
|
|
143
175
|
<div class="guide-typography-preview ${className}">Aa</div>
|
|
144
176
|
</td>
|
|
145
|
-
<td class="guide-table-value ${fontFamilyChanged ? 'guide-changed' : ''}">${fontFamilyName || cls.fontFamily || '-'}</td>
|
|
146
|
-
<td class="guide-table-value ${fontWeightChanged ? 'guide-changed' : ''}">${cls.fontWeight || '-'}</td>
|
|
147
|
-
<td class="guide-table-value ${letterSpacingChanged ? 'guide-changed' : ''}">${cls.letterSpacing || '-'}</td>
|
|
148
|
-
<td class="guide-table-value ${textTransformChanged ? 'guide-changed' : ''}">${cls.textTransform || '-'}</td>
|
|
177
|
+
<td class="guide-table-value ${fontFamilyChanged ? 'guide-changed' : ''}">${escapeHtml(fontFamilyName || cls.fontFamily || '-')}</td>
|
|
178
|
+
<td class="guide-table-value ${fontWeightChanged ? 'guide-changed' : ''}">${escapeHtml(cls.fontWeight || '-')}</td>
|
|
179
|
+
<td class="guide-table-value ${letterSpacingChanged ? 'guide-changed' : ''}">${escapeHtml(cls.letterSpacing || '-')}</td>
|
|
180
|
+
<td class="guide-table-value ${textTransformChanged ? 'guide-changed' : ''}">${escapeHtml(cls.textTransform || '-')}</td>
|
|
149
181
|
<td class="guide-mobile-value guide-value-center-blue ${mobileFontSizeChanged ? 'guide-changed' : ''}">${mobileRem}</td>
|
|
150
182
|
<td class="guide-mobile-value guide-value-center-orange ${mobileFontSizeChanged ? 'guide-changed' : ''}">${mobilePx}</td>
|
|
151
|
-
<td class="guide-mobile-value ${mobileLineHeightChanged ? 'guide-changed' : ''}">${cls.mobile?.lineHeight || '-'}</td>
|
|
183
|
+
<td class="guide-mobile-value ${mobileLineHeightChanged ? 'guide-changed' : ''}">${escapeHtml(cls.mobile?.lineHeight || '-')}</td>
|
|
152
184
|
<td class="guide-desktop-value guide-value-center-blue ${desktopFontSizeChanged ? 'guide-changed' : ''}">${desktopRem}</td>
|
|
153
185
|
<td class="guide-desktop-value guide-value-center-orange ${desktopFontSizeChanged ? 'guide-changed' : ''}">${desktopPx}</td>
|
|
154
|
-
<td class="guide-desktop-value ${desktopLineHeightChanged ? 'guide-changed' : ''}">${cls.desktop?.lineHeight || '-'}</td>
|
|
186
|
+
<td class="guide-desktop-value ${desktopLineHeightChanged ? 'guide-changed' : ''}">${escapeHtml(cls.desktop?.lineHeight || '-')}</td>
|
|
155
187
|
</tr>`;
|
|
156
188
|
}).join('');
|
|
157
189
|
const classesHTML = `
|
|
@@ -186,14 +218,24 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
186
218
|
// Generar tabla de font families
|
|
187
219
|
const fontFamiliesHTML = configData.fontFamilyMap ? Object.entries(configData.fontFamilyMap).map(([name, value]) => {
|
|
188
220
|
const varName = `--${prefix}-${category}-font-family-${name}`;
|
|
189
|
-
|
|
221
|
+
// El valor va dentro de un atributo style con comillas simples. Escapar
|
|
222
|
+
// como HTML (no con "\\'") evita que un valor con comillas rompa el
|
|
223
|
+
// atributo; el parser decodifica la entidad y el CSS recibe la comilla.
|
|
224
|
+
const styleValue = escapeHtml(value);
|
|
190
225
|
const isChanged = changedValues.has(`fontFamilyMap.${name}`);
|
|
226
|
+
// Grosor que debería tener este cut (override en config.fontWeightMap o
|
|
227
|
+
// inferido del nombre). El preview se pinta con ese font-weight además de
|
|
228
|
+
// la familia, para que se vea el peso real esperado.
|
|
229
|
+
const weight = resolveFontWeight(name, value, configData.fontWeightMap);
|
|
230
|
+
const weightCell = weight != null ? escapeHtml(weight) : '—';
|
|
231
|
+
const previewWeight = weight != null ? `font-weight: ${escapeHtml(weight)};` : '';
|
|
191
232
|
return `
|
|
192
233
|
<tr>
|
|
193
|
-
<td class="guide-table-name">${name}</td>
|
|
194
|
-
<td class="guide-font-family-preview" style='font-family: ${styleValue};'>Aa</td>
|
|
195
|
-
<td class="guide-table-value
|
|
196
|
-
<td class="guide-table-value">${
|
|
234
|
+
<td class="guide-table-name">${escapeHtml(name)}</td>
|
|
235
|
+
<td class="guide-font-family-preview" style='font-family: ${styleValue}; ${previewWeight}'>Aa</td>
|
|
236
|
+
<td class="guide-table-value">${weightCell}</td>
|
|
237
|
+
<td class="guide-table-value ${isChanged ? 'guide-changed' : ''}">${escapeHtml(value)}</td>
|
|
238
|
+
<td class="guide-table-value">${escapeHtml(varName)}</td>
|
|
197
239
|
</tr>`;
|
|
198
240
|
}).join('') : '';
|
|
199
241
|
const fontFamiliesTableHTML = configData.fontFamilyMap ? `
|
|
@@ -203,6 +245,7 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
203
245
|
<tr>
|
|
204
246
|
<th>Nombre</th>
|
|
205
247
|
<th>Preview</th>
|
|
248
|
+
<th>Grosor</th>
|
|
206
249
|
<th>Valor</th>
|
|
207
250
|
<th>Variable CSS</th>
|
|
208
251
|
</tr>
|
|
@@ -236,16 +279,19 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
236
279
|
// Para variables con conversión (spacing / font-size) mostramos rem + px
|
|
237
280
|
// (sin duplicar el rem en una columna aparte). Para el resto, solo el valor.
|
|
238
281
|
// Para variables de color añadimos un swatch a la derecha del valor.
|
|
282
|
+
const eValue = escapeHtml(variable.value);
|
|
283
|
+
const eName = escapeHtml(variable.name);
|
|
284
|
+
const ePx = escapeHtml(remToPx(variable.value, baseFontSize));
|
|
239
285
|
const swatchHTML = isColorVar
|
|
240
|
-
? `<span class="guide-variable-swatch" style="background:${
|
|
286
|
+
? `<span class="guide-variable-swatch" style="background:${eValue}" title="${eValue}"></span>`
|
|
241
287
|
: '';
|
|
242
288
|
const valueHTML = canConvert
|
|
243
|
-
? `<span class="guide-value-center-blue guide-copyable ${changedCls}" data-copy-value="${
|
|
244
|
-
<span class="guide-value-center-orange guide-copyable ${changedCls}" data-copy-value="${
|
|
245
|
-
: `<span class="guide-variable-value guide-copyable ${changedCls}" data-copy-value="${
|
|
289
|
+
? `<span class="guide-value-center-blue guide-copyable ${changedCls}" data-copy-value="${eValue}" title="Click para copiar ${eValue}">${eValue}</span>
|
|
290
|
+
<span class="guide-value-center-orange guide-copyable ${changedCls}" data-copy-value="${ePx}" title="Click para copiar ${ePx}">${ePx}</span>`
|
|
291
|
+
: `<span class="guide-variable-value guide-copyable ${changedCls}" data-copy-value="${eValue}" title="Click para copiar ${eValue}">${eValue}</span>`;
|
|
246
292
|
return `
|
|
247
293
|
<div class="guide-variable-item">
|
|
248
|
-
<span class="guide-variable-name guide-copyable ${changedCls}" data-copy-value="${
|
|
294
|
+
<span class="guide-variable-name guide-copyable ${changedCls}" data-copy-value="${eName}" title="Click para copiar ${eName}">${eName}</span>
|
|
249
295
|
<span class="guide-variable-values">${valueHTML}${swatchHTML}</span>
|
|
250
296
|
</div>`;
|
|
251
297
|
};
|
|
@@ -359,7 +405,7 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
359
405
|
<tr class="guide-table-synthesis-note">
|
|
360
406
|
<td class="guide-spacing-sides-cell"></td>
|
|
361
407
|
<td class="guide-table-name"><strong>Valores para <n>-percent</strong></td>
|
|
362
|
-
<td colspan="3" class="guide-table-value">${spacingPercentKeysLegacy}.</td>
|
|
408
|
+
<td colspan="3" class="guide-table-value">${escapeHtml(spacingPercentKeysLegacy)}.</td>
|
|
363
409
|
</tr>
|
|
364
410
|
</tbody>
|
|
365
411
|
</table>
|
|
@@ -438,12 +484,12 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
438
484
|
<tr class="guide-table-synthesis-note">
|
|
439
485
|
<td class="guide-spacing-sides-cell"></td>
|
|
440
486
|
<td class="guide-table-name"><strong>Valores para <valor></strong></td>
|
|
441
|
-
<td colspan="2" class="guide-table-value">${spacingNumericKeys}. Ver tabla Legacy arriba para rem/px.</td>
|
|
487
|
+
<td colspan="2" class="guide-table-value">${escapeHtml(spacingNumericKeys)}. Ver tabla Legacy arriba para rem/px.</td>
|
|
442
488
|
</tr>
|
|
443
489
|
<tr class="guide-table-synthesis-note">
|
|
444
490
|
<td class="guide-spacing-sides-cell"></td>
|
|
445
491
|
<td class="guide-table-name"><strong>Valores para <n>-percent</strong></td>
|
|
446
|
-
<td colspan="2" class="guide-table-value">${spacingPercentKeys}. Ver tabla Legacy arriba para equivalencias.</td>
|
|
492
|
+
<td colspan="2" class="guide-table-value">${escapeHtml(spacingPercentKeys)}. Ver tabla Legacy arriba para equivalencias.</td>
|
|
447
493
|
</tr>
|
|
448
494
|
</tbody>
|
|
449
495
|
</table>
|
|
@@ -451,7 +497,7 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
451
497
|
// Estilos dinámicos basados en config
|
|
452
498
|
const allStyles = `
|
|
453
499
|
body {
|
|
454
|
-
font-family: var(--${prefix}-${category}-font-family-primary);
|
|
500
|
+
font-family: var(--${prefix}-${category}-font-family-primary-regular);
|
|
455
501
|
}`;
|
|
456
502
|
// Generar tabla de layout helpers
|
|
457
503
|
const layoutHelpersHTML = configData.helpers ? Object.entries(configData.helpers).flatMap(([helperName, config]) => {
|
|
@@ -462,40 +508,40 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
462
508
|
const rows = [];
|
|
463
509
|
if (useSpacing && configData.spacingMap) {
|
|
464
510
|
Object.entries(configData.spacingMap).forEach(([key, value]) => {
|
|
465
|
-
const baseClass = `.${prefix}-${className}-${key}
|
|
466
|
-
const responsiveClass = responsive ? `.md:${prefix}-${className}-${key}` : '';
|
|
511
|
+
const baseClass = escapeHtml(`.${prefix}-${className}-${key}`);
|
|
512
|
+
const responsiveClass = responsive ? escapeHtml(`.md:${prefix}-${className}-${key}`) : '';
|
|
467
513
|
const remValue = value.endsWith('%') ? value : pxToRem(value, baseFontSize);
|
|
468
514
|
rows.push(`
|
|
469
515
|
<tr>
|
|
470
516
|
<td class="guide-layout-class-name guide-copyable" data-copy-value="${baseClass}" title="Click para copiar ${baseClass}">${baseClass}</td>
|
|
471
517
|
<td class="guide-layout-class-name ${responsiveClass ? 'guide-copyable' : ''}" ${responsiveClass ? `data-copy-value="${responsiveClass}" title="Click para copiar ${responsiveClass}"` : ''}>${responsiveClass || '-'}</td>
|
|
472
|
-
<td class="guide-layout-property">${property}: ${remValue}</td>
|
|
473
|
-
<td class="guide-layout-property">${helperDescription || '-'}</td>
|
|
518
|
+
<td class="guide-layout-property">${escapeHtml(property)}: ${escapeHtml(remValue)}</td>
|
|
519
|
+
<td class="guide-layout-property">${escapeHtml(helperDescription || '-')}</td>
|
|
474
520
|
</tr>`);
|
|
475
521
|
});
|
|
476
522
|
} else if (values) {
|
|
477
523
|
if (Array.isArray(values)) {
|
|
478
524
|
values.forEach(value => {
|
|
479
|
-
const baseClass = `.${prefix}-${className}-${value}
|
|
480
|
-
const responsiveClass = responsive ? `.md:${prefix}-${className}-${value}` : '';
|
|
525
|
+
const baseClass = escapeHtml(`.${prefix}-${className}-${value}`);
|
|
526
|
+
const responsiveClass = responsive ? escapeHtml(`.md:${prefix}-${className}-${value}`) : '';
|
|
481
527
|
rows.push(`
|
|
482
528
|
<tr>
|
|
483
529
|
<td class="guide-layout-class-name guide-copyable" data-copy-value="${baseClass}" title="Click para copiar ${baseClass}">${baseClass}</td>
|
|
484
530
|
<td class="guide-layout-class-name ${responsiveClass ? 'guide-copyable' : ''}" ${responsiveClass ? `data-copy-value="${responsiveClass}" title="Click para copiar ${responsiveClass}"` : ''}>${responsiveClass || '-'}</td>
|
|
485
|
-
<td class="guide-layout-property">${property}: ${value}</td>
|
|
486
|
-
<td class="guide-layout-property">${helperDescription || '-'}</td>
|
|
531
|
+
<td class="guide-layout-property">${escapeHtml(property)}: ${escapeHtml(value)}</td>
|
|
532
|
+
<td class="guide-layout-property">${escapeHtml(helperDescription || '-')}</td>
|
|
487
533
|
</tr>`);
|
|
488
534
|
});
|
|
489
535
|
} else {
|
|
490
536
|
Object.entries(values).forEach(([key, value]) => {
|
|
491
|
-
const baseClass = `.${prefix}-${className}-${key}
|
|
492
|
-
const responsiveClass = responsive ? `.md:${prefix}-${className}-${key}` : '';
|
|
537
|
+
const baseClass = escapeHtml(`.${prefix}-${className}-${key}`);
|
|
538
|
+
const responsiveClass = responsive ? escapeHtml(`.md:${prefix}-${className}-${key}`) : '';
|
|
493
539
|
rows.push(`
|
|
494
540
|
<tr>
|
|
495
541
|
<td class="guide-layout-class-name guide-copyable" data-copy-value="${baseClass}" title="Click para copiar ${baseClass}">${baseClass}</td>
|
|
496
542
|
<td class="guide-layout-class-name ${responsiveClass ? 'guide-copyable' : ''}" ${responsiveClass ? `data-copy-value="${responsiveClass}" title="Click para copiar ${responsiveClass}"` : ''}>${responsiveClass || '-'}</td>
|
|
497
|
-
<td class="guide-layout-property">${property}: ${value}</td>
|
|
498
|
-
<td class="guide-layout-property">${helperDescription || '-'}</td>
|
|
543
|
+
<td class="guide-layout-property">${escapeHtml(property)}: ${escapeHtml(value)}</td>
|
|
544
|
+
<td class="guide-layout-property">${escapeHtml(helperDescription || '-')}</td>
|
|
499
545
|
</tr>`);
|
|
500
546
|
});
|
|
501
547
|
}
|
|
@@ -533,15 +579,11 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
533
579
|
menuItems.push({ id: 'font-families', label: 'Font Families' });
|
|
534
580
|
}
|
|
535
581
|
menuItems.push(
|
|
536
|
-
{ id: 'tipografia', label: 'Tipografía' }
|
|
537
|
-
{ id: 'variables', label: 'Variables CSS' }
|
|
582
|
+
{ id: 'tipografia', label: 'Tipografía' }
|
|
538
583
|
);
|
|
539
584
|
if (spacingHelpersTableHTML) {
|
|
540
585
|
menuItems.push({ id: 'spacing', label: 'Spacing' });
|
|
541
586
|
}
|
|
542
|
-
if (layoutHelpersTableHTML) {
|
|
543
|
-
menuItems.push({ id: 'layout', label: 'Helpers de Layout' });
|
|
544
|
-
}
|
|
545
587
|
if (configData.grid && configData.grid.enabled) {
|
|
546
588
|
menuItems.push({ id: 'grid', label: 'Grid System' });
|
|
547
589
|
}
|
|
@@ -556,6 +598,11 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
556
598
|
if (activeThemes.length > 0) {
|
|
557
599
|
menuItems.push({ id: 'containers', label: 'Containers' });
|
|
558
600
|
}
|
|
601
|
+
// Helpers de Layout y Variables CSS van al final de la guía.
|
|
602
|
+
if (layoutHelpersTableHTML) {
|
|
603
|
+
menuItems.push({ id: 'layout', label: 'Helpers de Layout' });
|
|
604
|
+
}
|
|
605
|
+
menuItems.push({ id: 'variables', label: 'Variables CSS' });
|
|
559
606
|
const menuHTML = menuItems.map(item => `
|
|
560
607
|
<a href="#${item.id}" class="guide-menu-item" data-section="${item.id}">${item.label}</a>
|
|
561
608
|
`).join('');
|
|
@@ -577,35 +624,11 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html" class="gui
|
|
|
577
624
|
<meta http-equiv="Pragma" content="no-cache">
|
|
578
625
|
<meta http-equiv="Expires" content="0">
|
|
579
626
|
<title>HolyGrail5 - Guía de Tipografía</title>
|
|
580
|
-
<!-- Google Fonts - Solo para la guía -->
|
|
581
|
-
<link href="https://fonts.googleapis.com" rel="preconnect">
|
|
582
|
-
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin="anonymous">
|
|
583
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Instrument+Sans:regular,100,500,600,700" media="all">
|
|
584
|
-
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100&display=swap" rel="stylesheet">
|
|
585
627
|
|
|
586
|
-
<!-- Lenis Smooth Scroll - Solo para la guía -->
|
|
587
|
-
<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@1.0.29/bundled/lenis.min.js"></script>
|
|
588
628
|
<link rel="stylesheet" href="output.css?v=${Date.now()}">
|
|
589
629
|
<link rel="stylesheet" href="guide-styles.css?v=${Date.now()}">
|
|
590
630
|
<style>
|
|
591
631
|
${allStyles}
|
|
592
|
-
/* Lenis Smooth Scroll Styles - Solo para la guía */
|
|
593
|
-
html.lenis {
|
|
594
|
-
height: auto;
|
|
595
|
-
}
|
|
596
|
-
.lenis.lenis-smooth {
|
|
597
|
-
scroll-behavior: auto;
|
|
598
|
-
}
|
|
599
|
-
.lenis.lenis-smooth[data-lenis-prevent] {
|
|
600
|
-
overscroll-behavior: contain;
|
|
601
|
-
}
|
|
602
|
-
.lenis.lenis-stopped {
|
|
603
|
-
overflow: hidden;
|
|
604
|
-
}
|
|
605
|
-
/* Google Fonts - Solo para la guía (sobrescribe la fuente del body) */
|
|
606
|
-
body {
|
|
607
|
-
font-family: 'Instrument Sans', sans-serif !important;
|
|
608
|
-
}
|
|
609
632
|
</style>
|
|
610
633
|
</head>
|
|
611
634
|
<body>
|
|
@@ -625,12 +648,12 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html" class="gui
|
|
|
625
648
|
</p>
|
|
626
649
|
${packageVersion ? `
|
|
627
650
|
<p class="text-m guide-sidebar-meta-small">
|
|
628
|
-
Version: ${packageVersion}
|
|
651
|
+
Version: ${escapeHtml(packageVersion)}
|
|
629
652
|
</p>
|
|
630
653
|
` : ''}
|
|
631
654
|
${lastCommitAuthor ? `
|
|
632
655
|
<p class="text-s guide-sidebar-meta-small">
|
|
633
|
-
Last user: ${lastCommitAuthor}
|
|
656
|
+
Last user: ${escapeHtml(lastCommitAuthor)}
|
|
634
657
|
</p>
|
|
635
658
|
` : ''}
|
|
636
659
|
</div>
|
|
@@ -669,7 +692,7 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html" class="gui
|
|
|
669
692
|
<nav class="guide-nav">
|
|
670
693
|
<a href="index.html" class="active">Guía</a>
|
|
671
694
|
<a href="componentes.html">Componentes</a>
|
|
672
|
-
${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}</a>`).join('\n')}
|
|
695
|
+
${activeThemes.map(t => ` <a href="themes/${encodeURIComponent(t.name)}-demo.html">${escapeHtml(t.label)}</a>`).join('\n')}
|
|
673
696
|
<a href="skills.html">Skills</a>
|
|
674
697
|
</nav>
|
|
675
698
|
<button class="guide-header-button" onclick="toggleSidebar()">☰</button>
|
|
@@ -776,11 +799,6 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
776
799
|
</div>
|
|
777
800
|
</div>
|
|
778
801
|
<div class="guide-section-content">
|
|
779
|
-
<div id="variables">
|
|
780
|
-
<h3 class="title-m mb-16">Variables CSS</h3>
|
|
781
|
-
<p class="guide-section-description mb-24">Variables compartidas usadas por el spacing y el sistema.</p>
|
|
782
|
-
${variablesTableHTML}
|
|
783
|
-
</div>
|
|
784
802
|
<div class="guide-info-box guide-info-box-warning mb-32">
|
|
785
803
|
<strong class="mb-16" style="display: block;">¿Cómo se generan los helpers de espaciado?</strong>
|
|
786
804
|
<div class="row">
|
|
@@ -801,14 +819,14 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
801
819
|
<strong>Clases Modernas (RTL-aware):</strong> A estas clases legacy se añaden versiones inline con prefijo <code class="guide-info-box-code-info">hg-</code>: <code class="guide-info-box-code-info">.${prefix}-px-{valor}</code> (padding-inline/horizontal), <code class="guide-info-box-code-info">.${prefix}-py-{valor}</code> (padding-block/vertical), <code class="guide-info-box-code-info">.${prefix}-mx-{valor}</code> (margin-inline/horizontal), <code class="guide-info-box-code-info">.${prefix}-my-{valor}</code> (margin-block/vertical).
|
|
802
820
|
</p>
|
|
803
821
|
<p class="text-m guide-info-box-text-small">
|
|
804
|
-
<strong>Nota:</strong> Los helpers con prefijo <code class="guide-info-box-code-info">md:</code> funcionan como en Tailwind CSS y solo se aplican en el breakpoint desktop (≥${configData.breakpoints.desktop}). Puedes combinar clases base y con prefijo <code class="guide-info-box-code-info">md:</code> para crear diseños responsive. Las clases con <code class="guide-info-box-code-info">!</code> aplican !important y tienen prioridad sobre otras reglas CSS.
|
|
822
|
+
<strong>Nota:</strong> Los helpers con prefijo <code class="guide-info-box-code-info">md:</code> funcionan como en Tailwind CSS y solo se aplican en el breakpoint desktop (≥${escapeHtml(configData.breakpoints.desktop)}). Puedes combinar clases base y con prefijo <code class="guide-info-box-code-info">md:</code> para crear diseños responsive. Las clases con <code class="guide-info-box-code-info">!</code> aplican !important y tienen prioridad sobre otras reglas CSS.
|
|
805
823
|
</p>
|
|
806
824
|
</div>
|
|
807
825
|
<div class="col-xs-12 col-md-6 guide-spacing-explanation-col">
|
|
808
826
|
<p class="text-m guide-info-box-text"><strong>Ejemplos de uso:</strong></p>
|
|
809
827
|
<ul class="guide-info-box-list">
|
|
810
828
|
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.p-4</code> — Aplica padding de 4px en todos los tamaños de pantalla</li>
|
|
811
|
-
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.md:p-4</code> — Aplica padding de 4px solo en desktop (≥${configData.breakpoints.desktop})</li>
|
|
829
|
+
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.md:p-4</code> — Aplica padding de 4px solo en desktop (≥${escapeHtml(configData.breakpoints.desktop)})</li>
|
|
812
830
|
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.md:pr-8</code> — Aplica padding-right de 8px solo en desktop</li>
|
|
813
831
|
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.md:mt-16</code> — Aplica margin-top de 16px solo en desktop</li>
|
|
814
832
|
<li class="text-m guide-info-box-list-item"><code class="guide-info-box-code-info">.p-0!</code> — Aplica padding de 0 con !important (útil para sobrescribir otros estilos)</li>
|
|
@@ -822,54 +840,6 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
822
840
|
</div>
|
|
823
841
|
</div>
|
|
824
842
|
` : ''}
|
|
825
|
-
${layoutHelpersTableHTML ? `
|
|
826
|
-
<div class="guide-section" id="layout">
|
|
827
|
-
<div class="row mb-120">
|
|
828
|
-
<div class="col-xs-12 col-md-6"> <h2>Layout</h2> </div>
|
|
829
|
-
<div class="col-xs-12 col-md-6 guide-section-description">
|
|
830
|
-
<p class="text-m ">
|
|
831
|
-
Clases helper para display, flexbox, alignment y gap.
|
|
832
|
-
Todos los helpers marcados como responsive tienen variantes con prefijo .md: para desktop (≥${configData.breakpoints.desktop}).
|
|
833
|
-
</p> </div>
|
|
834
|
-
<div class="col-xs-12 col-md-12">
|
|
835
|
-
<hr>
|
|
836
|
-
</div>
|
|
837
|
-
</div>
|
|
838
|
-
<div class="guide-section-content">
|
|
839
|
-
${layoutHelpersTableHTML}
|
|
840
|
-
<div class="guide-section-title">
|
|
841
|
-
<div> </div>
|
|
842
|
-
<div class="demo-section-2">
|
|
843
|
-
<div>
|
|
844
|
-
<strong>Ejemplos de uso:</strong>
|
|
845
|
-
<ul class="guide-info-box-list">
|
|
846
|
-
<li class="text-m guide-info-box-list-item">
|
|
847
|
-
<code class="guide-info-box-code-info">.d-flex</code> - Display flex
|
|
848
|
-
</li>
|
|
849
|
-
<li class="text-m guide-info-box-list-item">
|
|
850
|
-
<code class="guide-info-box-code-info">.flex-column</code> - Flex direction column
|
|
851
|
-
</li>
|
|
852
|
-
<li class="text-m guide-info-box-list-item">
|
|
853
|
-
<code class="guide-info-box-code-info">.justify-center</code> - Justify content center
|
|
854
|
-
</li>
|
|
855
|
-
<li class="text-m guide-info-box-list-item">
|
|
856
|
-
<code class="guide-info-box-code-info">.items-center</code> - Align items center
|
|
857
|
-
</li>
|
|
858
|
-
<li class="text-m guide-info-box-list-item">
|
|
859
|
-
<code class="guide-info-box-code-info">.gap-16</code> - Gap de 16px (1rem)
|
|
860
|
-
</li>
|
|
861
|
-
<li class="text-m guide-info-box-list-item">
|
|
862
|
-
<code class="guide-info-box-code-info">.md:flex-row</code> - Flex direction row solo en desktop
|
|
863
|
-
</li>
|
|
864
|
-
</ul>
|
|
865
|
-
</div>
|
|
866
|
-
<div>
|
|
867
|
-
</div>
|
|
868
|
-
</div>
|
|
869
|
-
</div>
|
|
870
|
-
</div>
|
|
871
|
-
</div>
|
|
872
|
-
` : ''}
|
|
873
843
|
${configData.grid && configData.grid.enabled ? `
|
|
874
844
|
<div class="guide-section" id="grid">
|
|
875
845
|
<div class="row mb-120">
|
|
@@ -901,19 +871,19 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
901
871
|
<strong>.row</strong> - Contenedor flex con márgenes negativos para compensar el gutter
|
|
902
872
|
</li>
|
|
903
873
|
<li class="text-m guide-info-box-list-item">
|
|
904
|
-
<strong>.col-xs-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.xs} (12 columnas)
|
|
874
|
+
<strong>.col-xs-*</strong> - Columnas para pantallas desde ${escapeHtml(configData.grid.breakpoints.xs.minWidth || configData.grid.breakpoints.xs)} (12 columnas)
|
|
905
875
|
</li>
|
|
906
876
|
<li class="text-m guide-info-box-list-item">
|
|
907
|
-
<strong>.col-sm-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.sm} (12 columnas)
|
|
877
|
+
<strong>.col-sm-*</strong> - Columnas para pantallas desde ${escapeHtml(configData.grid.breakpoints.sm.minWidth || configData.grid.breakpoints.sm)} (12 columnas)
|
|
908
878
|
</li>
|
|
909
879
|
<li class="text-m guide-info-box-list-item">
|
|
910
|
-
<strong>.col-md-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.md} (12 columnas)
|
|
880
|
+
<strong>.col-md-*</strong> - Columnas para pantallas desde ${escapeHtml(configData.grid.breakpoints.md.minWidth || configData.grid.breakpoints.md)} (12 columnas)
|
|
911
881
|
</li>
|
|
912
882
|
<li class="text-m guide-info-box-list-item">
|
|
913
|
-
<strong>.col-lg-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.lg} (12 columnas)
|
|
883
|
+
<strong>.col-lg-*</strong> - Columnas para pantallas desde ${escapeHtml(configData.grid.breakpoints.lg.minWidth || configData.grid.breakpoints.lg)} (12 columnas)
|
|
914
884
|
</li>
|
|
915
885
|
<li class="text-m guide-info-box-list-item">
|
|
916
|
-
<strong>.col-xl-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.xl} (24 columnas)
|
|
886
|
+
<strong>.col-xl-*</strong> - Columnas para pantallas desde ${escapeHtml(configData.grid.breakpoints.xl.minWidth || configData.grid.breakpoints.xl)} (24 columnas)
|
|
917
887
|
</li>
|
|
918
888
|
<li class="text-m guide-info-box-list-item">
|
|
919
889
|
<strong>.bleed</strong> - Permite que las columnas vayan a sangre (full bleed), eliminando los márgenes laterales del gutter
|
|
@@ -923,7 +893,7 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
923
893
|
</li>
|
|
924
894
|
|
|
925
895
|
<li class="text-m guide-info-box-list-item">
|
|
926
|
-
<strong>Gutter:</strong> ${configData.grid.gutter} (padding horizontal en cada columna)
|
|
896
|
+
<strong>Gutter:</strong> ${escapeHtml(configData.grid.gutter)} (padding horizontal en cada columna)
|
|
927
897
|
</li>
|
|
928
898
|
</ul>
|
|
929
899
|
|
|
@@ -959,16 +929,18 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
959
929
|
const marginLateral = configData.grid.containerMargin || '-';
|
|
960
930
|
const marginLateralRem = marginLateral !== '-' && String(marginLateral).endsWith('px') ? pxToRem(marginLateral, baseFontSize) : marginLateral !== '-' ? marginLateral : '-';
|
|
961
931
|
const marginLateralPx = marginLateral;
|
|
932
|
+
const eName = escapeHtml(name);
|
|
933
|
+
const eColumns = escapeHtml(columns);
|
|
962
934
|
return `<tr>
|
|
963
|
-
<td class="guide-table-name">${
|
|
964
|
-
<td class="guide-table-value">${minWidth}</td>
|
|
965
|
-
<td class="guide-table-value">${minWidthRem}</td>
|
|
966
|
-
<td class="guide-table-value">${
|
|
967
|
-
<td class="guide-value-center-orange">${gutterPx}</td>
|
|
968
|
-
<td class="guide-value-center-blue">${gutterRem}</td>
|
|
969
|
-
<td class="guide-value-center-orange">${marginLateralPx}</td>
|
|
970
|
-
<td class="guide-value-center-blue">${marginLateralRem}</td>
|
|
971
|
-
<td class="guide-table-value">.col-${
|
|
935
|
+
<td class="guide-table-name">${eName}</td>
|
|
936
|
+
<td class="guide-table-value">${escapeHtml(minWidth)}</td>
|
|
937
|
+
<td class="guide-table-value">${escapeHtml(minWidthRem)}</td>
|
|
938
|
+
<td class="guide-table-value">${eColumns}</td>
|
|
939
|
+
<td class="guide-value-center-orange">${escapeHtml(gutterPx)}</td>
|
|
940
|
+
<td class="guide-value-center-blue">${escapeHtml(gutterRem)}</td>
|
|
941
|
+
<td class="guide-value-center-orange">${escapeHtml(marginLateralPx)}</td>
|
|
942
|
+
<td class="guide-value-center-blue">${escapeHtml(marginLateralRem)}</td>
|
|
943
|
+
<td class="guide-table-value">.col-${eName}-1 a .col-${eName}-${eColumns}</td>
|
|
972
944
|
</tr>`;
|
|
973
945
|
}).join('\n ')}
|
|
974
946
|
</tbody>
|
|
@@ -1003,10 +975,10 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1003
975
|
En <strong>xs</strong>: Ocupan 12 columnas cada una (100% de ancho, apiladas)
|
|
1004
976
|
</li>
|
|
1005
977
|
<li class="text-m guide-info-box-list-item">
|
|
1006
|
-
En <strong>md</strong> (≥${configData.grid.breakpoints.md}): Las dos primeras ocupan 6 columnas (50% cada una), la tercera 12 (100%)
|
|
978
|
+
En <strong>md</strong> (≥${escapeHtml(configData.grid.breakpoints.md.minWidth || configData.grid.breakpoints.md)}): Las dos primeras ocupan 6 columnas (50% cada una), la tercera 12 (100%)
|
|
1007
979
|
</li>
|
|
1008
980
|
<li class="text-m guide-info-box-list-item">
|
|
1009
|
-
En <strong>lg</strong> (≥${configData.grid.breakpoints.lg}): Cada una ocupa 4 columnas (33.33% cada una, 3 columnas por fila)
|
|
981
|
+
En <strong>lg</strong> (≥${escapeHtml(configData.grid.breakpoints.lg.minWidth || configData.grid.breakpoints.lg)}): Cada una ocupa 4 columnas (33.33% cada una, 3 columnas por fila)
|
|
1010
982
|
</li>
|
|
1011
983
|
</ul>
|
|
1012
984
|
</div>
|
|
@@ -1032,7 +1004,7 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1032
1004
|
</div>
|
|
1033
1005
|
</div></code></pre>
|
|
1034
1006
|
<p class="text-m guide-info-box-text-small">
|
|
1035
|
-
<strong>Nota:</strong> <code class="guide-info-box-code-info">.bleed</code> aplica márgenes negativos iguales al gutter (${configData.grid.gutter}) para que el contenido llegue hasta los bordes. <code class="guide-info-box-code-info">.bleed-0</code> elimina todo el padding y márgenes, útil para imágenes o contenido que debe ocupar todo el ancho disponible.
|
|
1007
|
+
<strong>Nota:</strong> <code class="guide-info-box-code-info">.bleed</code> aplica márgenes negativos iguales al gutter (${escapeHtml(configData.grid.gutter)}) para que el contenido llegue hasta los bordes. <code class="guide-info-box-code-info">.bleed-0</code> elimina todo el padding y márgenes, útil para imágenes o contenido que debe ocupar todo el ancho disponible.
|
|
1036
1008
|
</p>
|
|
1037
1009
|
</div>
|
|
1038
1010
|
</div>
|
|
@@ -1079,14 +1051,16 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1079
1051
|
${configData.aspectRatios.map(ratio => {
|
|
1080
1052
|
const { class: className, width, height, description } = ratio;
|
|
1081
1053
|
const ratioValue = `${width}:${height}`;
|
|
1054
|
+
const eClassName = escapeHtml(className);
|
|
1055
|
+
const eRatioValue = escapeHtml(ratioValue);
|
|
1082
1056
|
return `<tr>
|
|
1083
|
-
<td class="guide-table-name">.${prefix}-${
|
|
1084
|
-
<td class="guide-table-value">${
|
|
1085
|
-
<td class="guide-table-description">${description}</td>
|
|
1057
|
+
<td class="guide-table-name">.${prefix}-${eClassName}</td>
|
|
1058
|
+
<td class="guide-table-value">${eRatioValue}</td>
|
|
1059
|
+
<td class="guide-table-description">${escapeHtml(description)}</td>
|
|
1086
1060
|
<td class="guide-preview-cell">
|
|
1087
|
-
<div class="${prefix}-${
|
|
1061
|
+
<div class="${prefix}-${eClassName}" style="background: var(--${prefix}-color-primary); max-width: 100px;">
|
|
1088
1062
|
<div class="${prefix}-aspect-content">
|
|
1089
|
-
<img class="${prefix}-aspect-image" src="assets/introm.jpg" alt="Ejemplo ${
|
|
1063
|
+
<img class="${prefix}-aspect-image" src="assets/introm.jpg" alt="Ejemplo ${eRatioValue}" />
|
|
1090
1064
|
</div>
|
|
1091
1065
|
</div>
|
|
1092
1066
|
</td>
|
|
@@ -1176,15 +1150,15 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1176
1150
|
<tr>
|
|
1177
1151
|
<td class="guide-table-name">Mobile</td>
|
|
1178
1152
|
<td class="guide-table-value ${changedValues.has('breakpoints.mobile') ? 'guide-changed' : ''}">
|
|
1179
|
-
${configData.breakpoints.mobile}
|
|
1180
|
-
${configData.breakpoints.mobile.endsWith('px') ? `(${pxToRem(configData.breakpoints.mobile, baseFontSize)})` : ''}
|
|
1153
|
+
${escapeHtml(configData.breakpoints.mobile)}
|
|
1154
|
+
${configData.breakpoints.mobile.endsWith('px') ? `(${escapeHtml(pxToRem(configData.breakpoints.mobile, baseFontSize))})` : ''}
|
|
1181
1155
|
</td>
|
|
1182
1156
|
</tr>
|
|
1183
1157
|
<tr>
|
|
1184
1158
|
<td class="guide-table-name">Desktop</td>
|
|
1185
1159
|
<td class="guide-table-value ${changedValues.has('breakpoints.desktop') ? 'guide-changed' : ''}">
|
|
1186
|
-
${configData.breakpoints.desktop}
|
|
1187
|
-
${configData.breakpoints.desktop.endsWith('px') ? `(${pxToRem(configData.breakpoints.desktop, baseFontSize)})` : ''}
|
|
1160
|
+
${escapeHtml(configData.breakpoints.desktop)}
|
|
1161
|
+
${configData.breakpoints.desktop.endsWith('px') ? `(${escapeHtml(pxToRem(configData.breakpoints.desktop, baseFontSize))})` : ''}
|
|
1188
1162
|
</td>
|
|
1189
1163
|
</tr>
|
|
1190
1164
|
</tbody>
|
|
@@ -1198,7 +1172,7 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1198
1172
|
<div class="col-xs-12 col-md-6"> <h2>Containers</h2> </div>
|
|
1199
1173
|
<div class="col-xs-12 col-md-6 guide-section-description">
|
|
1200
1174
|
<p>
|
|
1201
|
-
Contenedores responsivos ${activeThemes.length === 1 ? 'del tema ' + activeThemes[0].label.replace(/^Tema\s+/, '') : 'de los temas activos'}. Cada container define un <code>max-width</code> y padding adaptativo según breakpoint.
|
|
1175
|
+
Contenedores responsivos ${activeThemes.length === 1 ? 'del tema ' + escapeHtml(activeThemes[0].label.replace(/^Tema\s+/, '')) : 'de los temas activos'}. Cada container define un <code>max-width</code> y padding adaptativo según breakpoint.
|
|
1202
1176
|
</p>
|
|
1203
1177
|
</div>
|
|
1204
1178
|
<div class="col-xs-12 col-md-12"><hr></div>
|
|
@@ -1360,6 +1334,69 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1360
1334
|
</div>
|
|
1361
1335
|
</div>
|
|
1362
1336
|
` : ''}
|
|
1337
|
+
${layoutHelpersTableHTML ? `
|
|
1338
|
+
<div class="guide-section" id="layout">
|
|
1339
|
+
<div class="row mb-120">
|
|
1340
|
+
<div class="col-xs-12 col-md-6"> <h2>Layout</h2> </div>
|
|
1341
|
+
<div class="col-xs-12 col-md-6 guide-section-description">
|
|
1342
|
+
<p class="text-m ">
|
|
1343
|
+
Clases helper para display, flexbox, alignment y gap.
|
|
1344
|
+
Todos los helpers marcados como responsive tienen variantes con prefijo .md: para desktop (≥${escapeHtml(configData.breakpoints.desktop)}).
|
|
1345
|
+
</p> </div>
|
|
1346
|
+
<div class="col-xs-12 col-md-12">
|
|
1347
|
+
<hr>
|
|
1348
|
+
</div>
|
|
1349
|
+
</div>
|
|
1350
|
+
<div class="guide-section-content">
|
|
1351
|
+
${layoutHelpersTableHTML}
|
|
1352
|
+
<div class="guide-section-title">
|
|
1353
|
+
<div> </div>
|
|
1354
|
+
<div class="demo-section-2">
|
|
1355
|
+
<div>
|
|
1356
|
+
<strong>Ejemplos de uso:</strong>
|
|
1357
|
+
<ul class="guide-info-box-list">
|
|
1358
|
+
<li class="text-m guide-info-box-list-item">
|
|
1359
|
+
<code class="guide-info-box-code-info">.d-flex</code> - Display flex
|
|
1360
|
+
</li>
|
|
1361
|
+
<li class="text-m guide-info-box-list-item">
|
|
1362
|
+
<code class="guide-info-box-code-info">.flex-column</code> - Flex direction column
|
|
1363
|
+
</li>
|
|
1364
|
+
<li class="text-m guide-info-box-list-item">
|
|
1365
|
+
<code class="guide-info-box-code-info">.justify-center</code> - Justify content center
|
|
1366
|
+
</li>
|
|
1367
|
+
<li class="text-m guide-info-box-list-item">
|
|
1368
|
+
<code class="guide-info-box-code-info">.items-center</code> - Align items center
|
|
1369
|
+
</li>
|
|
1370
|
+
<li class="text-m guide-info-box-list-item">
|
|
1371
|
+
<code class="guide-info-box-code-info">.gap-16</code> - Gap de 16px (1rem)
|
|
1372
|
+
</li>
|
|
1373
|
+
<li class="text-m guide-info-box-list-item">
|
|
1374
|
+
<code class="guide-info-box-code-info">.md:flex-row</code> - Flex direction row solo en desktop
|
|
1375
|
+
</li>
|
|
1376
|
+
</ul>
|
|
1377
|
+
</div>
|
|
1378
|
+
<div>
|
|
1379
|
+
</div>
|
|
1380
|
+
</div>
|
|
1381
|
+
</div>
|
|
1382
|
+
</div>
|
|
1383
|
+
</div>
|
|
1384
|
+
` : ''}
|
|
1385
|
+
<div class="guide-section" id="variables">
|
|
1386
|
+
<div class="row mb-120">
|
|
1387
|
+
<div class="col-xs-12 col-md-6"> <h2>Variables CSS</h2> </div>
|
|
1388
|
+
<div class="col-xs-12 col-md-6 guide-section-description">
|
|
1389
|
+
<p class="">
|
|
1390
|
+
Variables CSS compartidas (<code>--${prefix}-*</code>) usadas por el spacing y el resto del sistema.
|
|
1391
|
+
</p> </div>
|
|
1392
|
+
<div class="col-xs-12 col-md-12">
|
|
1393
|
+
<hr>
|
|
1394
|
+
</div>
|
|
1395
|
+
</div>
|
|
1396
|
+
<div class="guide-section-content">
|
|
1397
|
+
${variablesTableHTML}
|
|
1398
|
+
</div>
|
|
1399
|
+
</div>
|
|
1363
1400
|
</div>
|
|
1364
1401
|
</main>
|
|
1365
1402
|
<script>
|
|
@@ -1395,15 +1432,8 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1395
1432
|
if (targetSection) {
|
|
1396
1433
|
const offset = 80; // Offset para compensar header
|
|
1397
1434
|
const targetPosition = targetSection.offsetTop - offset;
|
|
1398
|
-
//
|
|
1399
|
-
|
|
1400
|
-
window.lenis.scrollTo(targetSection, { offset: -offset });
|
|
1401
|
-
} else {
|
|
1402
|
-
window.scrollTo({
|
|
1403
|
-
top: targetPosition,
|
|
1404
|
-
behavior: 'smooth'
|
|
1405
|
-
});
|
|
1406
|
-
}
|
|
1435
|
+
// Salto directo, sin suavizado
|
|
1436
|
+
window.scrollTo(0, targetPosition);
|
|
1407
1437
|
// Cerrar sidebar después de hacer clic
|
|
1408
1438
|
closeSidebar();
|
|
1409
1439
|
}
|
|
@@ -1632,31 +1662,6 @@ ${activeThemes.map(t => ` <a href="themes/${t.name}-demo.html">${t.label}
|
|
|
1632
1662
|
setupCopyToClipboard();
|
|
1633
1663
|
}
|
|
1634
1664
|
</script>
|
|
1635
|
-
<script>
|
|
1636
|
-
// Inicializar Lenis Smooth Scroll - Solo para la guía
|
|
1637
|
-
const lenis = new Lenis({
|
|
1638
|
-
duration: 1.2,
|
|
1639
|
-
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
|
|
1640
|
-
direction: 'vertical',
|
|
1641
|
-
gestureDirection: 'vertical',
|
|
1642
|
-
smooth: true,
|
|
1643
|
-
mouseMultiplier: 1,
|
|
1644
|
-
smoothTouch: false,
|
|
1645
|
-
touchMultiplier: 2,
|
|
1646
|
-
infinite: false,
|
|
1647
|
-
});
|
|
1648
|
-
function raf(time) {
|
|
1649
|
-
lenis.raf(time);
|
|
1650
|
-
requestAnimationFrame(raf);
|
|
1651
|
-
}
|
|
1652
|
-
requestAnimationFrame(raf);
|
|
1653
|
-
// Integrar con el scroll del navegador
|
|
1654
|
-
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
|
|
1655
|
-
// Puedes agregar callbacks aquí si es necesario
|
|
1656
|
-
});
|
|
1657
|
-
// Hacer lenis disponible globalmente para el scroll del menú
|
|
1658
|
-
window.lenis = lenis;
|
|
1659
|
-
</script>
|
|
1660
1665
|
</body>
|
|
1661
1666
|
</html>`;
|
|
1662
1667
|
}
|