85 lines
3.5 KiB
TypeScript
85 lines
3.5 KiB
TypeScript
|
import { html, type TemplateResult } from '@design.estate/dees-element';
|
||
|
import type { DeesInputFileupload } from './component.js';
|
||
|
|
||
|
export const renderFileupload = (component: DeesInputFileupload): TemplateResult => {
|
||
|
const hasFiles = component.value.length > 0;
|
||
|
const showClearAll = hasFiles && component.value.length > 1;
|
||
|
|
||
|
return html`
|
||
|
<div class="input-wrapper">
|
||
|
${component.label ? html`
|
||
|
<dees-label .label=${component.label}></dees-label>
|
||
|
` : ''}
|
||
|
<div class="hidden">
|
||
|
<input
|
||
|
type="file"
|
||
|
?multiple=${component.multiple}
|
||
|
accept="${component.accept}"
|
||
|
>
|
||
|
</div>
|
||
|
<div class="maincontainer ${component.state === 'dragOver' ? 'dragOver' : ''}">
|
||
|
${hasFiles ? html`
|
||
|
${showClearAll ? html`
|
||
|
<div class="clear-all-button">
|
||
|
<button @click=${component.clearAll}>Clear All</button>
|
||
|
</div>
|
||
|
` : ''}
|
||
|
<div class="files-container">
|
||
|
${component.value.map((fileArg) => {
|
||
|
const fileType = component.getFileType(fileArg);
|
||
|
const isImage = fileType === 'image';
|
||
|
return html`
|
||
|
<div class="uploadCandidate ${fileType}-file">
|
||
|
<div class="icon">
|
||
|
${isImage && component.canShowPreview(fileArg) ? html`
|
||
|
<img class="image-preview" src="${URL.createObjectURL(fileArg)}" alt="${fileArg.name}">
|
||
|
` : html`
|
||
|
<dees-icon .icon=${component.getFileIcon(fileArg)}></dees-icon>
|
||
|
`}
|
||
|
</div>
|
||
|
<div class="info">
|
||
|
<div class="filename" title="${fileArg.name}">${fileArg.name}</div>
|
||
|
<div class="filesize">${component.formatFileSize(fileArg.size)}</div>
|
||
|
</div>
|
||
|
<div class="actions">
|
||
|
<button
|
||
|
class="remove-button"
|
||
|
@click=${() => component.removeFile(fileArg)}
|
||
|
title="Remove file"
|
||
|
>
|
||
|
<dees-icon .icon=${'lucide:x'}></dees-icon>
|
||
|
</button>
|
||
|
</div>
|
||
|
</div>
|
||
|
`;
|
||
|
})}
|
||
|
</div>
|
||
|
` : html`
|
||
|
<div class="drop-hint">
|
||
|
<dees-icon .icon=${'lucide:cloud-upload'}></dees-icon>
|
||
|
<div>Drag files here or click to browse</div>
|
||
|
</div>
|
||
|
`}
|
||
|
<div class="uploadButton ${component.isLoading ? 'loading' : ''}" @click=${component.openFileSelector}>
|
||
|
<div class="button-content">
|
||
|
${component.isLoading ? html`
|
||
|
<div class="loading-spinner"></div>
|
||
|
<span>Opening...</span>
|
||
|
` : html`
|
||
|
<dees-icon .icon=${'lucide:upload'}></dees-icon>
|
||
|
${component.buttonText}
|
||
|
`}
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
${component.description ? html`
|
||
|
<div class="description-text">${component.description}</div>
|
||
|
` : ''}
|
||
|
${component.validationState === 'invalid' && component.validationMessage ? html`
|
||
|
<div class="validation-message">${component.validationMessage}</div>
|
||
|
` : ''}
|
||
|
</div>
|
||
|
`;
|
||
|
|
||
|
};
|