File Dropzone
FileDropzone takes files dropped onto it, and is also a button that opens the
file picker. Drop an image on it, or press it:
No file yet
import { Paragraph, Text, View } from '@hozo/core'import { FileDropzone } from '@hozo/ui'import { useState } from 'react'
export function FileDropzoneDemo() { const [message, setMessage] = useState('No file yet') return ( <View className="w-full max-w-md gap-3"> <FileDropzone accessibilityLabel="Upload a photo" accept={['image/png', 'image/jpeg']} maxSize={5_000_000} onFilesSelected={(files) => setMessage(`Chosen: ${files.map((f) => f.name).join(', ')}`)} onRejected={(rejections) => setMessage(`Refused: ${rejections.map((r) => r.reason).join(', ')}`) } > <Text className="font-semibold text-hozo-text">Drop a photo here</Text> <Text className="text-sm text-hozo-text-body">or press to choose one, up to 5 MB</Text> </FileDropzone> <Paragraph className="text-sm text-hozo-text-body">{message}</Paragraph> </View> )}- A button first. Dragging has no keyboard or screen-reader equivalent, so
the zone is a real
<button>, and Enter and Space open the picker. The drop is a shortcut on top of it. accept,maxSize,minSize,multipleandmaxFilesare the rules. Files that break one go toonRejectedwith a reason, and the rest go toonFilesSelected.- What was added and what was refused is announced in one sentence, such as “a.gif is not an accepted kind of file”, so a refusal is not only a red line a reader cannot see.
accessibilityLabelnames the button.childrenare what it shows.