npm package: @pagedotapp/page-media-preview
Description: PageMediaPreview - A reusable React component
Author: PageStudio
Latest version: 0.0.0-alpha.14

# PageMediaPreview

A versatile media preview component that supports images, videos, and audio files with custom playback controls.

## Installation

```bash
npm install @pagedotapp/page-media-preview
```

## Usage

```tsx
import { PageMediaPreview } from '@pagedotapp/page-media-preview';

// Image preview
<PageMediaPreview
  src="image.jpg"
  alt="Mountain landscape"
/>

// Video with controls
<PageMediaPreview
  src="video.mp4"
  alt="Demo video"
  thumbnail="poster.jpg"
/>

// Audio with thumbnail
<PageMediaPreview
  src="audio.mp3"
  alt="My favorite song"
  thumbnail="album-cover.jpg"
/>

// File upload preview
<PageMediaPreview
  src={fileObject}
  alt={fileObject.name}
/>
```

## Props

| Prop                | Type                                           | Default           | Description                                           |
| ------------------- | ---------------------------------------------- | ----------------- | ----------------------------------------------------- |
| `src`               | `string \| File`                               | -                 | The media source URL or File object (required)        |
| `alt`               | `string`                                       | `'Media preview'` | Alternative text for images or display name for audio |
| `type`              | `'image' \| 'video' \| 'audio' \| 'unknown'`   | Auto-detected     | Type of media                                         |
| `controls`          | `boolean`                                      | `true`            | Show controls for video/audio                         |
| `autoplay`          | `boolean`                                      | `false`           | Autoplay video/audio (muted for video)                |
| `loop`              | `boolean`                                      | `false`           | Loop video/audio playback                             |
| `thumbnail`         | `string`                                       | -                 | Thumbnail URL for video/audio                         |
| `aspectRatio`       | `'16/9' \| '4/3' \| '1/1' \| '9/16' \| 'auto'` | `'auto'`          | Aspect ratio for responsive sizing                    |
| `width`             | `number \| string`                             | -                 | Width of the media container                          |
| `height`            | `number \| string`                             | -                 | Height of the media container                         |
| `loading`           | `boolean`                                      | `false`           | Show loading state                                    |
| `className`         | `string`                                       | `''`              | Additional CSS class name                             |
| `onError`           | `(error: Error) => void`                       | -                 | Error handler                                         |
| `onClick`           | `() => void`                                   | -                 | Click handler                                         |
| `onPlayStateChange` | `(playing: boolean) => void`                   | -                 | Play state change handler                             |

## Features

### Auto-Detection

The component automatically detects media type from:

- File extensions (`.jpg`, `.mp4`, `.mp3`, etc.)
- MIME types for File objects
- Can be overridden with the `type` prop

### Image Support

- Displays images with proper aspect ratio
- Loading and error states
- Click handling

### Video Features

- Custom play/pause button with PageIconButton
- Time display (current/duration)
- Thumbnail/poster support
- Autoplay and loop options
- Muted autoplay for browser compatibility

### Audio Features

- Custom play/pause controls
- Album art/thumbnail display
- Time tracking
- Compact player design

### File Upload

- Direct support for File objects
- Automatic cleanup of object URLs
- Preview before upload

## Examples

### Basic Image

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

### Video with Custom Size

```tsx
<PageMediaPreview src="video.mp4" aspectRatio="16/9" width={800} />
```

### Audio Player

```tsx
<PageMediaPreview
	src="podcast.mp3"
	alt="Episode 42: React Patterns"
	thumbnail="podcast-cover.jpg"
/>
```

### File Upload with Preview

```tsx
const [file, setFile] = useState(null)

;<input
	type="file"
	accept="image/*,video/*,audio/*"
	onChange={(e) => setFile(e.target.files[0])}
/>

{
	file && <PageMediaPreview src={file} alt={file.name} />
}
```

### Gallery Layout

```tsx
<div
	style={{
		display: "grid",
		gridTemplateColumns: "repeat(3, 1fr)",
		gap: "16px",
	}}
>
	<PageMediaPreview src="photo1.jpg" aspectRatio="1/1" />
	<PageMediaPreview src="video.mp4" aspectRatio="1/1" />
	<PageMediaPreview src="audio.mp3" aspectRatio="1/1" />
</div>
```

### With Event Handlers

```tsx
<PageMediaPreview
	src="video.mp4"
	onPlayStateChange={(playing) => {
		console.log(playing ? "Playing" : "Paused")
	}}
	onError={(error) => {
		console.error("Media failed to load:", error)
	}}
	onClick={() => {
		console.log("Media clicked")
	}}
/>
```

## Styling

The component uses CSS modules with customizable CSS variables:

```css
/* Available CSS variables */
--color-background: #f5f5f5;
--color-error-light: #fef2f2;
--radius-medium: 8px;
--spacing-small: 8px;
--spacing-medium: 16px;
--spacing-large: 24px;
--font-size-small: 14px;
```

## Browser Support

- Modern browsers with ES6 support
- File API for file uploads
- HTML5 video/audio elements

## Dependencies

- `@pagedotapp/page-image` - For image display
- `@pagedotapp/page-icon-button` - For playback controls
- `@pagedotapp/page-loader` - For loading states
- `@pagedotapp/page-text` - For text display

## 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
```