Amplify UI

DropZone

The Dropzone component captures files from user with drag and drop

Usage

The DropZone component adds the necessary event handlers to an element and filters dropped files by file type. To get the files after they are dropped you can use the onDropComplete prop which is a function that has files and rejectedFiles arrays.

Drag images here
import * as React from 'react';
import { DropZone, Text } from '@aws-amplify/ui-react';

export default function DefaultDropZoneExample() {
  const [files, setFiles] = React.useState([]);
  return (
    <>
      <DropZone
        onDropComplete={({ acceptedFiles, rejectedFiles }) => {
          setFiles(acceptedFiles);
        }}
      >
        Drag images here
      </DropZone>
      {files.map((file) => (
        <Text key={file.name}>{file.name}</Text>
      ))}
    </>
  );
}

Disabled

Add an isDisabled prop to DropZone to make it disabled. Disabling the DropZone will remove any drag/drop handlers and style the DropZone so it looks disabled.

Drag images here
import { DropZone } from '@aws-amplify/ui-react';

export default function DisabledDropZoneExample() {
  return (
    <DropZone
      isDisabled
      onDropComplete={({ acceptedFiles }) => {
        console.log(acceptedFiles);
      }}
    >
      Drag images here
    </DropZone>
  );
}

Accepted and Rejected files

DropZone.Accept, DropZone.Reject and DropZone.Default are helper components that render at different times:

  • DropZone.Accept is visible when the user drags files that are all acceptable based on the acceptedFileTypes prop
  • Dropzone.Reject is visible when the user drags files that any are not acceptable based on the acceptedFileTypes prop.
  • DropZone.Default is the default state, visible when there is no drag interaction on the DropZone.

All of these helper components are mutually exclusive and cover all possible states. If the user is dragging files over the element the files will either be all acceptable or not.

Drag images here

import { DropZone, Flex, Text } from '@aws-amplify/ui-react';
import { MdCheckCircle, MdFileUpload, MdRemoveCircle } from 'react-icons/md';

export default function DefaultDropZoneExample() {
  return (
    <DropZone
      acceptedFileTypes={['image/*']}
      onDropComplete={({ acceptedFiles }) => {
        console.log(acceptedFiles);
      }}
    >
      <Flex direction="row" justifyContent="center" alignItems="center">
        <DropZone.Accepted>
          <MdCheckCircle fontSize="2rem" />
        </DropZone.Accepted>
        <DropZone.Rejected>
          <MdRemoveCircle fontSize="2rem" />
        </DropZone.Rejected>
        <DropZone.Default>
          <MdFileUpload fontSize="2rem" />
        </DropZone.Default>
        <Text>Drag images here</Text>
      </Flex>
    </DropZone>
  );
}

Opening the file picker

You can add a button to open the file picker by adding a hidden input and firing the click event on the input element. Using an input element will automatically disable selecting files that don't match the accepted file types.

Drag images here or

import * as React from 'react';
import {
  Button,
  DropZone,
  Flex,
  Text,
  VisuallyHidden,
} from '@aws-amplify/ui-react';

const acceptedFileTypes = ['image/png', 'image/jpeg'];

export default function DropZoneInputExample() {
  const [files, setFiles] = React.useState([]);
  const hiddenInput = React.useRef(null);

  const onFilePickerChange = (event) => {
    const { files } = event.target;
    if (!files || files.length === 0) {
      return;
    }
    setFiles(Array.from(files));
  };

  return (
    <>
      <DropZone
        acceptedFileTypes={acceptedFileTypes}
        onDropComplete={({ acceptedFiles, rejectedFiles }) => {
          setFiles(acceptedFiles);
        }}
      >
        <Flex direction="column" alignItems="center">
          <Text>Drag images here or</Text>
          <Button size="small" onClick={() => hiddenInput.current.click()}>
            Browse
          </Button>
        </Flex>
        <VisuallyHidden>
          <input
            type="file"
            tabIndex={-1}
            ref={hiddenInput}
            onChange={onFilePickerChange}
            multiple={true}
            accept={acceptedFileTypes.join(',')}
          />
        </VisuallyHidden>
      </DropZone>
      {files.map((file) => (
        <Text key={file.name}>{file.name}</Text>
      ))}
    </>
  );
}

