libreria-astro-lefebvre 0.1.94 → 0.1.96

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libreria-astro-lefebvre",
3
- "version": "0.1.94",
3
+ "version": "0.1.96",
4
4
  "description": "Librería de componentes Astro, React y Vue para Lefebvre",
5
5
  "author": "Equipo web desarrollo Lefebvre",
6
6
  "type": "module",
@@ -3,11 +3,11 @@ import type { ComponentMetadata } from '../interfaces/types';
3
3
  export const metadata: ComponentMetadata = {
4
4
  component_name: 'Grid_2026_Aldaia',
5
5
  category: 'Contenido con listas',
6
- name: 'Grid de cards con título: 3 columnas en escritorio y carrusel horizontal en móvil 2026',
7
- description: 'Bloque con título opcional (h2 centrado) y un listado de cards Contenido_2025_Montevideo (imagen, etiqueta, título y descripción, toda la card clicable). En escritorio se muestra como grid de máximo 3 columnas (2 en tablet) que crece en filas según el número de ítems. En móvil las cards se disponen en una fila con scroll horizontal y snap. Emite un ItemList en JSON-LD con los ítems',
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 y 2 en tablet, que crece en filas según el número de ítems; en móvil las cards se disponen en una fila con scroll horizontal y snap. 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
8
  framework: 'Astro',
9
9
  priority: 1,
10
- tags: ['grid', 'card', 'carrusel', 'scroll', 'imagen', 'boletines', 'listado'],
10
+ tags: ['grid', 'card', 'carrusel', 'scroll', 'imagen', 'boletines', 'listado', 'enlace'],
11
11
  fields: [
12
12
  {
13
13
  name: 'title',
@@ -17,20 +17,38 @@ export const metadata: ComponentMetadata = {
17
17
  help: 'Título (h2) centrado que aparece encima del grid. Si se deja vacío, no se muestra ningún título',
18
18
  example_value: 'Descubre nuestros boletines'
19
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
+ },
20
38
  {
21
39
  name: 'items',
22
40
  type: 'list',
23
41
  label: 'Listado de cards',
24
42
  mandatory: false,
25
- help: 'Cards del bloque. En escritorio se muestran en un grid de 3 columnas (a partir de la cuarta card se crea una nueva fila); en móvil se muestran en una fila con scroll horizontal. Cada card se renderiza con el componente Contenido_2025_Montevideo',
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 en móvil en una fila con scroll horizontal',
26
44
  items: {
27
45
  type: 'object',
28
46
  fields: [
29
47
  { name: 'title', type: 'text', label: 'Título', help: 'Título de la card (h3). Se muestra siempre', example_value: 'Apuntes & Consejos Impuestos' },
30
- { name: 'tag', type: 'text', label: 'Etiqueta', help: 'Etiqueta en mayúsculas que aparece sobre el título (p. ej. la materia). Si se deja vacía, NO se muestra', example_value: 'Fiscal' },
31
- { name: 'description', type: 'textArea', label: 'Descripción', help: 'Descripción breve de la card, debajo del título. Si se deja vacía, no ocupa espacio visible', example_value: 'Novedades fiscales explicadas de forma clara y práctica' },
32
- { name: 'link', type: 'text', label: 'Url del enlace', help: 'URL de destino al hacer click en la card (toda la card es clicable). Si se deja vacío, apunta a "#" (no navega)', example_value: '/fiscal-impuestos' },
33
- { name: 'image', type: 'image', label: 'Imagen', help: 'Imagen de la card (parte superior, proporción 16:9). 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' },
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' },
34
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' }
35
53
  ]
36
54
  }
@@ -1,20 +1,21 @@
1
1
  ---
2
- import Contenido_2025_Montevideo from "./Contenido_2025_Montevideo.astro";
3
2
  import { extractImageUrl, PAGE_ENTITY_ID } from '../../lib/functions.js';
4
3
 
5
4
  interface AldaiaItem {
6
5
  title?: string;
7
- tag?: string;
6
+ fecha?: string; // etiqueta de fecha para mostrar
7
+ keywords?: string; // keywords (p. ej. la materia), para etiqueta visual y JSON-LD
8
8
  image?: string;
9
9
  altImage?: string;
10
10
  link?: string;
11
- description?: string;
12
11
  }
13
12
 
14
13
  const {
15
14
  title = '',
15
+ etiquetaVisible = "keywords",
16
+ linkText = 'Más información',
16
17
  items = [],
17
- }: { title?: string; items?: AldaiaItem[] } = Astro.props;
18
+ }: { title?: string; etiquetaVisible?: "fecha" | "keywords"; linkText?: string; items?: AldaiaItem[] } = Astro.props;
18
19
 
19
20
  // isPartOf hacia el nodo de página (#webpage por defecto). Opt-out con pageId="".
20
21
  // itemListId opcional: si se pasa, el ItemList lleva ese @id (para ser mainEntity de la CollectionPage).
@@ -33,10 +34,10 @@ const structuredData = `<script type="application/ld+json">
33
34
  "itemListElement": [${items.map((item: AldaiaItem, i: number) => `{
34
35
  "@type": "ListItem",
35
36
  "position": ${i + 1},
36
- "name": "${escapeJson(item.title)}"${item.description ? `,
37
- "description": "${escapeJson(item.description)}"` : ""}${item.image ? `,
37
+ "name": "${escapeJson(item.title)}"${item.image ? `,
38
38
  "image": "${escapeJson(extractImageUrl(item.image))}"` : ""}${item.link ? `,
39
- "url": "${escapeJson(item.link)}"` : ""}
39
+ "url": "${escapeJson(item.link)}"` : ""}${item.keywords ? `,
40
+ "keywords": "${escapeJson(item.keywords)}"` : ""}
40
41
  }`).join(',')}]
41
42
  }
42
43
  </script>`;
@@ -46,25 +47,44 @@ const structuredData = `<script type="application/ld+json">
46
47
  {title && title.trim() !== '' && (
47
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>
48
49
  )}
49
- <ul class="aldaia-list list-none m-0 flex gap-4 overflow-x-auto snap-x snap-mandatory px-8 scroll-px-8 pb-4 md:grid md:grid-cols-2 lg:grid-cols-3 md:gap-8 md:overflow-visible md:pb-0 lg:px-0">
50
- {items.map((item: AldaiaItem) => (
51
- <li class="shrink-0 w-72 snap-start flex md:w-auto">
52
- <Contenido_2025_Montevideo
53
- link={item.link}
54
- image={item.image}
55
- altImage={item.altImage}
56
- title={item.title}
57
- tag={item.tag}
58
- description={item.description} />
50
+ <ul class="aldaia-list list-none m-0 w-full flex gap-4 overflow-x-auto snap-x snap-mandatory px-8 scroll-px-8 pb-4 mt-4 md:grid md:grid-cols-2 lg:grid-cols-4 md:gap-8 md:overflow-visible md:pb-0 md:mt-0 lg:px-0">
51
+ {items.map((item: AldaiaItem) => {
52
+ const tag = etiquetaVisible === "fecha" ? item.fecha : item.keywords;
53
+ return (
54
+ <li class="shrink-0 w-72 snap-start flex flex-col md:w-auto">
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>
59
70
  </li>
60
- ))}
71
+ );
72
+ })}
61
73
  </ul>
62
74
  </section>
63
75
 
64
76
  <Fragment set:html={structuredData} />
65
77
 
66
78
  <style>
67
- /* Ocultar la barra de scroll del carrusel en móvil (se navega con gesto/snap). */
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
+ /* El SVG ya apunta a la derecha (8x15); el rotate(-90deg) del diseño lo dejaba apuntando hacia arriba. */
83
+ .chevron {
84
+ width: 7.5px;
85
+ height: 15px;
86
+ }
87
+ /* Carrusel en móvil: se navega con gesto/snap, sin barra de scroll visible. */
68
88
  .aldaia-list {
69
89
  scrollbar-width: none;
70
90
  }