Download components/file-uploader.js from GuaccO/githubsupabasesync-wizard: direct link, hf CLI and curl.
- Browser
- Download file 3.16 kB
-
https://huggingface.co/spaces/GuaccO/githubsupabasesync-wizard/resolve/main/components/file-uploader.js
- Command line
-
hf download hf://spaces/GuaccO/githubsupabasesync-wizard/components/file-uploader.js
-
curl -L -o file-uploader.js https://huggingface.co/spaces/GuaccO/githubsupabasesync-wizard/resolve/main/components/file-uploader.js
3.16 kB
| class FileUploader extends HTMLElement { | |
| connectedCallback() { | |
| this.attachShadow({ mode: 'open' }); | |
| this.shadowRoot.innerHTML = ` | |
| <style> | |
| .upload-container { | |
| margin: 1rem 0; | |
| border: 2px dashed #ccc; | |
| border-radius: 0.5rem; | |
| padding: 1.5rem; | |
| text-align: center; | |
| transition: all 0.3s; | |
| } | |
| .upload-container:hover { | |
| border-color: #667eea; | |
| background: #f7fafc; | |
| } | |
| .file-input { | |
| display: none; | |
| } | |
| .upload-btn { | |
| background: #667eea; | |
| color: white; | |
| padding: 0.5rem 1rem; | |
| border-radius: 0.25rem; | |
| cursor: pointer; | |
| display: inline-block; | |
| margin-bottom: 1rem; | |
| } | |
| .file-list { | |
| text-align: left; | |
| margin-top: 1rem; | |
| } | |
| .file-item { | |
| display: flex; | |
| align-items: center; | |
| padding: 0.5rem; | |
| border-bottom: 1px solid #eee; | |
| } | |
| .file-name { | |
| flex-grow: 1; | |
| margin-left: 0.5rem; | |
| } | |
| .remove-btn { | |
| color: #f56565; | |
| cursor: pointer; | |
| margin-left: 0.5rem; | |
| } | |
| </style> | |
| <div class="upload-container"> | |
| <input type="file" class="file-input" multiple accept=".js,.ts,.sql,.json,.txt,.md,.html,.css"> | |
| <button class="upload-btn">Choose Files</button> | |
| <div class="file-list"></div> | |
| <p>Supported files: JavaScript, TypeScript, SQL, JSON, etc.</p> | |
| </div> | |
| `; | |
| const input = this.shadowRoot.querySelector('.file-input'); | |
| const button = this.shadowRoot.querySelector('.upload-btn'); | |
| const fileList = this.shadowRoot.querySelector('.file-list'); | |
| const files = []; | |
| button.addEventListener('click', () => input.click()); | |
| input.addEventListener('change', (e) => { | |
| files.length = 0; // Clear previous files | |
| fileList.innerHTML = ''; | |
| Array.from(e.target.files).forEach(file => { | |
| files.push(file); | |
| const fileItem = document.createElement('div'); | |
| fileItem.className = 'file-item'; | |
| fileItem.innerHTML = ` | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor"> | |
| <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" /> | |
| </svg> | |
| <span class="file-name">${file.name} (${(file.size / 1024).toFixed(2)} KB)</span> | |
| <span class="remove-btn">×</span> | |
| `; | |
| fileItem.querySelector('.remove-btn').addEventListener('click', () => { | |
| const index = files.indexOf(file); | |
| if (index > -1) { | |
| files.splice(index, 1); | |
| } | |
| fileItem.remove(); | |
| }); | |
| fileList.appendChild(fileItem); | |
| }); | |
| }); | |
| // Expose files to parent component | |
| this.getFiles = () => files; | |
| } | |
| } | |
| customElements.define('file-uploader', FileUploader); |