# Dropzone

<FrameworkCodeSwitcher>
  <div slot="astro">
```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<div class="w-full max-w-[400px]">
  <Dropzone />
</div>
```
  </div>
  <div slot="react">
```tsx
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";

export function Example() {
  return (
    <div className="w-full max-w-[400px]">
      <Dropzone />
    </div>
  );
}
```
  </div>
</FrameworkCodeSwitcher>

## Installation

```bash
npx starwind@latest add dropzone
```

## Usage

> **Info:** No dropped files on this page are uploaded anywhere.

### Default

The default Dropzone component displays a cloud upload icon with a prompt to upload files, and shows what files have been selected.

```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<Dropzone />
```

### Custom Content

The dropzone components can be customized through slots. The default `<Dropzone />` component has the following three components in the slot if nothing is passed:

```astro
<DropzoneUploadIndicator />
<DropzoneLoadingIndicator />
<DropzoneFilesList />
```

The `DropzoneUploadIndicator` and `DropzoneLoadingIndicator` each have their own slots to customize the upload and loading indicators. The `DropzoneFilesList` component can be passed any classes to use.

```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<Dropzone>
  <DropzoneUploadIndicator>
    <span class="my-6 text-lg">Your specific message</span>
  </DropzoneUploadIndicator>
  <DropzoneLoadingIndicator />
  <DropzoneFilesList />
</Dropzone>
```

### Loading

Nothing is actually uploaded when a file is selected, as internally a standard html `<input type="file">` is used. To show a loading indication initially, you can use the `isUploading` prop.

```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<Dropzone isUploading={true} />
```

You can also use the `data-is-uploading` attribute to show or hide a loading indicator at any time. This is useful if you want to show a loading indicator while a file is actually being uploaded (like on form submission).

```astro
---
import { Button } from "@/components/starwind/button";
import {
  Dropzone,
  DropzoneFilesList,
  DropzoneLoadingIndicator,
  DropzoneUploadIndicator,
} from "@/components/starwind/dropzone";
---

<div class="flex w-full max-w-[400px] flex-col gap-4">
  <form id="dropzone-form-demo" class="space-y-4">
    <Dropzone id="my-dropzone" name="dropzone-file" />
    <Button type="submit" class="w-full">Submit</Button>
  </form>
</div>

<script>
  function handleFormSubmit() {
    const form = document.querySelector("#dropzone-form-demo") as HTMLFormElement;
    const dropzone = document.querySelector("#my-dropzone") as HTMLElement;
    if (form) {
      form.addEventListener("submit", (e) => {
        e.preventDefault();

        dropzone.setAttribute("data-is-uploading", "true");

        const formData = new FormData(form);
        const formValues = Object.fromEntries(formData.entries());

        // demo form data logging
        console.log("Form submission values:", formValues);

        // You can add additional logic here like:
        // - Form validation
        // - API submission
        // - Success/error handling

        // Simulate API submission
        setTimeout(() => {
          dropzone.setAttribute("data-is-uploading", "false");
        }, 2000);
      });
    }
  }

  handleFormSubmit();

  document.addEventListener("astro:after-swap", handleFormSubmit);
</script>

```

### Accept Specific File Types

You can limit the types of files that users can select by using the `accept` attribute.

```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<Dropzone accept="image/*" />
```

### Multiple Files

Allow users to select multiple files by using the `multiple` attribute.

```astro
---
import { Dropzone, DropzoneFilesList, DropzoneLoadingIndicator, DropzoneUploadIndicator } from "@/components/starwind/dropzone";
---

<Dropzone multiple />
```

## Framework Availability
Dropzone is available for Astro and React.
Astro available; React available
| Framework | Status | Notes |
| --- | --- | --- |
| Astro | available | - |
| React | available | - |
## API Reference
### Dropzone
- Inherits input attributes. Omits `disabled` and `type`.

### DropzoneUploadIndicator
- Inherits div attributes.

### DropzoneLoadingIndicator
- Inherits div attributes.

### DropzoneFilesList
- Inherits div attributes.
### Primitive And Runtime API
Behavior, state, events, form participation, and imperative methods are documented in the lower-level references.
- Primitive: [Dropzone Primitive](/docs/primitives/dropzone/)
- Runtime factory: [`createDropzone`](/docs/runtime/#create-dropzone) from `@starwind-ui/runtime/dropzone`

## Changelog

### v2.0.0

- Rebuilt Dropzone on Starwind Runtime for drag-and-drop, file input, and component state handling.
- See the [Dropzone Primitive](/docs/primitives/dropzone/) for the underlying unstyled anatomy and behavior API.