UNPKG

fairy-webuploader

Version:

224 lines (190 loc) 8.12 kB
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); } }