libreria-astro-lefebvre 0.0.49 → 0.0.51

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.
Files changed (45) hide show
  1. package/README.md +68 -0
  2. package/package.json +12 -4
  3. package/src/carbins/AstroButton.ts +2 -14
  4. package/src/carbins/Contenido_2025_Alcorcon.ts +1 -1
  5. package/src/carbins/Contenido_2025_Malaga.ts +1 -1
  6. package/src/carbins/Contenido_2025_Montevideo.ts +1 -1
  7. package/src/carbins/Formulario_2025_Seul.ts +1 -1
  8. package/src/carbins/Formulario_2025_Teruel.ts +2 -2
  9. package/src/carbins/GeometricShapeCard.ts +1 -1
  10. package/src/carbins/ImageTextSimple.ts +1 -1
  11. package/src/carbins/Imagen_2025_Bogota.ts +1 -1
  12. package/src/carbins/Imagen_2025_Fukushima.ts +1 -1
  13. package/src/carbins/TextImageBackground.ts +1 -1
  14. package/src/carbins/TextImageBlock.ts +1 -1
  15. package/src/carbins/TextImageCard.ts +1 -1
  16. package/src/carbins/TextImageHeader.ts +1 -1
  17. package/src/components/Astro/Cabecera_2025_Madrid.astro +1 -1
  18. package/src/components/Astro/Contenido_2025_Alcorcon.astro +5 -3
  19. package/src/components/Astro/Contenido_2025_Malaga.astro +4 -2
  20. package/src/components/Astro/Contenido_2025_Montevideo.astro +3 -3
  21. package/src/components/Astro/CorpFooter.astro +1 -1
  22. package/src/components/Astro/CorpNavigation.astro +2 -2
  23. package/src/components/Astro/Footer_2025_Napoles.astro +1 -1
  24. package/src/components/Astro/Formulario_2025_Seul.astro +3 -1
  25. package/src/components/Astro/Formulario_2025_Teruel.astro +5 -2
  26. package/src/components/Astro/GeometricShape.astro +4 -1
  27. package/src/components/Astro/GeometricShapeCard.astro +4 -1
  28. package/src/components/Astro/HeaderCorporativo.astro +2 -2
  29. package/src/components/Astro/ImageTextSimple.astro +5 -1
  30. package/src/components/Astro/Imagen_2025_Bogota.astro +30 -16
  31. package/src/components/Astro/Imagen_2025_Fukushima.astro +5 -2
  32. package/src/components/Astro/Repetidor_2025_Cabra.astro +1 -1
  33. package/src/components/Astro/Repetidor_2025_Orcasitas.astro +2 -2
  34. package/src/components/Astro/Repetidor_2025_Oslo.astro +1 -1
  35. package/src/components/Astro/Repetidor_2025_Yakarta.astro +1 -1
  36. package/src/components/Astro/TextImageBackground.astro +6 -1
  37. package/src/components/Astro/TextImageBlock.astro +5 -1
  38. package/src/components/Astro/TextImageCard.astro +5 -1
  39. package/src/components/Astro/TextImageHeader.astro +5 -1
  40. package/src/components/Astro/Video_2025_Polop.astro +1 -1
  41. package/src/components/LimboImage.astro +89 -0
  42. package/src/index.ts +2 -0
  43. package/src/lib/functions.js +171 -0
  44. package/src/limbo/LimboProvider.astro +17 -1
  45. package/src/limbo/init.ts +138 -17
package/README.md CHANGED
@@ -8,6 +8,74 @@ Instrucciones:
8
8
  npm i libreria-astro-lefebvre
