fairy-webuploader
Version:
224 lines (190 loc) • 8.12 kB
JavaScript
import AbstractTemplate from "./AbstractTemplate.js";
export default class MinimalFileTemplate extends AbstractTemplate{
constructor(el, options) {
super(el, options);
}
initStyles(styleId) {
this.brandColor = '#4CAF50';
this.isDarkMode = true;
const style = document.createElement('style');
style.id = styleId;
style.textContent = `
.file-uploader-container {
background-color: white;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
padding: 40px;
text-align: center;
width: 100%;
max-width: 100%;
transition: all 0.2s ease;
position: relative;
cursor: pointer;
}
.file-uploader-container:hover,
.file-uploader-container:focus-within {
background-color: #FAFAFA;
}
.upload-icon {
width: 48px;
height: 48px;
fill: #888;
transition: fill 0.2s ease;
}
.upload-text {
font-family: Inter, Helvetica, system-ui, sans-serif;
font-size: 16px;
color: #888;
margin-top: 16px;
transition: color 0.2s ease;
}
.drag-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 120, 255, 0.05);
display: none;
justify-content: center;
align-items: center;
border-radius: 6px;
}
.drag-text {
font-family: Inter, Helvetica, system-ui, sans-serif;
font-size: 16px;
color: #0078FF;
}
.progress-bar {
height: 4px;
background-color: #EEE;
border-radius: 2px;
margin-top: 16px;
overflow: hidden;
}
.progress {
height: 100%;
background-color: ${this.brandColor};
width: 0%;
transition: width 0.3s ease;
}
.toast {
position: fixed;
top: 20px;
left: 50%;
transform: translateX(-50%);
padding: 12px 24px;
border-radius: 4px;
font-family: Inter, Helvetica, system-ui, sans-serif;
font-size: 14px;
color: white;
display: none;
z-index: 9999;
}
.toast.success {
background-color: #4CAF50;
}
.toast.error {
background-color: #F44336;
}
.dark-mode .file-uploader-container {
background-color: #1E1E1E;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}
.dark-mode .file-uploader-container:hover,
.dark-mode .file-uploader-container:focus-within {
background-color: #2A2A2A;
}
.dark-mode .upload-icon {
fill: #E0E0E0;
}
.dark-mode .upload-text {
color: #E0E0E0;
}
.dark-mode .progress-bar {
background-color: #3A3A3A;
}
`;
document.head.appendChild(style);
}
createUploader() {
this.uploaderContainer = document.createElement('div');
this.uploaderContainer.className = 'file-uploader-container';
this.uploaderContainer.id = AbstractTemplate.uploaderContainerId
const uploadIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
uploadIcon.classList.add('upload-icon');
uploadIcon.setAttribute('viewBox', '0 0 24 24');
uploadIcon.innerHTML = `
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
`;
const uploadText = document.createElement('div');
uploadText.className = 'upload-text';
uploadText.textContent = '上传文件';
const input = document.createElement('input');
input.id = AbstractTemplate.uploaderInputId;
input.type = 'file';
input.style.display = 'none';
input.multiple = this.options?.multiple || true;
input.accept = this.options?.accept || '*';
const dragOverlay = document.createElement('div');
dragOverlay.className = 'drag-overlay';
const dragText = document.createElement('div');
dragText.className = 'drag-text';
dragText.textContent = '松开上传';
dragOverlay.appendChild(dragText);
this.progressBar = document.createElement('div');
this.progressBar.className = 'progress-bar';
this.progress = document.createElement('div');
this.progress.className = 'progress';
this.progressBar.appendChild(this.progress);
this.toast = document.createElement('div');
this.toast.className = 'toast';
this.uploaderContainer.appendChild(uploadIcon);
this.uploaderContainer.appendChild(uploadText);
this.uploaderContainer.appendChild(input);
this.uploaderContainer.appendChild(dragOverlay);
this.uploaderContainer.appendChild(this.progressBar);
this.container.appendChild(this.uploaderContainer);
this.container.appendChild(this.toast);
this.input = input;
this.dragOverlay = dragOverlay;
}
setupEventListeners() {
this.uploaderContainer.addEventListener('click', () => {
this.input.click();
});
this.input.addEventListener('change', (e) => {
this.handleFileSelect(e.target.files);
});
this.uploaderContainer.addEventListener('dragover', (e) => {
e.preventDefault();
this.dragOverlay.style.display = 'flex';
});
this.uploaderContainer.addEventListener('dragleave', () => {
this.dragOverlay.style.display = 'none';
});
this.uploaderContainer.addEventListener('drop', (e) => {
e.preventDefault();
this.dragOverlay.style.display = 'none';
this.handleFileSelect(e.dataTransfer.files);
});
// 模拟暗黑模式切换
document.addEventListener('keydown', (e) => {
if (e.key === 'd') {
this.toggleDarkMode();
}
});
}
showToast(type, message) {
this.toast.className = `toast ${type}`;
this.toast.textContent = message;
this.toast.style.display = 'block';
setTimeout(() => {
this.toast.style.display = 'none';
}, 3000);
}
toggleDarkMode() {
this.isDarkMode = !this.isDarkMode;
document.body.classList.toggle('dark-mode', this.isDarkMode);
}
}