2025-10-17 20:32:10 +08:00

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