9
9
  ```
10
10
 
11
+ ## 🖼️ Imágenes de Limbo
12
+
13
+ La librería incluye utilidades para trabajar con imágenes de Limbo de forma sencilla.
14
+
15
+ ### Opción 1: Componente LimboImage (Recomendado para maquetadores)
16
+
17
+ El componente `<LimboImage>` extrae automáticamente la URL del JSON de Limbo:
18
+
19
+ ```astro
20
+ ---
21
+ import LimboImage from 'libreria-astro-lefebvre/components/LimboImage.astro';
22
+
23
+ const { imagen } = Astro.props; // Puede ser URL directa o JSON de Limbo
24
+ ---
25
+
26
+ <!-- Uso básico -->
27
+ <LimboImage src={imagen} alt="Descripción de la imagen" />
28
+
29
+ <!-- Con estilos -->
30
+ <LimboImage
31
+ src={imagen}
32
+ alt="Hero"
33
+ class="w-full h-auto rounded-lg"
34
+ />
35
+
36
+ <!-- Preferir imagen original en lugar del crop -->
37
+ <LimboImage src={imagen} prefer="original" alt="Original" />
38
+
39
+ <!-- Con fallback si no hay imagen -->
40
+ <LimboImage src={imagen} fallback="/default.jpg" alt="Con fallback" />
41
+ ```
42
+
43
+ ### Opción 2: Función extractImageUrl
44
+
45
+ Para casos donde necesitas más control:
46
+
47
+ ```astro
48
+ ---
49
+ import { extractImageUrl } from 'libreria-astro-lefebvre/lib/functions';
50
+
51
+ const { imagen } = Astro.props;
52
+
53
+ // Extraer URL (preferir crop por defecto)
54
+ const srcUrl = extractImageUrl(imagen);
55
+
56
+ // Preferir imagen original
57
+ const originalUrl = extractImageUrl(imagen, { prefer: 'original' });
58
+ ---
59
+
60
+ <img src={srcUrl} alt="Mi imagen" />
61
+ ```
62
+
63
+ ### Funciones disponibles
64
+
65
+ ```javascript
66
+ import {
67
+ extractImageUrl, // Extrae URL de JSON Limbo
68
+ parseImageData, // Obtiene datos completos (original + crops)
69
+ resolveUrl, // Convierte /files/... a URL absoluta
70
+ isValidImageUrl, // Verifica si URL es válida (no blob)
71
+ LIMBO_BASE_URL // { DEV: '...', PROD: '...' }
72
+ } from 'libreria-astro-lefebvre/lib/functions';
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Instalación y desarrollo
78
+
11
79
 
12
80
  Hacer un link en librería local:
