Skip to content

Commit 3cde0d4

Browse files
authored
DropZone docs release audit (#5151)
1 parent 30fe515 commit 3cde0d4

File tree

1 file changed

+82
-109
lines changed

1 file changed

+82
-109
lines changed

packages/@react-spectrum/dropzone/docs/DropZone.mdx

Lines changed: 82 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ import {Text} from 'react-aria-components';
4545

4646
function Example() {
4747
let [isFilled, setIsFilled] = React.useState(false);
48-
48+
4949
return (
5050
<>
5151
<Draggable />
@@ -57,16 +57,11 @@ function Example() {
5757
<Upload />
5858
<Heading>
5959
<Text slot="label">
60-
Drag and drop your file
60+
{isFilled ? 'You dropped something!' : 'Drag and drop your file'}
6161
</Text>
6262
</Heading>
6363
</IllustratedMessage>
6464
</DropZone>
65-
{isFilled &&
66-
<div className="dropped">
67-
You dropped something!
68-
</div>
69-
}
7065
</>
7166
)
7267
}
@@ -96,7 +91,6 @@ function Draggable() {
9691
);
9792
}
9893
```
99-
</details>
10094

10195
<details>
10296
<summary style={{fontWeight: 'bold'}}><ChevronRight size="S" /> Show CSS</summary>
@@ -116,18 +110,14 @@ function Draggable() {
116110
.draggable.dragging {
117111
opacity: 0.5;
118112
}
119-
120-
.dropped {
121-
margin-top: 20px;
122-
}
123113
```
124114
</details>
125-
115+
</details>
126116

127117

128118
## Content
129119

130-
A drop zone accepts an [IllustratedMessage](IllustratedMessage.html) as a child which is comprised of three areas: an illustration, a title, and a body. Each of these sections can be populated by providing the following components to the IllustratedMessage as children: a SVG, a [Heading](Heading.html) (title), and a [Content](Content.html) (body). A [FileTrigger](../react-aria/FileTrigger.html) is commonly paired with a DropZone to allow a user to choose files from their device.
120+
A DropZone accepts an [IllustratedMessage](IllustratedMessage.html) as a child which is comprised of three areas: an illustration, a title, and a body. Each of these sections can be populated by providing the following components to the IllustratedMessage as children: a SVG, a [Heading](Heading.html) (title), and a [Content](Content.html) (body). A [FileTrigger](../react-aria/FileTrigger.html) is commonly paired with a DropZone to allow a user to choose files from their device.
131121

132122
```tsx example
133123
import {FileTrigger} from 'react-aria-components';
@@ -147,7 +137,7 @@ function Example() {
147137
<Upload />
148138
<Heading>
149139
<Text slot="label">
150-
Drag and drop here
140+
{isFilled ? 'You dropped something!' : 'Drag and drop here'}
151141
</Text>
152142
</Heading>
153143
<Content>
@@ -158,70 +148,67 @@ function Example() {
158148
</Content>
159149
</IllustratedMessage>
160150
</DropZone>
161-
{isFilled &&
162-
<div className="dropped">
163-
You dropped something!
164-
</div>
165-
}
166151
</>
167152
)
168153
}
169154
```
170155

171156
### Accessibility
172157

173-
A visual label should be provided to `DropZone` using a `Text` element with a `label` slot. If it is not provided, then an `aria-label` or `aria-labelledby` prop must be passed to identify the visually hidden button to assistive technology.
158+
A visual label should be provided to `DropZone` using a `Text` element with a `label` slot. If it is not provided, then an `aria-label` or `aria-labelledby` prop must be passed to identify the visually hidden button to assistive technology.
174159

175160
### Internationalization
176161

177-
In order to internationalize a drop zone, a localized string should be passed to the `Text` element with a `label` slot or to the `aria-label` prop, in addition to the `replaceMessage` prop.
162+
In order to internationalize a DropZone, a localized string should be passed to the `Text` element with a `label` slot or to the `aria-label` prop, in addition to the `replaceMessage` prop.
178163

179164
## Events
180165

181-
`DropZone` supports drop operations via mouse, keyboard, and touch. You can handle all of these via the `onDrop` prop. In addition, the `onDropEnter`, `onDropMove`, and `onDropExit` events are fired as the user enter and exists the dropzone during a drag operation.
166+
`DropZone` supports drop operations via mouse, keyboard, and touch. You can handle all of these via the `onDrop` prop. In addition, the `onDropEnter`, `onDropMove`, and `onDropExit` events are fired as the user enter and exists the dropzone during a drag operation.
182167

183168
The following example uses an `onDrop` handler to update the filled status stored in React state.
184169

185170
```tsx example
186171
import File from '@spectrum-icons/illustrations/File';
187172
import {Text} from 'react-aria-components';
173+
import {Flex} from '@react-spectrum/layout';
188174

189175
function Example() {
190-
let [isFilled, setIsFilled] = React.useState(false);
191176
let [filledSrc, setFilledSrc] = React.useState(null);
192177

193178
return (
194179
<>
195180
<Draggable />
196181
<DropZone
197182
maxWidth="size-3000"
198-
isFilled={isFilled}
183+
isFilled={!!filledSrc}
199184
onDrop={async (e) => {
200185
e.items.find(async (item) => {
201186
if (item.kind === 'file') {
202187
setFilledSrc(item.name);
203-
setIsFilled(true);
204-
188+
205189
} else if (item.kind === 'text' && item.types.has('text/plain')) {
206190
setFilledSrc(await item.getText('text/plain'));
207-
setIsFilled(true);
208191
}
209192
});
210193
}}>
211-
<IllustratedMessage>
212-
<Upload />
213-
<Heading>
214-
<Text slot="label">
215-
Drag and drop here
216-
</Text>
217-
</Heading>
218-
</IllustratedMessage>
194+
{filledSrc
195+
? (
196+
<Flex direction="column" alignItems="center" justifyContent="center" gap="size-100">
197+
<File />
198+
{filledSrc}
199+
</Flex>
200+
)
201+
: (
202+
<IllustratedMessage>
203+
<Upload />
204+
<Heading>
205+
<Text slot="label">
206+
Drag and drop here
207+
</Text>
208+
</Heading>
209+
</IllustratedMessage>
210+
)}
219211
</DropZone>
220-
{isFilled &&
221-
<div className="dropped">
222-
<File />
223-
{filledSrc}
224-
</div>}
225212
</>
226213
);
227214
}
@@ -236,7 +223,7 @@ function Example() {
236223

237224
### Filled state
238225

239-
The user is responsible for both managing the filled state of a drop zone and handling the associated styling. To set the drop zone to a filled state, the user must pass the `isFilled` prop.
226+
The user is responsible for both managing the filled state of a DropZone and handling the associated styling. To set the DropZone to a filled state, the user must pass the `isFilled` prop.
240227

241228
The example below demonstrates one way of styling the filled state.
242229

@@ -245,13 +232,12 @@ import {Text} from 'react-aria-components';
245232

246233
function Example() {
247234
let [filledSrc, setFilledSrc] = React.useState(null);
248-
let [isFilled, setIsFilled] = React.useState(false);
249235

250236
return (
251237
<>
252238
<DraggableImage />
253239
<DropZone
254-
isFilled={isFilled}
240+
isFilled={!!filledSrc}
255241
maxWidth="size-3000"
256242
height="size-2400"
257243
getDropOperation={(types) => (types.has('image/png') || types.has('image/jpeg')) ? 'copy' : 'cancel'}
@@ -260,23 +246,24 @@ function Example() {
260246
if (item.kind === 'file') {
261247
if (item.type === 'image/jpeg' || item.type === 'image/png') {
262248
setFilledSrc(URL.createObjectURL(await item.getFile()));
263-
setIsFilled(true);
264249
}
265250
} else if (item.kind === 'text') {
266251
setFilledSrc(await item.getText('image/jpeg'));
267-
setIsFilled(true);
268252
}
269253
});
270254
}}>
271-
<IllustratedMessage>
272-
<Upload />
273-
<Heading>
274-
<Text slot="label">
275-
Drag and drop photos
276-
</Text>
277-
</Heading>
278-
</IllustratedMessage>
279-
{isFilled && <img className={'images'} alt="" src={filledSrc} />}
255+
{filledSrc
256+
? <img className="images" alt="" src={filledSrc} />
257+
: (
258+
<IllustratedMessage>
259+
<Upload />
260+
<Heading>
261+
<Text slot="label">
262+
Drag and drop photos
263+
</Text>
264+
</Heading>
265+
</IllustratedMessage>
266+
)}
280267
</DropZone>
281268
</>
282269
);
@@ -335,7 +322,7 @@ function DraggableImage() {
335322

336323
### Replace message
337324

338-
When a drop zone is in a filled state and has an object dragged over it, a message will appear in front of the drop zone. By default, this message will say "Drop file to replace". However, users can choose to customize this message through the `replaceMessage` prop. This message should describe the interaction that will occur when the object is dropped. It should also be internationalized if needed.
325+
When a DropZone is in a filled state and has an object dragged over it, a message will appear in front of the DropZone. By default, this message will say "Drop file to replace". However, users can choose to customize this message through the `replaceMessage` prop. This message should describe the interaction that will occur when the object is dropped. It should also be internationalized if needed.
339326

340327

341328
```tsx example
@@ -356,80 +343,66 @@ function Example() {
356343
<Upload />
357344
<Heading>
358345
<Text slot="label">
359-
Drag and drop here
346+
{isFilled ? 'You dropped something!' : 'Drag and drop here'}
360347
</Text>
361348
</Heading>
362349
</IllustratedMessage>
363350
</DropZone>
364-
{isFilled &&
365-
<div className="dropped">
366-
You dropped something!
367-
</div>
368-
}
369351
</>
370352
);
371353
}
372354
```
373355

374356
### Visual feedback
375357

376-
A drop zone displays visual feedback to the user when a drag hovers over the drop target by passing the `getDropOperation` function. If a drop target only supports data of specific types (e.g. images, videos, text, etc.), then it should implement the `getDropOperation` prop and return `cancel` for types that aren't supported. This will prevent visual feedback indicating that the drop target accepts the dragged data when this is not true. [Read more about getDropOperation.](../react-aria/useDrop.html#getdropoperation)
358+
A DropZone displays visual feedback to the user when a drag hovers over the drop target by passing the `getDropOperation` function. If a drop target only supports data of specific types (e.g. images, videos, text, etc.), then it should implement the `getDropOperation` prop and return `'cancel'` for types that aren't supported. This will prevent visual feedback indicating that the drop target accepts the dragged data when this is not true. [Read more about getDropOperation.](../react-aria/useDrop.html#getdropoperation)
377359

378360
```tsx example
379361
import {FileTrigger} from 'react-aria-components';
380362
import {Text} from 'react-aria-components';
381363
import {FileDropItem} from 'react-aria';
382364

