lightbox

g.lightbox — images, galleries, video and iframes in a media overlay

Images — standalone + gallery

Mark any link with the lightbox attribute — the href opens in the overlay. Give the attribute a VALUE and every element sharing it becomes one gallery with prev/next. Captions ride lightbox-title / lightbox-description.

Video & iframe — auto-detected from the href

YouTube, Vimeo and direct .mp4 links become video slides (played by Plyr, served from the app's own vendors — no CDN); any other URL opens as an iframe. Size iframe/video slides with lightbox-width / lightbox-height.

The video demos stream from YouTube/Vimeo — they need network access; everything else on this page is served locally.

From data — no DOM elements

When the media list comes from an API payload (a lister row's photos, a record's attachments), skip the markup: g.lightbox.open(items, startAt) builds the slideshow from plain objects.

The rules

  • The route declares 'vendors' => ['glightbox'] + 'libs' => ['lightbox']. Marked elements need NO page JS — the lib inits on load and re-scans on lister:loaded; after injecting marked elements yourself, call g.lightbox.refresh().
  • The attribute contract: bare lightbox = standalone, a shared value = one gallery; lightbox-title/lightbox-description caption the slide; lightbox-type forces image|video|external when the href alone cannot tell; lightbox-width/lightbox-height size video/iframe slides.
  • Captions and controls are theme-aware (both themes, focus-visible rings, reduced-motion honored); the overlay stays dark by design. Never restyle the vendor by hand — the lib's stylesheet already aligns it.
  • Docs: templates/app/docs/libs/lightbox.md; the harness: /tests/lightbox.