init
This commit is contained in:
121
file_drop.js
Normal file
121
file_drop.js
Normal file
@@ -0,0 +1,121 @@
|
||||
export default {
|
||||
template: `
|
||||
<div
|
||||
class="file-drop-zone"
|
||||
:class="{ 'dragging': isDragging }"
|
||||
@click="openFileDialog"
|
||||
@dragover.prevent="onDragOver"
|
||||
@dragleave.prevent="onDragLeave"
|
||||
@drop.prevent="onDrop"
|
||||
style="border: 2px dashed #d1d5db; border-radius: 8px; padding: 32px; text-align: center; cursor: pointer; transition: all 0.3s ease; min-height: 120px; display: flex; flex-direction: column; align-items: center; justify-content: center;"
|
||||
>
|
||||
<div style="color: #9ca3af; font-size: 48px; margin-bottom: 16px;">☁️</div>
|
||||
<div style="font-size: 18px; color: #6b7280; margin-bottom: 8px;">Drop files here or click to browse</div>
|
||||
<div style="font-size: 14px; color: #9ca3af;">Drag and drop your files</div>
|
||||
|
||||
<input
|
||||
ref="fileInput"
|
||||
type="file"
|
||||
:multiple="multiple"
|
||||
:accept="accept"
|
||||
@change="onFileInputChange"
|
||||
style="display: none;"
|
||||
/>
|
||||
</div>
|
||||
`,
|
||||
props: {
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
accept: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isDragging: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openFileDialog() {
|
||||
this.$refs.fileInput.click();
|
||||
},
|
||||
|
||||
onDragOver(e) {
|
||||
e.preventDefault();
|
||||
this.isDragging = true;
|
||||
},
|
||||
|
||||
onDragLeave(e) {
|
||||
e.preventDefault();
|
||||
this.isDragging = false;
|
||||
},
|
||||
|
||||
async onDrop(e) {
|
||||
e.preventDefault();
|
||||
this.isDragging = false;
|
||||
|
||||
const files = Array.from(e.dataTransfer.files);
|
||||
if (files.length === 0) return;
|
||||
|
||||
await this.processFiles(files);
|
||||
},
|
||||
|
||||
async onFileInputChange(e) {
|
||||
const files = Array.from(e.target.files);
|
||||
if (files.length === 0) return;
|
||||
|
||||
await this.processFiles(files);
|
||||
|
||||
// Clear the input
|
||||
e.target.value = '';
|
||||
},
|
||||
|
||||
async processFiles(files) {
|
||||
if (!this.multiple && files.length > 1) {
|
||||
files = [files[0]];
|
||||
}
|
||||
|
||||
const filesData = [];
|
||||
|
||||
for (const file of files) {
|
||||
const content = await this.readFileAsBase64(file);
|
||||
|
||||
filesData.push({
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type || 'application/octet-stream',
|
||||
content: content
|
||||
});
|
||||
}
|
||||
|
||||
this.$emit('upload', filesData);
|
||||
},
|
||||
|
||||
readFileAsBase64(file) {
|
||||
return new Promise((resolve) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
// Remove the data URL prefix to get just the base64 content
|
||||
const base64 = reader.result.split(',')[1];
|
||||
resolve(base64);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
style: `
|
||||
.file-drop-zone.dragging {
|
||||
border-color: #3b82f6 !important;
|
||||
background-color: #eff6ff !important;
|
||||
}
|
||||
|
||||
.file-drop-zone:hover {
|
||||
border-color: #9ca3af !important;
|
||||
background-color: #f9fafb !important;
|
||||
}
|
||||
`
|
||||
};
|
||||
Reference in New Issue
Block a user