npm package: @simpledotstudio/simple-image
Description: SimpleImage - A reusable React component
Author: SimpleStudio
Latest version: 2.0.0-alpha.4

# SimpleImage

A flexible image component with loading states, fallback support, and various display options.

## Installation

```bash
npm install @simpledotstudio/simple-image
```

## Usage

```tsx
import { SimpleImage } from '@simpledotstudio/simple-image';

function App() {
  return (
    <SimpleImage
      src="/path/to/image.jpg"
      alt="Description of image"
      width={400}
      height={300}
      fallback={<div>Failed to load</div>}
    />
  );
}
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `src` | `string` | - | Image source URL (required) |
| `alt` | `string` | - | Alternative text for accessibility (required) |
| `fallback` | `React.ReactNode` | Default icon | Fallback content when image fails to load |
| `fallbackSrc` | `string` | - | Fallback image URL to try if main src fails |
| `width` | `string \| number` | - | Width of the image container |
| `height` | `string \| number` | - | Height of the image container |
| `fit` | `ImageFit` | `'cover'` | Object fit behavior (contain, cover, fill, none, scale-down) |
| `aspectRatio` | `ImageAspectRatio` | `'auto'` | Aspect ratio (auto, square, 4/3, 16/9, 21/9, 9/16, 3/4) |
| `loading` | `'eager' \| 'lazy'` | `'lazy'` | Loading strategy |
| `showSkeleton` | `boolean` | `true` | Whether to show loading skeleton |
| `rounded` | `boolean` | `false` | Whether the image should be rounded |
| `circle` | `boolean` | `false` | Whether the image should be circular |
| `radius` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Border radius size (when rounded) |
| `className` | `string` | `''` | Additional CSS class name for the image |
| `containerClassName` | `string` | `''` | Additional CSS class name for the container |
| `onLoad` | `function` | - | Called when image loads successfully |
| `onError` | `function` | - | Called when image fails to load |
| `fadeIn` | `boolean` | `true` | Whether to fade in on load |
| `onClick` | `function` | - | Click handler for the image |

## Examples

### Basic Usage

```tsx
<SimpleImage
  src="https://example.com/photo.jpg"
  alt="Example photo"
/>
```

### With Dimensions and Aspect Ratio

```tsx
// Fixed dimensions
<SimpleImage
  src="/hero-image.jpg"
  alt="Hero image"
  width={800}
  height={400}
/>

// Aspect ratio
<SimpleImage
  src="/photo.jpg"
  alt="Photo"
  aspectRatio="16/9"
  width="100%"
/>

// Square image
<SimpleImage
  src="/avatar.jpg"
  alt="User avatar"
  aspectRatio="square"
  width={200}
/>
```

### Object Fit Options

```tsx
<SimpleImage
  src="/banner.jpg"
  alt="Banner"
  fit="cover"  // Default - covers entire container
  aspectRatio="21/9"
/>

<SimpleImage
  src="/logo.png"
  alt="Logo"
  fit="contain"  // Maintains aspect ratio within container
  width={200}
  height={100}
/>
```

### Shape Variants

```tsx
// Circular image (perfect for avatars)
<SimpleImage
  src="/avatar.jpg"
  alt="User avatar"
  circle
  width={100}
  height={100}
/>

// Rounded corners
<SimpleImage
  src="/card-image.jpg"
  alt="Card image"
  rounded
  radius="lg"
/>
```

### Loading States

```tsx
// With skeleton loader (default)
<SimpleImage
  src="/slow-loading.jpg"
  alt="Slow loading image"
  showSkeleton
/>

// Without skeleton loader
<SimpleImage
  src="/fast-loading.jpg"
  alt="Fast loading image"
  showSkeleton={false}
/>

// Eager loading for above-the-fold images
<SimpleImage
  src="/hero.jpg"
  alt="Hero image"
  loading="eager"
/>
```

### Error Handling

```tsx
// With custom fallback content
<SimpleImage
  src="/might-fail.jpg"
  alt="Image that might fail"
  fallback={
    <div style={{ padding: '2rem', textAlign: 'center' }}>
      <p>Unable to load image</p>
      <button>Retry</button>
    </div>
  }
/>

// With fallback image
<SimpleImage
  src="/primary-image.jpg"
  alt="Product photo"
  fallbackSrc="/placeholder.jpg"
/>

// Handle load/error events
<SimpleImage
  src="/tracked-image.jpg"
  alt="Tracked image"
  onLoad={() => console.log('Image loaded successfully')}
  onError={() => console.log('Image failed to load')}
/>
```

### Interactive Images

```tsx
// Clickable image with proper accessibility
<SimpleImage
  src="/clickable.jpg"
  alt="Click to enlarge"
  onClick={(e) => console.log('Image clicked')}
  style={{ cursor: 'pointer' }}
/>

// Image gallery item
<SimpleImage
  src="/gallery-item.jpg"
  alt="Gallery item"
  onClick={() => openLightbox()}
  rounded
  fadeIn
/>
```

### Advanced Examples

```tsx
// Product image with all features
<SimpleImage
  src={product.imageUrl}
  alt={product.name}
  fallbackSrc="/product-placeholder.jpg"
  aspectRatio="4/3"
  fit="contain"
  rounded
  radius="md"
  fadeIn
  loading="lazy"
  onClick={() => setShowZoom(true)}
  className="product-image"
  containerClassName="product-image-container"
/>

// Avatar with fallback
<SimpleImage
  src={user.avatarUrl}
  alt={`${user.name}'s avatar`}
  fallback={
    <div className="avatar-fallback">
      {user.name.charAt(0)}
    </div>
  }
  circle
  width={60}
  height={60}
/>

// Hero banner with specific handling
<SimpleImage
  src="/hero-banner.jpg"
  alt="Welcome to our site"
  aspectRatio="21/9"
  fit="cover"
  loading="eager"
  showSkeleton
  fadeIn={false}  // No fade for hero images
  onLoad={() => setHeroLoaded(true)}
/>
```

## Default Fallback

When an image fails to load and no custom fallback is provided, the component displays a default fallback with:
- A subtle image icon
- The alt text as a caption
- Proper styling to match your design

## TypeScript

The component exports the following types:

```typescript
import type {
  SimpleImageProps,
  ImageFit,
  ImageAspectRatio,
  ImageLoadingStrategy
} from '@simpledotstudio/simple-image';
```

## Styling

The component uses CSS modules for styling. You can override styles by:
- Passing a custom `className` for the image element
- Passing a custom `containerClassName` for the container
- Targeting the component's CSS classes in your global styles

## Accessibility

- Always provide meaningful `alt` text
- When using `onClick`, the component automatically adds `role="button"` and `tabIndex={0}`
- The component maintains proper aspect ratios to prevent layout shift

## Performance

- Lazy loading is enabled by default
- Images fade in smoothly when loaded (can be disabled)
- Skeleton loader provides visual feedback during loading
- Prevents layout shift with proper aspect ratio handling

## Development

To run the component in development mode:

```bash
npm run storybook
```

To run tests:

```bash
npm run test
```

To lint the component:

```bash
npm run lint
```