DropZone always returns error when glb/gltf file triggers `dragenter` event
#6.644 aberto em 15 de jul. de 2022
Métricas do repositório
- Stars
- (6.174 stars)
- Métricas de merge de PR
- (Métricas PR pendentes)
Description
DropZone
-
The validation error
dragErrorOverlayfordragenterevent relies onacceptproperty orcustomValidatorfunction property of<DropZone>https://github.com/Shopify/polaris/blob/b541f54498462ce513b9903dfcfcb966f43e0038/polaris-react/src/components/DropZone/DropZone.tsx#L190-L210 -
When
acceptproperty is present and its!fileAcceptedreturns true,customValidatornever gets evaluated. -
fileAccepted always returns false for glb/gltf file because:
-
When a file is
dragentered, it is not aFileinstance butDataTransferIteminstance andDataTransferItemonly haskindandtypeproperties. When a glb/gltfdragentered, however,DataTransferItem'stypehas an empty string; thus an-always validation error. This part is related to a situation whenacceptproperty is a mimeType string likemodel/gltf+json,model/gltf-binaryinstead of a dot string like.glb. The validation works for files likevideo/mp4becauseDataTransferItemhas a propertype. -
When
acceptproperty is a dot string like.glb,.mp4,.wav,fileAcceptedalways returns false becauseDataTransferItemdoes not havenameproperty. https://github.com/Shopify/polaris/blob/b541f54498462ce513b9903dfcfcb966f43e0038/polaris-react/src/components/DropZone/utils/index.ts#L30 This is a bug that should be fixed separately. all file types not working. -
Additionally,
Fileinstance ofdropevent hastypeproperty but it is an empty string.namegets correct information tho.file.namevalidation would work only whenacceptis a dot string.
-
-
To avoid
dragErrorOverlayshowing up for dragenter event, a file validation needs to rely oncustomValidatorand omitacceptproperty -
This compromises "click and select files" user interaction of System UI outside of browsers because to filter file types on System, it relies on
acceptproperty 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
fileAcceptedvalidation fordragenterevent whenDataTransferItem.typehas an empty string. (with a better documentation otherwise coders implicitly have to use a dot string foracceptprop) - prioritize
customValidatoroverfileAcceptedand 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 asacceptprop)
-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.