holygrail5 1.0.5 → 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 +467 -0
- package/config.json +168 -1
- package/package.json +5 -3
- package/src/dev.js +3 -2
- package/src/guide.js +36 -42
- package/src/parser.js +156 -85
package/README.md
CHANGED
|
@@ -578,4 +578,471 @@ Para desplegar en GitHub Pages, puedes:
|
|
|
578
578
|
|
|
579
579
|
---
|
|
580
580
|
|
|
581
|
+
## 🚀 ¿Por qué HolyGrail5? Evolución desde HolyGrail CSS (SASS)
|
|
582
|
+
|
|
583
|
+
### El Problema con SASS
|
|
584
|
+
|
|
585
|
+
HolyGrail CSS original se basaba en **SASS/SCSS**, lo que presentaba varios desafíos:
|
|
586
|
+
|
|
587
|
+
#### Limitaciones de SASS
|
|
588
|
+
|
|
589
|
+
1. **Dependencia de compilación**: Requiere herramientas de build (Gulp, Webpack, etc.) y procesos de compilación
|
|
590
|
+
2. **Curva de aprendizaje**: Necesitas conocer SASS/SCSS para personalizar
|
|
591
|
+
3. **Configuración compleja**: Variables SASS dispersas en múltiples archivos
|
|
592
|
+
4. **Sin documentación automática**: No genera guías visuales de las clases disponibles
|
|
593
|
+
5. **Mantenimiento manual**: Cambios en variables requieren editar código SASS directamente
|
|
594
|
+
6. **Sin historial**: No hay gestión automática de variables no usadas
|
|
595
|
+
7. **Menos portable**: Depende del ecosistema SASS y sus herramientas
|
|
596
|
+
|
|
597
|
+
### La Solución: HolyGrail5
|
|
598
|
+
|
|
599
|
+
HolyGrail5 nace de la necesidad de **simplificar, modernizar y potenciar** el framework original.
|
|
600
|
+
|
|
601
|
+
#### Ventajas Clave de HolyGrail5
|
|
602
|
+
|
|
603
|
+
##### 1. **Configuración Declarativa con JSON**
|
|
604
|
+
|
|
605
|
+
**Antes (SASS):**
|
|
606
|
+
```scss
|
|
607
|
+
// Variables dispersas en múltiples archivos
|
|
608
|
+
$font-size-mobile: 18px;
|
|
609
|
+
$font-size-desktop: 24px;
|
|
610
|
+
$spacing-16: 16px;
|
|
611
|
+
// ... más variables en diferentes archivos
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
**Ahora (JSON):**
|
|
615
|
+
```json
|
|
616
|
+
{
|
|
617
|
+
"classes": {
|
|
618
|
+
"h2": {
|
|
619
|
+
"mobile": { "fontSize": "18px" },
|
|
620
|
+
"desktop": { "fontSize": "24px" }
|
|
621
|
+
}
|
|
622
|
+
},
|
|
623
|
+
"spacingMap": { "16": "16px" }
|
|
624
|
+
}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
✅ **Ventaja**: Todo en un solo archivo, fácil de entender y modificar
|
|
628
|
+
|
|
629
|
+
##### 2. **Sin Dependencias de Build Complejas**
|
|
630
|
+
|
|
631
|
+
**Antes (SASS):**
|
|
632
|
+
- Requiere Gulp/Webpack/Grunt
|
|
633
|
+
- Configuración de compilación
|
|
634
|
+
- Dependencias de Node.js específicas
|
|
635
|
+
- Procesos de build complejos
|
|
636
|
+
|
|
637
|
+
**Ahora (HolyGrail5):**
|
|
638
|
+
```bash
|
|
639
|
+
npm run generate
|
|
640
|
+
# ¡Listo! CSS generado
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
✅ **Ventaja**: Un solo comando, sin configuración de build
|
|
644
|
+
|
|
645
|
+
##### 3. **Guía Interactiva Automática**
|
|
646
|
+
|
|
647
|
+
**Antes (SASS):**
|
|
648
|
+
- Documentación manual
|
|
649
|
+
- Sin preview visual
|
|
650
|
+
- Difícil saber qué clases están disponibles
|
|
651
|
+
|
|
652
|
+
**Ahora (HolyGrail5):**
|
|
653
|
+
- Guía HTML generada automáticamente
|
|
654
|
+
- Preview visual de todas las clases
|
|
655
|
+
- Búsqueda en tiempo real
|
|
656
|
+
- Detección de cambios
|
|
657
|
+
|
|
658
|
+
✅ **Ventaja**: Documentación siempre actualizada y visual
|
|
659
|
+
|
|
660
|
+
##### 4. **Gestión Inteligente de Variables**
|
|
661
|
+
|
|
662
|
+
**Antes (SASS):**
|
|
663
|
+
- Variables se eliminan si no se usan
|
|
664
|
+
- Puede romper CSS personalizado
|
|
665
|
+
- Sin historial
|
|
666
|
+
|
|
667
|
+
**Ahora (HolyGrail5):**
|
|
668
|
+
- Historial persistente de variables
|
|
669
|
+
- Nunca se eliminan automáticamente
|
|
670
|
+
- Comandos para gestionar variables no usadas
|
|
671
|
+
- Protege tu CSS personalizado
|
|
672
|
+
|
|
673
|
+
✅ **Ventaja**: Seguridad y control total sobre las variables
|
|
674
|
+
|
|
675
|
+
##### 5. **Variables CSS Nativas (No SASS)**
|
|
676
|
+
|
|
677
|
+
**Antes (SASS):**
|
|
678
|
+
```scss
|
|
679
|
+
// Variables SASS (solo en compilación)
|
|
680
|
+
$primary-color: #000000;
|
|
681
|
+
.my-class {
|
|
682
|
+
color: $primary-color; // Compilado a CSS estático
|
|
683
|
+
}
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
**Ahora (HolyGrail5):**
|
|
687
|
+
```css
|
|
688
|
+
/* Variables CSS nativas (runtime) */
|
|
689
|
+
:root {
|
|
690
|
+
--hg-color-primary: #000000;
|
|
691
|
+
}
|
|
692
|
+
.my-class {
|
|
693
|
+
color: var(--hg-color-primary); // Cambiable en runtime
|
|
694
|
+
}
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
✅ **Ventaja**: Variables CSS nativas, modificables en runtime, mejor rendimiento
|
|
698
|
+
|
|
699
|
+
##### 6. **Optimización Automática**
|
|
700
|
+
|
|
701
|
+
**Antes (SASS):**
|
|
702
|
+
- Duplicación de valores en múltiples lugares
|
|
703
|
+
- CSS más pesado
|
|
704
|
+
- Sin deduplicación automática
|
|
705
|
+
|
|
706
|
+
**Ahora (HolyGrail5):**
|
|
707
|
+
- Variables compartidas automáticamente
|
|
708
|
+
- Un valor único → una variable CSS
|
|
709
|
+
- CSS más pequeño y eficiente
|
|
710
|
+
|
|
711
|
+
✅ **Ventaja**: CSS optimizado automáticamente, menos código
|
|
712
|
+
|
|
713
|
+
##### 7. **Modo Watch Integrado**
|
|
714
|
+
|
|
715
|
+
**Antes (SASS):**
|
|
716
|
+
- Requiere configurar watch en Gulp/Webpack
|
|
717
|
+
- Configuración adicional necesaria
|
|
718
|
+
|
|
719
|
+
**Ahora (HolyGrail5):**
|
|
720
|
+
```bash
|
|
721
|
+
npm run watch
|
|
722
|
+
# Regenera automáticamente al cambiar config.json
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
✅ **Ventaja**: Watch listo para usar, sin configuración
|
|
726
|
+
|
|
727
|
+
##### 8. **Portabilidad y Simplicidad**
|
|
728
|
+
|
|
729
|
+
**Antes (SASS):**
|
|
730
|
+
- Múltiples archivos SASS
|
|
731
|
+
- Estructura compleja
|
|
732
|
+
- Dependencias de herramientas de build
|
|
733
|
+
|
|
734
|
+
**Ahora (HolyGrail5):**
|
|
735
|
+
- Un solo archivo JSON de configuración
|
|
736
|
+
- Estructura simple y clara
|
|
737
|
+
- Solo Node.js (sin SASS, Gulp, etc.)
|
|
738
|
+
|
|
739
|
+
✅ **Ventaja**: Más fácil de entender, mantener y compartir
|
|
740
|
+
|
|
741
|
+
##### 9. **Mejor para Equipos**
|
|
742
|
+
|
|
743
|
+
**Antes (SASS):**
|
|
744
|
+
- Solo desarrolladores que conocen SASS pueden modificar
|
|
745
|
+
- Cambios requieren conocimiento técnico
|
|
746
|
+
|
|
747
|
+
**Ahora (HolyGrail5):**
|
|
748
|
+
- Cualquiera puede editar JSON
|
|
749
|
+
- Cambios visibles inmediatamente
|
|
750
|
+
- Menos barrera de entrada
|
|
751
|
+
|
|
752
|
+
✅ **Ventaja**: Colaboración más fácil, menos dependencia de desarrolladores
|
|
753
|
+
|
|
754
|
+
##### 10. **Ecosistema Moderno**
|
|
755
|
+
|
|
756
|
+
**Antes (SASS):**
|
|
757
|
+
- Tecnología más antigua
|
|
758
|
+
- Menos integración con herramientas modernas
|
|
759
|
+
- Ecosistema SASS en declive
|
|
760
|
+
|
|
761
|
+
**Ahora (HolyGrail5):**
|
|
762
|
+
- Tecnología moderna (Node.js, JSON, CSS Variables)
|
|
763
|
+
- Mejor integración con herramientas actuales
|
|
764
|
+
- Alineado con estándares web modernos
|
|
765
|
+
|
|
766
|
+
✅ **Ventaja**: Framework preparado para el futuro
|
|
767
|
+
|
|
768
|
+
##### 11. **Separación de Componentes y Flexibilidad**
|
|
769
|
+
|
|
770
|
+
**Antes (HolyGrail CSS con Angular):**
|
|
771
|
+
- Framework acoplado a Angular
|
|
772
|
+
- Componentes incluidos (botones, cards, etc.) que aumentaban el peso
|
|
773
|
+
- CSS pesado con estilos de componentes que no siempre se usaban
|
|
774
|
+
- Difícil integrar otras librerías de componentes
|
|
775
|
+
- Dependencia de Angular y sus componentes
|
|
776
|
+
|
|
777
|
+
**Ahora (HolyGrail5):**
|
|
778
|
+
- **Solo CSS puro**: Sin dependencias de frameworks
|
|
779
|
+
- **Sin componentes incluidos**: Solo clases de utilidad y layout
|
|
780
|
+
- **CSS ligero**: Solo lo esencial (tipografía, spacing, layout, grid)
|
|
781
|
+
- **Integración flexible**: Puedes usar cualquier librería de componentes
|
|
782
|
+
- **Compatible con MDS de Inditex**: Diseñado para trabajar junto con sistemas de componentes externos
|
|
783
|
+
|
|
784
|
+
✅ **Ventaja**: Framework ligero, flexible y compatible con cualquier librería de componentes
|
|
785
|
+
|
|
786
|
+
##### 12. **Maquetación con IA**
|
|
787
|
+
|
|
788
|
+
**Antes (SASS + Angular):**
|
|
789
|
+
- Estructura compleja difícil de entender para IA
|
|
790
|
+
- Código SASS disperso
|
|
791
|
+
- Componentes acoplados
|
|
792
|
+
- Difícil generar código automáticamente
|
|
793
|
+
|
|
794
|
+
**Ahora (HolyGrail5):**
|
|
795
|
+
- **Configuración JSON clara**: Fácil de entender y generar por IA
|
|
796
|
+
- **Clases semánticas**: Nomenclatura clara y predecible
|
|
797
|
+
- **Superprompt disponible**: Guía completa para que IA genere código correcto
|
|
798
|
+
- **Estructura simple**: Patrones claros y repetibles
|
|
799
|
+
|
|
800
|
+
✅ **Ventaja**: Perfecto para maquetación asistida por IA, generación automática de código
|
|
801
|
+
|
|
802
|
+
### Separación de Responsabilidades
|
|
803
|
+
|
|
804
|
+
HolyGrail5 adopta una **filosofía de separación de responsabilidades**:
|
|
805
|
+
|
|
806
|
+
#### Lo que INCLUYE HolyGrail5:
|
|
807
|
+
- ✅ Sistema de tipografía
|
|
808
|
+
- ✅ Helpers de spacing (padding, margin)
|
|
809
|
+
- ✅ Helpers de layout (flexbox, grid)
|
|
810
|
+
- ✅ Sistema de grid responsive
|
|
811
|
+
- ✅ Variables CSS para colores
|
|
812
|
+
- ✅ Reset CSS mínimo
|
|
813
|
+
|
|
814
|
+
#### Lo que NO incluye (y por qué es mejor):
|
|
815
|
+
- ❌ Componentes UI (botones, cards, modales, etc.)
|
|
816
|
+
- ❌ Estilos de formularios
|
|
817
|
+
- ❌ Estilos de navegación
|
|
818
|
+
- ❌ Estilos específicos de Angular/React/Vue
|
|
819
|
+
|
|
820
|
+
**Razón**: Esto permite:
|
|
821
|
+
1. **Usar MDS de Inditex** u otras librerías de componentes sin conflictos
|
|
822
|
+
2. **CSS más ligero**: Solo lo esencial
|
|
823
|
+
3. **Flexibilidad total**: Eliges tus propios componentes
|
|
824
|
+
4. **Mejor mantenimiento**: Cada cosa en su lugar
|
|
825
|
+
|
|
826
|
+
### Integración con MDS de Inditex
|
|
827
|
+
|
|
828
|
+
HolyGrail5 está diseñado para trabajar **perfectamente** junto con MDS (Massimo Dutti System) de Inditex:
|
|
829
|
+
|
|
830
|
+
```html
|
|
831
|
+
<!-- Usa HolyGrail5 para layout y spacing -->
|
|
832
|
+
<div class="row">
|
|
833
|
+
<div class="col-xs-12 col-md-6">
|
|
834
|
+
<!-- Usa componentes MDS para UI -->
|
|
835
|
+
<mds-button variant="primary">Botón MDS</mds-button>
|
|
836
|
+
</div>
|
|
837
|
+
</div>
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
**Ventajas de esta combinación:**
|
|
841
|
+
- ✅ HolyGrail5 maneja el layout y estructura
|
|
842
|
+
- ✅ MDS proporciona los componentes UI
|
|
843
|
+
- ✅ Sin conflictos de estilos
|
|
844
|
+
- ✅ Mejor de ambos mundos
|
|
845
|
+
|
|
846
|
+
### Maquetación con IA
|
|
847
|
+
|
|
848
|
+
HolyGrail5 es **ideal para maquetación asistida por IA** gracias a:
|
|
849
|
+
|
|
850
|
+
1. **Superprompt disponible**: Guía completa (`SUPERPROMPT.md`) que permite a la IA entender el sistema
|
|
851
|
+
2. **Nomenclatura clara**: Clases predecibles y semánticas
|
|
852
|
+
3. **Patrones simples**: Estructura fácil de seguir
|
|
853
|
+
4. **Configuración JSON**: Fácil de generar y modificar automáticamente
|
|
854
|
+
|
|
855
|
+
**Ejemplo de uso con IA:**
|
|
856
|
+
```
|
|
857
|
+
Prompt: "Crea una página de restaurante con header, hero, menú de platos y footer usando HolyGrail5"
|
|
858
|
+
|
|
859
|
+
La IA puede:
|
|
860
|
+
- Consultar SUPERPROMPT.md para entender las clases
|
|
861
|
+
- Generar HTML con las clases correctas
|
|
862
|
+
- Usar el grid system apropiado
|
|
863
|
+
- Aplicar spacing y layout helpers correctamente
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
✅ **Ventaja**: Acelera el desarrollo con generación automática de código
|
|
867
|
+
|
|
868
|
+
### Comparación Directa
|
|
869
|
+
|
|
870
|
+
| Característica | HolyGrail CSS (SASS) | HolyGrail5 | ¿Por qué HolyGrail5 es mejor? |
|
|
871
|
+
|----------------|----------------------|------------|------------------------------|
|
|
872
|
+
| **Configuración** | Múltiples archivos SASS dispersos | Un solo archivo JSON (`config.json`) | ✅ **Simplicidad**: Todo en un lugar, fácil de entender y modificar |
|
|
873
|
+
| **Compilación** | Requiere Gulp/Webpack y configuración compleja | `npm run generate` (comando simple) | ✅ **Sin complejidad**: No necesitas configurar build tools |
|
|
874
|
+
| **Variables** | Variables SASS (compiladas, estáticas) | Variables CSS nativas (runtime, dinámicas) | ✅ **Flexibilidad**: Puedes cambiar valores en runtime con JavaScript |
|
|
875
|
+
| **Documentación** | Manual, requiere mantenimiento | Automática (HTML interactivo generado) | ✅ **Siempre actualizada**: Se genera automáticamente desde la configuración |
|
|
876
|
+
| **Gestión de variables** | Manual, propenso a errores | Automática con historial y herramientas CLI | ✅ **Seguridad**: Herramientas para detectar y eliminar variables no usadas |
|
|
877
|
+
| **Curva de aprendizaje** | Media-Alta (requiere conocer SASS) | Baja (solo JSON, fácil de entender) | ✅ **Accesibilidad**: Cualquiera puede editar sin conocimientos técnicos avanzados |
|
|
878
|
+
| **Portabilidad** | Media (depende de SASS y build tools) | Alta (solo Node.js, sin dependencias complejas) | ✅ **Fácil de mover**: Menos dependencias, más portable |
|
|
879
|
+
| **Optimización** | Manual (debes optimizar tú mismo) | Automática (elimina código no usado) | ✅ **Rendimiento**: CSS más pequeño automáticamente |
|
|
880
|
+
| **Watch mode** | Requiere configuración en Gulp/Webpack | Integrado (`npm run watch`) | ✅ **Desarrollo rápido**: Watch mode listo para usar |
|
|
881
|
+
| **Accesibilidad** | Solo desarrolladores con conocimientos SASS | Cualquiera puede editar (diseñadores, PMs, etc.) | ✅ **Colaboración**: Más personas pueden contribuir |
|
|
882
|
+
| **Componentes** | Incluidos (botones, cards, modales, etc.) | Separados (solo utilidades) | ✅ **Ligereza**: No incluye código que no uses |
|
|
883
|
+
| **Peso CSS** | Pesado (cientos de clases de componentes) | Ligero (solo utilidades esenciales) | ✅ **Rendimiento**: CSS más pequeño = páginas más rápidas |
|
|
884
|
+
| **Integración** | Acoplado a Angular | Compatible con cualquier librería | ✅ **Flexibilidad**: Puedes usar MDS, Material, Bootstrap, etc. |
|
|
885
|
+
| **Maquetación IA** | Difícil (estructura compleja) | Optimizado (JSON claro, superprompt) | ✅ **Futuro**: Perfecto para generación automática de código |
|
|
886
|
+
|
|
887
|
+
### Casos de Uso Ideales para HolyGrail5
|
|
888
|
+
|
|
889
|
+
✅ **Perfecto para:**
|
|
890
|
+
- Proyectos que buscan simplicidad
|
|
891
|
+
- Equipos con diferentes niveles técnicos
|
|
892
|
+
- Proyectos que necesitan documentación automática
|
|
893
|
+
- Aplicaciones que requieren variables CSS en runtime
|
|
894
|
+
- Proyectos que quieren evitar dependencias de build complejas
|
|
895
|
+
- Design systems que necesitan mantenimiento fácil
|
|
896
|
+
- **Proyectos que usan MDS de Inditex u otras librerías de componentes**
|
|
897
|
+
- **Maquetación asistida por IA**
|
|
898
|
+
- **Proyectos que necesitan CSS ligero sin componentes incluidos**
|
|
899
|
+
|
|
900
|
+
### Migración desde HolyGrail CSS (SASS)
|
|
901
|
+
|
|
902
|
+
Si vienes de HolyGrail CSS (SASS), la migración es sencilla:
|
|
903
|
+
|
|
904
|
+
1. **Extrae tus variables SASS** → Conviértelas a `config.json`
|
|
905
|
+
2. **Mantén tus clases HTML** → Son compatibles
|
|
906
|
+
3. **Regenera el CSS** → `npm run generate`
|
|
907
|
+
4. **Disfruta de las nuevas características** → Guía interactiva, watch mode, etc.
|
|
908
|
+
|
|
909
|
+
### Arquitectura Ligera y Flexible
|
|
910
|
+
|
|
911
|
+
#### El Problema del Framework Anterior
|
|
912
|
+
|
|
913
|
+
El framework original (HolyGrail CSS) incluía:
|
|
914
|
+
- **Componentes de Angular**: Botones, cards, modales, etc.
|
|
915
|
+
- **CSS pesado**: Estilos de componentes que no siempre se necesitaban
|
|
916
|
+
- **Acoplamiento**: Dependencia de Angular y sus componentes
|
|
917
|
+
- **Poco flexible**: Difícil usar otras librerías de componentes
|
|
918
|
+
|
|
919
|
+
**Ejemplos de clases incluidas en el framework antiguo (que aumentaban el peso):**
|
|
920
|
+
```css
|
|
921
|
+
/* Formularios acoplados a Angular */
|
|
922
|
+
.form-input-label-2
|
|
923
|
+
.form-input-label-2.has-ico-pre
|
|
924
|
+
.form-input-label-2.has-ico-post
|
|
925
|
+
.validation-error-messages
|
|
926
|
+
|
|
927
|
+
/* Botones y links específicos */
|
|
928
|
+
.btn
|
|
929
|
+
.link-line
|
|
930
|
+
.link-svg-pre
|
|
931
|
+
.link-svg-post
|
|
932
|
+
|
|
933
|
+
/* Componentes de navegación */
|
|
934
|
+
.header-account-back
|
|
935
|
+
.mn-mainmenu
|
|
936
|
+
.mn-mainbar
|
|
937
|
+
.tabs-mini
|
|
938
|
+
|
|
939
|
+
/* Componentes UI */
|
|
940
|
+
.tooltip-sm
|
|
941
|
+
.toast
|
|
942
|
+
.md-accordion
|
|
943
|
+
.md-toggle
|
|
944
|
+
.bottom-sheet
|
|
945
|
+
.tag-product
|
|
946
|
+
.list-state
|
|
947
|
+
|
|
948
|
+
/* Soporte RTL específico */
|
|
949
|
+
.is-rtl .form-input-label-2
|
|
950
|
+
.is-rtl .btn
|
|
951
|
+
.is-rtl .tooltip-sm
|
|
952
|
+
/* ... y cientos más */
|
|
953
|
+
```
|
|
954
|
+
|
|
955
|
+
**Problema**: Estas clases ocupaban espacio en el CSS final aunque no se usaran, y creaban conflictos al intentar usar otras librerías de componentes como MDS.
|
|
956
|
+
|
|
957
|
+
#### La Solución: Separación de Responsabilidades
|
|
958
|
+
|
|
959
|
+
HolyGrail5 adopta el principio de **"hacer una cosa y hacerla bien"**:
|
|
960
|
+
|
|
961
|
+
**HolyGrail5 se enfoca en:**
|
|
962
|
+
- Layout y estructura (grid, flexbox)
|
|
963
|
+
- Spacing y tipografía
|
|
964
|
+
- Variables CSS compartidas
|
|
965
|
+
- Helpers de utilidad
|
|
966
|
+
|
|
967
|
+
**NO incluye:**
|
|
968
|
+
- Componentes UI (botones, cards, etc.)
|
|
969
|
+
- Estilos de formularios
|
|
970
|
+
- Estilos específicos de frameworks
|
|
971
|
+
|
|
972
|
+
**Resultado:**
|
|
973
|
+
- ✅ CSS más ligero (solo lo esencial)
|
|
974
|
+
- ✅ Compatible con MDS de Inditex
|
|
975
|
+
- ✅ Compatible con cualquier librería de componentes
|
|
976
|
+
- ✅ Flexibilidad total para elegir tus componentes
|
|
977
|
+
|
|
978
|
+
### Integración con MDS de Inditex
|
|
979
|
+
|
|
980
|
+
HolyGrail5 está diseñado específicamente para trabajar junto con **MDS (Massimo Dutti System)** de Inditex:
|
|
981
|
+
|
|
982
|
+
```html
|
|
983
|
+
<!-- Layout con HolyGrail5 -->
|
|
984
|
+
<div class="row">
|
|
985
|
+
<div class="col-xs-12 col-md-6 p-16">
|
|
986
|
+
<!-- Componentes de MDS -->
|
|
987
|
+
<mds-button variant="primary">Reservar Mesa</mds-button>
|
|
988
|
+
<mds-card>
|
|
989
|
+
<mds-card-header>Título</mds-card-header>
|
|
990
|
+
<mds-card-content>Contenido</mds-card-content>
|
|
991
|
+
</mds-card>
|
|
992
|
+
</div>
|
|
993
|
+
</div>
|
|
994
|
+
```
|
|
995
|
+
|
|
996
|
+
**Ventajas:**
|
|
997
|
+
- ✅ Sin conflictos de estilos
|
|
998
|
+
- ✅ HolyGrail5 maneja layout, MDS maneja componentes
|
|
999
|
+
- ✅ Mejor de ambos mundos
|
|
1000
|
+
- ✅ CSS optimizado y ligero
|
|
1001
|
+
|
|
1002
|
+
### Maquetación con IA
|
|
1003
|
+
|
|
1004
|
+
HolyGrail5 es **perfecto para maquetación asistida por IA**:
|
|
1005
|
+
|
|
1006
|
+
#### ¿Por qué funciona tan bien con IA?
|
|
1007
|
+
|
|
1008
|
+
1. **Superprompt disponible**: `SUPERPROMPT.md` contiene toda la información necesaria
|
|
1009
|
+
2. **Nomenclatura clara**: Clases predecibles y semánticas
|
|
1010
|
+
3. **Patrones simples**: Estructura fácil de seguir
|
|
1011
|
+
4. **Configuración JSON**: Fácil de generar automáticamente
|
|
1012
|
+
5. **Sin complejidad**: No hay componentes acoplados que confundan a la IA
|
|
1013
|
+
|
|
1014
|
+
#### Ejemplo de Uso con IA
|
|
1015
|
+
|
|
1016
|
+
```
|
|
1017
|
+
Prompt para IA:
|
|
1018
|
+
"Crea una página de restaurante con header sticky, hero section,
|
|
1019
|
+
grid de 6 platos destacados, sección sobre nosotros y footer,
|
|
1020
|
+
usando HolyGrail5 según SUPERPROMPT.md"
|
|
1021
|
+
|
|
1022
|
+
La IA puede:
|
|
1023
|
+
✅ Generar HTML con las clases correctas
|
|
1024
|
+
✅ Usar el grid system apropiado
|
|
1025
|
+
✅ Aplicar spacing helpers correctamente
|
|
1026
|
+
✅ Crear layouts responsive
|
|
1027
|
+
✅ Integrar con componentes MDS si es necesario
|
|
1028
|
+
```
|
|
1029
|
+
|
|
1030
|
+
**Resultado**: Desarrollo más rápido y código consistente generado automáticamente.
|
|
1031
|
+
|
|
1032
|
+
### Conclusión
|
|
1033
|
+
|
|
1034
|
+
HolyGrail5 representa la **evolución natural** del framework original, eliminando las complejidades de SASS, separando los componentes pesados de Angular, y aprovechando las capacidades modernas de CSS y JavaScript.
|
|
1035
|
+
|
|
1036
|
+
**Es más simple, más ligero, más potente y más accesible**, manteniendo la filosofía de diseño que hizo grande a HolyGrail CSS, pero adaptado a las necesidades actuales:
|
|
1037
|
+
|
|
1038
|
+
- ✅ **Sin dependencias pesadas**: No incluye componentes Angular
|
|
1039
|
+
- ✅ **CSS ligero**: Solo utilidades esenciales
|
|
1040
|
+
- ✅ **Flexible**: Compatible con MDS de Inditex y cualquier librería
|
|
1041
|
+
- ✅ **IA-friendly**: Optimizado para maquetación asistida por IA
|
|
1042
|
+
- ✅ **Moderno**: Variables CSS nativas, JSON, Node.js
|
|
1043
|
+
|
|
1044
|
+
**En resumen**: HolyGrail5 es HolyGrail CSS **mejorado, simplificado, modernizado y optimizado** para el desarrollo web actual, con especial atención a la flexibilidad, ligereza y compatibilidad con sistemas de componentes externos.
|
|
1045
|
+
|
|
1046
|
+
---
|
|
1047
|
+
|
|
581
1048
|
**Hecho con ❤️ por HolyGrail CSS**
|
package/config.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"secondary": "\"ms-serif\", serif"
|
|
7
7
|
},
|
|
8
8
|
"breakpoints": {
|
|
9
|
-
"mobile": "
|
|
9
|
+
"mobile": "1px",
|
|
10
10
|
"desktop": "992px"
|
|
11
11
|
},
|
|
12
12
|
"spacingMap": {
|
|
@@ -235,7 +235,174 @@
|
|
|
235
235
|
"responsive": true,
|
|
236
236
|
"description": "Espacio entre filas y columnas",
|
|
237
237
|
"useSpacing": true
|
|
238
|
+
},
|
|
239
|
+
"text-align": {
|
|
240
|
+
"property": "text-align",
|
|
241
|
+
"class": "text",
|
|
242
|
+
"responsive": true,
|
|
243
|
+
"description": "Alineación del texto",
|
|
244
|
+
"values": {
|
|
245
|
+
"left": "left",
|
|
246
|
+
"center": "center",
|
|
247
|
+
"right": "right",
|
|
248
|
+
"justify": "justify"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"position": {
|
|
252
|
+
"property": "position",
|
|
253
|
+
"class": "position",
|
|
254
|
+
"responsive": true,
|
|
255
|
+
"description": "Tipo de posicionamiento",
|
|
256
|
+
"values": {
|
|
257
|
+
"static": "static",
|
|
258
|
+
"relative": "relative",
|
|
259
|
+
"absolute": "absolute",
|
|
260
|
+
"fixed": "fixed",
|
|
261
|
+
"sticky": "sticky"
|
|
262
|
+
}
|
|
263
|
+
},
|
|
264
|
+
"overflow": {
|
|
265
|
+
"property": "overflow",
|
|
266
|
+
"class": "overflow",
|
|
267
|
+
"responsive": true,
|
|
268
|
+
"description": "Control de desbordamiento",
|
|
269
|
+
"values": {
|
|
270
|
+
"auto": "auto",
|
|
271
|
+
"hidden": "hidden",
|
|
272
|
+
"visible": "visible",
|
|
273
|
+
"scroll": "scroll"
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
"overflow-x": {
|
|
277
|
+
"property": "overflow-x",
|
|
278
|
+
"class": "overflow-x",
|
|
279
|
+
"responsive": true,
|
|
280
|
+
"description": "Control de desbordamiento horizontal",
|
|
281
|
+
"values": {
|
|
282
|
+
"auto": "auto",
|
|
283
|
+
"hidden": "hidden",
|
|
284
|
+
"visible": "visible",
|
|
285
|
+
"scroll": "scroll"
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"overflow-y": {
|
|
289
|
+
"property": "overflow-y",
|
|
290
|
+
"class": "overflow-y",
|
|
291
|
+
"responsive": true,
|
|
292
|
+
"description": "Control de desbordamiento vertical",
|
|
293
|
+
"values": {
|
|
294
|
+
"auto": "auto",
|
|
295
|
+
"hidden": "hidden",
|
|
296
|
+
"visible": "visible",
|
|
297
|
+
"scroll": "scroll"
|
|
298
|
+
}
|
|
299
|
+
},
|
|
300
|
+
"visibility": {
|
|
301
|
+
"property": "visibility",
|
|
302
|
+
"class": "visibility",
|
|
303
|
+
"responsive": true,
|
|
304
|
+
"description": "Visibilidad del elemento",
|
|
305
|
+
"values": {
|
|
306
|
+
"visible": "visible",
|
|
307
|
+
"hidden": "hidden",
|
|
308
|
+
"collapse": "collapse"
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
"opacity": {
|
|
312
|
+
"property": "opacity",
|
|
313
|
+
"class": "opacity",
|
|
314
|
+
"responsive": true,
|
|
315
|
+
"description": "Transparencia del elemento",
|
|
316
|
+
"values": {
|
|
317
|
+
"0": "0",
|
|
318
|
+
"25": "0.25",
|
|
319
|
+
"50": "0.5",
|
|
320
|
+
"75": "0.75",
|
|
321
|
+
"100": "1"
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
"z-index": {
|
|
325
|
+
"property": "z-index",
|
|
326
|
+
"class": "z",
|
|
327
|
+
"responsive": true,
|
|
328
|
+
"description": "Nivel de apilamiento",
|
|
329
|
+
"values": {
|
|
330
|
+
"0": "0",
|
|
331
|
+
"10": "10",
|
|
332
|
+
"20": "20",
|
|
333
|
+
"30": "30",
|
|
334
|
+
"40": "40",
|
|
335
|
+
"50": "50",
|
|
336
|
+
"auto": "auto"
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
"cursor": {
|
|
340
|
+
"property": "cursor",
|
|
341
|
+
"class": "cursor",
|
|
342
|
+
"responsive": false,
|
|
343
|
+
"description": "Tipo de cursor",
|
|
344
|
+
"values": {
|
|
345
|
+
"auto": "auto",
|
|
346
|
+
"default": "default",
|
|
347
|
+
"pointer": "pointer",
|
|
348
|
+
"not-allowed": "not-allowed",
|
|
349
|
+
"wait": "wait",
|
|
350
|
+
"text": "text",
|
|
351
|
+
"move": "move",
|
|
352
|
+
"grab": "grab",
|
|
353
|
+
"grabbing": "grabbing"
|
|
354
|
+
}
|
|
355
|
+
},
|
|
356
|
+
"object-fit": {
|
|
357
|
+
"property": "object-fit",
|
|
358
|
+
"class": "object",
|
|
359
|
+
"responsive": true,
|
|
360
|
+
"description": "Ajuste de objeto (imágenes)",
|
|
361
|
+
"values": {
|
|
362
|
+
"contain": "contain",
|
|
363
|
+
"cover": "cover",
|
|
364
|
+
"fill": "fill",
|
|
365
|
+
"none": "none",
|
|
366
|
+
"scale-down": "scale-down"
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
"height": {
|
|
370
|
+
"property": "height",
|
|
371
|
+
"class": "h",
|
|
372
|
+
"responsive": true,
|
|
373
|
+
"description": "Altura del elemento",
|
|
374
|
+
"values": {
|
|
375
|
+
"auto": "auto",
|
|
376
|
+
"100-percent": "100%",
|
|
377
|
+
"100vh": "100vh",
|
|
378
|
+
"100svh": "100svh",
|
|
379
|
+
"100lvh": "100lvh",
|
|
380
|
+
"100dvh": "100dvh",
|
|
381
|
+
"50-percent": "50%",
|
|
382
|
+
"75-percent": "75%",
|
|
383
|
+
"fit-content": "fit-content",
|
|
384
|
+
"min-content": "min-content",
|
|
385
|
+
"max-content": "max-content"
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
"min-height": {
|
|
391
|
+
"property": "min-height",
|
|
392
|
+
"class": "min-h",
|
|
393
|
+
"responsive": true,
|
|
394
|
+
"description": "Altura mínima del elemento",
|
|
395
|
+
"values": {
|
|
396
|
+
"0": "0",
|
|
397
|
+
"100-percent": "100%",
|
|
398
|
+
"100vh": "100vh",
|
|
399
|
+
"100svh": "100svh",
|
|
400
|
+
"100lvh": "100lvh",
|
|
401
|
+
"100dvh": "100dvh",
|
|
402
|
+
"fit-content": "fit-content"
|
|
403
|
+
}
|
|
238
404
|
}
|
|
405
|
+
|
|
239
406
|
},
|
|
240
407
|
"classes": {
|
|
241
408
|
"h2": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "holygrail5",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Framework CSS generator con Node.js - Genera CSS optimizado con variables CSS desde un archivo JSON de configuración",
|
|
5
5
|
"main": "generator.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"generate": "node generator.js",
|
|
11
|
-
"
|
|
11
|
+
"build": "node generator.js",
|
|
12
|
+
"start": "node generator.js && NODE_NO_WARNINGS=1 npx http-server dist -p ${PORT:-5001} -o index.html",
|
|
12
13
|
"dev": "node src/dev.js",
|
|
13
14
|
"watch": "node src/watch.js",
|
|
14
|
-
"serve": "NODE_NO_WARNINGS=1 npx http-server dist -p
|
|
15
|
+
"serve": "NODE_NO_WARNINGS=1 npx http-server dist -p ${PORT:-5000} -o index.html",
|
|
15
16
|
"test": "node tests/run-all.js",
|
|
16
17
|
"prepublishOnly": "npm run generate",
|
|
17
18
|
"vars:list": "node src/cli-variables.js list",
|
|
@@ -19,6 +20,7 @@
|
|
|
19
20
|
"vars:remove": "node src/cli-variables.js remove",
|
|
20
21
|
"vars:remove-all-unused": "node src/cli-variables.js remove-all-unused",
|
|
21
22
|
"vars:show-all": "node src/cli-variables.js show-all"
|
|
23
|
+
|
|
22
24
|
},
|
|
23
25
|
"keywords": [
|
|
24
26
|
"css",
|
package/src/dev.js
CHANGED
|
@@ -13,14 +13,15 @@ const watchProcess = spawn('node', [path.join(__dirname, 'watch.js')], {
|
|
|
13
13
|
|
|
14
14
|
// Esperar un momento para que watch genere los archivos inicialmente
|
|
15
15
|
setTimeout(() => {
|
|
16
|
-
|
|
16
|
+
const port = process.env.PORT || '5000';
|
|
17
|
+
console.log(`\n🌐 Iniciando servidor HTTP en http://localhost:${port}\n`);
|
|
17
18
|
console.log('💡 Los archivos se regenerarán automáticamente cuando cambies config.json\n');
|
|
18
19
|
console.log('💡 Recarga el navegador (Cmd+Shift+R o Ctrl+Shift+R) para ver los cambios\n');
|
|
19
20
|
|
|
20
21
|
// Iniciar servidor HTTP
|
|
21
22
|
// Suprimir warnings de deprecación de http-server
|
|
22
23
|
// Servir desde dist/ como raíz, así la URL será /index.html sin mostrar "dist"
|
|
23
|
-
const serverProcess = spawn('npx', ['http-server', 'dist', '-p',
|
|
24
|
+
const serverProcess = spawn('npx', ['http-server', 'dist', '-p', port, '-o', 'index.html'], {
|
|
24
25
|
stdio: 'inherit',
|
|
25
26
|
shell: true,
|
|
26
27
|
env: { ...process.env, NODE_NO_WARNINGS: '1' }
|
package/src/guide.js
CHANGED
|
@@ -36,48 +36,9 @@ function saveCurrentValues(currentValues, previousValuesPath) {
|
|
|
36
36
|
function getChangedValues(currentValues, previousValues) {
|
|
37
37
|
const changes = new Set();
|
|
38
38
|
|
|
39
|
-
// Si no hay valores previos, marca
|
|
39
|
+
// Si no hay valores previos, no marca nada como cambiado (primera ejecución o build limpio)
|
|
40
|
+
// Solo se marcarán cambios cuando haya valores previos para comparar
|
|
40
41
|
if (!previousValues) {
|
|
41
|
-
// Marca todas las variables como nuevas
|
|
42
|
-
if (currentValues.variables) {
|
|
43
|
-
Object.keys(currentValues.variables).forEach(varName => {
|
|
44
|
-
changes.add(`variable.${varName}`);
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
// Marca todos los breakpoints como nuevos
|
|
48
|
-
if (currentValues.breakpoints) {
|
|
49
|
-
changes.add('breakpoints.mobile');
|
|
50
|
-
changes.add('breakpoints.desktop');
|
|
51
|
-
}
|
|
52
|
-
// Marca todas las fuentes como nuevas
|
|
53
|
-
if (currentValues.fontFamilyMap) {
|
|
54
|
-
Object.keys(currentValues.fontFamilyMap).forEach(fontName => {
|
|
55
|
-
changes.add(`fontFamilyMap.${fontName}`);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
// Marca todos los colores como nuevos
|
|
59
|
-
if (currentValues.colors) {
|
|
60
|
-
Object.keys(currentValues.colors).forEach(colorName => {
|
|
61
|
-
changes.add(`colors.${colorName}`);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
// Marca todas las clases como nuevas
|
|
65
|
-
if (currentValues.classes) {
|
|
66
|
-
Object.keys(currentValues.classes).forEach(className => {
|
|
67
|
-
const cls = currentValues.classes[className];
|
|
68
|
-
['fontFamily', 'fontWeight', 'letterSpacing', 'textTransform'].forEach(prop => {
|
|
69
|
-
if (cls[prop] !== undefined) {
|
|
70
|
-
changes.add(`${className}.${prop}`);
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
['mobile', 'desktop'].forEach(bp => {
|
|
74
|
-
if (cls[bp]) {
|
|
75
|
-
if (cls[bp].fontSize) changes.add(`${className}.${bp}.fontSize`);
|
|
76
|
-
if (cls[bp].lineHeight) changes.add(`${className}.${bp}.lineHeight`);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
42
|
return changes;
|
|
82
43
|
}
|
|
83
44
|
|
|
@@ -1661,6 +1622,12 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
1661
1622
|
<li class="text-m guide-info-box-list-item">
|
|
1662
1623
|
<strong>.col-xl-*</strong> - Columnas para pantallas desde ${configData.grid.breakpoints.xl} (24 columnas)
|
|
1663
1624
|
</li>
|
|
1625
|
+
<li class="text-m guide-info-box-list-item">
|
|
1626
|
+
<strong>.bleed</strong> - Permite que las columnas vayan a sangre (full bleed), eliminando los márgenes laterales del gutter
|
|
1627
|
+
</li>
|
|
1628
|
+
<li class="text-m guide-info-box-list-item">
|
|
1629
|
+
<strong>.bleed-0</strong> - Elimina completamente el padding y márgenes, útil para contenido que debe ocupar todo el ancho sin espacios
|
|
1630
|
+
</li>
|
|
1664
1631
|
</ul>
|
|
1665
1632
|
<p class="text-m guide-info-box-text">
|
|
1666
1633
|
<strong>Gutter:</strong> ${configData.grid.gutter} (padding horizontal en cada columna)
|
|
@@ -1719,7 +1686,7 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
1719
1686
|
</div>
|
|
1720
1687
|
|
|
1721
1688
|
<div class="guide-info-box guide-info-box-info guide-info-box-margin-top">
|
|
1722
|
-
<h3 class="guide-info-box-title guide-info-box-title-info">Ejemplo de uso</h3>
|
|
1689
|
+
<h3 class="guide-info-box-title guide-info-box-title-info">Ejemplo de uso básico</h3>
|
|
1723
1690
|
<p class="text-m guide-info-box-text">
|
|
1724
1691
|
<strong>HTML:</strong>
|
|
1725
1692
|
</p>
|
|
@@ -1749,6 +1716,33 @@ function generateHTML(configData, previousValuesPath = null) {
|
|
|
1749
1716
|
</li>
|
|
1750
1717
|
</ul>
|
|
1751
1718
|
</div>
|
|
1719
|
+
|
|
1720
|
+
|
|
1721
|
+
|
|
1722
|
+
<div class="guide-info-box guide-info-box-info guide-info-box-margin-top">
|
|
1723
|
+
<h3 class="guide-info-box-title guide-info-box-title-info">Columnas a sangre (Bleed)</h3>
|
|
1724
|
+
<p class="text-m guide-info-box-text">
|
|
1725
|
+
Cuando necesitas que las columnas vayan a sangre (full bleed), eliminando los márgenes laterales del gutter, usa la clase <code class="guide-info-box-code-info">.bleed</code>:
|
|
1726
|
+
</p>
|
|
1727
|
+
<pre class="guide-code-example"><code><div class="row">
|
|
1728
|
+
<div class="col-xs-12 bleed">
|
|
1729
|
+
Contenido que va a sangre (sin márgenes laterales)
|
|
1730
|
+
</div>
|
|
1731
|
+
</div></code></pre>
|
|
1732
|
+
<p class="text-m guide-info-box-text">
|
|
1733
|
+
Para eliminar completamente el padding y márgenes, usa <code class="guide-info-box-code-info">.bleed-0</code>:
|
|
1734
|
+
</p>
|
|
1735
|
+
<pre class="guide-code-example"><code><div class="bleed-0">
|
|
1736
|
+
<div class="row">
|
|
1737
|
+
<div class="col-xs-12">
|
|
1738
|
+
Contenido sin padding ni márgenes
|
|
1739
|
+
</div>
|
|
1740
|
+
</div>
|
|
1741
|
+
</div></code></pre>
|
|
1742
|
+
<p class="text-m guide-info-box-text-small">
|
|
1743
|
+
<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.
|
|
1744
|
+
</p>
|
|
1745
|
+
</div>
|
|
1752
1746
|
</div>
|
|
1753
1747
|
</div>
|
|
1754
1748
|
` : ''}
|
package/src/parser.js
CHANGED
|
@@ -329,7 +329,10 @@ function generateClassCSS(className, cls, breakpointName, valueMap, prefix, cate
|
|
|
329
329
|
// Genera una media query con todas las clases para un breakpoint
|
|
330
330
|
// Convierte el breakpoint a rem y genera el CSS de todas las clases
|
|
331
331
|
function generateMediaQuery(breakpointName, minWidth, classes, valueMap, prefix, category, baseFontSize, fontFamilyMap) {
|
|
332
|
-
|
|
332
|
+
// Convertir breakpoint a rem de forma consistente
|
|
333
|
+
const minWidthRem = typeof minWidth === 'string' && minWidth.includes('px')
|
|
334
|
+
? pxToRem(minWidth, baseFontSize)
|
|
335
|
+
: minWidth;
|
|
333
336
|
|
|
334
337
|
const cssClasses = Object.entries(classes)
|
|
335
338
|
.map(([className, cls]) => generateClassCSS(className, cls, breakpointName, valueMap, prefix, category, baseFontSize, fontFamilyMap))
|
|
@@ -341,7 +344,10 @@ function generateMediaQuery(breakpointName, minWidth, classes, valueMap, prefix,
|
|
|
341
344
|
// Genera un bloque de tipografías para un breakpoint específico con comentario descriptivo
|
|
342
345
|
// Incluye un comentario que indica qué breakpoint es y el min-width
|
|
343
346
|
function generateTypographyBlock(breakpointName, minWidth, classes, valueMap, prefix, category, baseFontSize, fontFamilyMap) {
|
|
344
|
-
|
|
347
|
+
// Convertir breakpoint a rem de forma consistente
|
|
348
|
+
const minWidthRem = typeof minWidth === 'string' && minWidth.includes('px')
|
|
349
|
+
? pxToRem(minWidth, baseFontSize)
|
|
350
|
+
: minWidth;
|
|
345
351
|
const breakpointLabel = breakpointName === 'mobile' ? 'Mobile' : 'Desktop';
|
|
346
352
|
|
|
347
353
|
const cssClasses = Object.entries(classes)
|
|
@@ -430,77 +436,80 @@ function generateSpacingHelpers(spacingMap, prefix, desktopBreakpoint, baseFontS
|
|
|
430
436
|
|
|
431
437
|
const helpers = [];
|
|
432
438
|
const desktopHelpers = [];
|
|
433
|
-
|
|
439
|
+
// Convertir breakpoint a rem de forma consistente
|
|
440
|
+
const desktopBreakpointRem = typeof desktopBreakpoint === 'string' && desktopBreakpoint.includes('px')
|
|
441
|
+
? pxToRem(desktopBreakpoint, baseFontSize)
|
|
442
|
+
: desktopBreakpoint;
|
|
434
443
|
|
|
435
|
-
|
|
436
|
-
|
|
444
|
+
// Generar helpers para cada valor en spacingMap
|
|
445
|
+
Object.entries(spacingMap).forEach(([key, value]) => {
|
|
446
|
+
const varName = `--${prefix}-spacing-${key}`;
|
|
447
|
+
|
|
448
|
+
// Padding helpers base (mobile) usando variables CSS con propiedades lógicas para RTL
|
|
449
|
+
helpers.push(` .p-${key} { padding: var(${varName}); }`);
|
|
450
|
+
helpers.push(` .pr-${key} { padding-inline-end: var(${varName}); }`);
|
|
451
|
+
helpers.push(` .pl-${key} { padding-inline-start: var(${varName}); }`);
|
|
452
|
+
helpers.push(` .pb-${key} { padding-bottom: var(${varName}); }`);
|
|
453
|
+
helpers.push(` .pt-${key} { padding-top: var(${varName}); }`);
|
|
454
|
+
|
|
455
|
+
// Margin helpers base (mobile) usando variables CSS con propiedades lógicas para RTL
|
|
456
|
+
helpers.push(` .m-${key} { margin: var(${varName}); }`);
|
|
457
|
+
helpers.push(` .mr-${key} { margin-inline-end: var(${varName}); }`);
|
|
458
|
+
helpers.push(` .ml-${key} { margin-inline-start: var(${varName}); }`);
|
|
459
|
+
helpers.push(` .mb-${key} { margin-bottom: var(${varName}); }`);
|
|
460
|
+
helpers.push(` .mt-${key} { margin-top: var(${varName}); }`);
|
|
461
|
+
|
|
462
|
+
// Padding helpers con prefijo md: (desktop) usando variables CSS con propiedades lógicas para RTL
|
|
463
|
+
desktopHelpers.push(` .md\\:p-${key} { padding: var(${varName}); }`);
|
|
464
|
+
desktopHelpers.push(` .md\\:pr-${key} { padding-inline-end: var(${varName}); }`);
|
|
465
|
+
desktopHelpers.push(` .md\\:pl-${key} { padding-inline-start: var(${varName}); }`);
|
|
466
|
+
desktopHelpers.push(` .md\\:pb-${key} { padding-bottom: var(${varName}); }`);
|
|
467
|
+
desktopHelpers.push(` .md\\:pt-${key} { padding-top: var(${varName}); }`);
|
|
468
|
+
|
|
469
|
+
// Margin helpers con prefijo md: (desktop) usando variables CSS con propiedades lógicas para RTL
|
|
470
|
+
desktopHelpers.push(` .md\\:m-${key} { margin: var(${varName}); }`);
|
|
471
|
+
desktopHelpers.push(` .md\\:mr-${key} { margin-inline-end: var(${varName}); }`);
|
|
472
|
+
desktopHelpers.push(` .md\\:ml-${key} { margin-inline-start: var(${varName}); }`);
|
|
473
|
+
desktopHelpers.push(` .md\\:mb-${key} { margin-bottom: var(${varName}); }`);
|
|
474
|
+
desktopHelpers.push(` .md\\:mt-${key} { margin-top: var(${varName}); }`);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
// Generar helpers con !important para los valores especificados en spacingImportant
|
|
478
|
+
if (spacingImportant && Array.isArray(spacingImportant)) {
|
|
479
|
+
spacingImportant.forEach(key => {
|
|
480
|
+
if (spacingMap[key]) {
|
|
437
481
|
const varName = `--${prefix}-spacing-${key}`;
|
|
438
482
|
|
|
439
|
-
// Padding helpers
|
|
440
|
-
helpers.push(` .p-${key} { padding: var(${varName}); }`);
|
|
441
|
-
helpers.push(` .pr-${key} { padding-inline-end: var(${varName}); }`);
|
|
442
|
-
helpers.push(` .pl-${key} { padding-inline-start: var(${varName}); }`);
|
|
443
|
-
helpers.push(` .pb-${key} { padding-bottom: var(${varName}); }`);
|
|
444
|
-
helpers.push(` .pt-${key} { padding-top: var(${varName}); }`);
|
|
483
|
+
// Padding helpers con !important (mobile)
|
|
484
|
+
helpers.push(` .p-${key}\\! { padding: var(${varName}) !important; }`);
|
|
485
|
+
helpers.push(` .pr-${key}\\! { padding-inline-end: var(${varName}) !important; }`);
|
|
486
|
+
helpers.push(` .pl-${key}\\! { padding-inline-start: var(${varName}) !important; }`);
|
|
487
|
+
helpers.push(` .pb-${key}\\! { padding-bottom: var(${varName}) !important; }`);
|
|
488
|
+
helpers.push(` .pt-${key}\\! { padding-top: var(${varName}) !important; }`);
|
|
445
489
|
|
|
446
|
-
// Margin helpers
|
|
447
|
-
helpers.push(` .m-${key} { margin: var(${varName}); }`);
|
|
448
|
-
helpers.push(` .mr-${key} { margin-inline-end: var(${varName}); }`);
|
|
449
|
-
helpers.push(` .ml-${key} { margin-inline-start: var(${varName}); }`);
|
|
450
|
-
helpers.push(` .mb-${key} { margin-bottom: var(${varName}); }`);
|
|
451
|
-
helpers.push(` .mt-${key} { margin-top: var(${varName}); }`);
|
|
490
|
+
// Margin helpers con !important (mobile)
|
|
491
|
+
helpers.push(` .m-${key}\\! { margin: var(${varName}) !important; }`);
|
|
492
|
+
helpers.push(` .mr-${key}\\! { margin-inline-end: var(${varName}) !important; }`);
|
|
493
|
+
helpers.push(` .ml-${key}\\! { margin-inline-start: var(${varName}) !important; }`);
|
|
494
|
+
helpers.push(` .mb-${key}\\! { margin-bottom: var(${varName}) !important; }`);
|
|
495
|
+
helpers.push(` .mt-${key}\\! { margin-top: var(${varName}) !important; }`);
|
|
452
496
|
|
|
453
|
-
// Padding helpers con prefijo md: (desktop)
|
|
454
|
-
desktopHelpers.push(` .md\\:p-${key} { padding: var(${varName}); }`);
|
|
455
|
-
desktopHelpers.push(` .md\\:pr-${key} { padding-inline-end: var(${varName}); }`);
|
|
456
|
-
desktopHelpers.push(` .md\\:pl-${key} { padding-inline-start: var(${varName}); }`);
|
|
457
|
-
desktopHelpers.push(` .md\\:pb-${key} { padding-bottom: var(${varName}); }`);
|
|
458
|
-
desktopHelpers.push(` .md\\:pt-${key} { padding-top: var(${varName}); }`);
|
|
497
|
+
// Padding helpers con !important y prefijo md: (desktop)
|
|
498
|
+
desktopHelpers.push(` .md\\:p-${key}\\! { padding: var(${varName}) !important; }`);
|
|
499
|
+
desktopHelpers.push(` .md\\:pr-${key}\\! { padding-inline-end: var(${varName}) !important; }`);
|
|
500
|
+
desktopHelpers.push(` .md\\:pl-${key}\\! { padding-inline-start: var(${varName}) !important; }`);
|
|
501
|
+
desktopHelpers.push(` .md\\:pb-${key}\\! { padding-bottom: var(${varName}) !important; }`);
|
|
502
|
+
desktopHelpers.push(` .md\\:pt-${key}\\! { padding-top: var(${varName}) !important; }`);
|
|
459
503
|
|
|
460
|
-
// Margin helpers con prefijo md: (desktop)
|
|
461
|
-
desktopHelpers.push(` .md\\:m-${key} { margin: var(${varName}); }`);
|
|
462
|
-
desktopHelpers.push(` .md\\:mr-${key} { margin-inline-end: var(${varName}); }`);
|
|
463
|
-
desktopHelpers.push(` .md\\:ml-${key} { margin-inline-start: var(${varName}); }`);
|
|
464
|
-
desktopHelpers.push(` .md\\:mb-${key} { margin-bottom: var(${varName}); }`);
|
|
465
|
-
desktopHelpers.push(` .md\\:mt-${key} { margin-top: var(${varName}); }`);
|
|
466
|
-
});
|
|
467
|
-
|
|
468
|
-
// Generar helpers con !important para los valores especificados en spacingImportant
|
|
469
|
-
if (spacingImportant && Array.isArray(spacingImportant)) {
|
|
470
|
-
spacingImportant.forEach(key => {
|
|
471
|
-
if (spacingMap[key]) {
|
|
472
|
-
const varName = `--${prefix}-spacing-${key}`;
|
|
473
|
-
|
|
474
|
-
// Padding helpers con !important (mobile)
|
|
475
|
-
helpers.push(` .p-${key}\\! { padding: var(${varName}) !important; }`);
|
|
476
|
-
helpers.push(` .pr-${key}\\! { padding-inline-end: var(${varName}) !important; }`);
|
|
477
|
-
helpers.push(` .pl-${key}\\! { padding-inline-start: var(${varName}) !important; }`);
|
|
478
|
-
helpers.push(` .pb-${key}\\! { padding-bottom: var(${varName}) !important; }`);
|
|
479
|
-
helpers.push(` .pt-${key}\\! { padding-top: var(${varName}) !important; }`);
|
|
480
|
-
|
|
481
|
-
// Margin helpers con !important (mobile)
|
|
482
|
-
helpers.push(` .m-${key}\\! { margin: var(${varName}) !important; }`);
|
|
483
|
-
helpers.push(` .mr-${key}\\! { margin-inline-end: var(${varName}) !important; }`);
|
|
484
|
-
helpers.push(` .ml-${key}\\! { margin-inline-start: var(${varName}) !important; }`);
|
|
485
|
-
helpers.push(` .mb-${key}\\! { margin-bottom: var(${varName}) !important; }`);
|
|
486
|
-
helpers.push(` .mt-${key}\\! { margin-top: var(${varName}) !important; }`);
|
|
487
|
-
|
|
488
|
-
// Padding helpers con !important y prefijo md: (desktop)
|
|
489
|
-
desktopHelpers.push(` .md\\:p-${key}\\! { padding: var(${varName}) !important; }`);
|
|
490
|
-
desktopHelpers.push(` .md\\:pr-${key}\\! { padding-inline-end: var(${varName}) !important; }`);
|
|
491
|
-
desktopHelpers.push(` .md\\:pl-${key}\\! { padding-inline-start: var(${varName}) !important; }`);
|
|
492
|
-
desktopHelpers.push(` .md\\:pb-${key}\\! { padding-bottom: var(${varName}) !important; }`);
|
|
493
|
-
desktopHelpers.push(` .md\\:pt-${key}\\! { padding-top: var(${varName}) !important; }`);
|
|
494
|
-
|
|
495
|
-
// Margin helpers con !important y prefijo md: (desktop)
|
|
496
|
-
desktopHelpers.push(` .md\\:m-${key}\\! { margin: var(${varName}) !important; }`);
|
|
497
|
-
desktopHelpers.push(` .md\\:mr-${key}\\! { margin-inline-end: var(${varName}) !important; }`);
|
|
498
|
-
desktopHelpers.push(` .md\\:ml-${key}\\! { margin-inline-start: var(${varName}) !important; }`);
|
|
499
|
-
desktopHelpers.push(` .md\\:mb-${key}\\! { margin-bottom: var(${varName}) !important; }`);
|
|
500
|
-
desktopHelpers.push(` .md\\:mt-${key}\\! { margin-top: var(${varName}) !important; }`);
|
|
501
|
-
}
|
|
502
|
-
});
|
|
504
|
+
// Margin helpers con !important y prefijo md: (desktop)
|
|
505
|
+
desktopHelpers.push(` .md\\:m-${key}\\! { margin: var(${varName}) !important; }`);
|
|
506
|
+
desktopHelpers.push(` .md\\:mr-${key}\\! { margin-inline-end: var(${varName}) !important; }`);
|
|
507
|
+
desktopHelpers.push(` .md\\:ml-${key}\\! { margin-inline-start: var(${varName}) !important; }`);
|
|
508
|
+
desktopHelpers.push(` .md\\:mb-${key}\\! { margin-bottom: var(${varName}) !important; }`);
|
|
509
|
+
desktopHelpers.push(` .md\\:mt-${key}\\! { margin-top: var(${varName}) !important; }`);
|
|
503
510
|
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
504
513
|
|
|
505
514
|
if (helpers.length === 0) {
|
|
506
515
|
return '';
|
|
@@ -520,13 +529,23 @@ ${desktopHelpers.join('\n')}
|
|
|
520
529
|
return baseHelpers;
|
|
521
530
|
}
|
|
522
531
|
|
|
532
|
+
// Genera helpers de layout (display, flexbox, alignment, etc.)
|
|
533
|
+
// Crea clases como hg-d-flex, hg-justify-center, etc.
|
|
534
|
+
// Agrupa todos los helpers responsive en un solo media query
|
|
523
535
|
function generateLayoutHelpers(helpers, spacingMap, prefix, desktopBreakpoint, baseFontSize = 16) {
|
|
524
536
|
if (!helpers || typeof helpers !== 'object') {
|
|
525
537
|
return '';
|
|
526
538
|
}
|
|
527
539
|
|
|
540
|
+
// Convertir breakpoint a rem de forma consistente
|
|
541
|
+
const breakpointInRem = typeof desktopBreakpoint === 'string' && desktopBreakpoint.includes('px')
|
|
542
|
+
? pxToRem(desktopBreakpoint, baseFontSize)
|
|
543
|
+
: desktopBreakpoint;
|
|
544
|
+
|
|
528
545
|
let css = '\n/* Layout Helpers */\n';
|
|
546
|
+
let responsiveCSS = '';
|
|
529
547
|
|
|
548
|
+
// Primero generar todas las clases base
|
|
530
549
|
Object.entries(helpers).forEach(([helperName, config]) => {
|
|
531
550
|
const { property, class: className, responsive, values, useSpacing } = config;
|
|
532
551
|
|
|
@@ -537,12 +556,10 @@ function generateLayoutHelpers(helpers, spacingMap, prefix, desktopBreakpoint, b
|
|
|
537
556
|
});
|
|
538
557
|
|
|
539
558
|
if (responsive) {
|
|
540
|
-
css += `\n@media (min-width: ${desktopBreakpoint}) {\n`;
|
|
541
559
|
Object.entries(spacingMap).forEach(([key, value]) => {
|
|
542
560
|
const finalValue = value.endsWith('%') ? value : pxToRem(value, baseFontSize);
|
|
543
|
-
|
|
561
|
+
responsiveCSS += ` .md\\:${prefix}-${className}-${key} { ${property}: ${finalValue}; }\n`;
|
|
544
562
|
});
|
|
545
|
-
css += '}\n';
|
|
546
563
|
}
|
|
547
564
|
} else if (values) {
|
|
548
565
|
if (Array.isArray(values)) {
|
|
@@ -551,11 +568,9 @@ function generateLayoutHelpers(helpers, spacingMap, prefix, desktopBreakpoint, b
|
|
|
551
568
|
});
|
|
552
569
|
|
|
553
570
|
if (responsive) {
|
|
554
|
-
css += `\n@media (min-width: ${desktopBreakpoint}) {\n`;
|
|
555
571
|
values.forEach(value => {
|
|
556
|
-
|
|
572
|
+
responsiveCSS += ` .md\\:${prefix}-${className}-${value} { ${property}: ${value}; }\n`;
|
|
557
573
|
});
|
|
558
|
-
css += '}\n';
|
|
559
574
|
}
|
|
560
575
|
} else if (typeof values === 'object') {
|
|
561
576
|
Object.entries(values).forEach(([key, value]) => {
|
|
@@ -563,18 +578,19 @@ function generateLayoutHelpers(helpers, spacingMap, prefix, desktopBreakpoint, b
|
|
|
563
578
|
});
|
|
564
579
|
|
|
565
580
|
if (responsive) {
|
|
566
|
-
css += `\n@media (min-width: ${desktopBreakpoint}) {\n`;
|
|
567
581
|
Object.entries(values).forEach(([key, value]) => {
|
|
568
|
-
|
|
582
|
+
responsiveCSS += ` .md\\:${prefix}-${className}-${key} { ${property}: ${value}; }\n`;
|
|
569
583
|
});
|
|
570
|
-
css += '}\n';
|
|
571
584
|
}
|
|
572
585
|
}
|
|
573
586
|
}
|
|
574
|
-
|
|
575
|
-
css += '\n';
|
|
576
587
|
});
|
|
577
588
|
|
|
589
|
+
// Agrupar todos los helpers responsive en un solo media query
|
|
590
|
+
if (responsiveCSS) {
|
|
591
|
+
css += `\n@media (min-width: ${breakpointInRem}) {\n${responsiveCSS}}\n`;
|
|
592
|
+
}
|
|
593
|
+
|
|
578
594
|
return css;
|
|
579
595
|
}
|
|
580
596
|
|
|
@@ -596,6 +612,14 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
596
612
|
const columnsXs = gridConfig.columnsXs || 12;
|
|
597
613
|
const columnsXl = gridConfig.columnsXl || 24;
|
|
598
614
|
|
|
615
|
+
// Función helper para convertir breakpoints a rem de forma consistente
|
|
616
|
+
const breakpointToRem = (value) => {
|
|
617
|
+
if (typeof value === 'string' && value.includes('px')) {
|
|
618
|
+
return pxToRem(value, baseFontSize);
|
|
619
|
+
}
|
|
620
|
+
return value;
|
|
621
|
+
};
|
|
622
|
+
|
|
599
623
|
let css = '\n/* Grid System */\n';
|
|
600
624
|
|
|
601
625
|
// Genera .row
|
|
@@ -609,7 +633,8 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
609
633
|
// Genera .row para cada breakpoint
|
|
610
634
|
Object.entries(breakpoints).forEach(([name, value]) => {
|
|
611
635
|
if (name !== 'xs') {
|
|
612
|
-
|
|
636
|
+
const remValue = breakpointToRem(value);
|
|
637
|
+
css += `@media (min-width: ${remValue}) {
|
|
613
638
|
.row {
|
|
614
639
|
margin-left: -${gutterValue};
|
|
615
640
|
margin-right: -${gutterValue};
|
|
@@ -625,8 +650,9 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
625
650
|
return percentage.replace(/\.?0+$/, '') || '0';
|
|
626
651
|
};
|
|
627
652
|
|
|
628
|
-
// Genera columnas para xs (12 columnas) -
|
|
629
|
-
|
|
653
|
+
// Genera columnas para xs (12 columnas) - convertir a rem
|
|
654
|
+
const xsBreakpoint = breakpointToRem(breakpoints.xs);
|
|
655
|
+
css += `@media (min-width: ${xsBreakpoint}) {\n`;
|
|
630
656
|
for (let i = 1; i <= columnsXs; i++) {
|
|
631
657
|
const percentage = formatPercentage(i / columnsXs);
|
|
632
658
|
css += ` .col-xs-${i} {
|
|
@@ -638,7 +664,8 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
638
664
|
|
|
639
665
|
// Genera columnas para sm (12 columnas)
|
|
640
666
|
if (breakpoints.sm) {
|
|
641
|
-
|
|
667
|
+
const smBreakpoint = breakpointToRem(breakpoints.sm);
|
|
668
|
+
css += `@media (min-width: ${smBreakpoint}) {\n`;
|
|
642
669
|
for (let i = 1; i <= columnsXs; i++) {
|
|
643
670
|
const percentage = formatPercentage(i / columnsXs);
|
|
644
671
|
css += ` .col-sm-${i} {
|
|
@@ -651,7 +678,8 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
651
678
|
|
|
652
679
|
// Genera columnas para md (12 columnas)
|
|
653
680
|
if (breakpoints.md) {
|
|
654
|
-
|
|
681
|
+
const mdBreakpoint = breakpointToRem(breakpoints.md);
|
|
682
|
+
css += `@media (min-width: ${mdBreakpoint}) {\n`;
|
|
655
683
|
for (let i = 1; i <= columnsXs; i++) {
|
|
656
684
|
const percentage = formatPercentage(i / columnsXs);
|
|
657
685
|
css += ` .col-md-${i} {
|
|
@@ -664,7 +692,8 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
664
692
|
|
|
665
693
|
// Genera columnas para lg (12 columnas)
|
|
666
694
|
if (breakpoints.lg) {
|
|
667
|
-
|
|
695
|
+
const lgBreakpoint = breakpointToRem(breakpoints.lg);
|
|
696
|
+
css += `@media (min-width: ${lgBreakpoint}) {\n`;
|
|
668
697
|
for (let i = 1; i <= columnsXs; i++) {
|
|
669
698
|
const percentage = formatPercentage(i / columnsXs);
|
|
670
699
|
css += ` .col-lg-${i} {
|
|
@@ -677,7 +706,8 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
677
706
|
|
|
678
707
|
// Genera columnas para xl (24 columnas)
|
|
679
708
|
if (breakpoints.xl) {
|
|
680
|
-
|
|
709
|
+
const xlBreakpoint = breakpointToRem(breakpoints.xl);
|
|
710
|
+
css += `@media (min-width: ${xlBreakpoint}) {\n`;
|
|
681
711
|
for (let i = 1; i <= columnsXl; i++) {
|
|
682
712
|
const percentage = formatPercentage(i / columnsXl);
|
|
683
713
|
css += ` .col-xl-${i} {
|
|
@@ -695,7 +725,48 @@ function generateGridSystem(gridConfig, baseFontSize = 16) {
|
|
|
695
725
|
padding-left: ${gutterValue};
|
|
696
726
|
padding-right: ${gutterValue};
|
|
697
727
|
position: relative;
|
|
698
|
-
}\n`;
|
|
728
|
+
}\n\n`;
|
|
729
|
+
|
|
730
|
+
// Estilos para bleed
|
|
731
|
+
css += `.bleed {
|
|
732
|
+
margin-left: -${gutterValue};
|
|
733
|
+
margin-right: -${gutterValue};
|
|
734
|
+
width: auto;
|
|
735
|
+
}\n\n`;
|
|
736
|
+
|
|
737
|
+
css += `.bleed.row {
|
|
738
|
+
margin-left: -${gutterValue};
|
|
739
|
+
margin-right: -${gutterValue};
|
|
740
|
+
}\n\n`;
|
|
741
|
+
|
|
742
|
+
css += `.bleed-0 {
|
|
743
|
+
padding: 0 0px 0 0px;
|
|
744
|
+
overflow: hidden;
|
|
745
|
+
}\n\n`;
|
|
746
|
+
|
|
747
|
+
css += `.bleed-0 .container-fluid {
|
|
748
|
+
margin-left: -0px;
|
|
749
|
+
margin-right: -0px;
|
|
750
|
+
padding: 0 0px 0 0px;
|
|
751
|
+
}\n\n`;
|
|
752
|
+
|
|
753
|
+
css += `.bleed-0 > .row {
|
|
754
|
+
margin-left: 0;
|
|
755
|
+
margin-right: 0;
|
|
756
|
+
box-sizing: border-box;
|
|
757
|
+
display: flex;
|
|
758
|
+
flex: 0 1 auto;
|
|
759
|
+
-webkit-box-orient: horizontal;
|
|
760
|
+
-webkit-box-direction: normal;
|
|
761
|
+
flex-flow: row wrap;
|
|
762
|
+
flex-wrap: wrap;
|
|
763
|
+
}\n\n`;
|
|
764
|
+
|
|
765
|
+
css += `.bleed-0 > [class*=col-],
|
|
766
|
+
.bleed-0 > .col {
|
|
767
|
+
padding: 0px;
|
|
768
|
+
box-sizing: border-box;
|
|
769
|
+
}\n\n`;
|
|
699
770
|
|
|
700
771
|
return css;
|
|
701
772
|
}
|