Styling

Theme

You can customize the appearance of all DropZone components in your application with a Theme.

DropZone Theme Source

Drag images here
import { DropZone, ThemeProvider, createTheme } from '@aws-amplify/ui-react';

const theme = createTheme({
  name: 'dropzone-theme',
  tokens: {
    components: {
      dropzone: {
        backgroundColor: '{colors.primary.10}',
        borderColor: '{colors.primary.80}',
      },
    },
  },
});

export default function DropZoneThemeExample() {
  return (
    <ThemeProvider theme={theme}>
      <DropZone
        onDropComplete={({ acceptedFiles }) => {
          console.log(acceptedFiles);
        }}
      >
        Drag images here
      </DropZone>
    </ThemeProvider>
  );
}

Target classes

ClassDescription
amplify-dropzoneClass applied to the DropZone component
  • --amplify-components-dropzone-accepted-background-color
  • --amplify-components-dropzone-accepted-border-color
  • --amplify-components-dropzone-accepted-border-radius
  • --amplify-components-dropzone-accepted-border-style
  • --amplify-components-dropzone-accepted-border-width
  • --amplify-components-dropzone-accepted-color
  • --amplify-components-dropzone-active-background-color
  • --amplify-components-dropzone-active-border-color
  • --amplify-components-dropzone-active-border-radius
  • --amplify-components-dropzone-active-border-style
  • --amplify-components-dropzone-active-border-width
  • --amplify-components-dropzone-active-color
  • --amplify-components-dropzone-background-color
  • --amplify-components-dropzone-border-color
  • --amplify-components-dropzone-border-radius
  • --amplify-components-dropzone-border-style
  • --amplify-components-dropzone-border-width
  • --amplify-components-dropzone-color
  • --amplify-components-dropzone-disabled-background-color
  • --amplify-components-dropzone-disabled-border-color
  • --amplify-components-dropzone-disabled-border-radius
  • --amplify-components-dropzone-disabled-border-style
  • --amplify-components-dropzone-disabled-border-width
  • --amplify-components-dropzone-disabled-color
  • --amplify-components-dropzone-gap
  • --amplify-components-dropzone-padding-block
  • --amplify-components-dropzone-padding-inline
  • --amplify-components-dropzone-rejected-background-color
  • --amplify-components-dropzone-rejected-border-color
  • --amplify-components-dropzone-rejected-border-radius
  • --amplify-components-dropzone-rejected-border-style
  • --amplify-components-dropzone-rejected-border-width
  • --amplify-components-dropzone-rejected-color
  • --amplify-components-dropzone-text-align

Global styling

To override styling on all Breadcrumbs components, you can set Amplify CSS variables or use the target classes like .amplify-dropzone class.

/* styles.css */
.amplify-dropzone {
  background-color: pink;
}

Local styling

To override styling on a specific DropZone component or sub-component, you can use (in order of increasing specificity): a class selector and style props.

Using a class selector:

<DropZone className="my-dropzone">
</DropZone>
/* styles.css */
.my-dropzone {
   background-color: pink;
}

Using style props:

Drag images here
import { DropZone } from '@aws-amplify/ui-react';

export default function DropZoneStyleExample() {
  return (
    <DropZone
      onDropComplete={({ acceptedFiles }) => {
        console.log(acceptedFiles);
      }}
      borderWidth="4px"
      borderColor="red"
    >
      Drag images here
    </DropZone>
  );
}

Amplify open source software, documentation and community are supported by Amazon Web Services.

© 2024 Amazon Web Services, Inc. and its affiliates. All rights reserved. View the site terms and privacy policy.

Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.