Project image, video, and PDF thumbs into ply-lightbox. They can share one gallery. Thumb size and aspect ratio stay on each thumb. Click a thumb to open that file in a focus-trapped overlay.
A single thumb works the same way — no prev/next controls appear. Use Tailwind for ratio and max width on the thumb itself.
<ply-lightbox>
<img
ply-lightbox-thumb
src="thumb.jpg"
fullSrc="full.jpg"
alt="Laptop"
class="aspect-video w-full max-w-xl cursor-pointer rounded-xl object-cover"
/>
</ply-lightbox>TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
Put layout classes on ply-lightbox (applied to the thumbs wrapper). Each thumb keeps its own ratio — square, video, or portrait.
<ply-lightbox class="grid grid-cols-2 gap-3 sm:grid-cols-3">
<img
ply-lightbox-thumb
src="…"
fullSrc="…"
alt="…"
class="aspect-square w-full cursor-pointer rounded-lg object-cover"
/>
<!-- more thumbs -->
</ply-lightbox>TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
Mix Tailwind aspect utilities on individual thumbs in the same gallery.
<ply-lightbox class="flex flex-wrap gap-3"> <img ply-lightbox-thumb … class="aspect-square h-28 w-28 object-cover" /> <img ply-lightbox-thumb … class="aspect-video h-28 w-48 object-cover" /> <img ply-lightbox-thumb … class="aspect-3/4 h-28 w-20 object-cover" /> </ply-lightbox>
TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
A poster image can open a clip when fullSrc is a video. A button can open a PDF. Leave mediaType empty when the viewer URL ends in .mp4, .webm, or .pdf.
<ply-lightbox class="grid grid-cols-3 gap-3">
<img ply-lightbox-thumb src="photo.jpg" alt="Coast" class="aspect-square w-full object-cover" />
<img
ply-lightbox-thumb
mediaType="video"
src="poster.jpg"
fullSrc="clip.mp4"
alt="Clip"
class="aspect-square w-full object-cover"
/>
<button type="button" ply-lightbox-thumb mediaType="pdf" fullSrc="note.pdf" imageAlt="Notes">
Notes
</button>
</ply-lightbox>TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
If a thumb (or the overlay image) fails to load, initials are taken from alt — e.g. "Jane Doe" → JD, "Coast" → CO. Disable with [initialsFallback]="false" on the thumb or the lightbox.



<ply-lightbox class="flex flex-wrap gap-3">
<img
ply-lightbox-thumb
src="https://cdn.example/missing.jpg"
alt="Jane Doe"
class="aspect-square h-28 w-28 rounded-md object-cover"
/>
</ply-lightbox>TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
Flip, rotate, and zoom apply to images. Video uses its own controls. PDF opens in the viewer. Download and fullscreen stay for every item. Keyboard: Esc closes, ←/→ move between items, +/− zoom an image.
<!-- Optional toggles --> <ply-lightbox [loop]="true" [showToolbar]="true" [showCounter]="true" [closeOnBackdrop]="true" [initialsFallback]="true" dialogLabel="Photo gallery" (opened)="onOpened($event)" (closed)="onClosed()" (indexChange)="onIndex($event)" > … </ply-lightbox>
TypeScript
import { Component } from '@angular/core';
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-lightbox-example',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class LightboxExampleComponent {}Install
npx ply-ui-cli add lightbox
Run the following command to add this component to your project:
npx ply-ui-cli add lightbox
For AI agents
Copy a prompt with the registry name, CLI install, and import — or add the Ply MCP server.
npx -y ply-ui-mcp
Ply provides standalone components. Import the exact elements you want to use into your component.
// Install: npx ply-ui-cli add lightbox
// Paths are relative to aliases.components (default: src/app/components)
import { LightboxThumbDirective } from './lightbox/lightbox-thumb.directive';
import { LightboxComponent } from './lightbox/lightbox.component';
@Component({
selector: 'app-your-component',
imports: [
LightboxComponent,
LightboxThumbDirective
],
template: `...`
})
export class YourComponent {} API for lightbox — generated from JSDoc in the library source.
| API | Member | Type | Default | Description |
|---|---|---|---|---|
ply-lightbox | class | string | '' | Classes for the thumbs layout wrapper (e.g. `grid grid-cols-3 gap-2`). Applied to an inner container so projected thumbs participate in that layout. |
ply-lightbox | loop | boolean | true | When true, prev/next wrap around the ends of the gallery. |
ply-lightbox | showToolbar | boolean | true | Whether to show the transform / download toolbar. |
ply-lightbox | showCounter | boolean | true | Whether to show the "n / total" counter when there is more than one image. |
ply-lightbox | closeOnBackdrop | boolean | true | Close the overlay when the backdrop is clicked. |
ply-lightbox | dialogLabel | unknown | 'Media lightbox' | Accessible name for the lightbox dialog. |
ply-lightbox | initialsFallback | boolean | true | When true (default), a broken or missing viewer image shows initials from the thumb's `alt` / `imageAlt` instead of an empty stage. |
ply-lightbox | (opened) | number | — | Emitted when the lightbox opens, with the active index. |
ply-lightbox | (closed) | void | — | Emitted when the lightbox closes. |
ply-lightbox | (indexChange) | number | — | Emitted whenever the active image index changes while open. |
[ply-lightbox-thumb] | mediaType | LightboxMediaType | '' | '' | Overlay kind. Leave empty to infer it from the viewer URL (`.mp4`, `.webm`, `.pdf`) or from a `<video>` host. Image, video, and PDF thumbs can share one gallery. |
[ply-lightbox-thumb] | fullSrc | string | '' | Optional full-resolution URL shown in the overlay. Falls back to the element's native `src` (or `imageSrc`) when omitted. A poster `src` plus a video or PDF `fullSrc` keeps the thumb an image. |
[ply-lightbox-thumb] | imageSrc | string | '' | Image URL for non-`<img>` hosts. Do **not** use this on `<img>` — bind the native `src` attribute instead so the thumbnail is visible. |
[ply-lightbox-thumb] | imageAlt | string | '' | Accessible label override for non-`<img>` hosts. On `<img>`, use native `alt`. |
[ply-lightbox-thumb] | downloadName | string | '' | Suggested filename for the download action. |
[ply-lightbox-thumb] | initialsFallback | boolean | true | When true (default), a broken or missing image is replaced by initials derived from `alt` / `imageAlt` (e.g. "Jane Doe" → "JD"). |
Content