File Input Drag Drop
<section class="p-6 bg-white rounded-lg shadow-sm">
<div class="max-w-md mx-auto">
<label class="block text-sm font-medium text-gray-700 mb-2">Drag & Drop Files</label>
<div
id="drop-area"
class="border-2 border-dashed border-gray-300 rounded-lg p-6 flex flex-col items-center justify-center bg-gray-50 hover:bg-gray-100 transition cursor-pointer">
<svg class="w-10 h-10 text-gray-400 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
</svg>
<p class="text-sm text-gray-600 mb-1">Drag and drop your files here</p>
<p class="text-xs text-gray-500 mb-3">or</p>
<button type="button" id="browse-button" class="text-sm bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
Browse Files
</button>
<input type="file" id="file-input" class="hidden" multiple />
<p class="text-xs text-gray-500 mt-3">Maximum file size: 10MB</p>
</div>
<!-- Preview files -->
<div id="file-list" class="mt-4 space-y-2"></div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const dropArea = document.getElementById('drop-area');
const fileInput = document.getElementById('file-input');
const browseButton = document.getElementById('browse-button');
const fileList = document.getElementById('file-list');
// Highlight drop area when dragging over it
['dragenter', 'dragover'].forEach(eventName => {
dropArea.addEventListener(eventName, function(e) {
e.preventDefault();
e.stopPropagation();
dropArea.classList.add('bg-blue-50', 'border-blue-300');
dropArea.classList.remove('bg-gray-50', 'border-gray-300');
}, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropArea.addEventListener(eventName, function(e) {
e.preventDefault();
e.stopPropagation();
dropArea.classList.remove('bg-blue-50', 'border-blue-300');
dropArea.classList.add('bg-gray-50', 'border-gray-300');
}, false);
});
// Handle file drop
dropArea.addEventListener('drop', function(e) {
fileInput.files = e.dataTransfer.files;
updateFileList(e.dataTransfer.files);
}, false);
// Handle browse button click
browseButton.addEventListener('click', function() {
fileInput.click();
});
// Handle file selection via input
fileInput.addEventListener('change', function() {
updateFileList(this.files);
});
// Display selected files
function updateFileList(files) {
fileList.innerHTML = '';
if (files.length === 0) return;
Array.from(files).forEach((file, index) => {
const fileItem = document.createElement('div');
fileItem.className = 'flex items-center justify-between bg-gray-100 p-2 rounded-md';
const fileInfo = document.createElement('div');
fileInfo.className = 'flex items-center';
const fileIcon = document.createElement('div');
fileIcon.className = 'text-blue-600 mr-2';
fileIcon.innerHTML = '<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>';
const fileName = document.createElement('span');
fileName.className = 'text-sm text-gray-700 truncate';
fileName.textContent = file.name;
fileInfo.appendChild(fileIcon);
fileInfo.appendChild(fileName);
fileItem.appendChild(fileInfo);
const fileSize = document.createElement('span');
fileSize.className = 'text-xs text-gray-500';
fileSize.textContent = formatFileSize(file.size);
fileItem.appendChild(fileSize);
fileList.appendChild(fileItem);
});
}
// Format file size
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
});
</script>
</section>
Copied to clipboard