@crtobiasdelsud/portal-ui 1.0.26 → 1.0.28

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": "@crtobiasdelsud/portal-ui",
3
- "version": "1.0.26",
3
+ "version": "1.0.28",
4
4
  "description": "Componentes compartidos entre el portal (Next) y el CMS (Vite) — widgets, views, providers para adapters y article pool.",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -3,15 +3,12 @@
3
3
  import styles from './ArticleHeroFull.module.scss'
4
4
  import { useSiteConfig } from '../../context/SiteConfigContext.jsx'
5
5
  import Carousel from '../Carousel/Carousel.jsx'
6
+ import AspectImage from '../UI/AspectImage/AspectImage.jsx'
6
7
 
7
8
  export default function ArticleHeroFull({ titulo, copete, imagen, imagenes, imagenEpigrafe, focalPoint, categoria }) {
8
9
  const { config } = useSiteConfig()
9
10
  const siteName = config?.slots?.header?.settings?.siteName ?? ''
10
11
 
11
- const objPos = focalPoint
12
- ? `${focalPoint.x ?? 50}% ${focalPoint.y ?? 50}%`
13
- : 'center center'
14
-
15
12
  // Slides del carrusel: `imagenes` (array) tiene prioridad; si no, la imagen
16
13
  // única. La primera es la principal.
17
14
  const slides = (Array.isArray(imagenes) && imagenes.length > 0)
@@ -20,26 +17,33 @@ export default function ArticleHeroFull({ titulo, copete, imagen, imagenes, imag
20
17
 
21
18
  const single = slides.length === 1 ? slides[0] : null
22
19
 
20
+ // Hero a pantalla casi completa → la imagen ocupa todo el ancho del viewport.
21
+ // `sizes="100vw"` deja que el navegador baje la variante responsive justa
22
+ // (ver AspectImage / ADR-0002) en vez del original a tamaño completo.
23
+ const heroSizes = '100vw'
24
+
23
25
  return (
24
26
  <div className={styles.hero}>
25
27
  {slides.length > 1 ? (
26
28
  <Carousel
27
- images={slides.map((s) => ({ url: s.url, alt: titulo ?? '' }))}
29
+ images={slides.map((s) => ({ url: s.url, alt: titulo ?? '', variants: s.variants ?? null }))}
28
30
  focalPoint={focalPoint}
31
+ sizes={heroSizes}
29
32
  fill
30
33
  showEpigrafe={false}
31
34
  dotsPosition="top"
32
35
  priority
33
36
  />
34
37
  ) : single ? (
35
- <img
38
+ <AspectImage
36
39
  src={single.url}
37
40
  alt={titulo ?? ''}
38
41
  className={styles.img}
39
- style={{ objectPosition: objPos }}
40
- decoding="async"
41
- loading="eager"
42
- fetchPriority="high"
42
+ fill
43
+ focalPoint={focalPoint}
44
+ variants={single.variants ?? null}
45
+ sizes={heroSizes}
46
+ priority
43
47
  />
44
48
  ) : null}
45
49
  <div className={styles.gradient} />
@@ -260,7 +260,11 @@
260
260
  color: var(--text-color, #252523);
261
261
  }
262
262
 
263
- @include respond(tablet) {
263
+ // Layout de imagen flex-fill solo desde laptop (>=960px), igual que la grilla
264
+ // `.list` de Categoria/CategoriaDos. En 768-960 la lista es columna flex sin
265
+ // altura definida: si esto arrancara en tablet, `flex:1`+`aspect-ratio:unset`
266
+ // colapsaria la imagen a 0. En ese rango la card queda en forma mobile (16:9).
267
+ @include respond(laptop) {
264
268
  height: 100%;
265
269
 
266
270
  .titulo {
@@ -284,7 +288,7 @@
284
288
  }
285
289
 
286
290
  .featuredLarge {
287
- @include respond(tablet) {
291
+ @include respond(laptop) {
288
292
  .titulo {
289
293
  font-weight: 700;
290
294
  font-size: 2.125em;
@@ -307,7 +311,7 @@
307
311
  gap: 5px;
308
312
  }
309
313
 
310
- @include respond(tablet) {
314
+ @include respond(laptop) {
311
315
  height: 100%;
312
316
 
313
317
  .imgLinkFill {
@@ -22,7 +22,12 @@ export default function V1({ article, important = false, inlineStyle }) {
22
22
  {article.volanta && <span className={styles.category}>{article.volanta}. </span>}
23
23
  {article.titulo}
24
24
  </p>
25
- <p className={styles.copete}> {article.copete}</p>
25
+ {article.copete && (
26
+ <p
27
+ className={styles.copete}
28
+ dangerouslySetInnerHTML={{ __html: article.copete }}
29
+ />
30
+ )}
26
31
  {article.autor?.nombre && (
27
32
  <span className={styles.autor}>Por {article.autor.nombre}</span>
28
33
  )}