class CustomFileUpload extends HTMLElement { connectedCallback() { this.attachShadow({ mode: 'open' }); this.shadowRoot.innerHTML = `
`; const input = this.shadowRoot.getElementById('srt-upload'); const dropZone = this.shadowRoot.getElementById('drop-zone'); const fileName = this.shadowRoot.getElementById('file-name'); // Handle click dropZone.addEventListener('click', () => { input.click(); }); // Handle file selection input.addEventListener('change', (e) => { if (e.target.files.length) { const file = e.target.files[0]; fileName.textContent = file.name; this.dispatchEvent(new CustomEvent('file-uploaded', { detail: { file }, bubbles: true, composed: true })); } }); // Handle drag and drop ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { dropZone.addEventListener(eventName, highlight, false); }); ['dragleave', 'drop'].forEach(eventName => { dropZone.addEventListener(eventName, unhighlight, false); }); function highlight() { dropZone.classList.add('border-blue-500', 'bg-blue-50'); } function unhighlight() { dropZone.classList.remove('border-blue-500', 'bg-blue-50'); } dropZone.addEventListener('drop', handleDrop, false); function handleDrop(e) { const dt = e.dataTransfer; const files = dt.files; if (files.length) { const file = files[0]; if (file.name.endsWith('.srt')) { fileName.textContent = file.name; input.files = files; this.dispatchEvent(new CustomEvent('file-uploaded', { detail: { file }, bubbles: true, composed: true })); } else { fileName.textContent = 'Please select a .srt file'; } } } } } customElements.define('custom-file-upload', CustomFileUpload);