/** * Copyright Aquera Inc 2025 * * This source code is licensed under the BSD-3-Clause license found in the * LICENSE file in the root directory of this source tree. */ import { styles } from './nile-file-upload.css'; import { ChangedPropsInterface } from './types/file-upload.type' import NileElement from '../internal/nile-element'; import { DragHandler } from './utils/drag-drop.util'; import { FileUploadDefaults } from './types/file-upload.enums'; import { LitElement, html, CSSResultArray, TemplateResult } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import { FileUploadState, FileUploadVariant, FileUploadError, FileUploadEvent } from './types/file-upload.enums'; import { setUpDragHandler, addGlobalListeners, addInternalListeners, uploadFiles, cancelFileUpload } from './utils/file-validation.util'; import { getHorizontalDefaultState, getHorizontalDragState, getVerticalDefaultState, getVerticalDisabledState, getVerticalDragState, getHorizontalErrorState, getVerticalErrorState, getHorizontalDisabledState } from './nile-file-upload.template'; /** * Nile file-upload component. * * @tag nile-file-upload * */ @customElement('nile-file-upload') export class NileFileUpload extends NileElement { /** * The styles for nile-file-upload * @remarks If you are extending this class you can extend the base styles with super. Eg `return [super(), myCustomStyles]` */ public static get styles(): CSSResultArray { return [styles]; } @property({ type: String }) size: string = "10MB"; @property({ type: Boolean}) error: boolean = false; @property({ type: String }) errorMessage: string = ""; @property({ type: Boolean}) allowMultiple: boolean = false; @property({ type: Boolean}) allowDuplicates: boolean = false; @property({ type: Array }) allowedTypes: string[] = []; @property({ type: Array }) uploadedFiles: File[] = []; @property({ type: String }) title: string = FileUploadDefaults.TITLE; @property({ type: String }) subtitle: string = FileUploadDefaults.SUBTITLE; @property({ type: String }) state: FileUploadState = FileUploadState.DEFAULT; @property({ type: String }) variant: FileUploadVariant = FileUploadVariant.HORIZONTAL; @property({ type: String }) fileUploadUrl: string = ""; @property({ type: Boolean}) autoUpload: boolean = true; @state() public doNotUpload: File[] = []; @query('input') input!: HTMLInputElement; @query('.horizontal-div') horizontalDiv!: HTMLDivElement; public uploadRequests = new Map(); public fileSizeExceededFilesNumber: number = 0; public isStringTruncated: boolean = false; private dragHandler!: DragHandler; connectedCallback(): void { super.connectedCallback(); this.emit(FileUploadEvent.NILE_INIT); } firstUpdated(changedProps: ChangedPropsInterface): void { super.firstUpdated(changedProps); this.dragHandler = new DragHandler(); setUpDragHandler(this, this.dragHandler); addInternalListeners(this, this.dragHandler, this.uploadRequests); addGlobalListeners(this.dragHandler); } updated(changedProps: ChangedPropsInterface): void { super.updated(changedProps); if (changedProps.has('uploadedFiles')) { if(this.fileUploadUrl && this.autoUpload) { uploadFiles(this); } this.emit(FileUploadEvent.NILE_CHANGE, { files: this.uploadedFiles }); } else if (changedProps.has('state')) { this.dragHandler.setValuesInDragHandler(this.state); } if(changedProps.has('autoUpload') && this.autoUpload) { if(this.fileUploadUrl && this.autoUpload) { uploadFiles(this); } this.emit(FileUploadEvent.NILE_CHANGE, { files: this.uploadedFiles }); } } public browseFiles(): void { this.emit(FileUploadEvent.NILE_BROWSE); this.errorMessage = ""; this.input.click(); } public setState = (newState: FileUploadState): void => { this.state = newState; } render(): TemplateResult { return html` ${this.getState()} `; } public clearAllUploadedFiles(): void { this.uploadedFiles = []; this.state = FileUploadState.DEFAULT; this.errorMessage = ""; } private getState(): TemplateResult { return this.variant === FileUploadVariant.HORIZONTAL ? this.getHorizontalState() : this.getVerticalState(); } private getHorizontalState(): TemplateResult { switch(this.state) { case FileUploadState.DEFAULT: return getHorizontalDefaultState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.state, this.errorMessage, this.allowedTypes, this); case FileUploadState.DISABLED: return getHorizontalDisabledState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.state, this.errorMessage, this.allowedTypes, this); case FileUploadState.DRAG: return getHorizontalDragState(); case FileUploadState.ERROR: return getHorizontalErrorState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.state, this.errorMessage, this.allowedTypes, this); default: return getHorizontalDefaultState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.state, this.errorMessage, this.allowedTypes, this); } } private getVerticalState(): TemplateResult { switch(this.state) { case FileUploadState.DEFAULT: return getVerticalDefaultState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.errorMessage, this.allowedTypes, this); case FileUploadState.DISABLED: return getVerticalDisabledState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.errorMessage, this.allowedTypes, this); case FileUploadState.DRAG: return getVerticalDragState(); case FileUploadState.ERROR: return getVerticalErrorState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.errorMessage, this.allowedTypes, this); default: return getVerticalDefaultState(this.browseFiles, this.title, this.subtitle, this.dragHandler, this.errorMessage, this.allowedTypes, this); } } disconnectedCallback(): void { this.emit(FileUploadEvent.NILE_DESTROY); } }