@nuralyui/file-upload 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,6 +8,7 @@ export declare class FileUpload extends LitElement {
8
8
  tip: string;
9
9
  limit: number;
10
10
  preview: boolean;
11
+ generatePreviewOnUpload: boolean;
11
12
  fileList: UploadFile[];
12
13
  isDragOver: boolean;
13
14
  showDragArea: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.component.d.ts","sourceRoot":"","sources":["../../../src/components/file-upload/file-upload.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC,qBACa,UAAW,SAAQ,UAAU;IACxC,OAAgB,MAAM,0BAAU;IAEJ,MAAM,EAAE,MAAM,CAAM;IACnB,QAAQ,EAAE,OAAO,CAAS;IAC1B,IAAI,EAAE,OAAO,CAAQ;IACtB,GAAG,EAAE,MAAM,CAAM;IACjB,KAAK,EAAE,MAAM,CAAK;IACjB,OAAO,EAAE,OAAO,CAAQ;IAE5C,QAAQ,EAAE,UAAU,EAAE,CAAM;IAC5B,UAAU,EAAE,OAAO,CAAS;IAC5B,YAAY,EAAE,OAAO,CAAS;IAC9B,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAC7C,WAAW,EAAE,MAAM,CAAK;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEnC,iBAAiB;IAUjB,oBAAoB;IAUpB,YAAY,CAAC,kBAAkB,EAAE,cAAc;IAKxD,OAAO,CAAC,oBAAoB,CAO1B;IAEF,OAAO,CAAC,oBAAoB,CAQ1B;IAEF,OAAO,CAAC,eAAe,CAOrB;IAEF,OAAO,CAAC,mBAAmB,CAYzB;IAEF,OAAO,CAAC,OAAO,CAWb;IAEF,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,SAAS,CAQf;YAEY,YAAY;IAmCnB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM;IAY7G,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IAIZ,MAAM;CAwGhB"}
1
+ {"version":3,"file":"file-upload.component.d.ts","sourceRoot":"","sources":["../../../src/components/file-upload/file-upload.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIxC,qBACa,UAAW,SAAQ,UAAU;IACxC,OAAgB,MAAM,0BAAU;IAEJ,MAAM,EAAE,MAAM,CAAM;IACnB,QAAQ,EAAE,OAAO,CAAS;IAC1B,IAAI,EAAE,OAAO,CAAQ;IACtB,GAAG,EAAE,MAAM,CAAM;IACjB,KAAK,EAAE,MAAM,CAAK;IACjB,OAAO,EAAE,OAAO,CAAQ;IACxB,uBAAuB,EAAE,OAAO,CAAS;IAE7D,QAAQ,EAAE,UAAU,EAAE,CAAM;IAC5B,UAAU,EAAE,OAAO,CAAS;IAC5B,YAAY,EAAE,OAAO,CAAS;IAC9B,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAQ;IAC7C,WAAW,EAAE,MAAM,CAAK;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAEnC,iBAAiB;IAUjB,oBAAoB;IAUpB,YAAY,CAAC,kBAAkB,EAAE,cAAc;IAKxD,OAAO,CAAC,oBAAoB,CAO1B;IAEF,OAAO,CAAC,oBAAoB,CAQ1B;IAEF,OAAO,CAAC,eAAe,CAOrB;IAEF,OAAO,CAAC,mBAAmB,CAYzB;IAEF,OAAO,CAAC,OAAO,CA2Bb;IAEF,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,SAAS,CAcf;YAEY,YAAY;IAiFnB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM;IAY7G,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IAIZ,MAAM;CAwGhB"}
@@ -26,6 +26,7 @@ let FileUpload = class FileUpload extends LitElement {
26
26
  this.tip = '';
27
27
  this.limit = 0;
28
28
  this.preview = true;
29
+ this.generatePreviewOnUpload = false;
29
30
  this.fileList = [];
30
31
  this.isDragOver = false;
31
32
  this.showDragArea = false;
@@ -75,6 +76,16 @@ let FileUpload = class FileUpload extends LitElement {
75
76
  this.isDragOver = false;
76
77
  this.showDragArea = false;
77
78
  if ((_a = e.dataTransfer) === null || _a === void 0 ? void 0 : _a.files) {
79
+ this.dispatchEvent(new CustomEvent(`files-changed`, {
80
+ detail: e.dataTransfer.files,
81
+ bubbles: true,
82
+ composed: true
83
+ }));
84
+ this.dispatchEvent(new CustomEvent(`file-drop`, {
85
+ detail: { files: e.dataTransfer.files },
86
+ bubbles: true,
87
+ composed: true
88
+ }));
78
89
  this._handleFiles(e.dataTransfer.files);
79
90
  }
80
91
  };
@@ -85,9 +96,13 @@ let FileUpload = class FileUpload extends LitElement {
85
96
  this._onChange = (e) => {
86
97
  const target = e.target;
87
98
  if (target.files) {
88
- this._dispatchEvent('files-change', { files: target.files });
99
+ this.dispatchEvent(new CustomEvent(`files-changed`, {
100
+ detail: target.files,
101
+ bubbles: true,
102
+ composed: true
103
+ }));
89
104
  this._handleFiles(target.files);
90
- target.value = ''; // Reset so same file can be selected again
105
+ target.value = '';
91
106
  }
92
107
  };
93
108
  }
@@ -116,10 +131,47 @@ let FileUpload = class FileUpload extends LitElement {
116
131
  }
117
132
  _handleFiles(files) {
118
133
  return __awaiter(this, void 0, void 0, function* () {
119
- if (this.limit > 0 && this.fileList.length + files.length > this.limit) {
134
+ // Early check for multiple mode
135
+ if (this.multiple && this.limit > 0 && this.fileList.length + files.length > this.limit) {
120
136
  this._dispatchEvent('exceed', { files });
121
137
  return;
122
138
  }
139
+ // If not multiple, keep only the last file
140
+ if (!this.multiple && files.length > 0) {
141
+ // Get the last file from the FileList
142
+ const lastFile = files[files.length - 1];
143
+ // If preview modal is showing a preview from a file that's being replaced, close it
144
+ if (this.previewImage && this.fileList.some(file => file.url === this.previewImage)) {
145
+ this.previewImage = null;
146
+ }
147
+ // If there are existing files, dispatch remove events for each one
148
+ const oldFiles = [...this.fileList];
149
+ for (const file of oldFiles) {
150
+ this._dispatchEvent('remove', { file });
151
+ }
152
+ // Clear the file list
153
+ this.fileList = [];
154
+ // Process only the last file
155
+ const isImage = fileUtils.isImageFile(lastFile);
156
+ const fileObj = {
157
+ name: lastFile.name,
158
+ size: fileUtils.formatFileSize(lastFile.size),
159
+ raw: lastFile,
160
+ status: 'ready',
161
+ percentage: 0,
162
+ uid: Date.now() + Math.random().toString(36).substring(2),
163
+ isImage
164
+ };
165
+ if (this.preview && this.generatePreviewOnUpload && isImage) {
166
+ fileObj.url = yield fileUtils.createFilePreview(lastFile);
167
+ }
168
+ this.fileList = [fileObj];
169
+ this.requestUpdate();
170
+ // Emit file-selected event with the new file
171
+ this._dispatchEvent('select', { files: [fileObj], fileList: this.fileList });
172
+ return;
173
+ }
174
+ // For multiple mode, process all files
123
175
  const newFiles = [];
124
176
  for (const file of Array.from(files)) {
125
177
  const isImage = fileUtils.isImageFile(file);
@@ -132,8 +184,7 @@ let FileUpload = class FileUpload extends LitElement {
132
184
  uid: Date.now() + Math.random().toString(36).substring(2),
133
185
  isImage
134
186
  };
135
- // Create preview URL for images if preview is enabled
136
- if (this.preview && isImage) {
187
+ if (this.preview && this.generatePreviewOnUpload && isImage) {
137
188
  fileObj.url = yield fileUtils.createFilePreview(file);
138
189
  }
139
190
  this.fileList = [...this.fileList, fileObj];
@@ -206,7 +257,7 @@ let FileUpload = class FileUpload extends LitElement {
206
257
  ${this.tip ? html `<div class="upload-tip">${this.tip}</div>` : ''}
207
258
  </div>
208
259
  ` : html `
209
- <button class="upload-button" @click=${this._onClick}>Upload File</button>
260
+ <hy-button @click=${this._onClick}>Upload File</hy-button>
210
261
  ${this.tip ? html `<div class="upload-tip">${this.tip}</div>` : ''}
211
262
  `}
212
263
 
@@ -303,6 +354,9 @@ __decorate([
303
354
  __decorate([
304
355
  property({ type: Boolean })
305
356
  ], FileUpload.prototype, "preview", void 0);
357
+ __decorate([
358
+ property({ type: Boolean })
359
+ ], FileUpload.prototype, "generatePreviewOnUpload", void 0);
306
360
  __decorate([
307
361
  state()
308
362
  ], FileUpload.prototype, "fileList", void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"file-upload.component.js","sourceRoot":"","sources":["../../../src/components/file-upload/file-upload.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { UploadFile } from './types.js';\nimport { styles } from './styles.js';\nimport { fileUtils } from './utils.js';\n\n@customElement('nr-file-upload')\nexport class FileUpload extends LitElement {\n static override styles = styles;\n\n @property({ type: String }) accept: string = '';\n @property({ type: Boolean }) multiple: boolean = false;\n @property({ type: Boolean }) drag: boolean = true;\n @property({ type: String }) tip: string = '';\n @property({ type: Number }) limit: number = 0;\n @property({ type: Boolean }) preview: boolean = true;\n\n @state() fileList: UploadFile[] = [];\n @state() isDragOver: boolean = false;\n @state() showDragArea: boolean = false;\n @state() inputElement: HTMLInputElement | null = null;\n @state() dragCounter: number = 0;\n @state() previewImage: string | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.drag) {\n document.addEventListener('dragenter', this._onDocumentDragEnter);\n document.addEventListener('dragleave', this._onDocumentDragLeave);\n document.addEventListener('drop', this._onDocumentDrop);\n document.addEventListener('dragover', this._onDocumentDragOver);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this.drag) {\n document.removeEventListener('dragenter', this._onDocumentDragEnter);\n document.removeEventListener('dragleave', this._onDocumentDragLeave);\n document.removeEventListener('drop', this._onDocumentDrop);\n document.removeEventListener('dragover', this._onDocumentDragOver);\n }\n }\n\n override firstUpdated(_changedProperties: PropertyValues) {\n super.firstUpdated(_changedProperties);\n this.inputElement = this.shadowRoot?.querySelector('input[type=\"file\"]') || null;\n }\n\n private _onDocumentDragEnter = (e: DragEvent) => {\n e.preventDefault();\n this.dragCounter++;\n \n if (this.dragCounter === 1) {\n this.showDragArea = true;\n }\n };\n\n private _onDocumentDragLeave = (e: DragEvent) => {\n e.preventDefault();\n this.dragCounter--;\n \n if (this.dragCounter === 0) {\n this.showDragArea = false;\n this.isDragOver = false;\n }\n };\n\n private _onDocumentDrop = (e: DragEvent) => {\n if (e.target !== this && !this.contains(e.target as Node)) {\n e.preventDefault();\n this.dragCounter = 0;\n this.showDragArea = false;\n this.isDragOver = false;\n }\n };\n\n private _onDocumentDragOver = (e: DragEvent) => {\n e.preventDefault();\n \n // Determine if the drag is over our component\n const path = e.composedPath();\n const isOverComponent = path.includes(this);\n \n if (isOverComponent) {\n this.isDragOver = true;\n } else {\n this.isDragOver = false;\n }\n };\n\n private _onDrop = (e: DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n \n this.dragCounter = 0;\n this.isDragOver = false;\n this.showDragArea = false;\n\n if (e.dataTransfer?.files) {\n this._handleFiles(e.dataTransfer.files);\n }\n };\n\n private _onClick = () => {\n this.inputElement?.click();\n };\n\n private _onChange = (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target.files) {\n this._dispatchEvent('files-change', { files: target.files });\n \n this._handleFiles(target.files);\n target.value = ''; // Reset so same file can be selected again\n }\n };\n\n private async _handleFiles(files: FileList) {\n if (this.limit > 0 && this.fileList.length + files.length > this.limit) {\n this._dispatchEvent('exceed', { files });\n return;\n }\n\n const newFiles: UploadFile[] = [];\n\n for (const file of Array.from(files)) {\n const isImage = fileUtils.isImageFile(file);\n const fileObj: UploadFile = {\n name: file.name,\n size: fileUtils.formatFileSize(file.size),\n raw: file,\n status: 'ready',\n percentage: 0,\n uid: Date.now() + Math.random().toString(36).substring(2),\n isImage\n };\n\n // Create preview URL for images if preview is enabled\n if (this.preview && isImage) {\n fileObj.url = await fileUtils.createFilePreview(file);\n }\n\n this.fileList = [...this.fileList, fileObj];\n newFiles.push(fileObj);\n }\n\n this.requestUpdate();\n\n // Emit file-selected event with the new files\n this._dispatchEvent('select', { files: newFiles, fileList: this.fileList });\n }\n\n public updateFileStatus(uid: string, status: 'ready' | 'uploading' | 'success' | 'error', percentage?: number) {\n const file = this.fileList.find(f => f.uid === uid);\n \n if (file) {\n file.status = status;\n if (percentage !== undefined) {\n file.percentage = percentage;\n }\n this._updateFile(file);\n }\n }\n\n private _updateFile(updatedFile: UploadFile) {\n this.fileList = this.fileList.map(file =>\n file.uid === updatedFile.uid ? updatedFile : file\n );\n this.requestUpdate();\n }\n\n private _removeFile(uid: string) {\n const file = this.fileList.find(file => file.uid === uid);\n this.fileList = this.fileList.filter(file => file.uid !== uid);\n if (file) {\n this._dispatchEvent('remove', { file });\n }\n this.requestUpdate();\n }\n\n private _dispatchEvent(name: string, data: any) {\n this.dispatchEvent(new CustomEvent(`file-${name}`, {\n detail: data,\n bubbles: true,\n composed: true\n }));\n }\n\n private _showPreview(url: string) {\n this.previewImage = url;\n }\n\n private _closePreview() {\n this.previewImage = null;\n }\n\n override render() {\n return html`\n <div class=\"upload\" @drop=${this._onDrop} @dragover=${(e: DragEvent) => e.preventDefault()}>\n <input \n type=\"file\" \n class=\"hidden\" \n accept=${this.accept}\n ?multiple=${this.multiple}\n @change=${this._onChange}\n />\n\n ${this.showDragArea ? html`\n <div \n class=\"upload-dragger ${this.isDragOver ? 'is-dragover' : ''}\" \n @click=${this._onClick}\n >\n <div class=\"upload-icon\">\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\n <polyline points=\"17 8 12 3 7 8\"></polyline>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"></line>\n </svg>\n </div>\n <div class=\"upload-text\">Drop file here or click to upload</div>\n ${this.tip ? html`<div class=\"upload-tip\">${this.tip}</div>` : ''}\n </div>\n ` : html`\n <button class=\"upload-button\" @click=${this._onClick}>Upload File</button>\n ${this.tip ? html`<div class=\"upload-tip\">${this.tip}</div>` : ''}\n `}\n\n <div class=\"file-list\">\n ${this.fileList.map(file => html`\n <div class=\"file-item\">\n ${file.isImage ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle>\n <polyline points=\"21 15 16 10 5 21\"></polyline>\n </svg>\n ` : html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n </svg>\n `}\n <div class=\"file-name\">${file.name}</div>\n <div class=\"file-size\">${file.size}</div>\n <div class=\"file-status\">\n ${file.status === 'success' ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#67c23a\" stroke-width=\"2\">\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n ` : file.status === 'error' ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#f56c6c\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n ` : file.status === 'uploading' ? html`${file.percentage}%` : ''}\n </div>\n <div class=\"file-actions\">\n ${file.isImage && file.url ? html`\n <button class=\"preview-icon\" @click=${() => this._showPreview(file.url!)}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n </svg>\n </button>\n ` : ''}\n <button @click=${() => this._removeFile(file.uid)}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n ${file.status === 'uploading' ? html`\n <div class=\"progress-bar\">\n <div class=\"progress-inner\" style=\"width: ${file.percentage}%\"></div>\n </div>\n ` : ''}\n </div>\n ${this.preview && file.isImage && file.url ? html`\n <div class=\"file-preview\">\n <img \n class=\"image-preview\" \n src=\"${file.url}\" \n alt=\"${file.name}\" \n @click=${() => this._showPreview(file.url!)}\n />\n </div>\n ` : ''}\n `)}\n </div>\n\n ${this.previewImage ? html`\n <div class=\"preview-modal\" @click=${this._closePreview}>\n <button class=\"preview-close\">×</button>\n <img src=\"${this.previewImage}\" alt=\"Preview\" />\n </div>\n ` : ''}\n </div>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"file-upload.component.js","sourceRoot":"","sources":["../../../src/components/file-upload/file-upload.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, PropertyValues } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { UploadFile } from './types.js';\nimport { styles } from './styles.js';\nimport { fileUtils } from './utils.js';\n\n@customElement('nr-file-upload')\nexport class FileUpload extends LitElement {\n static override styles = styles;\n\n @property({ type: String }) accept: string = '';\n @property({ type: Boolean }) multiple: boolean = false;\n @property({ type: Boolean }) drag: boolean = true;\n @property({ type: String }) tip: string = '';\n @property({ type: Number }) limit: number = 0;\n @property({ type: Boolean }) preview: boolean = true;\n @property({ type: Boolean }) generatePreviewOnUpload: boolean = false;\n\n @state() fileList: UploadFile[] = [];\n @state() isDragOver: boolean = false;\n @state() showDragArea: boolean = false;\n @state() inputElement: HTMLInputElement | null = null;\n @state() dragCounter: number = 0;\n @state() previewImage: string | null = null;\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.drag) {\n document.addEventListener('dragenter', this._onDocumentDragEnter);\n document.addEventListener('dragleave', this._onDocumentDragLeave);\n document.addEventListener('drop', this._onDocumentDrop);\n document.addEventListener('dragover', this._onDocumentDragOver);\n }\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n if (this.drag) {\n document.removeEventListener('dragenter', this._onDocumentDragEnter);\n document.removeEventListener('dragleave', this._onDocumentDragLeave);\n document.removeEventListener('drop', this._onDocumentDrop);\n document.removeEventListener('dragover', this._onDocumentDragOver);\n }\n }\n\n override firstUpdated(_changedProperties: PropertyValues) {\n super.firstUpdated(_changedProperties);\n this.inputElement = this.shadowRoot?.querySelector('input[type=\"file\"]') || null;\n }\n\n private _onDocumentDragEnter = (e: DragEvent) => {\n e.preventDefault();\n this.dragCounter++;\n \n if (this.dragCounter === 1) {\n this.showDragArea = true;\n }\n };\n\n private _onDocumentDragLeave = (e: DragEvent) => {\n e.preventDefault();\n this.dragCounter--;\n \n if (this.dragCounter === 0) {\n this.showDragArea = false;\n this.isDragOver = false;\n }\n };\n\n private _onDocumentDrop = (e: DragEvent) => {\n if (e.target !== this && !this.contains(e.target as Node)) {\n e.preventDefault();\n this.dragCounter = 0;\n this.showDragArea = false;\n this.isDragOver = false;\n }\n };\n\n private _onDocumentDragOver = (e: DragEvent) => {\n e.preventDefault();\n \n // Determine if the drag is over our component\n const path = e.composedPath();\n const isOverComponent = path.includes(this);\n \n if (isOverComponent) {\n this.isDragOver = true;\n } else {\n this.isDragOver = false;\n }\n };\n\n private _onDrop = (e: DragEvent) => {\n e.preventDefault();\n e.stopPropagation();\n \n this.dragCounter = 0;\n this.isDragOver = false;\n this.showDragArea = false;\n\n if (e.dataTransfer?.files) {\n this.dispatchEvent(\n new CustomEvent(`files-changed`, {\n detail: e.dataTransfer.files,\n bubbles: true,\n composed: true\n })\n );\n \n this.dispatchEvent(\n new CustomEvent(`file-drop`, {\n detail: { files: e.dataTransfer.files },\n bubbles: true,\n composed: true\n })\n );\n \n this._handleFiles(e.dataTransfer.files);\n }\n };\n\n private _onClick = () => {\n this.inputElement?.click();\n };\n\n private _onChange = (e: Event) => {\n const target = e.target as HTMLInputElement;\n if (target.files) {\n this.dispatchEvent(\n new CustomEvent(`files-changed`, {\n detail: target.files,\n bubbles: true,\n composed: true\n }\n ));\n \n this._handleFiles(target.files);\n target.value = ''; \n }\n };\n\n private async _handleFiles(files: FileList) {\n // Early check for multiple mode\n if (this.multiple && this.limit > 0 && this.fileList.length + files.length > this.limit) {\n this._dispatchEvent('exceed', { files });\n return;\n }\n \n // If not multiple, keep only the last file\n if (!this.multiple && files.length > 0) {\n // Get the last file from the FileList\n const lastFile = files[files.length - 1];\n \n // If preview modal is showing a preview from a file that's being replaced, close it\n if (this.previewImage && this.fileList.some(file => file.url === this.previewImage)) {\n this.previewImage = null;\n }\n \n // If there are existing files, dispatch remove events for each one\n const oldFiles = [...this.fileList];\n for (const file of oldFiles) {\n this._dispatchEvent('remove', { file });\n }\n \n // Clear the file list\n this.fileList = [];\n \n // Process only the last file\n const isImage = fileUtils.isImageFile(lastFile);\n const fileObj: UploadFile = {\n name: lastFile.name,\n size: fileUtils.formatFileSize(lastFile.size),\n raw: lastFile,\n status: 'ready',\n percentage: 0,\n uid: Date.now() + Math.random().toString(36).substring(2),\n isImage\n };\n\n if (this.preview && this.generatePreviewOnUpload && isImage) {\n fileObj.url = await fileUtils.createFilePreview(lastFile);\n }\n\n this.fileList = [fileObj];\n \n this.requestUpdate();\n\n // Emit file-selected event with the new file\n this._dispatchEvent('select', { files: [fileObj], fileList: this.fileList });\n \n return;\n }\n\n // For multiple mode, process all files\n const newFiles: UploadFile[] = [];\n\n for (const file of Array.from(files)) {\n const isImage = fileUtils.isImageFile(file);\n const fileObj: UploadFile = {\n name: file.name,\n size: fileUtils.formatFileSize(file.size),\n raw: file,\n status: 'ready',\n percentage: 0,\n uid: Date.now() + Math.random().toString(36).substring(2),\n isImage\n };\n\n if (this.preview && this.generatePreviewOnUpload && isImage) {\n fileObj.url = await fileUtils.createFilePreview(file);\n }\n\n this.fileList = [...this.fileList, fileObj];\n newFiles.push(fileObj);\n }\n\n this.requestUpdate();\n\n // Emit file-selected event with the new files\n this._dispatchEvent('select', { files: newFiles, fileList: this.fileList });\n }\n\n public updateFileStatus(uid: string, status: 'ready' | 'uploading' | 'success' | 'error', percentage?: number) {\n const file = this.fileList.find(f => f.uid === uid);\n \n if (file) {\n file.status = status;\n if (percentage !== undefined) {\n file.percentage = percentage;\n }\n this._updateFile(file);\n }\n }\n\n private _updateFile(updatedFile: UploadFile) {\n this.fileList = this.fileList.map(file =>\n file.uid === updatedFile.uid ? updatedFile : file\n );\n this.requestUpdate();\n }\n\n private _removeFile(uid: string) {\n const file = this.fileList.find(file => file.uid === uid);\n this.fileList = this.fileList.filter(file => file.uid !== uid);\n if (file) {\n this._dispatchEvent('remove', { file });\n }\n this.requestUpdate();\n }\n\n private _dispatchEvent(name: string, data: any) {\n this.dispatchEvent(new CustomEvent(`file-${name}`, {\n detail: data,\n bubbles: true,\n composed: true\n }));\n }\n\n private _showPreview(url: string) {\n this.previewImage = url;\n }\n\n private _closePreview() {\n this.previewImage = null;\n }\n\n override render() {\n return html`\n <div class=\"upload\" @drop=${this._onDrop} @dragover=${(e: DragEvent) => e.preventDefault()}>\n <input \n type=\"file\" \n class=\"hidden\" \n accept=${this.accept}\n ?multiple=${this.multiple}\n @change=${this._onChange}\n />\n\n ${this.showDragArea ? html`\n <div \n class=\"upload-dragger ${this.isDragOver ? 'is-dragover' : ''}\" \n @click=${this._onClick}\n >\n <div class=\"upload-icon\">\n <svg width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\n <polyline points=\"17 8 12 3 7 8\"></polyline>\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"></line>\n </svg>\n </div>\n <div class=\"upload-text\">Drop file here or click to upload</div>\n ${this.tip ? html`<div class=\"upload-tip\">${this.tip}</div>` : ''}\n </div>\n ` : html`\n <hy-button @click=${this._onClick}>Upload File</hy-button>\n ${this.tip ? html`<div class=\"upload-tip\">${this.tip}</div>` : ''}\n `}\n\n <div class=\"file-list\">\n ${this.fileList.map(file => html`\n <div class=\"file-item\">\n ${file.isImage ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle>\n <polyline points=\"21 15 16 10 5 21\"></polyline>\n </svg>\n ` : html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path>\n <polyline points=\"14 2 14 8 20 8\"></polyline>\n </svg>\n `}\n <div class=\"file-name\">${file.name}</div>\n <div class=\"file-size\">${file.size}</div>\n <div class=\"file-status\">\n ${file.status === 'success' ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#67c23a\" stroke-width=\"2\">\n <polyline points=\"20 6 9 17 4 12\"></polyline>\n </svg>\n ` : file.status === 'error' ? html`\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#f56c6c\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n ` : file.status === 'uploading' ? html`${file.percentage}%` : ''}\n </div>\n <div class=\"file-actions\">\n ${file.isImage && file.url ? html`\n <button class=\"preview-icon\" @click=${() => this._showPreview(file.url!)}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path>\n <circle cx=\"12\" cy=\"12\" r=\"3\"></circle>\n </svg>\n </button>\n ` : ''}\n <button @click=${() => this._removeFile(file.uid)}>\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n </svg>\n </button>\n </div>\n ${file.status === 'uploading' ? html`\n <div class=\"progress-bar\">\n <div class=\"progress-inner\" style=\"width: ${file.percentage}%\"></div>\n </div>\n ` : ''}\n </div>\n ${this.preview && file.isImage && file.url ? html`\n <div class=\"file-preview\">\n <img \n class=\"image-preview\" \n src=\"${file.url}\" \n alt=\"${file.name}\" \n @click=${() => this._showPreview(file.url!)}\n />\n </div>\n ` : ''}\n `)}\n </div>\n\n ${this.previewImage ? html`\n <div class=\"preview-modal\" @click=${this._closePreview}>\n <button class=\"preview-close\">×</button>\n <img src=\"${this.previewImage}\" alt=\"Preview\" />\n </div>\n ` : ''}\n </div>\n `;\n }\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuralyui/file-upload",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "type": "module",
package/styles.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/components/file-upload/styles.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM,yBAmQlB,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../../../src/components/file-upload/styles.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,MAAM,yBA0RlB,CAAC"}
package/styles.js CHANGED
@@ -72,7 +72,13 @@ export const styles = css `
72
72
  transition: all 0.3s;
73
73
  padding: 8px;
74
74
  border-radius: 4px;
75
- gap: 10px; /* Add consistent spacing between items */
75
+ gap: 8px;
76
+ width: 100%;
77
+ box-sizing: border-box;
78
+ min-width: 0;
79
+ flex-wrap: nowrap;
80
+ overflow: hidden;
81
+ max-width: 100%;
76
82
  }
77
83
  .file-item:hover {
78
84
  background-color: #f8f9fa;
@@ -83,17 +89,22 @@ export const styles = css `
83
89
  overflow: hidden;
84
90
  text-overflow: ellipsis;
85
91
  color: #606266;
86
- min-width: 0;
92
+ min-width: 0;
93
+ max-width: 100%;
94
+ word-break: break-all;
95
+ width: 0;
87
96
  }
88
97
  .file-size {
89
98
  color: #909399;
90
99
  font-size: 12px;
91
- flex-shrink: 0; /* Prevent shrinking */
100
+ flex-shrink: 0;
101
+ margin-left: 8px;
102
+ white-space: nowrap;
92
103
  }
93
104
  .file-status {
94
105
  display: flex;
95
106
  align-items: center;
96
- flex-shrink: 0; /* Prevent shrinking */
107
+ flex-shrink: 0;
97
108
  }
98
109
  .file-actions {
99
110
  display: flex;
@@ -200,6 +211,7 @@ export const styles = css `
200
211
  .file-container {
201
212
  width: 100%;
202
213
  position: relative;
214
+ overflow: hidden; /* Prevent child overflow */
203
215
  }
204
216
 
205
217
  /* Responsive styles */
@@ -225,6 +237,10 @@ export const styles = css `
225
237
  "actions actions";
226
238
  gap: 4px 8px;
227
239
  align-items: center;
240
+ padding: 8px;
241
+ width: 100%;
242
+ box-sizing: border-box;
243
+ overflow: hidden; /* Hide content that overflows */
228
244
  }
229
245
  .file-item > svg:first-child {
230
246
  grid-area: icon;
@@ -234,6 +250,13 @@ export const styles = css `
234
250
  grid-area: filename;
235
251
  margin: 0;
236
252
  padding: 2px 0;
253
+ white-space: nowrap;
254
+ overflow: hidden;
255
+ text-overflow: ellipsis;
256
+ width: 0; /* Force shrinking to minimum width */
257
+ max-width: 100%; /* Ensure it doesn't exceed its container */
258
+ word-break: break-all; /* Break extremely long words if necessary */
259
+ flex: 1; /* Take available space */
237
260
  }
238
261
  .file-size {
239
262
  grid-area: size;
package/styles.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/components/file-upload/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmQxB,CAAC","sourcesContent":["import { css } from 'lit';\nexport const styles = css`\n:host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n}\n.upload {\n width: 100%;\n}\n.upload-dragger {\n background-color: #f8f9fa;\n border: 1px dashed #d9d9d9;\n border-radius: 6px;\n box-sizing: border-box;\n width: 100%;\n height: 180px;\n text-align: center;\n cursor: pointer;\n position: relative;\n overflow: hidden;\n transition: border-color 0.3s;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n}\n.upload-dragger:hover {\n border-color: #409eff;\n}\n.upload-dragger.is-dragover {\n background-color: rgba(64, 158, 255, 0.06);\n border-color: #409eff;\n}\n.upload-icon {\n font-size: 28px;\n color: #c0c4cc;\n margin-bottom: 8px;\n}\n.upload-text {\n color: #606266;\n font-size: 14px;\n text-align: center;\n padding: 0 12px;\n}\n.upload-tip {\n font-size: 12px;\n color: #909399;\n margin-top: 7px;\n padding: 0 12px;\n}\n.upload-button {\n padding: 8px 16px;\n background-color: #409eff;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n transition: background-color 0.3s;\n}\n.upload-button:hover {\n background-color: #66b1ff;\n}\n.file-list {\n margin-top: 10px;\n width: 100%;\n}\n.file-item {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n transition: all 0.3s;\n padding: 8px;\n border-radius: 4px;\n gap: 10px; /* Add consistent spacing between items */\n}\n.file-item:hover {\n background-color: #f8f9fa;\n}\n.file-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #606266;\n min-width: 0;\n}\n.file-size {\n color: #909399;\n font-size: 12px;\n flex-shrink: 0; /* Prevent shrinking */\n}\n.file-status {\n display: flex;\n align-items: center;\n flex-shrink: 0; /* Prevent shrinking */\n}\n.file-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0; /* Prevent shrinking */\n}\n.file-actions button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #909399;\n}\n.file-actions button:hover {\n color: #409eff;\n}\n\n/* Progress bar styles - fixed to ensure full width */\n.progress-bar {\n height: 2px;\n width: 100%;\n background-color: #e6e6e6;\n margin-top: 4px;\n position: relative;\n border-radius: 2px;\n overflow: hidden;\n}\n.progress-inner {\n height: 100%;\n background-color: #409eff;\n position: absolute;\n left: 0;\n top: 0;\n transition: width 0.3s ease;\n}\n\n/* Progress percentage indicator */\n.progress-percentage {\n position: absolute;\n right: 0;\n top: -18px;\n font-size: 12px;\n color: #409eff;\n}\n\n.hidden {\n display: none;\n}\n.success {\n color: #67c23a;\n}\n.error {\n color: #f56c6c;\n}\n.icon-delete {\n color: #f56c6c;\n}\n.file-preview {\n width: 100%;\n margin-top: 4px;\n}\n.image-preview {\n display: block;\n max-width: 100%;\n max-height: 200px;\n border-radius: 4px;\n object-fit: contain;\n cursor: zoom-in;\n}\n.preview-modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.7);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n.preview-modal img {\n max-width: 90%;\n max-height: 90%;\n object-fit: contain;\n}\n.preview-close {\n position: absolute;\n top: 20px;\n right: 20px;\n color: white;\n font-size: 30px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.preview-icon {\n padding: 4px;\n color: #409eff;\n cursor: zoom-in;\n}\n\n/* File item container with progress bar */\n.file-container {\n width: 100%;\n position: relative;\n}\n\n/* Responsive styles */\n@media (max-width: 600px) {\n .upload-dragger {\n height: 140px;\n padding: 12px;\n }\n .upload-icon {\n font-size: 24px;\n }\n .upload-text,\n .upload-tip {\n font-size: 13px;\n }\n .file-item {\n display: grid;\n grid-template-columns: auto 1fr;\n grid-template-areas: \n \"icon filename\"\n \"size status\"\n \"progress progress\"\n \"actions actions\";\n gap: 4px 8px;\n align-items: center;\n }\n .file-item > svg:first-child {\n grid-area: icon;\n align-self: start;\n }\n .file-name {\n grid-area: filename;\n margin: 0;\n padding: 2px 0;\n }\n .file-size {\n grid-area: size;\n margin: 0;\n }\n .file-status {\n grid-area: status;\n justify-self: end;\n }\n .progress-bar {\n grid-area: progress;\n width: 100%;\n }\n .file-actions {\n grid-area: actions;\n margin: 4px 0 0 0;\n justify-content: flex-end;\n width: 100%;\n }\n .upload-button {\n width: 100%;\n font-size: 16px;\n }\n}\n`;"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/components/file-upload/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0RxB,CAAC","sourcesContent":["import { css } from 'lit';\nexport const styles = css`\n:host {\n display: block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n}\n.upload {\n width: 100%;\n}\n.upload-dragger {\n background-color: #f8f9fa;\n border: 1px dashed #d9d9d9;\n border-radius: 6px;\n box-sizing: border-box;\n width: 100%;\n height: 180px;\n text-align: center;\n cursor: pointer;\n position: relative;\n overflow: hidden;\n transition: border-color 0.3s;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n}\n.upload-dragger:hover {\n border-color: #409eff;\n}\n.upload-dragger.is-dragover {\n background-color: rgba(64, 158, 255, 0.06);\n border-color: #409eff;\n}\n.upload-icon {\n font-size: 28px;\n color: #c0c4cc;\n margin-bottom: 8px;\n}\n.upload-text {\n color: #606266;\n font-size: 14px;\n text-align: center;\n padding: 0 12px;\n}\n.upload-tip {\n font-size: 12px;\n color: #909399;\n margin-top: 7px;\n padding: 0 12px;\n}\n.upload-button {\n padding: 8px 16px;\n background-color: #409eff;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n transition: background-color 0.3s;\n}\n.upload-button:hover {\n background-color: #66b1ff;\n}\n.file-list {\n margin-top: 10px;\n width: 100%;\n}\n.file-item {\n display: flex;\n align-items: center;\n margin-bottom: 8px;\n transition: all 0.3s;\n padding: 8px;\n border-radius: 4px;\n gap: 8px; \n width: 100%;\n box-sizing: border-box;\n min-width: 0; \n flex-wrap: nowrap;\n overflow: hidden;\n max-width: 100%;\n}\n.file-item:hover {\n background-color: #f8f9fa;\n}\n.file-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #606266;\n min-width: 0; \n max-width: 100%;\n word-break: break-all; \n width: 0;\n}\n.file-size {\n color: #909399;\n font-size: 12px;\n flex-shrink: 0;\n margin-left: 8px; \n white-space: nowrap;\n}\n.file-status {\n display: flex;\n align-items: center;\n flex-shrink: 0;\n}\n.file-actions {\n display: flex;\n gap: 4px;\n flex-shrink: 0; /* Prevent shrinking */\n}\n.file-actions button {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: #909399;\n}\n.file-actions button:hover {\n color: #409eff;\n}\n\n/* Progress bar styles - fixed to ensure full width */\n.progress-bar {\n height: 2px;\n width: 100%;\n background-color: #e6e6e6;\n margin-top: 4px;\n position: relative;\n border-radius: 2px;\n overflow: hidden;\n}\n.progress-inner {\n height: 100%;\n background-color: #409eff;\n position: absolute;\n left: 0;\n top: 0;\n transition: width 0.3s ease;\n}\n\n/* Progress percentage indicator */\n.progress-percentage {\n position: absolute;\n right: 0;\n top: -18px;\n font-size: 12px;\n color: #409eff;\n}\n\n.hidden {\n display: none;\n}\n.success {\n color: #67c23a;\n}\n.error {\n color: #f56c6c;\n}\n.icon-delete {\n color: #f56c6c;\n}\n.file-preview {\n width: 100%;\n margin-top: 4px;\n}\n.image-preview {\n display: block;\n max-width: 100%;\n max-height: 200px;\n border-radius: 4px;\n object-fit: contain;\n cursor: zoom-in;\n}\n.preview-modal {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.7);\n display: flex;\n justify-content: center;\n align-items: center;\n z-index: 1000;\n}\n.preview-modal img {\n max-width: 90%;\n max-height: 90%;\n object-fit: contain;\n}\n.preview-close {\n position: absolute;\n top: 20px;\n right: 20px;\n color: white;\n font-size: 30px;\n background: none;\n border: none;\n cursor: pointer;\n}\n.preview-icon {\n padding: 4px;\n color: #409eff;\n cursor: zoom-in;\n}\n\n/* File item container with progress bar */\n.file-container {\n width: 100%;\n position: relative;\n overflow: hidden; /* Prevent child overflow */\n}\n\n/* Responsive styles */\n@media (max-width: 600px) {\n .upload-dragger {\n height: 140px;\n padding: 12px;\n }\n .upload-icon {\n font-size: 24px;\n }\n .upload-text,\n .upload-tip {\n font-size: 13px;\n }\n .file-item {\n display: grid;\n grid-template-columns: auto 1fr;\n grid-template-areas: \n \"icon filename\"\n \"size status\"\n \"progress progress\"\n \"actions actions\";\n gap: 4px 8px;\n align-items: center;\n padding: 8px;\n width: 100%;\n box-sizing: border-box;\n overflow: hidden; /* Hide content that overflows */\n }\n .file-item > svg:first-child {\n grid-area: icon;\n align-self: start;\n }\n .file-name {\n grid-area: filename;\n margin: 0;\n padding: 2px 0;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n width: 0; /* Force shrinking to minimum width */\n max-width: 100%; /* Ensure it doesn't exceed its container */\n word-break: break-all; /* Break extremely long words if necessary */\n flex: 1; /* Take available space */\n }\n .file-size {\n grid-area: size;\n margin: 0;\n }\n .file-status {\n grid-area: status;\n justify-self: end;\n }\n .progress-bar {\n grid-area: progress;\n width: 100%;\n }\n .file-actions {\n grid-area: actions;\n margin: 4px 0 0 0;\n justify-content: flex-end;\n width: 100%;\n }\n .upload-button {\n width: 100%;\n font-size: 16px;\n }\n}\n`;"]}