componente · @solu30/ui-kit/display
PhotoGalleryModal
Galería de fotos a pantalla completa con tira de miniaturas, que maneja su propio índice.
3 sitios de import en 2 de 15 verticales — un archivo que la importa cuenta una vez, monte una instancia o veinte.
- TheCharterPanel
- luigi
El componente, montado
Cargando el espécimen…
export function GaleriaDeFotosSpecimen() {
const [galleryIndex, setGalleryIndex] = useState<number | null>(null)
const [lightboxOpen, setLightboxOpen] = useState(false)
const [current, setCurrent] = useState(0)
return (
<Stage label="PhotoGalleryModal y Lightbox · la galería de un reclamo y el carrusel de una propuesta" tall wide>
<div className="flex w-full max-w-[460px] flex-col items-center gap-3 px-1 py-1">
{/* La grilla de miniaturas es del CONSUMIDOR: ninguna de las dos piezas
la trae. Es la que decide con qué índice abrir el visor — igual que
en reclamo-detail-sheet.tsx y en proposal-image-carousel.tsx. */}
<div className="grid w-full grid-cols-2 gap-2 sm:grid-cols-4">
{FOTOS_SALON.map((src, i) => (
<button
key={src}
type="button"
onClick={() => setGalleryIndex(i)}
className="overflow-hidden rounded-lg border border-content/10 transition-opacity hover:opacity-80"
>
<img src={src} alt={`Foto ${i + 1} del salón`} className="h-16 w-full object-cover sm:h-14" />
</button>
))}
</div>
<Row>
<Button variant="secondary" size="sm" onClick={() => setGalleryIndex(0)}>
Ver las 4 fotos
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => {
setCurrent(0)
setLightboxOpen(true)
}}
>
Abrir el carrusel
</Button>
</Row>
<p className="text-center text-[11px] text-content/60">
Las dos se dibujan sobre la página entera (`fixed inset-0`), no adentro de este escenario.
Se cierran con Escape, con la X o tocando el fondo.
</p>
</div>
{galleryIndex !== null && FOTOS_SALON.length > 0 && (
<PhotoGalleryModal
photos={FOTOS_SALON}
initialIndex={galleryIndex}
title="Reclamo #418"
onClose={() => setGalleryIndex(null)}
/>
)}
{lightboxOpen && (
<Lightbox
photos={FOTOS_SALON}
selectedIndex={current}
onClose={() => setLightboxOpen(false)}
onNavigate={setCurrent}
alt={`Imagen ${current + 1} de ${FOTOS_SALON.length}`}
/>
)}
</Stage>
)
}De specimens/display.tsx · GaleriaDeFotosSpecimen: el espécimen del Muestrario, no un ejemplo oficial del paquete. Muestra cómo se usa la pieza de verdad, montada contra los tipos instalados —eso es lo que vale— pero no es documentación del kit.
Cómo se usa
import { PhotoGalleryModal } from '@solu30/ui-kit/display'Props
| Prop | Requerida | Tipo | Qué hace |
|---|---|---|---|
| photos | sí | string[] | — |
| thumbnails | opcional | string[] | — |
| initialIndex | opcional | number | — |
| onClose | sí | () => void | — |
| title | opcional | string | — |
Ejemplo del paquete
// La galería completa con miniaturas; el Lightbox es la versión de una sola foto.
<PhotoGalleryModal photos={fotos} thumbnails={miniaturas} initialIndex={0}
title="Salón Norte" onClose={cerrar} />Del @example del JSDoc de @solu30/ui-kit, sin editar: son 65 de los 541 símbolos. La sangría y los renglones en blanco son los del paquete.