MkDowner provides an intuitive file upload interface with drag-and-drop support, multiple file selection, and real-time validation.
Drag-and-Drop Functionality
The upload area supports native browser drag-and-drop events for a seamless user experience:
src/components/UploadArea/UploadArea.tsx
const handleDragOver = (e: React.DragEvent) => {
e.preventDefault();
setIsDragOver(true);
};
const handleDragLeave = () => {
setIsDragOver(false);
};
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
setIsDragOver(false);
if (e.dataTransfer.files) {
onFilesSelected(e.dataTransfer.files);
}
};
The component visually indicates when files are being dragged over the upload area by applying a CSS class:
<div
className={`upload-card ${isDragOver ? 'is-dragover' : ''}`}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
onDrop={handleDrop}
>
Multiple File Selection
Users can select multiple files through either drag-and-drop or the file browser:
src/components/UploadArea/UploadArea.tsx
<input
type="file"
multiple
required
ref={fileInputRef}
onChange={handleFileChange}
className="upload-input-hidden"
/>
The UI dynamically updates based on the number of files selected:
const getButtonText = () => {
if (isUploading) return 'Converting...';
if (selectedFiles.length === 0) return 'Drop your PDF or browse';
if (selectedFiles.length === 1) return 'Convert file';
return `Convert ${selectedFiles.length} files`;
};
File Management
The useFileUpload hook provides methods for managing selected files:
src/hooks/useFileUpload.ts
const handleFilesSelected = (files: FileList) => {
setSelectedFiles(Array.from(files));
setShowSuccess(false);
};
const handleRemoveFile = (index: number) => {
setSelectedFiles(prev => prev.filter((_, i) => i !== index));
};
const handleClearAll = () => {
setSelectedFiles([]);
setShowSuccess(false);
clearFileInput();
};
File Size Limits
MkDowner supports files up to 24MB in size:
File size validation is enforced on the frontend. The limit is displayed to users in the upload interface.
{!showSuccess && (
<div className="hero-upload-footer">
Supports PDF files up to 24MB
</div>
)}
TypeScript Interface
The upload component uses a well-defined interface for type safety:
src/components/UploadArea/UploadArea.tsx
interface UploadAreaProps {
onFilesSelected: (files: FileList) => void;
onSubmit: (files: FileList) => void;
isUploading: boolean;
progress: number;
selectedFiles: File[];
showSuccess: boolean;
downloadedFileName: string;
onNewConversion: () => void;
}
User Experience Features
Click to Browse
The entire upload area is clickable, triggering the native file browser
Visual Feedback
Drag-over states and file count indicators provide clear feedback
File Reset
Built-in methods to clear selections and start fresh conversions
State Management
Comprehensive state tracking for upload, progress, and success states