/**
* File upload handler class
* Manages file uploads with drag and drop functionality
*/
export class FileUploadHandler {
private _files: File[] = [];
private _fileLabel: HTMLElement;
private _fileControl: HTMLElement;
private _originalFileControl: HTMLInputElement;
private _infileOutput: HTMLElement;
/**
* Handle the dragover event
*/
dragOver = (event: DragEvent): void => {
event.preventDefault();
this._fileLabel.classList.add('drag-over'); // Visual feedback
}
/**
* Handle the dragleave event
*/
dragLeave = (event: DragEvent): void => {
event.preventDefault();
this._fileLabel.classList.remove('drag-over');
};
/**
* Handle the drop event
*/
dragDrop = (event: DragEvent): void => {
event.preventDefault();
this._fileLabel.classList.remove('drag-over');
const files = event.dataTransfer?.files;
if (files && files.length > 0) {
console.log('Files dropped:', files);
this.fileChangedEvent({
target: { files }
} as unknown as Event);
}
}
/**
* Handle file selection changes
*/
fileChangedEvent = (event: Event): void => {
let files: File[];
console.debug('FileUploadHandler.fileChanged', event);
const target = event.target as HTMLInputElement;
if (!target.files || target.files.length === 0) {
this._infileOutput.innerHTML = "";
return;
}
files = Array.from(target.files);
const fileOutput = document.createElement('ul');
fileOutput.classList.add('hoo-infile-list');
console.debug('FileUploadHandler', files);
files.forEach(file => {
const fileItem = document.createElement('li');
fileItem.innerText = file.name;
fileOutput.appendChild(fileItem);
});
this._infileOutput.innerHTML = `
${this._infileOutput.title || 'Files Selected'}
${fileOutput.outerHTML}`;
}
/**
* Initialize the file upload handler
* @param htmlElement - The file upload container element
*/
constructor(htmlElement: HTMLElement) {
this._fileControl = htmlElement;
console.debug('FileUploadHandler', this._fileControl);
this._fileLabel = htmlElement.querySelector('.hoo-infile-label') as HTMLElement;
if (!this._fileLabel) {
throw new Error('File label element not found (.hoo-infile-label)');
}
this._fileLabel.addEventListener('dragover', this.dragOver as EventListener);
this._fileLabel.addEventListener('dragleave', this.dragLeave as EventListener);
this._fileLabel.addEventListener('drop', this.dragDrop as EventListener);
this._originalFileControl = this._fileControl.querySelector('.hoo-infile-context') as HTMLInputElement;
if (!this._originalFileControl) {
throw new Error('File input element not found (.hoo-infile-context)');
}
console.debug('FileUploadHandler', this._originalFileControl, this._originalFileControl.getAttribute('aria-describedby'));
this._originalFileControl.addEventListener('change', this.fileChangedEvent);
const describedBy = this._originalFileControl.getAttribute('aria-describedby');
if (!describedBy) {
throw new Error('File input is missing aria-describedby attribute');
}
console.debug('FileUploadHandler', describedBy, this._infileOutput, `#${describedBy.trim()}`);
this._infileOutput = document.querySelector(`#${describedBy.trim()}`) as HTMLElement;
if (!this._infileOutput) {
throw new Error(`Element with id "${describedBy.trim()}" not found`);
}
console.debug('Infile Output:', this._infileOutput);
}
}