@jjlmoya/utils-developer 1.16.0 → 1.18.0
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/package.json +1 -1
- package/src/category/index.ts +3 -1
- package/src/entries.ts +7 -1
- package/src/index.ts +4 -0
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/calculadoraTiempoDatos/data-time-calculator-web-speed-impact.css +498 -499
- package/src/tool/jwtDecoder/bibliography.astro +14 -0
- package/src/tool/jwtDecoder/bibliography.ts +12 -0
- package/src/tool/jwtDecoder/component.astro +209 -0
- package/src/tool/jwtDecoder/entry.ts +30 -0
- package/src/tool/jwtDecoder/i18n/de.ts +248 -0
- package/src/tool/jwtDecoder/i18n/en.ts +247 -0
- package/src/tool/jwtDecoder/i18n/es.ts +248 -0
- package/src/tool/jwtDecoder/i18n/fr.ts +248 -0
- package/src/tool/jwtDecoder/i18n/id.ts +248 -0
- package/src/tool/jwtDecoder/i18n/it.ts +248 -0
- package/src/tool/jwtDecoder/i18n/ja.ts +248 -0
- package/src/tool/jwtDecoder/i18n/ko.ts +248 -0
- package/src/tool/jwtDecoder/i18n/nl.ts +247 -0
- package/src/tool/jwtDecoder/i18n/pl.ts +247 -0
- package/src/tool/jwtDecoder/i18n/pt.ts +247 -0
- package/src/tool/jwtDecoder/i18n/ru.ts +248 -0
- package/src/tool/jwtDecoder/i18n/sv.ts +248 -0
- package/src/tool/jwtDecoder/i18n/tr.ts +248 -0
- package/src/tool/jwtDecoder/i18n/zh.ts +248 -0
- package/src/tool/jwtDecoder/index.ts +11 -0
- package/src/tool/jwtDecoder/jwt-decoder-parser-and-claims-inspector.css +358 -0
- package/src/tool/jwtDecoder/logic.ts +96 -0
- package/src/tool/jwtDecoder/seo.astro +15 -0
- package/src/tool/jwtDecoder/ui.ts +38 -0
- package/src/tool/serpPixelSimulator/bibliography.astro +11 -4
- package/src/tool/serpPixelSimulator/index.ts +0 -4
- package/src/tool/serpPixelSimulator/seo.astro +8 -5
- package/src/tool/visualCssGridFlexboxGenerator/bibliography.astro +14 -0
- package/src/tool/visualCssGridFlexboxGenerator/bibliography.ts +20 -0
- package/src/tool/visualCssGridFlexboxGenerator/canvas.ts +103 -0
- package/src/tool/visualCssGridFlexboxGenerator/component.astro +218 -0
- package/src/tool/visualCssGridFlexboxGenerator/entry.ts +30 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/de.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/en.ts +256 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/es.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/fr.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/id.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/it.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/ja.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/ko.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/nl.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/pl.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/pt.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/ru.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/sv.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/tr.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/i18n/zh.ts +110 -0
- package/src/tool/visualCssGridFlexboxGenerator/index.ts +11 -0
- package/src/tool/visualCssGridFlexboxGenerator/interactions.ts +45 -0
- package/src/tool/visualCssGridFlexboxGenerator/logic.ts +49 -0
- package/src/tool/visualCssGridFlexboxGenerator/presets.ts +63 -0
- package/src/tool/visualCssGridFlexboxGenerator/seo.astro +15 -0
- package/src/tool/visualCssGridFlexboxGenerator/ui.ts +58 -0
- package/src/tool/visualCssGridFlexboxGenerator/visual-css-grid-flexbox-generator.css +816 -0
- package/src/tool/visualCssGridFlexboxGenerator/workspace.ts +192 -0
- package/src/tools.ts +3 -1
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { VisualCssGridFlexboxGeneratorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'generador-visual-css-grid-flexbox';
|
|
7
|
+
const title = 'Generador Visual de Layouts CSS Grid y Flexbox';
|
|
8
|
+
const description = 'Diseña layouts responsive arrastrando bloques visuales, redimensionando el contenedor, ajustando controles de alineación y usando presets - luego copia CSS nativo limpio al instante.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{ name: 'Elige un preset o Flexbox / Grid', text: 'Empieza con un preset de layout (navbar, cards, hero, sidebar, gallery) o cambia entre Flexbox y Grid manualmente.' },
|
|
12
|
+
{ name: 'Redimensiona el layout', text: 'Redimensiona el contenedor desde la esquina inferior para probar cómo reacciona el diseño al espacio disponible.' },
|
|
13
|
+
{ name: 'Ajusta los controles de alineación', text: 'Usa sliders y selects para dirección, wrap, gap, columnas, justify-content, align-items, align-content, ancho, alto y tamaño de ítem.' },
|
|
14
|
+
{ name: 'Copia CSS listo para producción', text: 'Copia el CSS generado cuando el resultado visual coincida con la estructura que quieres implementar. Sin dependencias de frameworks.' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const faq = [
|
|
18
|
+
{ question: '¿Cuándo debo usar Flexbox en vez de CSS Grid?', answer: 'Usa Flexbox cuando el layout sea principalmente unidimensional - barras de navegación, grupos de botones, cards envueltas, contenido centrado. Usa Grid cuando filas y columnas importan juntas - dashboards, galerías, formularios y secciones de página estructuradas.' },
|
|
19
|
+
{ question: '¿Puede este generador crear layouts responsive?', answer: 'Sí. El CSS generado usa flex wrapping nativo o grid repeat columns. Redimensiona el canvas visual para probar cómo se comportan el espaciado y la alineación a diferentes tamaños antes de escribir media queries.' },
|
|
20
|
+
{ question: '¿Por qué justify-content y align-items se sienten diferentes en grid y flex?', answer: 'Flexbox distribuye ítems a lo largo de un eje principal y un eje transversal. Grid coloca ítems en tracks primero, luego alinea el contenido dentro de esos tracks. Alternar entre ambos modos en el mismo canvas hace visible esa diferencia de comportamiento.' },
|
|
21
|
+
{ question: '¿El CSS generado está atado a algún framework?', answer: 'No. El resultado es CSS nativo puro. Úsalo en HTML plano, Astro, React, Vue, Svelte, Web Components o cualquier proyecto que acepte CSS estándar.' },
|
|
22
|
+
{ question: '¿Para qué sirven los presets de layout?', answer: 'Los presets aceleran layouts comunes para que veas configuraciones realistas sin empezar desde cero. Cada preset configura modo, dirección, wrap, alineación y tamaño del contenedor para un patrón del mundo real.' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ui: VisualCssGridFlexboxGeneratorUI = {
|
|
26
|
+
modeLabel: 'Modo de layout',
|
|
27
|
+
flexMode: 'Flexbox',
|
|
28
|
+
gridMode: 'Grid',
|
|
29
|
+
canvasLabel: 'Canvas de layout interactivo',
|
|
30
|
+
addItem: 'Añadir ítem',
|
|
31
|
+
removeItem: 'Quitar ítem',
|
|
32
|
+
resetLayout: 'Restablecer layout',
|
|
33
|
+
gapLabel: 'Espaciado',
|
|
34
|
+
columnsLabel: 'Columnas del grid',
|
|
35
|
+
widthLabel: 'Ancho del contenedor',
|
|
36
|
+
heightLabel: 'Alto del contenedor',
|
|
37
|
+
justifyLabel: 'Justificar',
|
|
38
|
+
alignLabel: 'Alinear',
|
|
39
|
+
itemSizeLabel: 'Tamaño de ítem',
|
|
40
|
+
codeTitle: 'CSS Generado',
|
|
41
|
+
copyCode: 'Copiar CSS',
|
|
42
|
+
copied: '¡Copiado!',
|
|
43
|
+
dragHint: 'Redimensiona el canvas desde la esquina - ¡el CSS se actualiza en vivo!',
|
|
44
|
+
outputLabel: 'Salida de CSS generado',
|
|
45
|
+
justifyStart: 'Inicio',
|
|
46
|
+
justifyCenter: 'Centro',
|
|
47
|
+
justifyEnd: 'Fin',
|
|
48
|
+
justifyBetween: 'Space between',
|
|
49
|
+
justifyAround: 'Space around',
|
|
50
|
+
justifyEvenly: 'Space evenly',
|
|
51
|
+
alignStart: 'Inicio',
|
|
52
|
+
alignCenter: 'Centro',
|
|
53
|
+
alignEnd: 'Fin',
|
|
54
|
+
alignStretch: 'Estirar',
|
|
55
|
+
alignBaseline: 'Línea base',
|
|
56
|
+
itemPrefix: 'Bloque',
|
|
57
|
+
directionLabel: 'Dirección',
|
|
58
|
+
directionRow: 'Fila →',
|
|
59
|
+
directionRowReverse: '← Fila rev',
|
|
60
|
+
directionColumn: 'Columna ↓',
|
|
61
|
+
directionColumnReverse: '↑ Col rev',
|
|
62
|
+
wrapLabel: 'Wrap',
|
|
63
|
+
wrapNoWrap: 'Sin wrap',
|
|
64
|
+
wrapWrap: 'Wrap',
|
|
65
|
+
wrapWrapReverse: 'Wrap rev',
|
|
66
|
+
alignContentLabel: 'Al content',
|
|
67
|
+
alignContentStart: 'Inicio',
|
|
68
|
+
alignContentCenter: 'Centro',
|
|
69
|
+
alignContentEnd: 'Fin',
|
|
70
|
+
alignContentBetween: 'Space between',
|
|
71
|
+
alignContentAround: 'Space around',
|
|
72
|
+
alignContentEvenly: 'Space evenly',
|
|
73
|
+
alignContentStretch: 'Estirar',
|
|
74
|
+
presetsLabel: 'Presets',
|
|
75
|
+
presetNavbar: 'Navbar',
|
|
76
|
+
presetCards: 'Cards',
|
|
77
|
+
presetHero: 'Hero',
|
|
78
|
+
presetSidebar: 'Sidebar',
|
|
79
|
+
presetGallery: 'Galería',
|
|
80
|
+
shakeLimit: '¡Se necesitan al menos 2 ítems!',
|
|
81
|
+
spanHint: 'Doble clic en un ítem para cambiar su span de columna (1-3) en modo Grid',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const faqSchema: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
85
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name, text: step.text })) };
|
|
86
|
+
const appSchema: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'DeveloperApplication', operatingSystem: 'Any', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } };
|
|
87
|
+
|
|
88
|
+
export const content: ToolLocaleContent<VisualCssGridFlexboxGeneratorUI> = {
|
|
89
|
+
slug, title, description, ui,
|
|
90
|
+
faqTitle: 'FAQ del generador de layouts CSS',
|
|
91
|
+
faq,
|
|
92
|
+
bibliographyTitle: 'Referencias de CSS Grid y Flexbox',
|
|
93
|
+
bibliography,
|
|
94
|
+
howTo,
|
|
95
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
96
|
+
seo: [
|
|
97
|
+
{ type: 'title', text: 'Construye layouts CSS viendo el comportamiento, no memorizando propiedades', level: 2 },
|
|
98
|
+
{ type: 'paragraph', html: 'CSS Grid y Flexbox son potentes porque describen relaciones de layout en vez de coordenadas fijas. Lo difícil es predecir cómo interactúan <strong>gap</strong>, <strong>justify-content</strong>, <strong>align-items</strong>, dirección, wrapping, tracks y el espacio disponible. Este generador visual convierte esas propiedades abstractas en un playground vivo con presets, reordenación y salida CSS en tiempo real.' },
|
|
99
|
+
{ type: 'stats', columns: 3, items: [{ value: '5', label: 'Presets de layout rápidos', icon: 'mdi:view-grid-plus' }, { value: 'En vivo', label: 'CSS se actualiza con cada cambio', icon: 'mdi:code-braces' }, { value: '0', label: 'Dependencias de framework en el CSS', icon: 'mdi:language-css3' }] },
|
|
100
|
+
{ type: 'title', text: 'Flexbox vs Grid: elige el modelo antes de pulir la alineación', level: 3 },
|
|
101
|
+
{ type: 'comparative', columns: 2, items: [{ title: 'Flexbox', description: 'Ideal para flujos unidimensionales donde los ítems se alinean en fila o columna y pueden envolverse.', icon: 'mdi:format-align-justify', highlight: true, points: ['Barras de navegación', 'Grupos de botones', 'Cards envueltas', 'Contenido centrado'] }, { title: 'CSS Grid', description: 'Ideal para estructuras bidimensionales donde filas y columnas definen la forma de la composición.', icon: 'mdi:grid', points: ['Dashboards', 'Galerías', 'Formularios', 'Secciones editoriales'] }] },
|
|
102
|
+
{ type: 'title', text: 'Qué te enseña cada control', level: 3 },
|
|
103
|
+
{ type: 'table', headers: ['Control', 'Propiedad CSS', 'Qué observar'], rows: [['Dirección', '<code>flex-direction</code>', 'Cómo fluye el eje principal - cambia fila por columna para cambiar toda la lógica del layout.'], ['Wrap', '<code>flex-wrap</code>', 'Si los ítems se quedan en una línea o fluyen a nuevas filas cuando se acaba el espacio.'], ['Gap', '<code>gap</code>', 'El espacio entre ítems sin añadir márgenes que se rompen en los bordes.'], ['Justificar', '<code>justify-content</code>', 'Cómo se distribuye el espacio libre a lo largo del eje principal.'], ['Alinear', '<code>align-items</code>', 'Cómo se sitúan los ítems en el eje transversal.'], ['Align content', '<code>align-content</code>', 'Cómo las líneas envueltas o filas del grid distribuyen el espacio extra del eje transversal.'], ['Columnas', '<code>grid-template-columns</code>', 'Cuántos tracks iguales crea el grid antes de que los ítems pasen a otra fila.'], ['Tamaño contenedor', '<code>width</code> y <code>min-height</code>', 'Cómo reacciona el mismo CSS cuando cambia el espacio disponible.']] },
|
|
104
|
+
{ type: 'tip', title: 'Primero redimensiona, luego optimiza', html: 'Empieza por redimensionar el canvas visual a un tamaño realista. Luego ajusta gap y alineación. Así el CSS generado funciona en escenarios reales, no solo en el tamaño por defecto.' },
|
|
105
|
+
{ type: 'title', text: 'CSS limpio que puedes adaptar', level: 3 },
|
|
106
|
+
{ type: 'code', ariaLabel: 'Ejemplo de CSS generado', code: '.layout-playground {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 24px;\n justify-content: center;\n align-items: center;\n}' },
|
|
107
|
+
{ type: 'diagnostic', variant: 'info', title: 'Por qué importa el redimensionado visual', html: 'Muchos bugs de layout solo aparecen cuando el contenedor es más estrecho, más alto o tiene distinto número de ítems. Redimensionar el playground mientras el CSS se actualiza en vivo te ayuda a detectar wrapping incómodo, gaps excesivos y decisiones de alineación que solo funcionan a un tamaño.' },
|
|
108
|
+
{ type: 'summary', title: 'Flujo de trabajo recomendado', items: ['Elige un preset o Flexbox para flujos unidimensionales y Grid para estructura bidimensional.', 'Redimensiona el canvas visual antes de copiar CSS para que el layout sobreviva restricciones realistas.', 'Usa gap para espaciado entre ítems en vez de añadir márgenes a cada hijo.', 'Copia el CSS generado como punto de partida, luego añade selectores específicos y media queries.'] },
|
|
109
|
+
],
|
|
110
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { VisualCssGridFlexboxGeneratorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'generateur-visuel-css-grid-flexbox';
|
|
7
|
+
const title = 'Générateur Visuel de Layout CSS Grid & Flexbox';
|
|
8
|
+
const description = 'Concevez des layouts responsives en déplaçant des blocs visuels, en redimensionnant le conteneur, en ajustant l\'alignement et en utilisant des presets - puis copiez du CSS natif propre instantanément.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{ name: 'Choisissez un preset ou Flexbox / Grid', text: 'Commencez avec un preset de layout (navbar, cards, hero, sidebar, gallery) ou basculez entre Flexbox et Grid manuellement.' },
|
|
12
|
+
{ name: 'Redimensionnez le layout', text: 'Redimensionnez le conteneur depuis le coin inférieur pour tester comment le design réagit à l\'espace disponible.' },
|
|
13
|
+
{ name: 'Ajustez les contrôles d\'alignement', text: 'Utilisez les sliders et selects pour la direction, le wrap, l\'écart, les colonnes, justify-content, align-items, align-content, la largeur, la hauteur et la taille des éléments.' },
|
|
14
|
+
{ name: 'Copiez du CSS prêt pour la production', text: 'Copiez le CSS généré quand le résultat visuel correspond à la structure souhaitée. Sans dépendance de framework.' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const faq = [
|
|
18
|
+
{ question: 'Quand utiliser Flexbox plutôt que CSS Grid ?', answer: 'Utilisez Flexbox pour les layouts unidimensionnels - barres de navigation, groupes de boutons, cartes enveloppées, contenu centré. Grid quand lignes et colonnes comptent ensemble - dashboards, galeries, formulaires, sections structurées.' },
|
|
19
|
+
{ question: 'Ce générateur peut-il créer des layouts responsives ?', answer: 'Oui. Le CSS généré utilise le flex wrapping natif ou les colonnes répétées de grid. Redimensionnez le canvas visuel pour tester l\'espacement et l\'alignement à différentes tailles.' },
|
|
20
|
+
{ question: 'Pourquoi justify-content et align-items semblent-ils différents en grid et flex ?', answer: 'Flexbox distribue les éléments le long d\'un axe principal et d\'un axe transversal. Grid place d\'abord les éléments dans des tracks, puis aligne le contenu dans ces tracks. Basculer entre les deux modes rend cette différence immédiatement visible.' },
|
|
21
|
+
{ question: 'Le CSS généré est-il lié à un framework ?', answer: 'Non. Le résultat est du CSS natif pur. Utilisez-le en HTML simple, Astro, React, Vue, Svelte, Web Components ou tout projet acceptant du CSS standard.' },
|
|
22
|
+
{ question: 'À quoi servent les presets de layout ?', answer: 'Les presets accélèrent les layouts courants pour voir des configurations réalistes sans partir de zéro. Chaque preset configure le mode, la direction, le wrap, l\'alignement et la taille du conteneur pour un motif réel.' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ui: VisualCssGridFlexboxGeneratorUI = {
|
|
26
|
+
modeLabel: 'Mode de layout',
|
|
27
|
+
flexMode: 'Flexbox',
|
|
28
|
+
gridMode: 'Grid',
|
|
29
|
+
canvasLabel: 'Canvas de layout interactif',
|
|
30
|
+
addItem: 'Ajouter élément',
|
|
31
|
+
removeItem: 'Retirer élément',
|
|
32
|
+
resetLayout: 'Réinitialiser',
|
|
33
|
+
gapLabel: 'Écart',
|
|
34
|
+
columnsLabel: 'Colonnes grid',
|
|
35
|
+
widthLabel: 'Largeur conteneur',
|
|
36
|
+
heightLabel: 'Hauteur conteneur',
|
|
37
|
+
justifyLabel: 'Justifier',
|
|
38
|
+
alignLabel: 'Aligner',
|
|
39
|
+
itemSizeLabel: 'Taille élément',
|
|
40
|
+
codeTitle: 'CSS Généré',
|
|
41
|
+
copyCode: 'Copier CSS',
|
|
42
|
+
copied: 'Copié !',
|
|
43
|
+
dragHint: 'Redimensionnez le canvas depuis le coin - le CSS se met à jour en direct !',
|
|
44
|
+
outputLabel: 'Sortie CSS générée',
|
|
45
|
+
justifyStart: 'Début',
|
|
46
|
+
justifyCenter: 'Centre',
|
|
47
|
+
justifyEnd: 'Fin',
|
|
48
|
+
justifyBetween: 'Space between',
|
|
49
|
+
justifyAround: 'Space around',
|
|
50
|
+
justifyEvenly: 'Space evenly',
|
|
51
|
+
alignStart: 'Début',
|
|
52
|
+
alignCenter: 'Centre',
|
|
53
|
+
alignEnd: 'Fin',
|
|
54
|
+
alignStretch: 'Étirer',
|
|
55
|
+
alignBaseline: 'Ligne de base',
|
|
56
|
+
itemPrefix: 'Bloc',
|
|
57
|
+
directionLabel: 'Direction',
|
|
58
|
+
directionRow: 'Ligne →',
|
|
59
|
+
directionRowReverse: '← Ligne inv',
|
|
60
|
+
directionColumn: 'Colonne ↓',
|
|
61
|
+
directionColumnReverse: '↑ Col inv',
|
|
62
|
+
wrapLabel: 'Retour',
|
|
63
|
+
wrapNoWrap: 'Sans retour',
|
|
64
|
+
wrapWrap: 'Avec retour',
|
|
65
|
+
wrapWrapReverse: 'Retour inv',
|
|
66
|
+
alignContentLabel: 'Aligner contenu',
|
|
67
|
+
alignContentStart: 'Début',
|
|
68
|
+
alignContentCenter: 'Centre',
|
|
69
|
+
alignContentEnd: 'Fin',
|
|
70
|
+
alignContentBetween: 'Space between',
|
|
71
|
+
alignContentAround: 'Space around',
|
|
72
|
+
alignContentEvenly: 'Space evenly',
|
|
73
|
+
alignContentStretch: 'Étirer',
|
|
74
|
+
presetsLabel: 'Presets',
|
|
75
|
+
presetNavbar: 'Navbar',
|
|
76
|
+
presetCards: 'Cartes',
|
|
77
|
+
presetHero: 'Hero',
|
|
78
|
+
presetSidebar: 'Sidebar',
|
|
79
|
+
presetGallery: 'Galerie',
|
|
80
|
+
shakeLimit: 'Au moins 2 éléments requis !',
|
|
81
|
+
spanHint: 'Double-cliquez sur un élément pour changer sa portée de colonne (1-3) en mode Grid',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const faqSchema: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
85
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name, text: step.text })) };
|
|
86
|
+
const appSchema: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'DeveloperApplication', operatingSystem: 'Any', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } };
|
|
87
|
+
|
|
88
|
+
export const content: ToolLocaleContent<VisualCssGridFlexboxGeneratorUI> = {
|
|
89
|
+
slug, title, description, ui,
|
|
90
|
+
faqTitle: 'FAQ du générateur de layout CSS',
|
|
91
|
+
faq,
|
|
92
|
+
bibliographyTitle: 'Références CSS Grid et Flexbox',
|
|
93
|
+
bibliography,
|
|
94
|
+
howTo,
|
|
95
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
96
|
+
seo: [
|
|
97
|
+
{ type: 'title', text: 'Créez des layouts CSS en observant le comportement, pas en mémorisant', level: 2 },
|
|
98
|
+
{ type: 'paragraph', html: 'CSS Grid et Flexbox sont puissants car ils décrivent des relations de layout au lieu de coordonnées fixes. Le difficile est de prédire comment <strong>gap</strong>, <strong>justify-content</strong>, <strong>align-items</strong>, direction, retour, tracks et espace disponible interagissent. Ce générateur transforme ces propriétés abstraites en un terrain de jeu vivant avec presets et CSS en temps réel.' },
|
|
99
|
+
{ type: 'stats', columns: 3, items: [{ value: '5', label: 'Presets de démarrage rapide', icon: 'mdi:view-grid-plus' }, { value: 'Direct', label: 'CSS mis à jour à chaque changement', icon: 'mdi:code-braces' }, { value: '0', label: 'Dépendances framework dans le CSS', icon: 'mdi:language-css3' }] },
|
|
100
|
+
{ type: 'title', text: 'Flexbox vs Grid: choisissez le modèle avant de peaufiner l\'alignement', level: 3 },
|
|
101
|
+
{ type: 'comparative', columns: 2, items: [{ title: 'Flexbox', description: 'Idéal pour les flux unidimensionnels où les éléments s\'alignent en ligne ou colonne et peuvent se retourner.', icon: 'mdi:format-align-justify', highlight: true, points: ['Navigation', 'Groupes de boutons', 'Cartes enveloppées', 'Contenu centré'] }, { title: 'CSS Grid', description: 'Idéal pour les structures bidimensionnelles où lignes et colonnes définissent la composition.', icon: 'mdi:grid', points: ['Dashboards', 'Galeries', 'Formulaires', 'Sections éditoriales'] }] },
|
|
102
|
+
{ type: 'title', text: 'Ce que chaque contrôle vous apprend', level: 3 },
|
|
103
|
+
{ type: 'table', headers: ['Contrôle', 'Propriété CSS', 'À observer'], rows: [['Direction', '<code>flex-direction</code>', 'Comment l\'axe principal s\'écoule - passer de ligne à colonne change toute la logique.'], ['Retour', '<code>flex-wrap</code>', 'Si les éléments restent sur une ligne ou passent à la ligne suivante.'], ['Écart', '<code>gap</code>', 'L\'espace entre éléments sans marges qui cassent aux bords.'], ['Justifier', '<code>justify-content</code>', 'Comment l\'espace libre est distribué le long de l\'axe principal.'], ['Aligner', '<code>align-items</code>', 'Comment les éléments se positionnent sur l\'axe transversal.'], ['Aligner contenu', '<code>align-content</code>', 'Comment les lignes enveloppées ou rangées de grid distribuent l\'espace supplémentaire.'], ['Colonnes', '<code>grid-template-columns</code>', 'Combien de tracks égales le grid crée avant que les éléments passent à une autre ligne.'], ['Taille conteneur', '<code>width</code> et <code>min-height</code>', 'Comment le même CSS réagit quand l\'espace disponible change.']] },
|
|
104
|
+
{ type: 'tip', title: 'Redimensionnez d\'abord, optimisez ensuite', html: 'Commencez par redimensionner le canvas à une taille réaliste. Puis ajustez l\'écart et l\'alignement. Ainsi le CSS généré fonctionne dans des conditions réelles.' },
|
|
105
|
+
{ type: 'title', text: 'CSS propre que vous pouvez adapter', level: 3 },
|
|
106
|
+
{ type: 'code', ariaLabel: 'Exemple de CSS généré', code: '.layout-playground {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 24px;\n justify-content: center;\n align-items: center;\n}' },
|
|
107
|
+
{ type: 'diagnostic', variant: 'info', title: 'Pourquoi le redimensionnement visuel est important', html: 'Beaucoup de bugs de layout n\'apparaissent que lorsque le conteneur est plus étroit, plus haut ou rempli différemment. Redimensionner pendant que le CSS se met à jour en direct aide à repérer les retours gênants et les choix d\'alignement fragiles.' },
|
|
108
|
+
{ type: 'summary', title: 'Workflow recommandé', items: ['Choisissez un preset ou Flexbox pour les flux unidimensionnels et Grid pour la structure bidimensionnelle.', 'Redimensionnez le canvas avant de copier le CSS pour que le layout survive aux contraintes réelles.', 'Utilisez gap pour l\'espacement entre éléments au lieu d\'ajouter des marges à chaque enfant.', 'Copiez le CSS généré comme point de départ, puis ajoutez des sélecteurs spécifiques et des media queries.'] },
|
|
109
|
+
],
|
|
110
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { VisualCssGridFlexboxGeneratorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'generator-visual-css-grid-flexbox';
|
|
7
|
+
const title = 'Generator Visual Layout CSS Grid & Flexbox';
|
|
8
|
+
const description = 'Rancang layout responsif dengan memindahkan blok visual, mengubah ukuran kontainer, menyesuaikan perataan, dan menggunakan preset - lalu salin CSS native bersih secara instan.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{ name: 'Pilih preset atau Flexbox / Grid', text: 'Mulai dengan preset layout (navbar, cards, hero, sidebar, gallery) atau beralih antara Flexbox dan Grid secara manual.' },
|
|
12
|
+
{ name: 'Ubah ukuran layout', text: 'Ubah ukuran kontainer dari sudut bawah untuk menguji bagaimana desain bereaksi terhadap ruang yang tersedia.' },
|
|
13
|
+
{ name: 'Sesuaikan kontrol perataan', text: 'Gunakan slider dan dropdown untuk arah, wrap, jarak, kolom, justify-content, align-items, align-content, lebar, tinggi, dan ukuran item.' },
|
|
14
|
+
{ name: 'Salin CSS siap produksi', text: 'Salin CSS yang dihasilkan saat hasil visual sesuai dengan struktur yang diinginkan. Tanpa ketergantungan framework.' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const faq = [
|
|
18
|
+
{ question: 'Kapan menggunakan Flexbox daripada CSS Grid?', answer: 'Gunakan Flexbox untuk layout satu dimensi - bilah navigasi, grup tombol, kartu yang membungkus, konten terpusat. Grid saat baris dan kolom sama-sama penting - dashboard, galeri, formulir, bagian halaman terstruktur.' },
|
|
19
|
+
{ question: 'Bisakah generator ini membuat layout responsif?', answer: 'Ya. CSS yang dihasilkan menggunakan flex wrapping native atau kolom berulang grid. Ubah ukuran kanvas visual untuk menguji jarak dan perataan pada berbagai ukuran.' },
|
|
20
|
+
{ question: 'Mengapa justify-content dan align-items terasa berbeda di grid dan flex?', answer: 'Flexbox mendistribusikan item di sepanjang sumbu utama dan sumbu silang. Grid menempatkan item di track terlebih dahulu, lalu meratakan konten di dalamnya. Beralih antara kedua mode membuat perbedaan itu langsung terlihat.' },
|
|
21
|
+
{ question: 'Apakah CSS yang dihasilkan terikat pada framework?', answer: 'Tidak. Hasilnya adalah CSS native murni. Gunakan di HTML biasa, Astro, React, Vue, Svelte, Web Components, atau proyek apa pun yang menerima CSS standar.' },
|
|
22
|
+
{ question: 'Untuk apa preset layout?', answer: 'Preset mempercepat layout umum sehingga Anda melihat konfigurasi realistis tanpa mulai dari nol. Setiap preset mengatur mode, arah, wrap, perataan, dan ukuran kontainer untuk pola dunia nyata.' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ui: VisualCssGridFlexboxGeneratorUI = {
|
|
26
|
+
modeLabel: 'Mode layout',
|
|
27
|
+
flexMode: 'Flexbox',
|
|
28
|
+
gridMode: 'Grid',
|
|
29
|
+
canvasLabel: 'Kanvas layout interaktif',
|
|
30
|
+
addItem: 'Tambah item',
|
|
31
|
+
removeItem: 'Hapus item',
|
|
32
|
+
resetLayout: 'Reset layout',
|
|
33
|
+
gapLabel: 'Jarak',
|
|
34
|
+
columnsLabel: 'Kolom grid',
|
|
35
|
+
widthLabel: 'Lebar kontainer',
|
|
36
|
+
heightLabel: 'Tinggi kontainer',
|
|
37
|
+
justifyLabel: 'Ratakan',
|
|
38
|
+
alignLabel: 'Ratakan',
|
|
39
|
+
itemSizeLabel: 'Ukuran item',
|
|
40
|
+
codeTitle: 'CSS Dihasilkan',
|
|
41
|
+
copyCode: 'Salin CSS',
|
|
42
|
+
copied: 'Tersalin!',
|
|
43
|
+
dragHint: 'Ubah ukuran kanvas dari sudut - CSS diperbarui langsung!',
|
|
44
|
+
outputLabel: 'Output CSS yang dihasilkan',
|
|
45
|
+
justifyStart: 'Awal',
|
|
46
|
+
justifyCenter: 'Tengah',
|
|
47
|
+
justifyEnd: 'Akhir',
|
|
48
|
+
justifyBetween: 'Space between',
|
|
49
|
+
justifyAround: 'Space around',
|
|
50
|
+
justifyEvenly: 'Space evenly',
|
|
51
|
+
alignStart: 'Awal',
|
|
52
|
+
alignCenter: 'Tengah',
|
|
53
|
+
alignEnd: 'Akhir',
|
|
54
|
+
alignStretch: 'Rentang',
|
|
55
|
+
alignBaseline: 'Garis dasar',
|
|
56
|
+
itemPrefix: 'Blok',
|
|
57
|
+
directionLabel: 'Arah',
|
|
58
|
+
directionRow: 'Baris →',
|
|
59
|
+
directionRowReverse: '← Baris blk',
|
|
60
|
+
directionColumn: 'Kolom ↓',
|
|
61
|
+
directionColumnReverse: '↑ Kol blk',
|
|
62
|
+
wrapLabel: 'Bungkus',
|
|
63
|
+
wrapNoWrap: 'Tanpa bungkus',
|
|
64
|
+
wrapWrap: 'Bungkus',
|
|
65
|
+
wrapWrapReverse: 'Bungkus blk',
|
|
66
|
+
alignContentLabel: 'Ratakan konten',
|
|
67
|
+
alignContentStart: 'Awal',
|
|
68
|
+
alignContentCenter: 'Tengah',
|
|
69
|
+
alignContentEnd: 'Akhir',
|
|
70
|
+
alignContentBetween: 'Space between',
|
|
71
|
+
alignContentAround: 'Space around',
|
|
72
|
+
alignContentEvenly: 'Space evenly',
|
|
73
|
+
alignContentStretch: 'Rentang',
|
|
74
|
+
presetsLabel: 'Preset',
|
|
75
|
+
presetNavbar: 'Navbar',
|
|
76
|
+
presetCards: 'Kartu',
|
|
77
|
+
presetHero: 'Hero',
|
|
78
|
+
presetSidebar: 'Sidebar',
|
|
79
|
+
presetGallery: 'Galeri',
|
|
80
|
+
shakeLimit: 'Butuh minimal 2 item!',
|
|
81
|
+
spanHint: 'Klik dua kali item untuk mengubah rentang kolom (1-3) dalam mode Grid',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const faqSchema: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
85
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name, text: step.text })) };
|
|
86
|
+
const appSchema: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'DeveloperApplication', operatingSystem: 'Any', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } };
|
|
87
|
+
|
|
88
|
+
export const content: ToolLocaleContent<VisualCssGridFlexboxGeneratorUI> = {
|
|
89
|
+
slug, title, description, ui,
|
|
90
|
+
faqTitle: 'FAQ generator layout CSS',
|
|
91
|
+
faq,
|
|
92
|
+
bibliographyTitle: 'Referensi CSS Grid dan Flexbox',
|
|
93
|
+
bibliography,
|
|
94
|
+
howTo,
|
|
95
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
96
|
+
seo: [
|
|
97
|
+
{ type: 'title', text: 'Bangun layout CSS dengan melihat perilaku, bukan menghafal properti', level: 2 },
|
|
98
|
+
{ type: 'paragraph', html: 'CSS Grid dan Flexbox kuat karena mendeskripsikan hubungan layout alih-alih koordinat tetap. Yang sulit adalah memprediksi bagaimana <strong>gap</strong>, <strong>justify-content</strong>, <strong>align-items</strong>, arah, pembungkusan, track, dan ruang yang tersedia berinteraksi. Generator ini mengubah properti abstrak menjadi taman bermain langsung dengan preset dan CSS real-time.' },
|
|
99
|
+
{ type: 'stats', columns: 3, items: [{ value: '5', label: 'Preset layout cepat', icon: 'mdi:view-grid-plus' }, { value: 'Langsung', label: 'CSS diperbarui setiap perubahan', icon: 'mdi:code-braces' }, { value: '0', label: 'Ketergantungan framework di CSS', icon: 'mdi:language-css3' }] },
|
|
100
|
+
{ type: 'title', text: 'Flexbox vs Grid: pilih model sebelum menyempurnakan perataan', level: 3 },
|
|
101
|
+
{ type: 'comparative', columns: 2, items: [{ title: 'Flexbox', description: 'Terbaik untuk aliran satu dimensi di mana item berbaris dalam baris atau kolom dan membungkus secara alami.', icon: 'mdi:format-align-justify', highlight: true, points: ['Bilah navigasi', 'Grup tombol', 'Kartu membungkus', 'Konten terpusat'] }, { title: 'CSS Grid', description: 'Terbaik untuk struktur dua dimensi di mana baris dan kolom menentukan bentuk komposisi.', icon: 'mdi:grid', points: ['Dashboard', 'Galeri', 'Formulir', 'Bagian editorial'] }] },
|
|
102
|
+
{ type: 'title', text: 'Apa yang diajarkan setiap kontrol', level: 3 },
|
|
103
|
+
{ type: 'table', headers: ['Kontrol', 'Properti CSS', 'Yang perlu diperhatikan'], rows: [['Arah', '<code>flex-direction</code>', 'Bagaimana sumbu utama mengalir - beralih dari baris ke kolom mengubah seluruh logika layout.'], ['Bungkus', '<code>flex-wrap</code>', 'Apakah item tetap di satu baris atau mengalir ke baris baru saat ruang habis.'], ['Jarak', '<code>gap</code>', 'Ruang antara item tanpa margin yang rusak di tepi.'], ['Ratakan', '<code>justify-content</code>', 'Bagaimana ruang kosong didistribusikan di sepanjang sumbu utama.'], ['Ratakan', '<code>align-items</code>', 'Bagaimana item duduk di sumbu silang.'], ['Ratakan konten', '<code>align-content</code>', 'Bagaimana baris flex yang terbungkus atau baris grid mendistribusikan ruang sumbu silang tambahan.'], ['Kolom', '<code>grid-template-columns</code>', 'Berapa banyak track sama yang dibuat grid sebelum item pindah ke baris lain.'], ['Ukuran kontainer', '<code>width</code> dan <code>min-height</code>', 'Bagaimana CSS yang sama bereaksi saat ruang yang tersedia berubah.']] },
|
|
104
|
+
{ type: 'tip', title: 'Skalakan dulu, optimalkan kemudian', html: 'Mulailah dengan menskalakan kanvas ke ukuran realistis. Kemudian sesuaikan jarak dan perataan. Dengan begitu CSS yang dihasilkan berfungsi dalam kondisi nyata.' },
|
|
105
|
+
{ type: 'title', text: 'CSS bersih yang dapat Anda adaptasi', level: 3 },
|
|
106
|
+
{ type: 'code', ariaLabel: 'Contoh CSS yang dihasilkan', code: '.layout-playground {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 24px;\n justify-content: center;\n align-items: center;\n}' },
|
|
107
|
+
{ type: 'diagnostic', variant: 'info', title: 'Mengapa penskalaan visual penting', html: 'Banyak bug layout hanya muncul saat kontainer lebih sempit, lebih tinggi, atau diisi dengan jumlah item berbeda. Menskalakan saat CSS diperbarui langsung membantu menemukan pembungkusan yang canggung dan pilihan perataan yang rapuh.' },
|
|
108
|
+
{ type: 'summary', title: 'Alur kerja yang direkomendasikan', items: ['Pilih preset atau Flexbox untuk aliran satu dimensi dan Grid untuk struktur dua dimensi.', 'Skalakan kanvas sebelum menyalin CSS agar layout bertahan dalam batasan realistis.', 'Gunakan gap untuk jarak antar item alih-alih menambahkan margin ke setiap anak.', 'Salin CSS yang dihasilkan sebagai titik awal, lalu tambahkan selector spesifik proyek dan media queries.'] },
|
|
109
|
+
],
|
|
110
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { VisualCssGridFlexboxGeneratorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'generatore-visuale-css-grid-flexbox';
|
|
7
|
+
const title = 'Generatore Visivo di Layout CSS Grid & Flexbox';
|
|
8
|
+
const description = 'Progetta layout responsivi spostando blocchi visivi, ridimensionando il contenitore, regolando l\'allineamento e usando i preset - poi copia CSS nativo pulito all\'istante.';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{ name: 'Scegli un preset o Flexbox / Grid', text: 'Inizia con un preset di layout (navbar, cards, hero, sidebar, gallery) o passa manualmente tra Flexbox e Grid.' },
|
|
12
|
+
{ name: 'Ridimensiona il layout', text: 'Ridimensiona il contenitore dall\'angolo inferiore per testare come il design reagisce allo spazio disponibile.' },
|
|
13
|
+
{ name: 'Regola i controlli di allineamento', text: 'Usa slider e select per direzione, wrap, gap, colonne, justify-content, align-items, align-content, larghezza, altezza e dimensione elementi.' },
|
|
14
|
+
{ name: 'Copia CSS pronto per la produzione', text: 'Copia il CSS generato quando il risultato visivo corrisponde alla struttura desiderata. Nessuna dipendenza da framework.' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const faq = [
|
|
18
|
+
{ question: 'Quando usare Flexbox invece di CSS Grid?', answer: 'Usa Flexbox per layout unidimensionali - barre di navigazione, gruppi di pulsanti, card a capo, contenuto centrato. Grid quando righe e colonne contano insieme - dashboard, gallerie, form, sezioni strutturate.' },
|
|
19
|
+
{ question: 'Questo generatore può creare layout responsivi?', answer: 'Sì. Il CSS generato usa flex wrapping nativo o colonne ripetute grid. Ridimensiona il canvas visivo per testare spaziatura e allineamento a diverse dimensioni.' },
|
|
20
|
+
{ question: 'Perché justify-content e align-items sembrano diversi in grid e flex?', answer: 'Flexbox distribuisce gli elementi lungo un asse principale e uno trasversale. Grid posiziona prima gli elementi nei track, poi allinea il contenuto al loro interno. Passare da un modo all\'altro rende questa differenza immediatamente visibile.' },
|
|
21
|
+
{ question: 'Il CSS generato è legato a un framework?', answer: 'No. Il risultato è CSS nativo puro. Usalo in HTML semplice, Astro, React, Vue, Svelte, Web Components o qualsiasi progetto che accetti CSS standard.' },
|
|
22
|
+
{ question: 'A cosa servono i preset di layout?', answer: 'I preset accelerano i layout comuni per vedere configurazioni realistiche senza partire da zero. Ogni preset imposta modalità, direzione, wrap, allineamento e dimensione del contenitore per un pattern reale.' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ui: VisualCssGridFlexboxGeneratorUI = {
|
|
26
|
+
modeLabel: 'Modalità layout',
|
|
27
|
+
flexMode: 'Flexbox',
|
|
28
|
+
gridMode: 'Grid',
|
|
29
|
+
canvasLabel: 'Canvas layout interattivo',
|
|
30
|
+
addItem: 'Aggiungi elemento',
|
|
31
|
+
removeItem: 'Rimuovi elemento',
|
|
32
|
+
resetLayout: 'Ripristina layout',
|
|
33
|
+
gapLabel: 'Spaziatura',
|
|
34
|
+
columnsLabel: 'Colonne grid',
|
|
35
|
+
widthLabel: 'Larghezza contenitore',
|
|
36
|
+
heightLabel: 'Altezza contenitore',
|
|
37
|
+
justifyLabel: 'Giustifica',
|
|
38
|
+
alignLabel: 'Allinea',
|
|
39
|
+
itemSizeLabel: 'Dimensione elemento',
|
|
40
|
+
codeTitle: 'CSS Generato',
|
|
41
|
+
copyCode: 'Copia CSS',
|
|
42
|
+
copied: 'Copiato!',
|
|
43
|
+
dragHint: 'Ridimensiona il canvas dall\'angolo - il CSS si aggiorna in tempo reale!',
|
|
44
|
+
outputLabel: 'Output CSS generato',
|
|
45
|
+
justifyStart: 'Inizio',
|
|
46
|
+
justifyCenter: 'Centro',
|
|
47
|
+
justifyEnd: 'Fine',
|
|
48
|
+
justifyBetween: 'Space between',
|
|
49
|
+
justifyAround: 'Space around',
|
|
50
|
+
justifyEvenly: 'Space evenly',
|
|
51
|
+
alignStart: 'Inizio',
|
|
52
|
+
alignCenter: 'Centro',
|
|
53
|
+
alignEnd: 'Fine',
|
|
54
|
+
alignStretch: 'Estendi',
|
|
55
|
+
alignBaseline: 'Linea base',
|
|
56
|
+
itemPrefix: 'Blocco',
|
|
57
|
+
directionLabel: 'Direzione',
|
|
58
|
+
directionRow: 'Riga →',
|
|
59
|
+
directionRowReverse: '← Riga inv',
|
|
60
|
+
directionColumn: 'Colonna ↓',
|
|
61
|
+
directionColumnReverse: '↑ Col inv',
|
|
62
|
+
wrapLabel: 'A capo',
|
|
63
|
+
wrapNoWrap: 'No a capo',
|
|
64
|
+
wrapWrap: 'A capo',
|
|
65
|
+
wrapWrapReverse: 'A capo inv',
|
|
66
|
+
alignContentLabel: 'Allinea contenuto',
|
|
67
|
+
alignContentStart: 'Inizio',
|
|
68
|
+
alignContentCenter: 'Centro',
|
|
69
|
+
alignContentEnd: 'Fine',
|
|
70
|
+
alignContentBetween: 'Space between',
|
|
71
|
+
alignContentAround: 'Space around',
|
|
72
|
+
alignContentEvenly: 'Space evenly',
|
|
73
|
+
alignContentStretch: 'Estendi',
|
|
74
|
+
presetsLabel: 'Preset',
|
|
75
|
+
presetNavbar: 'Navbar',
|
|
76
|
+
presetCards: 'Cards',
|
|
77
|
+
presetHero: 'Hero',
|
|
78
|
+
presetSidebar: 'Sidebar',
|
|
79
|
+
presetGallery: 'Galleria',
|
|
80
|
+
shakeLimit: 'Servono almeno 2 elementi!',
|
|
81
|
+
spanHint: 'Doppio clic su un elemento per cambiare l\'estensione di colonna (1-3) in modalità Grid',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const faqSchema: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
85
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name, text: step.text })) };
|
|
86
|
+
const appSchema: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'DeveloperApplication', operatingSystem: 'Any', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } };
|
|
87
|
+
|
|
88
|
+
export const content: ToolLocaleContent<VisualCssGridFlexboxGeneratorUI> = {
|
|
89
|
+
slug, title, description, ui,
|
|
90
|
+
faqTitle: 'FAQ generatore layout CSS',
|
|
91
|
+
faq,
|
|
92
|
+
bibliographyTitle: 'Riferimenti CSS Grid e Flexbox',
|
|
93
|
+
bibliography,
|
|
94
|
+
howTo,
|
|
95
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
96
|
+
seo: [
|
|
97
|
+
{ type: 'title', text: 'Costruisci layout CSS osservando il comportamento, non memorizzando proprietà', level: 2 },
|
|
98
|
+
{ type: 'paragraph', html: 'CSS Grid e Flexbox sono potenti perché descrivono relazioni di layout invece di coordinate fisse. La difficoltà è prevedere come interagiscono <strong>gap</strong>, <strong>justify-content</strong>, <strong>align-items</strong>, direzione, a capo, track e spazio disponibile. Questo generatore trasforma proprietà astratte in un playground vivo con preset e CSS in tempo reale.' },
|
|
99
|
+
{ type: 'stats', columns: 3, items: [{ value: '5', label: 'Preset layout rapidi', icon: 'mdi:view-grid-plus' }, { value: 'Live', label: 'CSS aggiornato a ogni modifica', icon: 'mdi:code-braces' }, { value: '0', label: 'Dipendenze framework nel CSS', icon: 'mdi:language-css3' }] },
|
|
100
|
+
{ type: 'title', text: 'Flexbox vs Grid: scegli il modello prima di rifinire l\'allineamento', level: 3 },
|
|
101
|
+
{ type: 'comparative', columns: 2, items: [{ title: 'Flexbox', description: 'Ideale per flussi unidimensionali dove gli elementi si allineano in riga o colonna e vanno a capo naturalmente.', icon: 'mdi:format-align-justify', highlight: true, points: ['Navigazione', 'Gruppi di pulsanti', 'Card a capo', 'Contenuto centrato'] }, { title: 'CSS Grid', description: 'Ideale per strutture bidimensionali dove righe e colonne definiscono la forma della composizione.', icon: 'mdi:grid', points: ['Dashboard', 'Gallerie', 'Form', 'Sezioni editoriali'] }] },
|
|
102
|
+
{ type: 'title', text: 'Cosa insegna ogni controllo', level: 3 },
|
|
103
|
+
{ type: 'table', headers: ['Controllo', 'Proprietà CSS', 'Cosa osservare'], rows: [['Direzione', '<code>flex-direction</code>', 'Come scorre l\'asse principale - passare da riga a colonna cambia tutta la logica.'], ['A capo', '<code>flex-wrap</code>', 'Se gli elementi restano su una riga o vanno a capo quando lo spazio finisce.'], ['Spaziatura', '<code>gap</code>', 'Lo spazio tra elementi senza margini che si rompono ai bordi.'], ['Giustifica', '<code>justify-content</code>', 'Come lo spazio libero è distribuito lungo l\'asse principale.'], ['Allinea', '<code>align-items</code>', 'Come gli elementi si posizionano sull\'asse trasversale.'], ['Allinea contenuto', '<code>align-content</code>', 'Come le righe a capo o le righe grid distribuiscono lo spazio extra.'], ['Colonne', '<code>grid-template-columns</code>', 'Quanti track uguali crea il grid prima che gli elementi vadano a capo.'], ['Dim. contenitore', '<code>width</code> e <code>min-height</code>', 'Come lo stesso CSS reagisce quando lo spazio disponibile cambia.']] },
|
|
104
|
+
{ type: 'tip', title: 'Prima ridimensiona, poi ottimizza', html: 'Inizia ridimensionando il canvas a una dimensione realistica. Poi regola spaziatura e allineamento. Così il CSS generato funziona in condizioni reali.' },
|
|
105
|
+
{ type: 'title', text: 'CSS pulito che puoi adattare', level: 3 },
|
|
106
|
+
{ type: 'code', ariaLabel: 'Esempio CSS generato', code: '.layout-playground {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 24px;\n justify-content: center;\n align-items: center;\n}' },
|
|
107
|
+
{ type: 'diagnostic', variant: 'info', title: 'Perché il ridimensionamento visivo è importante', html: 'Molti bug di layout compaiono solo quando il contenitore è più stretto, più alto o con un numero diverso di elementi. Ridimensionare mentre il CSS si aggiorna in diretta aiuta a individuare ritorni a capo scomodi e scelte di allineamento fragili.' },
|
|
108
|
+
{ type: 'summary', title: 'Workflow consigliato', items: ['Scegli un preset o Flexbox per flussi unidimensionali e Grid per struttura bidimensionale.', 'Ridimensiona il canvas prima di copiare il CSS affinché il layout sopravviva a vincoli realistici.', 'Usa gap per la spaziatura tra elementi invece di aggiungere margini a ogni figlio.', 'Copia il CSS generato come punto di partenza, poi aggiungi selettori specifici e media queries.'] },
|
|
109
|
+
],
|
|
110
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { VisualCssGridFlexboxGeneratorUI } from '../ui';
|
|
4
|
+
import { bibliography } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'visual-css-grid-flexbox-generator';
|
|
7
|
+
const title = 'ビジュアルCSS Grid & Flexboxレイアウトジェネレーター';
|
|
8
|
+
const description = 'ビジュアルブロックを移動し、コンテナをリサイズし、配置を調整し、プリセットを使用してレスポンシブレイアウトを設計 - クリーンなネイティブCSSをすぐにコピー。';
|
|
9
|
+
|
|
10
|
+
const howTo = [
|
|
11
|
+
{ name: 'プリセットまたはFlexbox/Gridを選択', text: 'レイアウトプリセット(navbar, cards, hero, sidebar, gallery)から始めるか、FlexboxとGridを手動で切り替えます。' },
|
|
12
|
+
{ name: 'レイアウトをリサイズ', text: '右下隅からコンテナをリサイズして、デザインが利用可能なスペースにどう反応するかテストします。' },
|
|
13
|
+
{ name: '配置コントロールを調整', text: '方向、折り返し、間隔、列数、justify-content、align-items、align-content、幅、高さ、アイテムサイズのスライダーとセレクトを使用します。' },
|
|
14
|
+
{ name: '本番対応CSSをコピー', text: '視覚的な結果が目的の構造と一致したら、生成されたCSSをコピーします。フレームワーク依存なし。' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const faq = [
|
|
18
|
+
{ question: 'Flexboxの代わりにCSS Gridを使うべきタイミングは?', answer: '1次元レイアウトにはFlexboxを使用 - ナビゲーションバー、ボタングループ、折り返しカード、中央揃えコンテンツ。行と列が共に重要な場合はGrid - ダッシュボード、ギャラリー、フォーム、構造化されたページセクション。' },
|
|
19
|
+
{ question: 'このジェネレーターでレスポンシブレイアウトを作成できますか?', answer: 'はい。生成されるCSSはネイティブのflex折り返しまたは繰り返しgrid列を使用します。ビジュアルキャンバスをリサイズして、異なるサイズでの間隔と配置をテストできます。' },
|
|
20
|
+
{ question: 'justify-contentとalign-itemsがgridとflexで異なる理由は?', answer: 'Flexboxは主軸と交差軸に沿ってアイテムを分散します。Gridは最初にアイテムをトラックに配置し、その中でコンテンツを整列させます。両モードを切り替えると、その違いがすぐに分かります。' },
|
|
21
|
+
{ question: '生成されたCSSはフレームワークに依存しますか?', answer: 'いいえ。結果は純粋なネイティブCSSです。プレーンHTML、Astro、React、Vue、Svelte、Web Componentsなど、標準CSSを受け入れるあらゆるプロジェクトで使用できます。' },
|
|
22
|
+
{ question: 'レイアウトプリセットの目的は?', answer: 'プリセットは一般的なレイアウトを加速し、ゼロから始めずに現実的な設定を確認できます。各プリセットは、実際のパターンに合わせてモード、方向、折り返し、配置、コンテナサイズを設定します。' },
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ui: VisualCssGridFlexboxGeneratorUI = {
|
|
26
|
+
modeLabel: 'レイアウトモード',
|
|
27
|
+
flexMode: 'Flexbox',
|
|
28
|
+
gridMode: 'Grid',
|
|
29
|
+
canvasLabel: 'インタラクティブレイアウトキャンバス',
|
|
30
|
+
addItem: 'アイテム追加',
|
|
31
|
+
removeItem: 'アイテム削除',
|
|
32
|
+
resetLayout: 'レイアウトをリセット',
|
|
33
|
+
gapLabel: '間隔',
|
|
34
|
+
columnsLabel: 'Grid列数',
|
|
35
|
+
widthLabel: 'コンテナ幅',
|
|
36
|
+
heightLabel: 'コンテナ高さ',
|
|
37
|
+
justifyLabel: '水平配置',
|
|
38
|
+
alignLabel: '垂直配置',
|
|
39
|
+
itemSizeLabel: 'アイテムサイズ',
|
|
40
|
+
codeTitle: '生成されたCSS',
|
|
41
|
+
copyCode: 'CSSをコピー',
|
|
42
|
+
copied: 'コピーしました!',
|
|
43
|
+
dragHint: '隅からキャンバスをリサイズ - CSSがライブ更新!',
|
|
44
|
+
outputLabel: '生成されたCSS出力',
|
|
45
|
+
justifyStart: '先頭',
|
|
46
|
+
justifyCenter: '中央',
|
|
47
|
+
justifyEnd: '末尾',
|
|
48
|
+
justifyBetween: 'Space between',
|
|
49
|
+
justifyAround: 'Space around',
|
|
50
|
+
justifyEvenly: 'Space evenly',
|
|
51
|
+
alignStart: '先頭',
|
|
52
|
+
alignCenter: '中央',
|
|
53
|
+
alignEnd: '末尾',
|
|
54
|
+
alignStretch: 'ストレッチ',
|
|
55
|
+
alignBaseline: 'ベースライン',
|
|
56
|
+
itemPrefix: 'ブロック',
|
|
57
|
+
directionLabel: '方向',
|
|
58
|
+
directionRow: '行 →',
|
|
59
|
+
directionRowReverse: '← 行 逆',
|
|
60
|
+
directionColumn: '列 ↓',
|
|
61
|
+
directionColumnReverse: '↑ 列 逆',
|
|
62
|
+
wrapLabel: '折り返し',
|
|
63
|
+
wrapNoWrap: '折り返しなし',
|
|
64
|
+
wrapWrap: '折り返す',
|
|
65
|
+
wrapWrapReverse: '逆折り返し',
|
|
66
|
+
alignContentLabel: 'コンテンツ配置',
|
|
67
|
+
alignContentStart: '先頭',
|
|
68
|
+
alignContentCenter: '中央',
|
|
69
|
+
alignContentEnd: '末尾',
|
|
70
|
+
alignContentBetween: 'Space between',
|
|
71
|
+
alignContentAround: 'Space around',
|
|
72
|
+
alignContentEvenly: 'Space evenly',
|
|
73
|
+
alignContentStretch: 'ストレッチ',
|
|
74
|
+
presetsLabel: 'プリセット',
|
|
75
|
+
presetNavbar: 'ナビバー',
|
|
76
|
+
presetCards: 'カード',
|
|
77
|
+
presetHero: 'ヒーロー',
|
|
78
|
+
presetSidebar: 'サイドバー',
|
|
79
|
+
presetGallery: 'ギャラリー',
|
|
80
|
+
shakeLimit: '最低2つのアイテムが必要です!',
|
|
81
|
+
spanHint: 'Gridモードでアイテムをダブルクリックして列スパン(1-3)を変更',
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const faqSchema: WithContext<FAQPage> = { '@context': 'https://schema.org', '@type': 'FAQPage', mainEntity: faq.map((item) => ({ '@type': 'Question', name: item.question, acceptedAnswer: { '@type': 'Answer', text: item.answer } })) };
|
|
85
|
+
const howToSchema: WithContext<HowTo> = { '@context': 'https://schema.org', '@type': 'HowTo', name: title, description, step: howTo.map((step, index) => ({ '@type': 'HowToStep', position: index + 1, name: step.name, text: step.text })) };
|
|
86
|
+
const appSchema: WithContext<SoftwareApplication> = { '@context': 'https://schema.org', '@type': 'SoftwareApplication', name: title, description, applicationCategory: 'DeveloperApplication', operatingSystem: 'Any', offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' } };
|
|
87
|
+
|
|
88
|
+
export const content: ToolLocaleContent<VisualCssGridFlexboxGeneratorUI> = {
|
|
89
|
+
slug, title, description, ui,
|
|
90
|
+
faqTitle: 'CSSレイアウトジェネレーター FAQ',
|
|
91
|
+
faq,
|
|
92
|
+
bibliographyTitle: 'CSS GridとFlexboxのリファレンス',
|
|
93
|
+
bibliography,
|
|
94
|
+
howTo,
|
|
95
|
+
schemas: [appSchema, faqSchema, howToSchema],
|
|
96
|
+
seo: [
|
|
97
|
+
{ type: 'title', text: 'プロパティを暗記せず、動作を見てCSSレイアウトを構築', level: 2 },
|
|
98
|
+
{ type: 'paragraph', html: 'CSS GridとFlexboxは、固定座標ではなくレイアウト関係を記述するため強力です。難しいのは、<strong>gap</strong>、<strong>justify-content</strong>、<strong>align-items</strong>、方向、折り返し、トラック、利用可能なスペースがどのように相互作用するかを予測することです。このジェネレーターは、抽象的なプロパティをプリセットとリアルタイムCSSを備えた生きたプレイグラウンドに変えます。' },
|
|
99
|
+
{ type: 'stats', columns: 3, items: [{ value: '5', label: 'クイックスタートプリセット', icon: 'mdi:view-grid-plus' }, { value: 'ライブ', label: '変更ごとにCSSが更新', icon: 'mdi:code-braces' }, { value: '0', label: 'CSSのフレームワーク依存', icon: 'mdi:language-css3' }] },
|
|
100
|
+
{ type: 'title', text: 'Flexbox vs Grid: 配置を調整する前にモデルを選択', level: 3 },
|
|
101
|
+
{ type: 'comparative', columns: 2, items: [{ title: 'Flexbox', description: 'アイテムが行または列に並び、自然に折り返す1次元フローに最適。', icon: 'mdi:format-align-justify', highlight: true, points: ['ナビゲーションバー', 'ボタングループ', '折り返しカード', '中央揃えコンテンツ'] }, { title: 'CSS Grid', description: '行と列がコンポジションの形状を定義する2次元構造に最適。', icon: 'mdi:grid', points: ['ダッシュボード', 'ギャラリー', 'フォーム', '編集セクション'] }] },
|
|
102
|
+
{ type: 'title', text: '各コントロールが教えること', level: 3 },
|
|
103
|
+
{ type: 'table', headers: ['コントロール', 'CSSプロパティ', '注目点'], rows: [['方向', '<code>flex-direction</code>', '主軸の流れ方 - 行から列に切り替えるとレイアウト全体のロジックが変わる。'], ['折り返し', '<code>flex-wrap</code>', 'アイテムが1行に留まるか、スペースが尽きると新しい行に流れるか。'], ['間隔', '<code>gap</code>', '端で崩れないアイテム間のスペース。'], ['水平配置', '<code>justify-content</code>', '空きスペースが主軸に沿ってどのように分配されるか。'], ['垂直配置', '<code>align-items</code>', 'アイテムが交差軸上でどのように配置されるか。'], ['コンテンツ配置', '<code>align-content</code>', '折り返されたflex行またはgrid行が追加の交差軸スペースをどのように分配するか。'], ['列数', '<code>grid-template-columns</code>', 'アイテムが次の行に移動する前にgridが作成する等しいトラックの数。'], ['コンテナサイズ', '<code>width</code>と<code>min-height</code>', '利用可能なスペースが変わったときに同じCSSがどのように反応するか。']] },
|
|
104
|
+
{ type: 'tip', title: 'まずスケール、次に最適化', html: 'まずキャンバスを現実的なサイズにスケールします。次に間隔と配置を調整します。これにより、生成されたCSSが実際の条件下で機能します。' },
|
|
105
|
+
{ type: 'title', text: '適応可能なクリーンなCSS', level: 3 },
|
|
106
|
+
{ type: 'code', ariaLabel: '生成CSSの例', code: '.layout-playground {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n gap: 24px;\n justify-content: center;\n align-items: center;\n}' },
|
|
107
|
+
{ type: 'diagnostic', variant: 'info', title: 'ビジュアルスケーリングが重要な理由', html: '多くのレイアウトバグは、コンテナがより狭く、より高く、または異なるアイテム数で満たされたときにのみ現れます。CSSがライブ更新されている間にスケーリングすることで、ぎこちない折り返しや脆弱な配置選択を発見できます。' },
|
|
108
|
+
{ type: 'summary', title: '推奨ワークフロー', items: ['1次元フローにはプリセットまたはFlexbox、2次元構造にはGridを選択。', 'CSSをコピーする前にキャンバスをスケールして、レイアウトが現実的な制約に耐えられるように。', '各子にマージンを追加する代わりに、アイテム間の間隔にgapを使用。', '生成されたCSSを出発点としてコピーし、プロジェクト固有のセレクタとメディアクエリを追加。'] },
|
|
109
|
+
],
|
|
110
|
+
};
|