This component is based on Cambio Image by Raphael Salaja.
Installation
pnpm dlx shadcn@latest add https://deltacomponents.dev/r/cambio-image.jsonAdd the following CSS to your globals.css for proper z-index management in grid layouts:
.root {
isolation: isolate;
}
[data-state="open"] {
z-index: 999 !important;
}Usage
import { CambioImage } from "@/components/ui/cambio-image"
export default function Example() {
return (
<CambioImage
src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=600&fit=crop"
alt="Beautiful mountain landscape"
width={800}
height={600}
motion="smooth"
className="rounded-lg"
/>
)
}Examples
Grid Gallery
When using images in a grid, pass the index prop to ensure correct layering during the close animation.
Dismiss on Scroll
Automatically dismiss the zoomed image when the user scrolls. This is useful for maintaining a smooth browsing experience.
The dismissOnScroll behavior may not function as expected when the component is rendered within constrained scroll containers such as demo previews or tab panels. For the best experience testing this functionality, view the full-screen demo where scroll events propagate correctly.
Features
- Click to zoom: Images can be clicked to open in a full-screen overlay
- Intersection Observer: Lazy loading with optional blur-to-focus animation
- Animation control: Toggle initial animation with
enableInitialAnimationprop - Motion presets: Customizable animation styles (smooth, snappy, bouncy, reduced)
- Dismissible: Click outside or use escape key to close
- Responsive: Automatically scales on different screen sizes
- Grid-friendly: Proper z-index management for grid layouts
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| src | string | - | Required. Image source URL |
| alt | string | - | Required. Image alt text for accessibility |
| width | number | - | Required. Image width in pixels |
| height | number | - | Required. Image height in pixels |
| loading | "lazy" | "eager" | "lazy" | Image loading strategy |
| index | number | 0 | Z-index offset for stacking multiple images |
| motion | MotionPreset | MotionConfig | "smooth" | Animation preset or custom configuration |
| dismissible | boolean | true | Whether the zoom overlay can be dismissed |
| dismissOnScroll | boolean | false | Automatically dismiss the overlay when scrolling |
| className | string | - | Additional CSS classes for styling |
| draggable | boolean | false | Whether the image can be dragged |
| enableInitialAnimation | boolean | true | Enable blur-to-focus animation when image enters viewport |
| dismissOnImageClick | boolean | false | Allow dismissing the zoomed image by clicking on it |
Motion Presets
| Preset | Description |
|---|---|
| "smooth" | Default smooth animation |
| "snappy" | Quick, snappy transitions |
| "bouncy" | Bouncy spring animation |
| "reduced" | Reduced motion for accessibility |
Motion Configuration
For advanced users, you can provide a custom motion configuration:
<CambioImage
motion={{
trigger: "smooth",
popup: "bouncy",
backdrop: "reduced",
}}
// ... other props
/>Disabling Initial Animation
To disable the blur-to-focus animation and show images immediately:
<CambioImage
src="your-image-url"
alt="Description"
width={800}
height={600}
enableInitialAnimation={false}
/>