13
81
  ``` npm link ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libreria-astro-lefebvre",
3
- "version": "0.0.49",
3
+ "version": "0.0.51",
4
4
  "description": "Librería de componentes Astro, React y Vue para Lefebvre",
5
5
  "author": "Equipo web desarrollo Lefebvre",
6
6
  "type": "module",
@@ -12,7 +12,9 @@
12
12
  },
13
13
  "./list": "./src/list.ts",
14
14
  "./limbo": "./src/limbo/index.ts",
15
- "./limbo/LimboProvider.astro": "./src/limbo/LimboProvider.astro"
15
+ "./limbo/LimboProvider.astro": "./src/limbo/LimboProvider.astro",
16
+ "./components/LimboImage.astro": "./src/components/LimboImage.astro",
17
+ "./lib/functions": "./src/lib/functions.js"
16
18
  },
17
19
  "files": [
18
20
  "src"
@@ -26,12 +28,18 @@
26
28
  ],
27
29
  "peerDependencies": {
28
30
  "astro": "^5.11.0",
29
- "limbo-component": "latest"
31
+ "limbo-component": "latest",
32
+ "vue": "^3.3.0",
33
+ "react": "^18.0.0 || ^19.0.0",
34
+ "react-dom": "^18.0.0 || ^19.0.0"
30
35
  },
31
36
  "scripts": {
32
37
  "generate:registry": "node scripts/generateRegistry.js"
33
38
  },
34
39
  "devDependencies": {
35
- "typescript": "^5.8.3"
40
+ "typescript": "^5.8.3",
41
+ "vue": "^3.5.0",
42
+ "react": "^19.0.0",
43
+ "react-dom": "^19.0.0"
36
44
  }
37
45
  }
@@ -27,20 +27,8 @@ export const metadata: ComponentMetadata = {
27
27
  name: 'imagen',
28
28
  type: 'image',
29
29
  label: 'Imagen de prueba',
30
- mandatory: true,
31
- example_value: '',
32
- image_cuts: [
33
- {
34
- label: "mobile",
35
- width: "300",
36
- height: "100"
37
- },
38
- {
39
- label: "desktop",
40
- width: "400",
41
- height: "400"
42
- },
43
- ]
30
+ mandatory: false,
31
+ example_value: ''
44
32
  },
45
33
  {
46
34
  name: 'target',
@@ -53,7 +53,7 @@ export const metadata: ComponentMetadata = {
53
53
  },
54
54
  {
55
55
  name: 'src',
56
- type: 'text',
56
+ type: 'image',
57
57
  label: 'Src de la imagen',
58
58
  mandatory: false,
59
59
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-w-3-4.png'
@@ -39,7 +39,7 @@ export const metadata: ComponentMetadata = {
39
39
  },
40
40
  {
41
41
  name: 'image',
42
- type: 'text',
42
+ type: 'image',
43
43
  label: 'Src de la imagen',
44
44
  mandatory: false,
45
45
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-w-4-3.png'
@@ -39,7 +39,7 @@ export const metadata: ComponentMetadata = {
39
39
  },
40
40
  {
41
41
  name: 'image',
42
- type: 'text',
42
+ type: 'image',
43
43
  label: 'Src de la imagen',
44
44
  mandatory: false,
45
45
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-16-9.png'
@@ -25,7 +25,7 @@ export const metadata: ComponentMetadata = {
25
25
  },
26
26
  {
27
27
  name: 'imageSrc',
28
- type: 'text',
28
+ type: 'image',
29
29
  label: 'Src de la imagen',
30
30
  mandatory: false,
31
31
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-3-4.png'
@@ -97,7 +97,7 @@ export const metadata: ComponentMetadata = {
97
97
  },
98
98
  {
99
99
  name: 'imageModal',
100
- type: 'text',
100
+ type: 'image',
101
101
  label: 'Src de la imagen modal',
102
102
  mandatory: false,
103
103
  example_value: ''
@@ -118,7 +118,7 @@ export const metadata: ComponentMetadata = {
118
118
  },
119
119
  {
120
120
  name: 'imageSrc',
121
- type: 'text',
121
+ type: 'image',
122
122
  label: 'Src de la imagen',
123
123
  mandatory: false,
124
124
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-16-9.png'
@@ -33,7 +33,7 @@ export const metadata: ComponentMetadata = {
33
33
  },
34
34
  {
35
35
  name: 'imageSrc',
36
- type: 'text',
36
+ type: 'image',
37
37
  label: 'URL de la imagen',
38
38
  mandatory: true,
39
39
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-16-9.png'
@@ -28,7 +28,7 @@ export const metadata: ComponentMetadata = {
28
28
  },
29
29
  {
30
30
  name: 'image',
31
- type: 'text',
31
+ type: 'image',
32
32
  label: 'URL de la imagen',
33
33
  mandatory: true,
34
34
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-1-1.png'
@@ -46,7 +46,7 @@ export const metadata: ComponentMetadata = {
46
46
  },
47
47
  {
48
48
  name: 'src',
49
- type: 'text',
49
+ type: 'image',
50
50
  label: 'Src de la imagen',
51
51
  mandatory: false,
52
52
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-16-9.png'
@@ -11,7 +11,7 @@ export const metadata: ComponentMetadata = {
11
11
  fields: [
12
12
  {
13
13
  name: 'image',
14
- type: 'text',
14
+ type: 'image',
15
15
  label: 'Src de la imagen del logo',
16
16
  mandatory: false,
17
17
  example_value: 'https://lefebvre.es/genia-l/images/genial/img-iso4.webp'
@@ -29,7 +29,7 @@ export const metadata: ComponentMetadata = {
29
29
  },
30
30
  {
31
31
  name: 'image',
32
- type: 'text',
32
+ type: 'image',
33
33
  label: 'URL de la imagen',
34
34
  mandatory: true,
35
35
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-w-16-9.png'
@@ -44,7 +44,7 @@ export const metadata: ComponentMetadata = {
44
44
  },
45
45
  {
46
46
  name: 'image',
47
- type: 'text',
47
+ type: 'image',
48
48
  label: 'URL de la imagen',
49
49
  mandatory: true,
50
50
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-4-3.png'
@@ -26,7 +26,7 @@ export const metadata: ComponentMetadata = {
26
26
  },
27
27
  {
28
28
  name: 'image',
29
- type: 'text',
29
+ type: 'image',
30
30
  label: 'URL de la imagen',
31
31
  mandatory: true,
32
32
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-1-1.png'
@@ -50,7 +50,7 @@ export const metadata: ComponentMetadata = {
50
50
  },
51
51
  {
52
52
  name: 'image',
53
- type: 'text',
53
+ type: 'image',
54
54
  label: 'URL de la imagen',
55
55
  mandatory: true,
56
56
  example_value: 'https://assets.lefebvre.es/media/img/preview-comp/comp-4-3.png'
@@ -90,7 +90,7 @@ const categories = [
90
90
 
91
91
  <div class="max-w-7xl flex items-center justify-between mx-auto">
92
92
  <a href={subdirectory + '/'} class="flex items-center">
93
- <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" class="h-[40px]" alt="GenIA-L Lefebvre">
93
+ <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" class="h-[40px]" alt="GenIA-L Lefebvre" loading="lazy">
94
94
  </a>
95
95
  <div class="flex items-center gap-4">
96
96
  <div class="flex items-center gap-4">
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
3
+
2
4
  const {
3
5
  title,
4
6
  subtitle,
@@ -11,7 +13,7 @@ const {
11
13
  showBtn = true
12
14
  } = Astro.props;
13
15
 
14
-
16
+ const srcUrl = extractImageUrl(src);
15
17
  ---
16
18
 
17
19
  <section class="w-full flex items-center justify-center pb-[36px]">
@@ -20,8 +22,8 @@ const {
20
22
 
21
23
  <div class="max-w-7xl w-full flex justify-center items-center relative md:w-4/5">
22
24
  <div class="relative w-full max-w-7xl min-h-[400px] md:min-h-[500px] lg:min-h-[auto]">
23
- {src && src !== "" ? (
24
- <img src={src} alt={alt} title={title} class="object-cover object-center w-full h-full lg:max-h-[446px] min-h-[400px] md:min-h-[500px] lg:min-h-[auto] rounded-2xl">
25
+ {srcUrl && srcUrl !== "" ? (
26
+ <img src={srcUrl} alt={alt} title={title} class="object-cover object-center w-full h-full lg:max-h-[446px] min-h-[400px] md:min-h-[500px] lg:min-h-[auto] rounded-2xl">
25
27
  ) : (
26
28
  <video autoplay loop muted playsinline class="object-cover object-center w-full h-full lg:max-h-[446px] min-h-[400px] md:min-h-[500px] lg:min-h-[auto] rounded-2xl">
27
29
  <source src={iframeSrc} type="video/mp4" />
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
3
+
2
4
  const {
3
5
  title,
4
6
  description,
@@ -17,7 +19,7 @@ const {
17
19
  alignItems = 'start',
18
20
  } = Astro.props;
19
21
 
20
-
22
+ const imageUrl = extractImageUrl(image);
21
23
  ---
22
24
 
23
25
  <section class="w-full flex items-center justify-center">
@@ -94,7 +96,7 @@ const {
94
96
  )}
95
97
 
96
98
  <div class={`w-full lg:w-1/2 p-4 flex items-center ${orientation === 'left' ? 'justify-end' : 'justify-start'} aspect-square`}>
97
- <img src={image} alt={title} class="w-[100%] h-[100%] object-cover rounded-lg" />
99
+ <img src={imageUrl} alt={title} class="w-[100%] h-[100%] object-cover rounded-lg" />
98
100
  </div>
99
101
  </div>
100
102
  </article>
@@ -1,6 +1,6 @@
1
1
  ---
2
-
3
2
  import Titulo_2025_Santorini from './Titulo_2025_Santorini.astro';
3
+ import { extractImageUrl } from '../../lib/functions.js';
4
4
 
5
5
  const {
6
6
  link='#',
@@ -11,14 +11,14 @@ const {
11
11
  description=''
12
12
  } = Astro.props;
13
13
 
14
-
14
+ const imageUrl = extractImageUrl(image);
15
15
  ---
16
16
 
17
17
  <a href={link} class="w-full flex flex-col cursor-pointer px-4 md:px-0">
18
18
  <article class="w-full h-full flex flex-col rounded-lg border border-gray-200 items-center shadow-article hover:bg-gradient-to-r from-[#001978] via-[#2134F1] to-[#F81BBD] transition-all duration-300 p-[1px]">
19
19
  <div class="bg-white mt-[1px] rounded-tl-[7px] rounded-tr-[7px] h-full">
20
20
  <div class="w-full">
21
- <img class="cursor-pointer rounded-tr-lg rounded-tl-lg mx-auto h-full" src={image} alt={altImage} />
21
+ <img class="cursor-pointer rounded-tr-lg rounded-tl-lg mx-auto h-full" src={imageUrl} alt={altImage} />
22
22
  </div>
23
23
  <div class="p-6 flex-grow flex flex-col">
24
24
  {tag && tag !== '' && <Titulo_2025_Santorini description={tag} />}
@@ -60,7 +60,7 @@ const categories = [
60
60
 
61
61
  <div class="flex flex-col flex-[4_4_0%]">
62
62
  <div class="mb-8">
63
- <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-10" />
63
+ <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-10" loading="lazy" />
64
64
  </div>
65
65
  <div>
66
66
  <ul class="flex flex-wrap gap-4 text-sm text-gray-800">
@@ -43,14 +43,14 @@ const categories = [
43
43
  <nav class="px-4 py-2 w-full border-b-1 border-gray-400">
44
44
 
45
45
  <div class="w-1/2 flex items-center justify-between py-2 mx-auto">
46
- <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-[55px]" />
46
+ <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-[55px]" loading="lazy" />
47
47
 
48
48
  <div class="flex items-center gap-4">
49
49
  <a href="https://lefebvre.es/tienda" class="underline flex items-center gap-1 cursor-pointer">
50
50
  <span>
51
51
  Tienda
52
52
  </span>
53
- <img src="https://assets.lefebvre.es/media/icons-2/svg/icon-basket.svg" class="w-5"></a>
53
+ <img src="https://assets.lefebvre.es/media/icons-2/svg/icon-basket.svg" class="w-5" loading="lazy"></a>
54
54
  <a href="https://espaciolefebvre.lefebvre.es/login/" class="px-4 py-3 border-1 border-black text-black hover:bg-black hover:text-white transition-all duration-300 rounded-lg font-semibold cursor-pointer">Entrar</a>
55
55
  </div>
56
56
 
@@ -86,7 +86,7 @@ const categories = [
86
86
  <div class="flex flex-col md:flex-row gap-8 max-w-7xl mx-auto p-[32px] md:px-2">
87
87
  <div class="flex flex-col flex-[4_4_0%]">
88
88
  <div class="mb-8">
89
- <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-10" />
89
+ <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" alt="Logo" class="h-10" loading="lazy" />
90
90
  </div>
91
91
  <div>
92
92
  <ul class="flex flex-wrap gap-2 text-sm text-gray-800">
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
2
3
 
3
4
  const {
4
5
  title,
@@ -10,6 +11,7 @@ const {
10
11
  businessAction = false
11
12
  } = Astro.props;
12
13
 
14
+ const imageSrcUrl = extractImageUrl(imageSrc);
13
15
  const idTargetLf2 = 'lf2-form-' + Math.random().toString(36).substring(2, 15);
14
16
 
15
17
  const structuredData = `<script type="application/ld+json">
