A drop zone is an area into which one or multiple objects can be dragged and dropped.
Theme
Drop or paste text or images here
Example
DropZone.tsx
DropZone.css
Example
DropZone.tsx
DropZone.css
import {DropZone, Text} from './DropZone';
import {useState} from 'react';
import React from 'react';
function Example() {
let [content, setContent] = useState<string | React.ReactElement | null>(null);
return (
<DropZone
// Determine whether dragged content should be accepted.
getDropOperation={types => (
['text/plain', 'image/jpeg', 'image/png', 'image.gif'].some(t => types.has(t))
? 'copy'
: 'cancel'
)}
onDrop={async (event) => {
// Find the first accepted item.
let item = event.items.find(item => (
(item.kind === 'text' && item.types.has('text/plain')) ||
(item.kind === 'file' && item.type.startsWith('image/'))
));
if (item?.kind === 'text') {
let text = await item.getText('text/plain');
setContent(text);
} else if (item?.kind === 'file') {
let file = await item.getFile();
let url = URL.createObjectURL(file);
setContent(<img src={url} alt={item.name} style={{maxHeight: 100, maxWidth: '100%'}} />)
}
}}>
<Text slot="label">
{content || "Drop or paste text or images here"}
</Text>
</DropZone>
);
}
FileTrigger
To allow the selection of files from the user's device, pass FileTrigger as a child of DropZone.
Drop files here, or click Browse
import {DropZone, Text} from './DropZone';
import {FileTrigger} from 'react-aria-components';
import {Button} from './Button';
import {useState} from 'react';
import React from 'react';
function Example() {
let [content, setContent] = useState<string | React.ReactElement | null>(null);
async function handleFiles(files: FileList | null) {
let file = files && [...files].find(f => f.type.startsWith('image/'));
if (file) {
let url = URL.createObjectURL(file);
setContent(<img src={url} alt={file.name} style={{maxHeight: 100, maxWidth: '100%'}} />);
}
}
return (
<DropZone
getDropOperation={types => (
['text/plain', 'image/jpeg', 'image/png', 'image/gif'].some(t => types.has(t))
? 'copy'
: 'cancel'
)}
onDrop={async (event) => {
let item = event.items.find(item => (
(item.kind === 'text' && item.types.has('text/plain')) ||
(item.kind === 'file' && item.type.startsWith('image/'))
));
if (item?.kind === 'text') {
let text = await item.getText('text/plain');
setContent(text);
} else if (item?.kind === 'file') {
let file = await item.getFile();
let url = URL.createObjectURL(file);
setContent(<img src={url} alt={item.name} style={{maxHeight: 100, maxWidth: '100%'}} />)
}
}}>
<div style={{display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8}}>
<Text slot="label">
{content || "Drop files here, or click Browse"}
</Text>
<FileTrigger acceptedFileTypes={['image/*']} onSelect={handleFiles}>
<Button>Browse</Button>
</FileTrigger>
</div>
</DropZone>
);
}
Examples
API
<DropZone>
<Text slot="label" />
</DropZone>
DropZone
| Name | Type | |
|---|---|---|
getDropOperation | | |
A function returning the drop operation to be performed when items matching the given types are dropped on the drop target. | ||
isDisabled | boolean | |
Whether the drop target is disabled. If true, the drop target will not accept any drops. | ||
children | ChildrenOrFunction | |
The children of the component. A function may be provided to alter the children based on component state. | ||
Default className: react-aria-DropZone
| Render Prop | CSS Selector |
|---|---|
isHovered | CSS Selector: [data-hovered]
|
| Whether the dropzone is currently hovered with a mouse. | |
isFocused | CSS Selector: [data-focused]
|
| Whether the dropzone is focused, either via a mouse or keyboard. | |
isFocusVisible | CSS Selector: [data-focus-visible]
|
| Whether the dropzone is keyboard focused. | |
isDropTarget | CSS Selector: [data-drop-target]
|
| Whether the dropzone is the drop target. | |
isDisabled | CSS Selector: [data-disabled]
|
| Whether the dropzone is disabled. | |