Description
DropZone
-
The validation error
dragErrorOverlay
fordragenter
event relies onaccept
property orcustomValidator
function property of<DropZone>
polaris/polaris-react/src/components/DropZone/DropZone.tsx
Lines 190 to 210 in b541f54
-
When
accept
property is present and its!fileAccepted
returns true,customValidator
never gets evaluated. -
fileAccepted always returns false for glb/gltf file because:
-
When a file is
dragenter
ed, it is not aFile
instance butDataTransferItem
instance andDataTransferItem
only haskind
andtype
properties. When a glb/gltfdragenter
ed, however,DataTransferItem
'stype
has an empty string; thus an-always validation error. This part is related to a situation whenaccept
property is a mimeType string likemodel/gltf+json
,model/gltf-binary
instead of a dot string like.glb
. The validation works for files likevideo/mp4
becauseDataTransferItem
has a propertype
. -
When
This is a bug that should be fixed separately. all file types not working.accept
property is a dot string like.glb,.mp4,.wav
,fileAccepted
always returns false becauseDataTransferItem
does not havename
property. -
Additionally,
File
instance ofdrop
event hastype
property but it is an empty string.name
gets correct information tho.file.name
validation would work only whenaccept
is a dot string.
-
-
To avoid
dragErrorOverlay
showing up for dragenter event, a file validation needs to rely oncustomValidator
and omitaccept
property -
This compromises "click and select files" user interaction of System UI outside of browsers because to filter file types on System, it relies on
accept
property of<input type="file">
tag.
Examples
dragErrorOverlay
showing up even tho DropZone actually accepts glb
const [files, setFiles] = useState<File[]>()
const handleDrop = (acceptedFiles: File[]) => setFiles(acceptedFiles)
const fileUpload = !files.length && <DropZone.FileUpload />
const uploadedFiles = files.length > 0 && (
<Stack vertical>
{files.map((file, index) => (
<Stack alignment="center" key={index}>
<Thumbnail
size="small"
alt={file.name}
source={window.URL.createObjectURL(file)}
/>
<div>
{file.name} <Caption>{file.size} bytes</Caption>
</div>
</Stack>
))}
</Stack>
);
...
<DropZone accept="model/gltf-binary" type="file" onDropAccepted={handleDrop}>
{uploadedFiles}
{fileUpload}
</DropZone>
Best practices
The DropZone component should either:
- skip
fileAccepted
validation fordragenter
event whenDataTransferItem.type
has an empty string. (with a better documentation otherwise coders implicitly have to use a dot string foraccept
prop) - prioritize
customValidator
overfileAccepted
and give coders a better control. If customValidator is present, just skip fileAccepted. (This is because I would rather have a mimetype <=> a dot string extension conversion in the customValidator and check both file.name and file.type with a specified filetypes asaccept
prop)
-ps
I would like to create a PR but I wanted to make sure that we have a consensus on which solution would be better.