import * as colors from './00colors.js'; import * as plugins from './00plugins.js'; import { DeesContextmenu } from './dees-contextmenu.js'; import { customElement, DeesElement, type TemplateResult, property, html, css, unsafeCSS, cssManager, type CSSResult, domtools, } from '@design.estate/dees-element'; declare global { interface HTMLElementTagNameMap { 'dees-input-fileupload': DeesInputFileupload; } } @customElement('dees-input-fileupload') export class DeesInputFileupload extends DeesElement { public static demo = () => html``; // INSTANCE public changeSubject = new domtools.plugins.smartrx.rxjs.Subject(); @property({ type: String, }) public label: string = null; @property({ type: String, reflect: true, }) public key: string; @property({ attribute: false, }) public value: File[] = []; @property() public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle'; @property({ type: Boolean, }) public required: boolean = false; @property({ type: Boolean, }) public disabled: boolean = false; @property({ type: String, }) public buttonText: string = 'Upload File...'; constructor() { super(); } public static styles = [ cssManager.defaultStyles, css` :host { position: relative; display: grid; margin: 10px 0px; margin-bottom: 24px; color: ${cssManager.bdTheme('#333', '#ccc')}; } .hidden { display: none; } .maincontainer { position: relative; border-radius: 3px; padding: 8px; background: ${cssManager.bdTheme('#fafafa', '#222222')}; color: ${cssManager.bdTheme('#333', '#ccc')}; border-top: 1px solid #ffffff10; } .maincontainer::after { top: 2px; right: 2px; left: 2px; bottom: 2px; transform: scale3d(0.98, 0.9, 1); position: absolute; content: ''; display: block; border: 2px dashed rgba(255, 255, 255, 0); transition: all 0.2s; pointer-events: none; background: #00000000; } .maincontainer.dragOver::after { transform: scale3d(1, 1, 1); border: 2px dashed rgba(255, 255, 255, 0.3); background: #00000080; } .label { font-size: 14px; margin-bottom: 8px; } .uploadButton { position: relative; padding: 8px; max-width: 600px; background: ${cssManager.bdTheme('#fafafa', '#333333')}; border-radius: 3px; text-align: center; font-size: 14px; cursor: default; } .uploadButton:hover { color: #fff; background: ${unsafeCSS(colors.dark.blue)}; } .uploadCandidate { display: grid; grid-template-columns: 48px auto; background: #333; padding: 8px 8px 8px 0px; margin-bottom: 8px; text-align: left; border-radius: 3px; color: ${cssManager.bdTheme('#666', '#ccc')}; font-family: 'Roboto', 'Inter', sans-serif; cursor: default; transition: all 0.2s; border-top: 1px solid #ffffff10; } .uploadCandidate:last-child { margin-bottom: 8px; } .uploadCandidate .icon { display: flex; align-items: center; justify-content: center; font-size: 16px; } .uploadCandidate:hover { background: #393939; } .uploadCandidate .description { font-size: 14px; border-left: 1px solid #ffffff10; padding-left: 8px; } `, ]; public render(): TemplateResult { return html` ${this.label ? html`
${this.label}
` : null}
${this.value.map( (fileArg) => html`
{ DeesContextmenu.openContextMenuWithOptions(eventArg, [{ iconName: 'trash', name: 'Remove', action: async () => { this.value.splice(this.value.indexOf(fileArg), 1); this.requestUpdate(); } }]); }}>
${fileArg.name}
${fileArg.size}
` )}
${this.buttonText}
`; } public async openFileSelector() { const inputFile: HTMLInputElement = this.shadowRoot.querySelector('input[type="file"]'); inputFile.click(); this.state = 'idle'; this.buttonText = 'Upload more files...'; } public async updateValue(eventArg: Event) { const target: any = eventArg.target; this.value = target.value; this.changeSubject.next(this); } public firstUpdated() { const inputFile: HTMLInputElement = this.shadowRoot.querySelector('input[type="file"]'); inputFile.addEventListener('change', (event: Event) => { const target = event.target as HTMLInputElement; for (const file of Array.from(target.files)) { this.value.push(file); } this.requestUpdate(); console.log(`Got ${this.value.length} files!`); // Reset the input value to allow selecting the same file again if needed target.value = ''; }); // lets handle drag and drop const dropArea = this.shadowRoot.querySelector('.maincontainer'); const handlerFunction = (eventArg: DragEvent) => { eventArg.preventDefault(); switch (eventArg.type) { case 'dragover': this.state = 'dragOver'; this.buttonText = 'release to upload file...'; break; case 'dragleave': this.state = 'idle'; this.buttonText = 'Upload File...'; break; case 'drop': this.state = 'idle'; this.buttonText = 'Upload more files...'; } console.log(eventArg); for (const file of Array.from(eventArg.dataTransfer.files)) { this.value.push(file); this.requestUpdate(); } console.log(`Got ${this.value.length} files!`); }; dropArea.addEventListener('dragenter', handlerFunction, false); dropArea.addEventListener('dragleave', handlerFunction, false); dropArea.addEventListener('dragover', handlerFunction, false); dropArea.addEventListener('drop', handlerFunction, false); } }