# GalleryLightbox

> Event-driven fullscreen lightbox overlay with thumbnail sidebar navigation

Canonical URL: https://fa7e86e3d553:3005/islands/content/gallery-lightbox

> Fullscreen image lightbox triggered via DOM events. Mount once per page — all galleries share the same instance. Click any image to open a scroll-snap viewer with synced thumbnail sidebar.

## Preview

**Category**: Content

## Props

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| backdrop | string | no | "rgba(255,255,255,0.97)" | Background color of the lightbox overlay |
| showSidebar | boolean | no | true | Show thumbnail sidebar on desktop (hidden on mobile regardless) |

## Event API

The lightbox is **event-driven** — no direct prop wiring needed. Any element on the page can trigger it:

### Open

```js
document.dispatchEvent(new CustomEvent('lx:lightbox:open', {
  detail: {
    images: [
      { src: 'https://cdn.shopify.com/img1-large.jpg', alt: 'Product front' },
      { src: 'https://cdn.shopify.com/img2-large.jpg', alt: 'Product back' },
    ],
    startIndex: 0 // which image to scroll to initially
  }
}));
```

### Close (emitted by the island)

```js
document.addEventListener('lx:lightbox:close', () => {
  // lightbox was closed — restore any state if needed
});
```

## Embed Example

```html
<lx-island name="GalleryLightbox">
  <script type="application/json">
{}
  </script>
</lx-island>
```

## CSS Custom Properties

Style the lightbox from the parent section using these variables:

| Variable | Default | Description |
|----------|---------|-------------|
| --lx-lightbox-bg | rgba(255,255,255,0.97) | Backdrop color |
| --lx-lightbox-thumb-size | 80px | Sidebar thumbnail column width |
| --lx-lightbox-active-border | #111 | Border color on active thumbnail |

```css
[data-part="gallery-lightbox"] {
  --lx-lightbox-bg: rgba(0, 0, 0, 0.95);
  --lx-lightbox-active-border: #fff;
}
```

## Features

- **Scroll-snap viewer**: Images snap into place as user scrolls vertically
- **Thumbnail sidebar**: 80px strip on desktop, highlights the currently visible image
- **ESC to close**: Keyboard accessible
- **Body scroll lock**: Prevents background scroll while open
- **Image counter**: Shows "2 / 8" in bottom-right
- **Lazy loading**: Only first 2 images load eagerly, rest lazy
- **SSR-safe**: Renders nothing on server, hydrates on idle

## When to Use

- Gallery grids (lookbooks, Instagram feeds, UGC collections)
- Product detail pages (additional photos beyond the main gallery)
- Blog posts with inline image grids
- Any section where clicking an image should show it fullscreen

## When NOT to Use

- Inline hover-zoom (use `ImageZoom` instead)
- Product variant galleries with swatch selection (use `ProductGallery`)
- Single hero images that don't need expanded view
- Video content (use `VideoPlayer`)

## Architecture Note

This island follows the **event bus pattern** — it decouples the trigger (any gallery grid, any click handler) from the viewer (the lightbox). Benefits:

1. One lightbox instance serves the entire page
2. Template sections don't need to know about React — just fire a CustomEvent
3. Multiple galleries on one page share the same lightbox (no duplication)
4. Plain HTML template sections (no island) can still trigger it via inline JS
