A powerful, headless React hook for file inputs with drag-and-drop support. Build beautiful file upload experiences with complete control.
npm install @wmik/use-file-input
Extends the Map API with minimal abstraction, making it incredibly easy to use and integrate.
Native HTML5 Drag and Drop API support built right in, no extra configuration needed.
Flexible settings that adapt to your specific requirements and use cases.
Build your own custom interface that perfectly matches your design system.
import { useFileInput } from '@wmik/use-file-input';
function FileInputComponent() {
const LABEL_TEXT_DEFAULT = 'Click or drag/drop files to upload';
const LABEL_TEXT_HOVER = 'Drop files to upload';
const PLACEHOLDER_TEXT = 'No files';
let {
files,
fileInputRef,
isDraggingOver,
onFileInputChange,
onFileInputDragStart,
onFileInputDragOver,
onFileInputDragLeave,
onFileInputDrop
} = useFileInput();
let hasFiles = Array.from(files?.values() ?? [])?.length > 0;
let styles = {
container: {
width: 400,
height: 400,
border: '1px dashed #dddccc'
},
label: {},
input: {
display: 'none'
},
list: {
display: hasFiles ? 'block' : 'none'
},
placeholder: {
display: !hasFiles ? 'block' : 'none'
}
};
return (
<main>
<div
style={styles.container}
onDragOver={onFileInputDragOver}
onDragStart={onFileInputDragStart}
onDragLeave={onFileInputDragLeave}
onDrop={onFileInputDrop}
>
<label
htmlFor="files"
style={styles.label}
children={isDraggingOver ? LABEL_TEXT_HOVER : LABEL_TEXT_DEFAULT}
/>
<input
multiple
id="files"
type="file"
name="files"
ref={fileInputRef}
style={styles.input}
onChange={onFileInputChange}
/>
</div>
<ul style={styles.list}>
{Array.from(files.values())?.map(file => (
<li key={file?.name}>
<span children={file?.name} />
<button
type="button"
aria-roledescription="delete"
onClick={() => files.delete(file)}
>
DELETE
</button>
</li>
))}
</ul>
<p style={styles.placeholder} children={PLACEHOLDER_TEXT} />
</main>
);
}
Install the package and start building better file upload experiences today.
View on GitHub