# 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