# File Upload

> Drag-and-drop uploader whose dashed border marches on dragover; files slide in with spring progress bars, oversized files show an error and shake the zone, and rows exit sideways when removed.

- Collection: Blocks
- Tier: pro
- Docs: https://geturui.com/docs/file-upload
- Install: `npx shadcn@latest add @geturui-pro/file-upload`
- Dependencies: motion, lucide-react

## Usage

```tsx
"use client";
import * as React from "react";
import { FileUpload, type UploadFile } from "@/components/blocks/file-upload";

export function Attachments() {
  const [files, setFiles] = React.useState<UploadFile[]>([]);
  return (
    <FileUpload
      files={files}
      maxSize={25 * 1024 * 1024}
      accept="image/*,.pdf"
      onFilesAdded={(added) => {
        // start your uploads here and update progress in `files`
        setFiles((cur) => [...added.map((f) => ({ id: f.name, name: f.name, size: f.size, progress: 0, status: "uploading" as const })), ...cur]);
      }}
      onRemove={(id) => setFiles((cur) => cur.filter((f) => f.id !== id))}
    />
  );
}
```

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| files | `UploadFile[]` | — | Controlled list { id, name, size, progress, status, error? }. When set, the parent owns progress. |
| defaultFiles | `UploadFile[]` | [] | Initial list when uncontrolled. |
| simulate | `boolean` | true | Uncontrolled only: fake upload progress so the block works standalone. |
| onFilesAdded | `(files: File[]) => void` | — | Accepted files from a drop or the picker. |
| onRemove | `(id: string) => void` | — | A row's remove/cancel button was pressed. |
| onReject | `(file: File, reason: string) => void` | — | A file exceeded maxSize. |
| maxSize | `number` | 10485760 | Max bytes per file (10 MB). |
| accept | `string` | — | Passed to the file input. |
| multiple | `boolean` | true | Allow several files at once. |
| label / hint | `string` | — | Drop-zone copy. |

## Accessibility

- The drop zone is a focusable button: Enter or Space opens the file picker, so dragging is never required.
- Each upload has a labelled progressbar with aria-valuenow; errors pair a danger colour with an icon and message.
- Remove buttons name the file ("Cancel upload of report.pdf"); the upload count is announced politely.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
