libreria-astro-lefebvre 0.1.93 → 0.1.95
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
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ComponentMetadata } from '../interfaces/types';
|
|
2
|
+
|
|
3
|
+
export const metadata: ComponentMetadata = {
|
|
4
|
+
component_name: 'Grid_2026_Aldaia',
|
|
5
|
+
category: 'Contenido con listas',
|
|
6
|
+
name: 'Grid de cards con imagen, etiqueta, título y enlace "Más información" (4 columnas) 2026',
|
|
7
|
+
description: 'Bloque con título opcional (h2 centrado) y un grid de cards: 4 columnas en escritorio, 2 en tablet y 1 en móvil, que crece en filas según el número de ítems. Cada card muestra la imagen recortada a 154px de alto, una etiqueta en mayúsculas (fecha o keywords), el título y un enlace "Más información" con flecha; toda la card es clicable. Emite un ItemList en JSON-LD con los ítems',
|
|
8
|
+
framework: 'Astro',
|
|
9
|
+
priority: 1,
|
|
10
|
+
tags: ['grid', 'card', 'imagen', 'boletines', 'listado', 'enlace'],
|
|
11
|
+
fields: [
|
|
12
|
+
{
|
|
13
|
+
name: 'title',
|
|
14
|
+
type: 'text',
|
|
15
|
+
mandatory: false,
|
|
16
|
+
label: 'Título del bloque',
|
|
17
|
+
help: 'Título (h2) centrado que aparece encima del grid. Si se deja vacío, no se muestra ningún título',
|
|
18
|
+
example_value: 'Descubre nuestros boletines'
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'etiquetaVisible',
|
|
22
|
+
type: 'select',
|
|
23
|
+
options: ['keywords', 'fecha'],
|
|
24
|
+
options_labels: ['Keywords', 'Fecha'],
|
|
25
|
+
mandatory: false,
|
|
26
|
+
label: 'Etiqueta visible en la card',
|
|
27
|
+
help: 'Qué se muestra como etiqueta en mayúsculas sobre el título de cada card: las keywords (p. ej. la materia) o la fecha. Default: keywords',
|
|
28
|
+
example_value: 'keywords'
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'linkText',
|
|
32
|
+
type: 'text',
|
|
33
|
+
mandatory: false,
|
|
34
|
+
label: 'Texto del enlace',
|
|
35
|
+
help: 'Texto del enlace con flecha que aparece al pie de cada card. Default: "Más información"',
|
|
36
|
+
example_value: 'Más información'
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'items',
|
|
40
|
+
type: 'list',
|
|
41
|
+
label: 'Listado de cards',
|
|
42
|
+
mandatory: false,
|
|
43
|
+
help: 'Cards del bloque. Se muestran en un grid de 4 columnas en escritorio (a partir de la quinta card se crea una nueva fila), 2 en tablet y 1 en móvil',
|
|
44
|
+
items: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
fields: [
|
|
47
|
+
{ name: 'title', type: 'text', label: 'Título', help: 'Título de la card (h3). Se muestra siempre', example_value: 'Apuntes & Consejos Impuestos' },
|
|
48
|
+
{ name: 'keywords', type: 'text', label: 'Keywords', help: 'Palabras clave (p. ej. la materia). Se muestran como etiqueta en mayúsculas sobre el título si "Etiqueta visible" es Keywords, y se incluyen siempre en los datos estructurados (JSON-LD keywords)', example_value: 'Fiscal' },
|
|
49
|
+
{ name: 'fecha', type: 'text', label: 'Fecha (etiqueta)', help: 'Fecha que aparece como etiqueta sobre el título cuando "Etiqueta visible" es Fecha. Si se deja vacía, NO se muestra', example_value: '10 de enero de 2026' },
|
|
50
|
+
{ name: 'link', type: 'text', label: 'Url del enlace', help: 'URL de destino al hacer click en la card o en "Más información" (toda la card es clicable). Si se deja vacío, apunta a "#" (no navega)', example_value: '/fiscal-impuestos' },
|
|
51
|
+
{ name: 'image', type: 'image', label: 'Imagen', help: 'Imagen de la card. Se recorta a 154px de alto mostrando la parte superior (object-fit cover, object-position top). Se renderiza siempre; si se deja vacía aparece una imagen rota', example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-16-9.png' },
|
|
52
|
+
{ name: 'altImage', type: 'text', label: 'Alt de la imagen', help: 'Texto alternativo de la imagen para accesibilidad', example_value: 'Portada del boletín Apuntes & Consejos Impuestos' }
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { extractImageUrl, PAGE_ENTITY_ID } from '../../lib/functions.js';
|
|
3
|
+
|
|
4
|
+
interface AldaiaItem {
|
|
5
|
+
title?: string;
|
|
6
|
+
fecha?: string; // etiqueta de fecha para mostrar
|
|
7
|
+
keywords?: string; // keywords (p. ej. la materia), para etiqueta visual y JSON-LD
|
|
8
|
+
image?: string;
|
|
9
|
+
altImage?: string;
|
|
10
|
+
link?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
title = '',
|
|
15
|
+
etiquetaVisible = "keywords",
|
|
16
|
+
linkText = 'Más información',
|
|
17
|
+
items = [],
|
|
18
|
+
}: { title?: string; etiquetaVisible?: "fecha" | "keywords"; linkText?: string; items?: AldaiaItem[] } = Astro.props;
|
|
19
|
+
|
|
20
|
+
// isPartOf hacia el nodo de página (#webpage por defecto). Opt-out con pageId="".
|
|
21
|
+
// itemListId opcional: si se pasa, el ItemList lleva ese @id (para ser mainEntity de la CollectionPage).
|
|
22
|
+
const { pageId = PAGE_ENTITY_ID, itemListId = '' } = Astro.props;
|
|
23
|
+
|
|
24
|
+
const escapeJson = (s = "") => String(s).replace(/<[^>]*>/g, '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/</g, '\\u003c').replace(/>/g, '\\u003e').replace(/[\n\r\t]+/g, ' ');
|
|
25
|
+
|
|
26
|
+
const structuredData = `<script type="application/ld+json">
|
|
27
|
+
{
|
|
28
|
+
"@context": "https://schema.org",
|
|
29
|
+
"@type": "ItemList",${itemListId ? `
|
|
30
|
+
"@id": "${itemListId}",` : ''}${pageId ? `
|
|
31
|
+
"isPartOf": { "@id": "${pageId}" },` : ''}${title ? `
|
|
32
|
+
"name": "${escapeJson(title)}",` : ''}
|
|
33
|
+
"numberOfItems": ${items.length},
|
|
34
|
+
"itemListElement": [${items.map((item: AldaiaItem, i: number) => `{
|
|
35
|
+
"@type": "ListItem",
|
|
36
|
+
"position": ${i + 1},
|
|
37
|
+
"name": "${escapeJson(item.title)}"${item.image ? `,
|
|
38
|
+
"image": "${escapeJson(extractImageUrl(item.image))}"` : ""}${item.link ? `,
|
|
39
|
+
"url": "${escapeJson(item.link)}"` : ""}${item.keywords ? `,
|
|
40
|
+
"keywords": "${escapeJson(item.keywords)}"` : ""}
|
|
41
|
+
}`).join(',')}]
|
|
42
|
+
}
|
|
43
|
+
</script>`;
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
<section class="w-full max-w-7xl mx-auto flex flex-col mb-4">
|
|
47
|
+
{title && title.trim() !== '' && (
|
|
48
|
+
<h2 class="font-poppins text-[#262626] text-[36px] md:text-[40px] font-normal text-center leading-[48px] my-8 md:mb-8 px-8" set:html={title}></h2>
|
|
49
|
+
)}
|
|
50
|
+
<ul class="list-none m-0 w-full grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8 px-8 lg:px-0 mt-4 md:mt-0">
|
|
51
|
+
{items.map((item: AldaiaItem) => {
|
|
52
|
+
const tag = etiquetaVisible === "fecha" ? item.fecha : item.keywords;
|
|
53
|
+
return (
|
|
54
|
+
<li class="w-full flex flex-col">
|
|
55
|
+
<article class="relative w-full h-full flex flex-col rounded-lg border border-gray-200 shadow-article hover:bg-gradient-to-r from-[#001978] via-[#2134F1] to-[#F81BBD] transition-all duration-300 p-px">
|
|
56
|
+
<div class="w-full h-full flex flex-col bg-white mt-px rounded-tl-[7px] rounded-tr-[7px] rounded-b-lg overflow-hidden">
|
|
57
|
+
<img class="w-full h-[154px] object-cover object-top" src={extractImageUrl(item.image)} alt={item.altImage ?? ''} width="400" height="154" loading="lazy" />
|
|
58
|
+
<div class="p-6 flex flex-col flex-grow">
|
|
59
|
+
{tag && <p class="font-inter text-[#001978] text-sm font-semibold text-left tracking-[2px] uppercase mb-1">{tag}</p>}
|
|
60
|
+
<h3 class="font-poppins text-xl font-semibold text-[#262626] mb-6">{item.title}</h3>
|
|
61
|
+
<a href={item.link || '#'} class="mt-auto inline-flex items-center gap-3 font-inter text-base font-semibold text-[#363942] no-underline after:absolute after:inset-0 after:content-['']">
|
|
62
|
+
{linkText}
|
|
63
|
+
<svg class="chevron shrink-0" xmlns="http://www.w3.org/2000/svg" width="8" height="15" viewBox="0 0 8 15" fill="none" aria-hidden="true">
|
|
64
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.204584 14.8375C-0.0508271 14.6053 -0.06965 14.21 0.162542 13.9546L6.03034 7.5L0.162542 1.04542C-0.0696498 0.790005 -0.0508269 0.394725 0.204584 0.162533C0.459995 -0.0696602 0.855275 -0.0508366 1.08747 0.204574L7.33747 7.07958C7.55418 7.31796 7.55418 7.68203 7.33747 7.92042L1.08747 14.7954C0.855275 15.0508 0.459995 15.0696 0.204584 14.8375Z" fill="#363942"/>
|
|
65
|
+
</svg>
|
|
66
|
+
</a>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
</article>
|
|
70
|
+
</li>
|
|
71
|
+
);
|
|
72
|
+
})}
|
|
73
|
+
</ul>
|
|
74
|
+
</section>
|
|
75
|
+
|
|
76
|
+
<Fragment set:html={structuredData} />
|
|
77
|
+
|
|
78
|
+
<style>
|
|
79
|
+
.shadow-article {
|
|
80
|
+
box-shadow: 0 2px 4px -2px rgba(0, 0, 0, 0.08), 0 4px 8px -2px rgba(0, 0, 0, 0.04);
|
|
81
|
+
}
|
|
82
|
+
.chevron {
|
|
83
|
+
width: 15px;
|
|
84
|
+
height: 7.5px;
|
|
85
|
+
transform: rotate(-90deg);
|
|
86
|
+
}
|
|
87
|
+
</style>
|
|
@@ -48,6 +48,7 @@ import * as Formulario_2026_Carabanchel from '../carbins/Formulario_2026_Caraban
|
|
|
48
48
|
import * as Formulario_2026_Wichita from '../carbins/Formulario_2026_Wichita.ts';
|
|
49
49
|
import * as Galeria_2026_Segorbe from '../carbins/Galeria_2026_Segorbe.ts';
|
|
50
50
|
import * as GeometricShapeCard from '../carbins/GeometricShapeCard.ts';
|
|
51
|
+
import * as Grid_2026_Aldaia from '../carbins/Grid_2026_Aldaia.ts';
|
|
51
52
|
import * as HeaderCorporativo from '../carbins/HeaderCorporativo.ts';
|
|
52
53
|
import * as Hero_2025_Benidorm from '../carbins/Hero_2025_Benidorm.ts';
|
|
53
54
|
import * as Hero_2026_Benidorm from '../carbins/Hero_2026_Benidorm.ts';
|
|
@@ -143,6 +144,7 @@ export const components = [
|
|
|
143
144
|
{component: Formulario_2026_Wichita},
|
|
144
145
|
{component: Galeria_2026_Segorbe},
|
|
145
146
|
{component: GeometricShapeCard},
|
|
147
|
+
{component: Grid_2026_Aldaia},
|
|
146
148
|
{component: HeaderCorporativo},
|
|
147
149
|
{component: Hero_2025_Benidorm},
|
|
148
150
|
{component: Hero_2026_Benidorm},
|
package/src/index.ts
CHANGED
|
@@ -55,6 +55,7 @@ import Formulario_2026_Wichita from './components/Astro/Formulario_2026_Wichita.
|
|
|
55
55
|
import Galeria_2026_Segorbe from './components/Astro/Galeria_2026_Segorbe.astro';
|
|
56
56
|
import GeometricShape from './components/Astro/GeometricShape.astro';
|
|
57
57
|
import GeometricShapeCard from './components/Astro/GeometricShapeCard.astro';
|
|
58
|
+
import Grid_2026_Aldaia from './components/Astro/Grid_2026_Aldaia.astro';
|
|
58
59
|
import HeaderCorporativo from './components/Astro/HeaderCorporativo.astro';
|
|
59
60
|
import Hero_2025_Benidorm from './components/Astro/Hero_2025_Benidorm.astro';
|
|
60
61
|
import Hero_2026_Benidorm from './components/Astro/Hero_2026_Benidorm.astro';
|
|
@@ -103,7 +104,7 @@ import ReactButton from './components/React/ReactButton.jsx';
|
|
|
103
104
|
// Exporta todos los componentes uno a uno para que puedan ser usados directamente.
|
|
104
105
|
|
|
105
106
|
|
|
106
|
-
export { VueButton, Author_2025_Algarve, Button, CTA_2025_Formentera, Cabecera_2025_Barcelona, Cabecera_2025_Madrid, Cabecera_2026_Bilbao, Cabecera_2026_Dakota, Cabecera_2026_Madrid, Calculadora_2026_Lisboa, Card_2025_Malta, Contenido_2025_Alcorcon, Contenido_2025_Cordoba, Contenido_2025_Granada, Contenido_2025_Malaga, Contenido_2025_Montevideo, Contenido_2026_Cabra, Contenido_2026_Denia, Contenido_2026_Dubai, Contenido_2026_Estepona, Contenido_2026_Estocolmo, Contenido_2026_Huesca, Contenido_2026_Jaen, Contenido_2026_Leon, Contenido_2026_Mallorca, Contenido_2026_Marruecos, Contenido_2026_Menorca, Contenido_2026_Michigan, Contenido_2026_Moraira, Contenido_2026_Mostoles, Contenido_2026_Orcasitas, Contenido_2026_Oslo, Contenido_2026_Quito, Contenido_2026_Seattle, Contenido_2026_Sevilla, Contenido_2026_Tokyo, Contenido_2026_Ubeda, Contenido_2026_Yakarta, CorpFooter, CorpHero, CorpNavigation, Enlace_2025_Venecia, FAQ_2025_Hiroshima, Footer_2025_Napoles, Formulario_2025_Nara, Formulario_2025_Seul, Formulario_2025_Teruel, Formulario_2026_Carabanchel, Formulario_2026_Wichita, Galeria_2026_Segorbe, GeometricShape, GeometricShapeCard, HeaderCorporativo, Hero_2025_Benidorm, Hero_2026_Benidorm, Hero_2026_Lliria, ImageTextSimple, Imagen_2025_Bogota, Imagen_2025_Fukushima, Imagen_2026_Algar, Indice_2025_Taiwan, Mapa_2026_Girona, Modal_2025_Sagunto, Modal_2026_Almeria, Paginacion_2025_Paris, RRSS_2025_Pisa, SEO_Head_Section, SEO_Schema_Page, Separador_2025_Reinosa, Separador_2025_Toledo, Separador_2026_Teulada, Share_2025_Florencia, SpectrumSeparator, Sumario_2025_Beijing, Tabla_2025_Fuenlabrada, Tabla_2026_Cadiz, Tag_2025_Bolonia, TestHijo, TestPadre, Test_2026_Gaza, TextBox, TextImageBackground, TextImageBlock, TextImageCard, TextImageHeader, Texto_2025_Kyoto, Texto_2026_Alicante, Texto_2026_Castellon, Tiempo_2025_Londres, Titulo_2025_Algeciras, Titulo_2025_Santorini, VideoAutoplay, Video_2025_Polop, Video_2025_Valencia, Video_2026_Andujar, ReactButton };
|
|
107
|
+
export { VueButton, Author_2025_Algarve, Button, CTA_2025_Formentera, Cabecera_2025_Barcelona, Cabecera_2025_Madrid, Cabecera_2026_Bilbao, Cabecera_2026_Dakota, Cabecera_2026_Madrid, Calculadora_2026_Lisboa, Card_2025_Malta, Contenido_2025_Alcorcon, Contenido_2025_Cordoba, Contenido_2025_Granada, Contenido_2025_Malaga, Contenido_2025_Montevideo, Contenido_2026_Cabra, Contenido_2026_Denia, Contenido_2026_Dubai, Contenido_2026_Estepona, Contenido_2026_Estocolmo, Contenido_2026_Huesca, Contenido_2026_Jaen, Contenido_2026_Leon, Contenido_2026_Mallorca, Contenido_2026_Marruecos, Contenido_2026_Menorca, Contenido_2026_Michigan, Contenido_2026_Moraira, Contenido_2026_Mostoles, Contenido_2026_Orcasitas, Contenido_2026_Oslo, Contenido_2026_Quito, Contenido_2026_Seattle, Contenido_2026_Sevilla, Contenido_2026_Tokyo, Contenido_2026_Ubeda, Contenido_2026_Yakarta, CorpFooter, CorpHero, CorpNavigation, Enlace_2025_Venecia, FAQ_2025_Hiroshima, Footer_2025_Napoles, Formulario_2025_Nara, Formulario_2025_Seul, Formulario_2025_Teruel, Formulario_2026_Carabanchel, Formulario_2026_Wichita, Galeria_2026_Segorbe, GeometricShape, GeometricShapeCard, Grid_2026_Aldaia, HeaderCorporativo, Hero_2025_Benidorm, Hero_2026_Benidorm, Hero_2026_Lliria, ImageTextSimple, Imagen_2025_Bogota, Imagen_2025_Fukushima, Imagen_2026_Algar, Indice_2025_Taiwan, Mapa_2026_Girona, Modal_2025_Sagunto, Modal_2026_Almeria, Paginacion_2025_Paris, RRSS_2025_Pisa, SEO_Head_Section, SEO_Schema_Page, Separador_2025_Reinosa, Separador_2025_Toledo, Separador_2026_Teulada, Share_2025_Florencia, SpectrumSeparator, Sumario_2025_Beijing, Tabla_2025_Fuenlabrada, Tabla_2026_Cadiz, Tag_2025_Bolonia, TestHijo, TestPadre, Test_2026_Gaza, TextBox, TextImageBackground, TextImageBlock, TextImageCard, TextImageHeader, Texto_2025_Kyoto, Texto_2026_Alicante, Texto_2026_Castellon, Tiempo_2025_Londres, Titulo_2025_Algeciras, Titulo_2025_Santorini, VideoAutoplay, Video_2025_Polop, Video_2025_Valencia, Video_2026_Andujar, ReactButton };
|
|
107
108
|
|
|
108
109
|
|
|
109
110
|
// Exporta la función listComponents para que sea usado en el Pagebuilder en Vue.
|
|
@@ -170,6 +171,7 @@ export const components = {
|
|
|
170
171
|
Galeria_2026_Segorbe: Galeria_2026_Segorbe,
|
|
171
172
|
GeometricShape: GeometricShape,
|
|
172
173
|
GeometricShapeCard: GeometricShapeCard,
|
|
174
|
+
Grid_2026_Aldaia: Grid_2026_Aldaia,
|
|
173
175
|
HeaderCorporativo: HeaderCorporativo,
|
|
174
176
|
Hero_2025_Benidorm: Hero_2025_Benidorm,
|
|
175
177
|
Hero_2026_Benidorm: Hero_2026_Benidorm,
|