vaiperui

componentes / lightbox

Lightbox

Visor de imágenes a pantalla completa con navegación, contador y subtítulos.

Cómo usar

Un `role="dialog"` modal renderizado en un portal: el foco queda atrapado, el scroll de la página se bloquea, Esc cierra y ←/→ navegan (dando la vuelta). `open` e `index` pueden ser controlados; sin ellos guarda su propio estado (`defaultOpen`, `defaultIndex`). El foco vuelve al elemento de origen al cerrar, salvo que `onCloseAutoFocus` llame a `preventDefault()`.

preview
Lightbox.tsx
import { useState } from "react";
import { Lightbox } from "vaiperui";
const [open, setOpen] = useState(false);
<button onClick={() => setOpen(true)}>Abrir</button>
<Lightbox
open={open}
onOpenChange={setOpen}
items={[
{ src: "/photos/road.jpg", alt: "Mountain road", caption: "Road" },
{ src: "/photos/sky.jpg", alt: "Starry sky" },
]}
/>

Predeterminado

preview
Clic para abrir
predeterminado.tsx
<Lightbox open={open} onOpenChange={setOpen} items={items} />

Props

PropValoresPredeterminadoDescripción
items{ src, alt, caption? }[]—Imágenes a mostrar
open / defaultOpenbooleanfalseVisibilidad controlada / inicial
onOpenChange(open: boolean) => voidningunoLlamado cuando pide cerrarse
index / defaultIndexnumber0Imagen controlada / inicial
onIndexChange(index: number) => voidningunoLlamado cuando cambia la imagen
labelstringImage viewerNombre accesible del diálogo
closeLabel / previousLabel / nextLabelstringClose / Previous image / Next imageNombres accesibles de los botones
counterLabel(index, total) => string1 / 6Texto del contador
onCloseAutoFocus(event: Event) => voidningunoAl cerrar; preventDefault() evita devolver el foco

Accesibilidad

  • El visor es un `role="dialog"` con `aria-modal="true"`, nombrado por `label`, renderizado en un portal.
  • Al abrir, el foco entra y Tab circula dentro del diálogo (focus trap); el scroll de la página se bloquea mientras está abierto.
  • Al cerrar, el foco vuelve al elemento que lo tenía antes, salvo que `onCloseAutoFocus` llame a `preventDefault()`.
  • Cerrar, anterior y siguiente son botones reales nombrados por `closeLabel`, `previousLabel` y `nextLabel`; anterior/siguiente solo existen con más de una imagen y dan la vuelta.
  • La imagen usa su `alt`, dentro de un `<figure>` con la `caption` como `<figcaption>`.
  • El contador (`counterLabel`, p. ej. `2 / 5`) es una región `aria-live="polite"`, así que el cambio de imagen se anuncia.

Teclado

TeclaAcción
EscCierra el visor
ArrowLeft / ArrowRightImagen anterior / siguiente (con más de una)
Tab / Shift+TabCircula por los botones dentro del diálogo

Ten en cuenta

  • Cada elemento necesita un `alt`; el componente no lo genera.
  • Hacer clic en el fondo oscuro también cierra, pero es un atajo de mouse; quien usa teclado cierra con Esc o el botón de cerrar. Traduce las etiquetas al idioma de la página.