383365
function Example() {
384-
let [isFilled, setIsFilled] = React.useState(false);
385366
let [filledSrc, setFilledSrc] = React.useState(null);
386367

387368
return (
388-
<>
389-
<DropZone
390-
maxWidth="size-3000"
391-
isFilled={isFilled}
392-
getDropOperation={(types) => types.has('image/png') ? 'copy' : 'cancel'}
393-
onDrop={async (e) => {
394-
let item = e.items.find((item: FileDropItem) => item.kind === 'file' && item.type === 'image/png') as FileDropItem;
395-
if (item) {
396-
setFilledSrc({
397-
type: item.type,
398-
name: item.name});
399-
setIsFilled(true);
400-
}
401-
}}>
402-
<IllustratedMessage>
403-
<Upload />
404-
<Heading>
405-
<Text slot="label">
406-
Drag and drop here
407-
</Text>
408-
</Heading>
409-
<Content>
410-
<FileTrigger
411-
acceptedFileTypes={['image/png']}
412-
onSelect={(e) => {
413-
let file = (Array.from(e)).find((file) => file.type === "image/png")
414-
if (file) {
415-
setFilledSrc({
416-
type: file.type,
417-
name: file.name
418-
})
419-
setIsFilled(true);
420-
}
421-
}}>
422-
<Button variant="primary">Browse</Button>
423-
</FileTrigger>
424-
</Content>
425-
</IllustratedMessage>
426-
</DropZone>
427-
{isFilled &&
428-
<div className="dropped">
429-
{`${filledSrc.type} ${filledSrc.name}`}
430-
</div>
431-
}
432-
</>
369+
<DropZone
370+
maxWidth="size-3000"
371+
isFilled={!!filledSrc}
372+
getDropOperation={(types) => types.has('image/png') ? 'copy' : 'cancel'}
373+
onDrop={async (e) => {
374+
let item = e.items.find((item: FileDropItem) => item.kind === 'file' && item.type === 'image/png') as FileDropItem;
375+
if (item) {
376+
setFilledSrc({
377+
type: item.type,
378+
name: item.name
379+
});
380+
}
381+
}}>
382+
<IllustratedMessage>
383+
<Upload />
384+
<Heading>
385+
<Text slot="label">
386+
{filledSrc ? `${filledSrc.type} ${filledSrc.name}` : 'Drag and drop here'}
387+
</Text>
388+
</Heading>
389+
<Content>
390+
<FileTrigger
391+
acceptedFileTypes={['image/png']}
392+
onSelect={(e) => {
393+
let file = (Array.from(e)).find((file) => file.type === "image/png")
394+
if (file) {
395+
setFilledSrc({
396+
type: file.type,
397+
name: file.name
398+
})
399+
}
400+
}}>
401+
<Button variant="primary">Browse</Button>
402+
</FileTrigger>
403+
</Content>
404+
</IllustratedMessage>
405+
</DropZone>
433406
);
434407
}
435408
```

0 commit comments

Comments
 (0)