# ExpandedImageView Component
Displays full-size images in modal overlays with loading, error, and success states.
## Features
- **Loading State:** Purple spinner with descriptive text
- **Error State:** Clear error message with retry button
- **Success State:** Smooth fade-in transition
- **Optional Metadata:** Display filename, dimensions, and file size
- **Responsive Padding:** Adapts to mobile, tablet, and desktop
- **Accessibility:** ARIA live regions, semantic roles, keyboard support
## Props
```typescript
interface ExpandedImageViewProps {
imageUrl: string; // Required: Image URL to display
alt?: string; // Optional: Alt text (default: 'Full size view')
metadata?: { // Optional: Image metadata
filename?: string; // e.g., 'sunset_1024x768.png'
size?: string; // e.g., '2.4 MB'
dimensions?: string; // e.g., '1024 × 768'
};
showMetadata?: boolean; // Optional: Show metadata bar (default: false)
}
```
## Usage Examples
### Basic Usage
```tsx
import { ExpandedImageView } from '@/components/shared/ExpandedImageView';
export default function ImageModal({ imageUrl }: { imageUrl: string }) {
return (
);
}
```
### With Metadata
```tsx
import { ExpandedImageView } from '@/components/shared/ExpandedImageView';
export default function ImageGalleryModal({ image }: { image: Image }) {
return (
);
}
```
### In Page Provider System
```tsx
'use client';
import { useState } from 'react';
import { ExpandedImageView } from '@/components/shared/ExpandedImageView';
import { CompactFooter } from '@/components/shared/CompactFooter';
export default function ImageViewerPage() {
const [selectedImage, setSelectedImage] = useState(null);
return (
<>
{/* Gallery */}
{images.map((img) => (

setSelectedImage(img.fullUrl)}
className="cursor-pointer hover:opacity-80"
/>
))}
{/* Overlay */}
{selectedImage && (
setSelectedImage(null)}
>
)}
>
);
}
```
## Accessibility Features
### ARIA Roles
- **Loading State:** `role="status"` with `aria-live="polite"`
- **Error State:** `role="alert"` with `aria-live="assertive"`
- **Icon Elements:** `aria-hidden="true"` (decorative only)
### Keyboard Support
- Retry button is keyboard accessible (Enter/Space)
- Image click event stops propagation (prevents modal close)
- Integrates with modal close handlers (Escape key)
### Visual Design
- **Loading:** Purple spinner (`border-purple-600`) matches Banatie design
- **Error:** Red color scheme (`red-900/20`, `red-700/50`, `red-400`)
- **Image:** Shadow (`shadow-2xl`) and rounded corners (`rounded-lg`)
- **Metadata:** Subtle bar with Banatie card styling
## Layout Constraints
- **Max Image Height:** `calc(100vh - 12rem)` reserves space for nav/footer
- **Object Fit:** `object-contain` maintains aspect ratio
- **Responsive Padding:** `p-4 sm:p-6 md:p-8`
- **Metadata Wrapping:** Flexbox with `flex-wrap` for mobile
## Performance
- **Lazy State Management:** Only renders visible state (loading/error/success)
- **Event Handlers:** Optimized with direct callbacks
- **Image Loading:** Native browser lazy loading via `onLoad`/`onError`
- **Transition:** CSS-only fade animation (no JavaScript)
## Error Handling
- **Network Failures:** Catches `onerror` events
- **User Retry:** Resets state and triggers re-render
- **Clear Messaging:** Friendly error text with actionable button
- **Visual Feedback:** Icon and color coding for quick recognition