laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
143 lines (117 loc) • 6.75 kB
Markdown
# FilePreview
## Overview
Compact file chip with name, format/size info, optional remove button, and optional action menu (preview/download/remove). Automatically adapts its preview based on file type (image, text, generic).
---
## Props
| Prop | Type | Default | Description |
| ---------------- | ------------------------------------------------------------------------------------ | ------------ | --------------------------------------------------------------------------------------------------------------- |
| `file` | `File \| { name: string; url: string; type?: string }` | **required** | File object or remote descriptor with `url`. |
| `clickable` | `boolean` | `true` | Whether the chip container is interactive (click/keyboard). |
| `onClick` | `(event: React.MouseEvent \| React.KeyboardEvent) => void \| Promise<void> \| false` | `undefined` | Optional container click handler. Takes precedence over `onPreview`. Not allowed when `showActionMenu` is true. |
| `onRemove` | `(url: string) => void \| Promise<void>` | `undefined` | Called when user removes the file. |
| `onPreview` | `(url: string) => void \| Promise<void>` | `undefined` | Called when user clicks Preview from the action menu. |
| `onDownload` | `(url: string) => void \| Promise<void>` | `undefined` | Called when user clicks Download from the action menu. |
| `showActionMenu` | `boolean` | `false` | Show overflow menu (Preview/Download/Delete if provided). |
| `showThumbnail` | `boolean` | `true` | Controls whether a thumbnail/text preview is rendered when available. |
| `variant` | `"default" \| "outline" \| "ghost"` | `"default"` | Visual style of the chip container. |
| `size` | `"default" \| "sm"` | `"default"` | Visual size of the chip container and its internal elements. |
| `className` | `string` | `""` | Additional classes for the wrapper. |
---
## Behavior
- **Automatic preview**:
- Images: thumbnail preview (falls back to an icon if the image cannot be loaded).
- Text: small snippet (first 100 chars) only when `file` is a native `File`.
- Generic: file-type icon and labels.
- **Format & size**: Displays file size (if available) and format label (e.g., PDF, JPG).
- **Actions**:
- Inline remove button if `onRemove` is provided and `showActionMenu` is false.
- Popover action menu when `showActionMenu` is true, using `onPreview`, `onDownload`, `onRemove`.
- **Container click**:
- If `clickable` is `false`, the container is not interactive.
- If `onClick` is provided, it takes precedence over `onPreview` when the container is activated.
- Otherwise, if `onPreview` is provided, it is used when the container is activated.
- When `showActionMenu` is `true`, `clickable` and `onClick` props are not allowed.
- **Thumbnails**:
- Images: if `showThumbnail` is `false`, an icon is shown instead of the image.
- Text: if `showThumbnail` is `false` (or a preview can't be extracted), an icon is shown instead of the text snippet.
---
## Examples
### Image
```tsx
import { FilePreview } from "laif-ds";
export function ImagePreview() {
return (
<FilePreview
file={{
name: "photo.jpg",
url: "https://picsum.photos/id/237/200/200",
type: "image/jpeg",
}}
onPreview={(url) => console.log("preview", url)}
onDownload={(url) => console.log("download", url)}
/>
);
}
```
### With Remove Button
```tsx
import { FilePreview } from "laif-ds";
export function RemovablePreview() {
return (
<FilePreview
file={{
name: "document.docx",
url: "https://example.com/document.docx",
type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
}}
onRemove={(url) => console.log("remove", url)}
onPreview={(url) => console.log("preview", url)}
onDownload={(url) => console.log("download", url)}
/>
);
}
```
### With Action Menu
```tsx
import { FilePreview } from "laif-ds";
export function WithMenu() {
return (
<FilePreview
file={{
name: "presentation.ppt",
url: "https://example.com/presentation.ppt",
type: "application/vnd.ms-powerpoint",
}}
showActionMenu
onPreview={(url) => console.log("preview", url)}
onDownload={(url) => console.log("download", url)}
onRemove={(url) => console.log("remove", url)}
/>
);
}
```
### With Custom Click Handler
```tsx
import { FilePreview } from "laif-ds";
export function CustomClick() {
return (
<FilePreview
file={{
name: "document.pdf",
url: "https://example.com/document.pdf",
type: "application/pdf",
}}
variant="outline"
size="sm"
onClick={(event) => console.log("custom click handler", event)}
onRemove={(url) => console.log("remove", url)}
/>
);
}
```
---
## Notes
- **Thumbnails**: Image previews use object-fit to contain within the chip.
- **Security**: For local `File` previews, temporary object URLs are created and revoked on unmount/change.
- **Internationalization**: Text labels in the action menu can be adjusted at call sites when needed.
- **Async support**: All callback functions (`onClick`, `onRemove`, `onPreview`, `onDownload`) support async operations and can return Promise<void>.