# FileDropZone

Die FileDropZone ermöglicht das Hochladen von Dateien per Drag-and-Drop oder durch manuelle Auswahl.

```tsx
import {
  Button,
  FileDropZone,
  FileField,
  Heading,
  IconUpload,
  Section,
} from "@mittwald/flow-react-components";

<Section>
  <FileDropZone onChange={(files) => console.log(files)}>
    <IconUpload />
    <Heading>Datei ablegen</Heading>
    <FileField>
      <Button>Datei auswählen</Button>
    </FileField>
  </FileDropZone>
</Section>
```

---

# Best Practices

- Biete immer eine alternative Upload-Möglichkeit über einen
  [Button](/04-components/actions/button).
- Kommuniziere zulässige Dateitypen und mögliche Größenbeschränkungen deutlich.
- Formuliere
  [Fehlermeldungen](/02-foundations/03-content-guidelines/03-fehlermeldungen)
  klar und hilfreich.

---

# Vorgegebene Dateitypen

Verwende `<Text />`, um den User über erlaubte Dateitypen und maximale
Dateigrößen beim Hochladen zu informieren.

```tsx
import {
  Button,
  FileDropZone,
  FileField,
  Heading,
  IconImage,
  Section,
  Text,
} from "@mittwald/flow-react-components";

<Section>
  <FileDropZone
    accept="image/png"
    onChange={(files) => console.log(files)}
  >
    <IconImage />
    <Heading>Bild ablegen</Heading>
    <Text>
      Es sind nur Bilder vom Typ image/png erlaubt.
    </Text>
    <FileField>
      <Button>Bild auswählen</Button>
    </FileField>
  </FileDropZone>
</Section>
```

---

# Mehrere Dateien

Über die Property `multiple` wird das gleichzeitige Hochladen mehrerer Dateien
ermöglicht. Beim erneuten Hochladen werden bestehende Dateien ersetzt. Ein
Beispiel für das Hochladen und Verwalten mehrerer Dateien findest du im
Codesnippet [Multi Upload](/03-patterns/02-codesnippets/multi-upload).

```tsx
import {
  Button,
  FileDropZone,
  FileField,
  Heading,
  IconUpload,
  Section,
} from "@mittwald/flow-react-components";

<Section>
  <FileDropZone
    multiple
    onChange={(files) => console.log(files)}
  >
    <IconUpload />
    <Heading>Dateien ablegen</Heading>
    <FileField>
      <Button>Dateien auswählen</Button>
    </FileField>
  </FileDropZone>
</Section>
```

---

# Kombiniere mit ...

## FileCardList

Stelle die hochgeladenen Dateien übersichtlich mit einer
[FileCardList](/04-components/upload/file-card-list) dar – für eine einzelne
Datei genügt eine [FileCard](/04-components/upload/file-card).

```tsx
import {
  Button,
  FileCard,
  FileCardList,
  FileDropZone,
  FileField,
  Heading,
  IconUpload,
  Section,
} from "@mittwald/flow-react-components";
import { useState } from "react";

export default () => {
  const [files, setFiles] = useState<File[]>([]);

  return (
    <Section>
      <FileDropZone
        multiple
        onChange={(value) => {
          if (value) {
            setFiles([...files, ...value]);
          }
        }}
      >
        <IconUpload />
        <Heading>Dateien ablegen</Heading>
        <FileField>
          <Button>Dateien auswählen</Button>
        </FileField>
      </FileDropZone>

      <FileCardList>
        {files.map((file) => (
          <FileCard
            name={file.name}
            type={file.type}
            key={file.name}
            sizeInBytes={file.size}
            onDelete={() =>
              setFiles(
                files.filter((watched) => watched !== file),
              )
            }
          />
        ))}
      </FileCardList>
    </Section>
  );
}
```

---

# Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `isReadOnly` | `boolean` | - | Whether the component is read only. |
| `className` | `string` | - | The elements class name. |
| `wrapWith` | `ReactElement<unknown, string \| JSXElementConstructor<any>>` | - | A React element the component is wrapped with. The element is cloned and receives the component as its only child — useful to render the component inside a link, a tooltip trigger or any other wrapper without changing the surrounding markup. |
| `ref` | `Ref<HTMLSpanElement>` | - | Allows getting a ref to the component instance. Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref). @see [React Docs](https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom) |
| `key` | `Key` | - | - |
| `children` | `ReactNode` | - | - |
| `name` | `string` | - | - |
| `accept` | `string` | - | - |
| `multiple` | `boolean` | - | - |
| `isDisabled` | `boolean` | - | Whether the drop target is disabled. If true, the drop target will not accept any drops. |

### Events

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `onChange` | `FileInputOnChangeHandler` | - | Called with the dropped or selected files whenever the selection changes. |

