handle-files-react
v1.1.4
Published
A react component and hooks to handle files
Downloads
258
Readme
Handle Files React
Description
Easy and Quick way to handle files in React with <Dropzone/>
and useFileInput()
hook.
Installation
npm install handle-files-react
yarn add handle-files-react
pnpm add handle-files-react
Quick Start
useFileInput()
import { useFileInput, FileWithMeta, convertToBytes } from 'handle-files-react';
function App(){
const { open } = useFileInput();
const [files, setFiles] = useState<FileWithMeta[]>([]);
return (
<div>
<button onClick={async ()=>{
try {
const files = await open({
multiple: true,
maxBytes: convertToBytes(10, "MB"), // 10MB
accept: ".mp4, .png", // native input accept attribute
maxFiles:5,
customValidator: (file) => file.name.includes("Blender")
});
setFiles(files);
} catch (e) {
console.error(e);
}
}}>Select</button>
<ul>
{files.map((file) => (
<li key={file.origin.name}>
{file.origin.name} ({file.toUnit("MB", 1)})
</li>
))}
</ul>
</div>
)
}
<Dropzone/>
function App() {
const [files, setFiles] = useState<FileWithMeta[]>([]);
const [refEl, setRefEl] = useState<HTMLDivElement | null>(null);
return (
<div>
<DropZone
onDrop={(files) => {
setFiles(files);
}}
onError={(e) => {
console.error(e);
}}
multiple={true}
maxBytes={convertToBytes(10, "MB")}
accept={".mp4, .png"}
maxFiles={5}
customValidator={(file) => {
return file.name.includes("Blender");
}}
>
<div
ref={(el) => {
if(!refEl) {
setRefEl(el); // use ref element with state
}
}}
style={{
width: 500,
height: 500,
backgroundColor: "gray",
}}
>
DROP ZONE
<ul>
{files.map((file) => (
<li key={file.origin.name}>
{file.origin.name} ({file.toUnit("MB", 1)})
</li>
))}
</ul>
</div>
</DropZone>
</div>
);
}
API
common
const units = [
"B",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB",
] as const;
interface FileInputOptions {
multiple?: boolean;
accept?: string;
maxBytes?: number;
maxFiles?: number;
customValidator?: (file: File) => boolean;
};
interface FileWithMeta {
origin: File;
toUnit: TGetUnit;
}
useFileInput()
function useFileInput(){
const open = (options?: FileInputOptions) => {
// ...
}
return { open };
}
<Dropzone/>
interface Props {
children: React.ReactElement;
onDrop: (files: FileWithMeta[]) => void;
onError?: (error: Error) => void;
onDragEnter?: (e: React.DragEvent) => void;
onDragLeave?: (e: React.DragEvent) => void;
}
function DropZone(props:Props & FileInputOptions){
// return clone children
}
Utils
convertToBytes(value: number, unit: TUnit): number
value * 1024^index (index is the index of the unit in the units
array)
convertToBytes(10, "MB"); // 10485760
convertToBytes(10, "GB"); // 10737418240
convertToBytes(10, "TB"); // 10995116277760
FileWithMeta.toUnit(unit: TUnit, fixed?: number): string
fileWithMeta.toUnit("MB", 1); // 10.0MB
fileWithMeta.toUnit("GB", 2); // 10.00GB
fileWithMeta.toUnit("TB", 3); // 10.000TB
Tips
Infer the type of the file
accept
option is used to filter the file type and use the File.type
property.
Here, is the situation where image.ai
is not an type of .ai
but application/postscript
.
But you can get actual file type by error.