@@ -44,7 +46,7 @@ const structuredData = `<script type="application/ld+json">
44
46
  <div id={idTargetLf2} class="w-full flex flex-col mx-auto gap-3"></div>
45
47
  </div>
46
48
  <div class={`w-full p-0 md:p-4 flex items-center ${orientation === 'left' ? 'justify-end' : 'justify-start'}`}>
47
- <img src={imageSrc} alt={title} class="w-full md:w-4/5 min-h-auto md:min-h-[650px] object-cover rounded-lg" />
49
+ <img src={imageSrcUrl} alt={title} class="w-full md:w-4/5 min-h-auto md:min-h-[650px] object-cover rounded-lg" />
48
50
  </div>
49
51
  </div>
50
52
  </article>
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
2
3
 
3
4
  const {
4
5
  bottomBorder = false,
@@ -22,6 +23,8 @@ const {
22
23
 
23
24
  } = Astro.props;
24
25
 
26
+ const imageSrcUrl = extractImageUrl(imageSrc);
27
+ const imageModalUrl = extractImageUrl(imageModal);
25
28
  const randomId = Math.floor(Math.random() * 1000);
26
29
 
27
30
 
@@ -53,7 +56,7 @@ const randomId = Math.floor(Math.random() * 1000);
53
56
  )}
54
57
  </div>
55
58
  <div class={`w-full md:w-1/2 p-4 flex items-center ${orientation === 'left' ? 'justify-end' : 'justify-start'}`}>
56
- <img src={imageSrc} alt={title} class="w-full md:w-1/2 rounded-2xl" />
59
+ <img src={imageSrcUrl} alt={title} class="w-full md:w-1/2 rounded-2xl" />
57
60
  </div>
58
61
  </div>
59
62
 
@@ -66,7 +69,7 @@ const randomId = Math.floor(Math.random() * 1000);
66
69
  </div>
67
70
  <div class="w-full h-full flex flex-col lg:flex-row items-start justify-center gap-8">
68
71
  <div class="w-full lg:w-1/3 flex justify-center items-center p-0 lg:p-4 mt-[32px] lg:mt-0">
69
- <img src={imageModal} alt={altModal} class="w-fit" />
72
+ <img src={imageModalUrl} alt={altModal} class="w-fit" />
70
73
  </div>
71
74
  <div class="w-full lg:w-2/3">
72
75
  <h2 class="font-poppins text-[#262626] text-[28px] lg:text-[32px] font-normal text-left leading-[40px] mb-[32px]">{titleModal}</h2>
@@ -1,5 +1,8 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
3
+
2
4
  const { imageSrc, orientation, figure = 'Trapecio', gradiantIndex = 0 } = Astro.props;
5
+ const imageSrcUrl = extractImageUrl(imageSrc);
3
6
  const polygons = [
4
7
  {
5
8
  name: 'Trapeze',
@@ -36,5 +39,5 @@ const selectedPolygon = polygons.find(p => p.name === figure) || polygons[0];
36
39
  ---
37
40
  <div class={`w-[400px] h-[400px] relative ${orientation === 'right' ? '' : '-scale-x-100'}`}>
38
41
  <div class={`absolute bottom-0 right-0 w-full h-full bg-cover mask-no-repeat mask-bottom-right ${gradiants[gradiantIndex]}`} style={`mask-image: url(${selectedPolygon.polygon});`}></div>
39
- <img src={`${imageSrc}`} loading="lazy" class="absolute bottom-0 right-0 max-h-[400px] h-auto z-10 mask-no-repeat mask-bottom-right" style={`mask-image: url(${selectedPolygon.full});`} alt="Figura Geométrica" />
42
+ <img src={`${imageSrcUrl}`} loading="lazy" class="absolute bottom-0 right-0 max-h-[400px] h-auto z-10 mask-no-repeat mask-bottom-right" style={`mask-image: url(${selectedPolygon.full});`} alt="Figura Geométrica" />
40
43
  </div>
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  import GeometricShape from './GeometricShape.astro';
3
+ import { extractImageUrl } from '../../lib/functions.js';
3
4
 
4
5
 
5
6
  const {
@@ -12,13 +13,15 @@ const {
12
13
  gradiantIndex = 0
13
14
  } = Astro.props;
14
15
 
16
+ const imageSrcUrl = extractImageUrl(imageSrc);
17
+
15
18
  const randomId = `geo-shape-card-`+ Math.random().toString(36).substring(2, 15);
16
19
 
17
20
  ---
18
21
 
19
22
  <section class={`flex my-8 items-center justify-center relative min-h-[500px]`}>
20
23
  <div class={`absolute top-0 ${orientation === 'right' ? 'right-0' : 'left-0'}`}>
21
- <GeometricShape imageSrc={imageSrc} orientation={orientation} figure={figure} gradiantIndex={gradiantIndex} />
24
+ <GeometricShape imageSrc={imageSrcUrl} orientation={orientation} figure={figure} gradiantIndex={gradiantIndex} />
22
25
  </div>
23
26
  <div class={`flex text-gray-800 flex-col w-3/5 mx-auto ${orientation === 'right' ? 'text-left items-start' : 'text-right items-end'}`}>
24
27
  <h2 class="text-4xl font-bold mb-5 max-w-3xl">{title}</h2>
@@ -13,12 +13,12 @@ const {
13
13
  <div class="flex flex-wrap justify-between items-center mx-auto max-w-screen-xl">
14
14
 
15
15
  <a href="/" class="flex justify-between items-center">
16
- <img src={logo} class="" alt={alt}/>
16
+ <img src={logo} class="" alt={alt} loading="lazy"/>
17
17
  </a>
18
18
 
19
19
 
20
20
  {showLefebvreLogo && (
21
- <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" class="" alt="Lefebvre"/>
21
+ <img src="https://assets.lefebvre.es/media/logos-2/svg/lefebvre.svg" loading="lazy" class="" alt="Lefebvre"/>
22
22
  )}
23
23
 
24
24
  </div>
@@ -1,10 +1,14 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
3
+
2
4
  const {
3
5
  image,
4
6
  title,
5
7
  video ,
6
8
  description,
7
9
  } = Astro.props;
10
+
11
+ const imageUrl = extractImageUrl(image);
8
12
  ---
9
13
 
10
14
  <!-- Componente que sirve para las páginas soluciones-profesionales y conocenos entre otras. Si se le pasa por parámetro una imagen, la muestra a la izquierda y el texto a la derecha. Si se le pasa un vídeo, muestra el vídeo a la izquierda y el texto a la derecha. -->
@@ -15,7 +19,7 @@ const {
15
19
 
16
20
  {image
17
21
  ? (
18
- <div class="w-full lg:w-1/2 lg:mx-4 mask-add mask-[url(https://assets.lefebvre.es/media/logos-2/svg/lefebvre-iso.svg)] mask-no-repeat mask-center bg-cover" style={`background-image: url('${image}')`} id="rotating-image"></div>
22
+ <div class="w-full lg:w-1/2 lg:mx-4 mask-add mask-[url(https://assets.lefebvre.es/media/logos-2/svg/lefebvre-iso.svg)] mask-no-repeat mask-center bg-cover" style={`background-image: url('${imageUrl}')`} id="rotating-image"></div>
19
23
  )
20
24
  : video
21
25
  ? (
@@ -1,4 +1,12 @@
1
1
  ---
2
+ /**
3
+ * 🎯 Imagen_2025_Bogota
4
+ *
5
+ * Componente de imagen con overlay de texto.
6
+ * Usa LimboImage para simplificar el manejo de imágenes de Limbo.
7
+ */
8
+ import LimboImage from '../LimboImage.astro';
9
+
2
10
  const {
3
11
  title,
4
12
  description,
@@ -10,19 +18,19 @@ const {
10
18
  showBtn = true,
11
19
  showDescription = true,
12
20
  color = '#ffffff',
13
- } = Astro.props;
21
+ } = Astro.props;
14
22
 
15
- const structuredData = `<script type="application/ld+json">
16
- {
17
- "@context": "https://schema.org",
18
- "@type": "ImageObject",
19
- "name": "${title || ''}",
20
- "description": "${description ? description.replace(/<[^>]*>/g, '').replace(/"/g, '\\"') : ''}",
21
- "url": "${src || iframeSrc || ''}",
22
- "contentUrl": "${src || iframeSrc || ''}",
23
- ${src ? `"encodingFormat": "image"` : `"encodingFormat": "video/mp4"`}
24
- }
25
- </script>`;
23
+ const structuredData = `<script type="application/ld+json">
24
+ {
25
+ "@context": "https://schema.org",
26
+ "@type": "ImageObject",
27
+ "name": "${title || ''}",
28
+ "description": "${description ? description.replace(/<[^>]*>/g, '').replace(/"/g, '\\"') : ''}",
29
+ "url": "${src || iframeSrc || ''}",
30
+ "contentUrl": "${src || iframeSrc || ''}",
31
+ ${src ? `"encodingFormat": "image"` : `"encodingFormat": "video/mp4"`}
32
+ }
33
+ </script>`;
26
34
  ---
27
35
 
28
36
  <section class="w-full flex items-center justify-center">
@@ -32,13 +40,19 @@ const {
32
40
  <div class="max-w-full lg:max-w-7xl h-full flex justify-center items-center aspect-auto relative md:w-4/5 lg:aspect-video">
33
41
  <div class="absolute inset-0">
34
42
 
35
- {src && src !== "" ? (
36
- <img src={src} alt={alt} title={title} class="object-cover object-center w-full h-full rounded-2xl shadow-lg">
37
- ) : (
43
+ {src ? (
44
+ <LimboImage
45
+ src={src}
46
+ alt={alt || title || ''}
47
+ title={title}
48
+ class="object-cover object-center w-full h-full rounded-2xl shadow-lg"
49
+ fallback={iframeSrc}
50
+ />
51
+ ) : iframeSrc ? (
38
52
  <video autoplay loop muted playsinline class="object-cover object-center w-full h-full rounded-2xl shadow-lg">
39
53
  <source src={iframeSrc} type="video/mp4" />
40
54
  </video>
41
- )}
55
+ ) : null}
42
56
  </div>
43
57
 
44
58
  <div class="w-4/5 relative z-10 flex flex-col justify-center items-center h-full text-center p-0 py-8 md:p-6">
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import { extractImageUrl } from '../../lib/functions.js';
3
+
2
4
  const {
3
5
  link = false,
4
6
  image,
@@ -6,6 +8,7 @@ const {
6
8
  descriptionImage
7
9
  } = Astro.props;
8
10
 
11
+ const imageUrl = extractImageUrl(image);
9
12
  ---
10
13
 
11
14
 
@@ -14,12 +17,12 @@ const {
14
17
  <div class="w-full">
15
18
  {(link && link !== '') ? (
16
19
  <a href={link} class="w-full flex flex-col flex-1 justify-center items-center">
17
- <img class="max-w-[80px] w-fit mb-4" src={image} alt={altImage} />
20
+ <img class="max-w-[80px] w-fit mb-4" src={imageUrl} alt={altImage} />
18
21
  <p class="text-[14px] text-[#363942]" set:html={descriptionImage}></p>
19
22
  </a>
20
23
  ) : (
21
24
  <div class="w-full flex flex-col flex-1 justify-center items-center max-h-[94px]">
22
- <img class="max-w-[80px] w-fit mb-4" src={image} alt={altImage} />
25
+ <img class="max-w-[80px] w-fit mb-4" src={imageUrl} alt={altImage} />
23
26
  </div>
24
27
  <div class="w-full flex flex-col flex-1 justify-center items-center">
25
28
  <p class="text-[14px] text-[#363942]" set:html={descriptionImage}></p>