I am looking for a way to select files through the file dialogue. The file selector needs to:
be restricted to only directory selection
capture all selected files in a single callback so that they can be set to a state
include the relative path for all files in the file list
I've tried the file selector components from a few libraries such as antd
, react-dropzone
, @rpldy/uploady
, react-file-reader
, and react-file-picker
already, but none seem to be able to fulfill all three requirements.
CodePudding user response:
You can achieve this with Uploady.
When using the webkitdirectory flag for the file input element, you do get the webkitRelativePath property in all browsers (at least chrome & firefox) per the spec.
Now, to get the list of files, you'd use the useBatchAddListener hook.
import React, { useState } from "react";
import Uploady, { useBatchAddListener } from "@rpldy/uploady";
import UploadButton from "@rpldy/upload-button";
const MyUploadButton = ({ addFilesToState }) => {
useBatchAddListener((batch) => {
addFilesToState(batch.items.map(({ file }) => file));
});
return <UploadButton>Upload Files</UploadButton>;
};
const Uploader = () => {
const [_, setFiles] = useState([]);
return (
<MyUploadButton
addFilesToState={(files) => setFiles((prev) => [...prev, ...files])}
/>
);
};
export default function App() {
return (
<Uploady destination={{ url: "[upload-url]" }} webkitdirectory="true" debug>
<div className="App">
<Uploader />
</div>
</Uploady>
);
}
See sandbox.
CodePudding user response:
Not sure if there is a React library for that, but you can take a look at the File System Access API. It only works in Chrome, though, but maybe that <input type="file" webkitdirectory>
works in other browsers and would be enough for your needs.