libreria-astro-lefebvre 0.2.29 → 0.2.32
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
CHANGED
|
@@ -4,7 +4,7 @@ export const metadata: ComponentMetadata = {
|
|
|
4
4
|
component_name: 'Cabecera_2027_Guadalajara',
|
|
5
5
|
category: 'Header',
|
|
6
6
|
name: 'Cabecera sticky con menú configurable 2027',
|
|
7
|
-
description: 'Cabecera fija (sticky top-0)
|
|
7
|
+
description: 'Cabecera fija (sticky top-0) en dos filas en escritorio: logo de Lefebvre (enlaza a lefebvre.es) arriba y, debajo, menú horizontal completamente configurable vía prop "categories" y botón CTA a la derecha. En móvil, una sola fila con el logo, el botón y la hamburguesa. Cada ítem admite target (_self o _blank). Los ítems personalizados no admiten subcategorías desde Mecano; solo el menú por defecto (si no se pasa menú custom) incluye el desplegable de Blog al hacer hover. Incluye hamburguesa en móvil y structured data schema.org (SiteNavigationElement raíz con la jerarquía del menú)',
|
|
8
8
|
framework: 'Astro',
|
|
9
9
|
priority: 1,
|
|
10
10
|
tags: ['header', 'cabecera', 'navegacion', 'sticky', 'menu', 'cta', 'configurable'],
|
|
@@ -54,6 +54,7 @@ export const metadata: ComponentMetadata = {
|
|
|
54
54
|
{ name: 'name', type: 'text', help: 'Texto visible del ítem del menú principal', label: 'Texto del ítem', example_value: 'Cómo funciona' },
|
|
55
55
|
{ name: 'link', type: 'text', help: 'URL de destino del ítem. Debe ser la ruta completa (no se le concatena "subdirectory")', label: 'URL del ítem', example_value: '/genia-l/conoce-genia-l/' },
|
|
56
56
|
{ name: 'target', type: 'select', help: 'Cómo se abre el enlace: "_self" en la misma pestaña, "_blank" en una pestaña nueva', label: 'Apertura del enlace', options: ['_self', '_blank'], options_labels: ['Misma pestaña', 'Nueva pestaña'], example_value: '_self' },
|
|
57
|
+
{ name: 'featured', type: 'boolean', help: 'Muestra este ítem como el nombre del sitio (tipografía serif en negrita), junto al logo. En móvil sale de la hamburguesa. Actívalo solo en un ítem', label: 'Mostrar como marca del sitio', options: ['false', 'true'], options_labels: ['Falso', 'Verdadero'], example_value: false },
|
|
57
58
|
]
|
|
58
59
|
}
|
|
59
60
|
},
|
|
@@ -9,6 +9,7 @@ interface MenuItem {
|
|
|
9
9
|
name: string;
|
|
10
10
|
link: string;
|
|
11
11
|
target?: string;
|
|
12
|
+
featured?: boolean | string;
|
|
12
13
|
subcategories: SubMenuItem[];
|
|
13
14
|
}
|
|
14
15
|
|
|
@@ -88,20 +89,32 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
|
|
|
88
89
|
|
|
89
90
|
const structuredData = `<script type="application/ld+json">${structuredDataJson}</script>`;
|
|
90
91
|
|
|
92
|
+
// El CTA se pinta dos veces (barra superior en móvil, fila del menú en escritorio); solo uno es visible a la vez.
|
|
93
|
+
// Ítem marcado como "featured" (p. ej. GenIA-L): estilo "Lead/Bold". En móvil sale de la hamburguesa y va en la barra superior.
|
|
94
|
+
// El menú por defecto no tiene ninguno; cada página decide cuál destacar.
|
|
95
|
+
const firstItem = categories.find((c: any) => String(c.featured) === 'true');
|
|
96
|
+
const firstItemClass = 'font-heading text-xl not-italic font-semibold leading-7 tracking-[-0.05px] text-[#1b1b1b] whitespace-nowrap';
|
|
97
|
+
const ctaClass = 'h-12 max-[375px] px-3 md:px-5 py-3 font-body font-semibold max-[375px]:text-sm max-[375px]:leading-[21px] text-base leading-6 border-1 border-[#d71635] bg-[#d71635] text-[#ffffff] hover:border-[#71131f] hover:bg-[#71131f] transition-all duration-300 rounded-full cursor-pointer shadow-[0_2px_4px_-2px_rgba(107,58,8,0.08),0_4px_8px_-2px_rgba(107,58,8,0.04)] whitespace-nowrap';
|
|
98
|
+
|
|
91
99
|
|
|
92
100
|
---
|
|
93
101
|
|
|
94
102
|
<header class="sticky top-0 w-full font-body bg-[rgba(250,250,245,0.80)] backdrop-blur-lg z-50 flex flex-col justify-center align-center items-center p-0">
|
|
95
|
-
<
|
|
96
|
-
|
|
97
|
-
<div class="max-w-
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
103
|
+
<div class="px-4 md:px-8 py-3 md:py-1 w-full">
|
|
104
|
+
|
|
105
|
+
<div class="max-w-[1376px] flex items-center justify-between gap-2 mx-auto">
|
|
106
|
+
<div class="flex items-center gap-3 min-w-0">
|
|
107
|
+
<a href="https://lefebvre.es" class="flex items-center shrink-0">
|
|
108
|
+
<img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" class="h-7 w-auto" alt="Lefebvre" width="104" height="28" loading={loading}>
|
|
109
|
+
</a>
|
|
110
|
+
{firstItem && (
|
|
111
|
+
<a href={firstItem.link} target={firstItem.target ?? '_self'} class={`${firstItemClass} min-w-0 truncate md:hidden`}>{firstItem.name}</a>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
<div class="flex items-center gap-2 shrink-0 lg:hidden">
|
|
102
115
|
{label && (
|
|
103
116
|
<div class="flex items-center gap-4">
|
|
104
|
-
<a href={url} class=
|
|
117
|
+
<a href={url} class={ctaClass}>{label}</a>
|
|
105
118
|
</div>
|
|
106
119
|
)}
|
|
107
120
|
<button onclick="document.getElementById('navbar-default').classList.toggle('hidden'); event.target.classList.toggle('bg-[#fafaf5]');"
|
|
@@ -117,17 +130,18 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
|
|
|
117
130
|
</div>
|
|
118
131
|
|
|
119
132
|
</div>
|
|
120
|
-
</
|
|
121
|
-
<nav class="w-full
|
|
122
|
-
<
|
|
133
|
+
</div>
|
|
134
|
+
<nav class="hidden md:block w-full px-8">
|
|
135
|
+
<div class="max-w-[1376px] flex items-center gap-6 mx-auto">
|
|
136
|
+
<ul class="flex items-center justify-start">
|
|
123
137
|
{categories.map((category, index) => {
|
|
124
138
|
const isActive = currentPath.includes(category.link) ||
|
|
125
139
|
(subdirectory !== '' && (subdirectory + currentPath).includes(category.link));
|
|
126
140
|
const hasSub = category.subcategories?.length > 0;
|
|
127
141
|
const submenuId = `${identifier}-d-${index}`;
|
|
128
142
|
return (
|
|
129
|
-
<li class={`relative flex items-center border-b-4 hover:border-b-4 hover:border-[#d71635] hover:bg-[#ebe7da] ${isActive ? 'border-b-4 border-[#d71635] active' : 'border-transparent'}`}>
|
|
130
|
-
<a href={category.link} target={category.target ?? '_self'} class={`flex items-center
|
|
143
|
+
<li class={`relative flex items-center h-[72px] border-b-4 hover:border-b-4 hover:border-[#d71635] hover:bg-[#ebe7da] ${isActive ? 'border-b-4 border-[#d71635] active' : 'border-transparent'}`}>
|
|
144
|
+
<a href={category.link} target={category.target ?? '_self'} class={`flex items-center h-full pl-4 ${hasSub ? '' : 'pr-4'} ${category === firstItem ? firstItemClass : ''}`}>
|
|
131
145
|
<span>
|
|
132
146
|
{category.name}
|
|
133
147
|
</span>
|
|
@@ -135,7 +149,7 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
|
|
|
135
149
|
{hasSub && (
|
|
136
150
|
<button
|
|
137
151
|
type="button"
|
|
138
|
-
class={`${identifier}-toggle flex items-center
|
|
152
|
+
class={`${identifier}-toggle flex items-center h-full pl-2 pr-4 cursor-pointer`}
|
|
139
153
|
aria-label={`Mostrar submenú de ${category.name}`}
|
|
140
154
|
aria-expanded="false"
|
|
141
155
|
aria-controls={submenuId}
|
|
@@ -161,6 +175,12 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
|
|
|
161
175
|
</li>
|
|
162
176
|
)})}
|
|
163
177
|
</ul>
|
|
178
|
+
{label && (
|
|
179
|
+
<div class="ml-auto hidden lg:flex items-center">
|
|
180
|
+
<a href={url} class={ctaClass}>{label}</a>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
</div>
|
|
164
184
|
</nav>
|
|
165
185
|
|
|
166
186
|
<nav class="hidden w-full bg-white border-[#e1c8b4]" id="navbar-default">
|
|
@@ -173,6 +193,7 @@ const categories: MenuItem[] = (categoriesProp && categoriesProp.length > 0)
|
|
|
173
193
|
(subdirectory !== '' && (subdirectory + currentPath).includes(category.link));
|
|
174
194
|
const hasSub = category.subcategories?.length > 0;
|
|
175
195
|
const submenuId = `${identifier}-m-${index}`;
|
|
196
|
+
if (category === firstItem) return null;
|
|
176
197
|
return (
|
|
177
198
|
<li class={`relative flex items-center px-6 py-4 border-b-2 hover:border-b-2 hover:border-[#d71635] ${isActive ? 'border-b-4 border-[#d71635] active' : 'border-transparent'}`}>
|
|
178
199
|
<a href={category.link} target={category.target ?? '_self'} class="flex items-center">
|
|
@@ -83,6 +83,8 @@ const structuredData = `<script type="application/ld+json">
|
|
|
83
83
|
${index === 0 ? 'active' : ''}
|
|
84
84
|
bg-[#ebe7da] text-gray-100 max-w-10 max-h-5 text-[0px] md:w-[150px]
|
|
85
85
|
md:bg-transparent md:text-[#403830] md:max-w-none md:max-h-none md:text-[16px]
|
|
86
|
+
[&.active]:!bg-[#1b1b1b] [&.active]:!text-white [&.active]:max-w-none [&.active]:max-h-none [&.active]:text-[16px]
|
|
87
|
+
md:[&.active]:shadow-[0_2px_4px_0_rgba(107,58,8,0.08),0_4px_8px_0_rgba(107,58,8,0.04)]
|
|
86
88
|
`}
|
|
87
89
|
>{tab.name || `Pestaña ${index + 1}`}</button>
|
|
88
90
|
</p>
|
|
@@ -123,23 +125,6 @@ const structuredData = `<script type="application/ld+json">
|
|
|
123
125
|
|
|
124
126
|
|
|
125
127
|
<style>
|
|
126
|
-
.active{
|
|
127
|
-
background-color: #1b1b1b !important;
|
|
128
|
-
color: #ffffff !important;
|
|
129
|
-
max-width: none;
|
|
130
|
-
max-height: none;
|
|
131
|
-
font-size: 16px;
|
|
132
|
-
|
|
133
|
-
&:hover{
|
|
134
|
-
background-color: #1b1b1b;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
@media (min-width: 768px) {
|
|
138
|
-
.active {
|
|
139
|
-
box-shadow: 0 2px 4px 0 rgba(107, 58, 8, 0.08), 0 4px 8px 0 rgba(107, 58, 8, 0.04);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
128
|
.listIco :global(ul) {
|
|
144
129
|
list-style: none;
|
|
145
130
|
padding-left: 0;
|