laif-ds
Version:
Design System di Laif con componenti React basati su principi di Atomic Design
130 lines (99 loc) • 5.14 kB
Markdown
Drag-and-drop uploader with keyboard activation, file type filtering, limits (count/total size), previews via `FilePreview`, and external upload integration.
---
| Prop | Type | Default | Description |
| ------------------ | --------------------------------------- | --------------------------------------------------------- | ---------------------------------------------------------- |
| `extensions` | `AcceptItem[]` | `["pdf","image","video","audio"]` | Allowed extensions/categories (maps to accept attribute). |
| `multiple` | `boolean` | `false` | Enables multiple file selection. |
| `onUpload` | `(files: File[]) => void` | `undefined` | Called whenever selected files change. |
| `description` | `string` | `"Trascina un file o clicca per selezionare"` | Dropzone hint. |
| `formatDescription`| `string` | `"Formato accettato: PDF, Immagini, Video, Audio"` | Accepted formats hint. |
| `selectedLabel` | `string` | `"File selezionati"` | Title shown above selected files list. |
| `removeAllLabel` | `string` | `"rimuovi tutto"` | Label for the "remove all" button. |
| `maxTotalSize` | `number` (bytes) | `undefined` | Maximum total size of selected files. |
| `maxFiles` | `number` | `undefined` | Maximum number of files (when `multiple` is true). |
`AcceptItem` includes: `pdf | doc | docx | xls | xlsx | ppt | pptx | txt | csv | jpg | jpeg | png | gif | image | video | audio`.
---
## Behavior
- **Dropzone**: Click or drag files; keyboard accessible (Enter/Space opens file dialog).
- **Filtering**: `extensions` map to accept string; only matching files are added.
- **Limits**: Enforces `maxFiles` and `maxTotalSize` (with compact error caption).
- **Previews**: Renders selected files with `FilePreview`; supports remove per file and remove-all.
- **Integration**: `onUpload` provides the current `File[]`; perform the actual upload externally.
---
```tsx
import { FileUploader } from "laif-ds";
export function DefaultUploader() {
return <FileUploader multiple={false} />;
}
```
```tsx
import { FileUploader, type AcceptItem } from "laif-ds";
const exts: AcceptItem[] = [
"pdf","doc","docx","xls","xlsx","ppt","pptx","txt","csv","jpg","jpeg","png","gif","image","video","audio",
];
export function MultiUploader() {
return (
<FileUploader
multiple
extensions={exts}
description="Seleziona più file"
formatDescription="Trascina o clicca per selezionare più file"
/>
);
}
```
```tsx
import { FileUploader } from "laif-ds";
export function LimitedUploader() {
return (
<FileUploader
multiple
maxFiles={3}
maxTotalSize={10 * 1024 * 1024} // 10 MB
description="Con limiti su numero e dimensione totale"
formatDescription="Esempio: max 3 file, max totale 10 MB"
/>
);
}
```
```tsx
import * as React from "react";
import { Button } from "laif-ds";
import { FileUploader } from "laif-ds";
export function ExternalUploadExample() {
const [files, setFiles] = React.useState<File[]>([]);
const [loading, setLoading] = React.useState(false);
const handleSubmit = async () => {
setLoading(true);
// ...upload files
await new Promise((r) => setTimeout(r, 1500));
setLoading(false);
alert(`Upload completato: ${files.length} file`);
};
return (
<div className="space-y-4">
<FileUploader multiple onUpload={setFiles} />
{files.length > 0 && (
<div className="flex justify-end">
<Button onClick={handleSubmit} isLoading={loading} iconLeft="Upload">
{loading ? "Caricamento..." : `Carica ${files.length} file`}
</Button>
</div>
)}
</div>
);
}
```
---
- **A11y**: Dropzone is a button-like region with `aria-describedby` hints and keyboard support.
- **Errors**: Limit violations are summarized in a compact caption.
- **Localization**: Provide localized `description`/`formatDescription`/labels when needed.