forked from 77media/video-flow
114 lines
3.7 KiB
Markdown
114 lines
3.7 KiB
Markdown
# PhotoPreviewSection Component
|
|
|
|
Compact photo preview component with type indicators for characters, scenes, and props.
|
|
|
|
## Features
|
|
|
|
✅ **Type Indicators** - Icons in bottom-left corner show photo type
|
|
✅ **Compact Design** - 64x64px photos with horizontal scroll
|
|
✅ **Smart Visibility** - Auto-hides when no photos
|
|
✅ **Preview Support** - Click to view full-size image
|
|
✅ **Delete Functionality** - X button appears on hover
|
|
✅ **Dark Theme** - Fully styled for dark UI
|
|
|
|
## Usage
|
|
|
|
```tsx
|
|
import { PhotoPreviewSection } from './PhotoPreview';
|
|
import type { PhotoItem } from './PhotoPreview';
|
|
|
|
function MyComponent() {
|
|
const [photos, setPhotos] = useState<PhotoItem[]>([
|
|
{ url: 'photo1.jpg', type: 'character', id: '1' },
|
|
{ url: 'photo2.jpg', type: 'scene', id: '2' },
|
|
{ url: 'photo3.jpg', type: 'prop', id: '3' },
|
|
]);
|
|
|
|
const handleDelete = (index: number) => {
|
|
setPhotos(prev => prev.filter((_, i) => i !== index));
|
|
};
|
|
|
|
return (
|
|
<PhotoPreviewSection
|
|
photos={photos}
|
|
onDelete={handleDelete}
|
|
/>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Props
|
|
|
|
| Prop | Type | Default | Description |
|
|
|------|------|---------|-------------|
|
|
| `photos` | `PhotoItem[]` | `[]` | Array of photos with type information |
|
|
| `onDelete` | `(index: number) => void` | optional | Callback when a photo is deleted |
|
|
| `className` | `string` | `''` | Additional CSS classes |
|
|
|
|
## Photo Types
|
|
|
|
### PhotoItem Interface
|
|
|
|
```typescript
|
|
interface PhotoItem {
|
|
url: string; // Photo URL
|
|
type: PhotoType; // 'character' | 'scene' | 'prop'
|
|
id?: string; // Optional unique identifier
|
|
}
|
|
```
|
|
|
|
### Type Icons
|
|
|
|
- **Character** (👤): `UserOutlined` - Cyan icon in bottom-left
|
|
- **Scene** (📷): `CameraOutlined` - Cyan icon in bottom-left
|
|
- **Prop** (💡): `BulbOutlined` - Cyan icon in bottom-left
|
|
|
|
## Design Specifications
|
|
|
|
- **Photo Size**: 64x64px (w-16 h-16)
|
|
- **Gap**: 8px between items
|
|
- **Border Radius**: 6px (rounded-md)
|
|
- **Type Icon**: 20x20px square, bottom-left corner with backdrop blur
|
|
- **Delete Button**: Circular gray button, top-right corner (hover only)
|
|
- **Scrollbar**: 4px height, appears on hover
|
|
|
|
## Interactions
|
|
|
|
- **Click Photo**: Opens full-screen preview modal
|
|
- **Hover Photo**: Shows delete button at top-right corner
|
|
- **Click Delete**: Triggers `onDelete` callback with photo index
|
|
- **Type Icon**: Always visible in bottom-left corner
|
|
|
|
## Visual Layout
|
|
|
|
```
|
|
┌───────────────────────────────────┐
|
|
│ ┌──────┐ ┌──────┐ ┌──────┐ │
|
|
│ │ │ │ │ │ │ │
|
|
│ │ [img]│ │ [img]│ │ [img]│ │
|
|
│ │ 👤 │ │ 📷 │ │ 💡 │ │
|
|
│ └──────┘ └──────┘ └──────┘ │
|
|
│ Char Scene Prop │
|
|
└───────────────────────────────────┘
|
|
```
|
|
|
|
- Top-right: Delete button (X) - appears on hover
|
|
- Bottom-left: Type icon - always visible
|
|
|
|
## Styling
|
|
|
|
The component uses Tailwind CSS with custom dark theme colors:
|
|
|
|
- **Primary Color**: `cyan-400` for type icons
|
|
- **Text Colors**: White with varying opacity
|
|
- **Borders**: White with 10% opacity, hover to cyan-400 with 60% opacity
|
|
- **Backgrounds**: Black/White with low opacity + backdrop blur
|
|
- **Delete Button**: Gray (`#636364`) with 80% opacity
|
|
|
|
## Notes
|
|
|
|
- Component returns `null` when `photos` array is empty
|
|
- Upload functionality should be implemented externally
|
|
- Each photo should have a unique `id` for optimal React key handling
|
|
- Preview uses antd's Image component for full-screen viewing
|