feat: add DeesInputFileupload and DeesInputRichtext components
- Implemented DeesInputFileupload component with file upload functionality, including drag-and-drop support, file previews, and clear all option. - Developed DeesInputRichtext component featuring a rich text editor with a formatting toolbar, link management, and word count display. - Created demo for DeesInputRichtext showcasing various use cases including basic editing, placeholder text, different heights, and disabled state. - Added styles for both components to ensure a consistent and user-friendly interface. - Introduced types for toolbar buttons in the rich text editor for better type safety and maintainability.
This commit is contained in:
84
ts_web/elements/dees-input-fileupload/template.ts
Normal file
84
ts_web/elements/dees-input-fileupload/template.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
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>
|
||||
`;
|
||||
|
||||
};
|
Reference in New Issue
Block a user