dees-catalog/ts_web/elements/dees-input-fileupload.ts

213 lines
5.3 KiB
TypeScript
Raw Normal View History

2021-05-05 20:55:49 +00:00
import {
customElement,
DeesElement,
2023-08-07 18:02:18 +00:00
type TemplateResult,
2021-05-05 20:55:49 +00:00
property,
html,
css,
unsafeCSS,
cssManager,
2023-08-07 18:02:18 +00:00
type CSSResult,
2023-10-23 14:13:02 +00:00
domtools,
2023-08-07 17:13:29 +00:00
} from '@design.estate/dees-element';
2021-05-05 20:55:49 +00:00
declare global {
interface HTMLElementTagNameMap {
'dees-input-fileupload': DeesInputFileupload;
}
}
@customElement('dees-input-fileupload')
export class DeesInputFileupload extends DeesElement {
2022-12-06 13:07:12 +00:00
public static demo = () => html`<dees-input-fileupload .label=${'Attachments'}></dees-input-fileupload>`;
2021-05-05 20:55:49 +00:00
2021-08-19 22:25:14 +00:00
// INSTANCE
2023-10-23 15:26:03 +00:00
public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
2021-08-19 22:25:14 +00:00
2021-05-05 20:55:49 +00:00
@property({
type: String,
})
public label: string = null;
@property({
type: String,
2023-08-28 07:49:51 +00:00
reflect: true,
2021-05-05 20:55:49 +00:00
})
public key: string;
@property({
attribute: false,
})
public value: File[] = [];
@property()
public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';
2021-08-25 11:51:55 +00:00
@property({
type: Boolean,
})
public required: boolean = false;
2021-08-26 19:30:35 +00:00
@property({
2022-12-06 12:11:06 +00:00
type: Boolean,
2021-08-26 19:30:35 +00:00
})
public disabled: boolean = false;
2022-12-06 12:11:06 +00:00
@property({
type: String,
})
public buttonText: string = 'Upload File...';
2021-08-25 11:51:55 +00:00
constructor() {
2022-12-06 12:11:06 +00:00
super();
2021-08-25 11:51:55 +00:00
}
2021-05-05 20:55:49 +00:00
public static styles = [
cssManager.defaultStyles,
css`
:host {
position: relative;
display: grid;
margin: 10px 0px;
margin-bottom: 24px;
}
2022-12-11 16:24:12 +00:00
.hidden {
display: none;
}
2021-05-05 20:55:49 +00:00
.maincontainer {
color: ${cssManager.bdTheme('#333', '#ccc')};
2022-12-06 13:07:12 +00:00
2021-05-05 20:55:49 +00:00
}
.label {
font-size: 14px;
margin-bottom: 5px;
}
.uploadButton {
position: relative;
cursor: pointer;
2022-12-06 12:11:06 +00:00
padding: 8px;
max-width: 600px;
2021-05-05 20:55:49 +00:00
background: ${cssManager.bdTheme('#fafafa', '#333333')};
border-radius: 3px;
text-align: center;
}
2022-12-06 13:07:12 +00:00
.uploadButton:hover {
color: #fff;
background: rgb(3, 155, 229);
}
2021-05-05 20:55:49 +00:00
.uploadButton::after {
2022-12-06 12:11:06 +00:00
top: 2px;
right: 2px;
left: 2px;
bottom: 2px;
transform: scale3d(0.98, 0.9, 1);
2021-05-05 20:55:49 +00:00
position: absolute;
content: '';
display: block;
2022-12-06 12:11:06 +00:00
border: 2px dashed rgba(255, 255, 255, 0);
2021-05-05 20:55:49 +00:00
transition: all 0.2s;
}
.uploadButton.dragOver::after {
transform: scale3d(1, 1, 1);
2022-12-06 12:11:06 +00:00
border: 2px dashed rgba(255, 255, 255, 0.3);
}
.uploadCandidate {
text-align: left;
border-bottom: 1px dashed #444;
2022-12-06 13:07:12 +00:00
color: ${cssManager.bdTheme('#666', '#ccc')};
2022-12-06 12:11:06 +00:00
padding: 8px;
2023-10-05 12:36:59 +00:00
font-family: 'Roboto', 'Inter', sans-serif;
2022-12-06 12:11:06 +00:00
}
2022-12-06 13:07:12 +00:00
.uploadButton:hover .uploadCandidate {
color: ${cssManager.bdTheme('#fff', '#fff')};
border-bottom: 1px dashed #fff;
}
2022-12-06 12:11:06 +00:00
.uploadCandidate:last-child {
margin-bottom: 8px;
2021-05-05 20:55:49 +00:00
}
`,
];
public render(): TemplateResult {
return html`
2022-12-11 16:24:12 +00:00
<div class="hidden">
<input type="file"></div>
</div>
2021-05-05 20:55:49 +00:00
<div class="maincontainer">
${this.label ? html`<div class="label">${this.label}</div>` : null}
2022-12-11 16:24:12 +00:00
${this.value.map((fileArg) => html` <div class="uploadCandidate">${fileArg.name} | ${fileArg.size}</div> `)}
<div class="uploadButton ${this.state === 'dragOver' ? 'dragOver' : ''}" @click=${this.openFileSelector}>
2022-12-06 12:11:06 +00:00
${this.buttonText}
</div>
2021-05-05 20:55:49 +00:00
</div>
`;
}
2022-12-11 16:24:12 +00:00
public async openFileSelector() {
const inputFile: HTMLInputElement = this.shadowRoot.querySelector('input[type="file"]');
inputFile.click();
2023-08-19 09:47:45 +00:00
this.state = 'idle';
this.buttonText = 'Upload more files...';
2022-12-11 16:24:12 +00:00
}
2023-08-19 09:47:45 +00:00
2022-12-11 16:24:12 +00:00
2021-05-05 20:55:49 +00:00
public async updateValue(eventArg: Event) {
const target: any = eventArg.target;
this.value = target.value;
2021-08-19 22:25:14 +00:00
this.changeSubject.next(this);
2021-05-05 20:55:49 +00:00
}
public firstUpdated() {
2023-08-19 09:47:45 +00:00
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
2021-05-05 20:55:49 +00:00
const dropArea = this.shadowRoot.querySelector('.uploadButton');
const handlerFunction = (eventArg: DragEvent) => {
eventArg.preventDefault();
2022-12-06 12:11:06 +00:00
switch (eventArg.type) {
2021-05-05 20:55:49 +00:00
case 'dragover':
this.state = 'dragOver';
2022-12-06 12:11:06 +00:00
this.buttonText = 'release to upload file...';
2021-05-05 20:55:49 +00:00
break;
case 'dragleave':
this.state = 'idle';
2022-12-06 12:11:06 +00:00
this.buttonText = 'Upload File...';
2021-05-05 20:55:49 +00:00
break;
2022-12-06 12:11:06 +00:00
case 'drop':
this.state = 'idle';
this.buttonText = 'Upload more files...';
2021-05-05 20:55:49 +00:00
}
console.log(eventArg);
for (const file of Array.from(eventArg.dataTransfer.files)) {
this.value.push(file);
2022-12-06 12:11:06 +00:00
this.requestUpdate();
}
2021-05-05 20:55:49 +00:00
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);
}
}