{
- DeesContextmenu.openContextMenuWithOptions(eventArg, [{
- iconName: 'trash',
- name: 'Remove',
- action: async () => {
- this.value.splice(this.value.indexOf(fileArg), 1);
- this.requestUpdate();
- }
- }]);
- }}>
-
`;
}
+ private validationMessage: string = '';
+
+ // Utility methods
+ private formatFileSize(bytes: number): string {
+ const sizes = ['Bytes', 'KB', 'MB', 'GB'];
+ if (bytes === 0) return '0 Bytes';
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
+ return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i];
+ }
+
+ private getFileType(file: File): string {
+ const type = file.type.toLowerCase();
+ if (type.startsWith('image/')) return 'image';
+ if (type === 'application/pdf') return 'pdf';
+ if (type.includes('word') || type.includes('document')) return 'doc';
+ if (type.includes('sheet') || type.includes('excel')) return 'spreadsheet';
+ if (type.includes('presentation') || type.includes('powerpoint')) return 'presentation';
+ if (type.startsWith('video/')) return 'video';
+ if (type.startsWith('audio/')) return 'audio';
+ if (type.includes('zip') || type.includes('compressed')) return 'archive';
+ return 'file';
+ }
+
+ private getFileIcon(file: File): string {
+ const type = this.getFileType(file);
+ const iconMap = {
+ 'image': 'lucide:image',
+ 'pdf': 'lucide:file-text',
+ 'doc': 'lucide:file-text',
+ 'spreadsheet': 'lucide:table',
+ 'presentation': 'lucide:presentation',
+ 'video': 'lucide:video',
+ 'audio': 'lucide:music',
+ 'archive': 'lucide:archive',
+ 'file': 'lucide:file'
+ };
+ return iconMap[type] || 'lucide:file';
+ }
+
+ private canShowPreview(file: File): boolean {
+ return file.type.startsWith('image/') && file.size < 5 * 1024 * 1024; // 5MB limit for previews
+ }
+
+ private validateFile(file: File): boolean {
+ // Check file size
+ if (this.maxSize > 0 && file.size > this.maxSize) {
+ this.validationMessage = `File "${file.name}" exceeds maximum size of ${this.formatFileSize(this.maxSize)}`;
+ this.validationState = 'invalid';
+ return false;
+ }
+
+ // Check file type
+ if (this.accept) {
+ const acceptedTypes = this.accept.split(',').map(s => s.trim());
+ let isAccepted = false;
+
+ for (const acceptType of acceptedTypes) {
+ if (acceptType.startsWith('.')) {
+ // Extension check
+ if (file.name.toLowerCase().endsWith(acceptType.toLowerCase())) {
+ isAccepted = true;
+ break;
+ }
+ } else if (acceptType.endsWith('/*')) {
+ // MIME type wildcard check
+ const mimePrefix = acceptType.slice(0, -2);
+ if (file.type.startsWith(mimePrefix)) {
+ isAccepted = true;
+ break;
+ }
+ } else if (file.type === acceptType) {
+ // Exact MIME type check
+ isAccepted = true;
+ break;
+ }
+ }
+
+ if (!isAccepted) {
+ this.validationMessage = `File type not accepted. Please upload: ${this.accept}`;
+ this.validationState = 'invalid';
+ return false;
+ }
+ }
+
+ return true;
+ }
+
public async openFileSelector() {
+ if (this.disabled) return;
const inputFile: HTMLInputElement = this.shadowRoot.querySelector('input[type="file"]');
inputFile.click();
- this.state = 'idle';
- this.buttonText = 'Upload more files...';
+ }
+
+ private removeFile(file: File) {
+ const index = this.value.indexOf(file);
+ if (index > -1) {
+ this.value.splice(index, 1);
+ this.requestUpdate();
+ this.validate();
+ this.changeSubject.next(this);
+ }
+ }
+
+ private clearAll() {
+ this.value = [];
+ this.requestUpdate();
+ this.validate();
+ this.changeSubject.next(this);
}
public async updateValue(eventArg: Event) {
@@ -198,52 +512,131 @@ export class DeesInputFileupload extends DeesInputBase
-
+ ${hasFiles ? html`
+ ${showClearAll ? html`
+
+ ` : ''}
+
+ ${this.description ? html`
+
+ ${this.value.map((fileArg) => {
+ const fileType = this.getFileType(fileArg);
+ const isImage = fileType === 'image';
+ return html`
+
-
+
+ `;
+ })}
+ ${isImage && this.canShowPreview(fileArg) ? html`
+
+ ` : html`
+
+ `}
+
+
+
+ ${fileArg.name}
+ ${this.formatFileSize(fileArg.size)}
+
+
+
+
- ${fileArg.name}
- ${fileArg.size} + ` : html` +
`
- )}
- - ${fileArg.size} + ` : html` +
+
+
- Drag files here or click to browse
- ${this.buttonText}
+ `}
+
-
+
+ ${this.buttonText}
+
${this.description}
+ ` : ''}
+ ${this.validationState === 'invalid' && this.validationMessage ? html`
+
+ ` : ''}