import { type ReactNode } from "react";
export type LightboxImage = {
readonly alt: string;
readonly src: string;
readonly caption?: ReactNode;
};
export type LightboxProps = {
/** Optional ordered gallery. The trigger opens at initialIndex. */
images?: readonly LightboxImage[];
initialIndex?: number;
/**
* Required, and the whole reason this is not a bare `
` in a
* dialog. It names both the enlarged image and — via `heading`'s
* default below — the dialog itself, and a poster grid of unnamed
* images is unnavigable rather than merely imperfect. Same rule
* `MediaTile` makes.
*/
alt: string;
/** Shown under the enlarged image. A year, a source, a filename. */
caption?: ReactNode;
/** Applied to the built-in trigger button, not the dialog. */
className?: string;
/**
* The dialog's accessible name and visible heading. Defaults to
* `alt`, which is right when the thumbnail's alt is already the
* title ("THE OUTFIT poster"); pass it when the two should differ.
*/
heading?: string;
/**
* **Controlled** open state. Omit for the uncontrolled default,
* where the trigger owns it through `useVisibility`. Present means
* the caller owns it and the built-in trigger becomes a plain
* button that only *reports* intent through `onOpenChange`.
*/
isOpen?: boolean;
onOpenChange?: (isOpen: boolean) => void;
src: string;
/**
* The clickable thumbnail — a smaller `
`, usually. Omitted in
* the controlled, trigger-elsewhere case, where something else in
* the page opens the lightbox and this renders only the overlay.
*/
thumbnail?: ReactNode;
};
/**
* A thumbnail that opens its own full-size view — the one image
* interaction three apps hand-roll and none get the focus trap or
* the scroll lock right. It is a **skin over `Dialog`**, not a second
* dialog: `Dialog` (through `Modal`/`OverlayPanel`) owns the portal,
* the scrim, Escape, the focus trap and `lockScrollBehind`, and
* everything that makes those correct in every browser the fleet
* runs. What this adds is the image-specific part — a `cursor-zoom-in`
* trigger and an `object-contain` image clamped to the viewport so a
* 2:3 poster and a 16:9 still both land whole.
*
* ### Controlled and not, one component
*
* `useVisibility` runs unconditionally — hooks cannot be conditional
* — but is *consulted* only when `isOpen` is absent. A caller that
* passes `isOpen` owns the truth; the internal store is then an
* unread two-field object, which is cheaper than splitting this into
* two components that share a Modal body.
*/
export declare const Lightbox: ({ alt, caption, className, heading, images, initialIndex, isOpen, onOpenChange, src, thumbnail, }: LightboxProps) => ReactNode;
//# sourceMappingURL=Lightbox.d.ts.map