@digital-realty/ix-file-uploader 1.0.32 → 1.0.34
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.
- package/dist/IxFileChip.d.ts +2 -1
- package/dist/IxFileChip.js.map +1 -1
- package/dist/IxFileUploader.d.ts +3 -1
- package/dist/IxFileUploader.js +8 -3
- package/dist/IxFileUploader.js.map +1 -1
- package/dist/internal/file-change-info.d.ts +2 -1
- package/dist/internal/file-change-info.js.map +1 -1
- package/dist/internal/file-info.d.ts +2 -1
- package/dist/internal/file-info.js.map +1 -1
- package/dist/internal/file-upload-result.d.ts +1 -0
- package/dist/internal/file-upload-result.js.map +1 -1
- package/dist/internal/files-uploaded-info.d.ts +2 -1
- package/dist/internal/files-uploaded-info.js.map +1 -1
- package/dist/internal/process-files.d.ts +3 -1
- package/dist/internal/process-files.js +34 -11
- package/dist/internal/process-files.js.map +1 -1
- package/dist/internal/sort-files-ascending.d.ts +2 -1
- package/dist/internal/sort-files-ascending.js.map +1 -1
- package/dist/internal/uploader-file.d.ts +4 -0
- package/dist/internal/uploader-file.js +2 -0
- package/dist/internal/uploader-file.js.map +1 -0
- package/dist/ix-file-uploader.min.js +1 -1
- package/package.json +2 -2
package/dist/IxFileChip.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import '@digital-realty/theme';
|
|
2
2
|
import '@digital-realty/ix-icon-button/ix-icon-button.js';
|
|
3
3
|
import { LitElement, TemplateResult } from 'lit';
|
|
4
|
+
import UploaderFile from './internal/uploader-file.js';
|
|
4
5
|
export declare class IxFileChip extends LitElement {
|
|
5
6
|
static readonly styles: import("lit").CSSResult[];
|
|
6
|
-
file?:
|
|
7
|
+
file?: UploaderFile;
|
|
7
8
|
private onClick;
|
|
8
9
|
private onDelete;
|
|
9
10
|
protected render(): TemplateResult<1>;
|
package/dist/IxFileChip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IxFileChip.js","sourceRoot":"","sources":["../src/IxFileChip.ts"],"names":[],"mappings":";AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,kDAAkD,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"IxFileChip.js","sourceRoot":"","sources":["../src/IxFileChip.ts"],"names":[],"mappings":";AAAA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,kDAAkD,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,UAAU,EAAkB,MAAM,KAAK,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAG7C,OAAO,gBAAgB,MAAM,iCAAiC,CAAC;AAG/D,MAAM,OAAO,UAAW,SAAQ,UAAU;IAKhC,OAAO;QACb,MAAM,KAAK,GAAG,IAAI,WAAW,CAAW,eAAe,EAAE;YACvD,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEO,QAAQ;QACd,MAAM,KAAK,GAAG,IAAI,WAAW,CAAW,gBAAgB,EAAE;YACxD,MAAM,EAAE;gBACN,IAAI,EAAE,IAAI,CAAC,IAAI;aAChB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAES,MAAM;;QACd,OAAO,IAAI,CAAA;qBACM,IAAI,CAAC,OAAO,KAAK,MAAA,IAAI,CAAC,IAAI,0CAAE,IAAI;;;iBAGpC,IAAI,CAAC,QAAQ;;;;;;UAMpB,CAAC;IACT,CAAC;;AApCe,iBAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAEhB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;wCAAqB","sourcesContent":["import '@digital-realty/theme';\nimport '@digital-realty/ix-icon-button/ix-icon-button.js';\nimport { html, LitElement, TemplateResult } from 'lit';\nimport { property } from 'lit/decorators.js';\n\nimport FileInfo from './internal/file-info.js';\nimport IxFileChipStyles from './styles/ix-file-chip-styles.js';\nimport UploaderFile from './internal/uploader-file.js';\n\nexport class IxFileChip extends LitElement {\n static readonly styles = [IxFileChipStyles];\n\n @property({ type: Object }) file?: UploaderFile;\n\n private onClick(): void {\n const event = new CustomEvent<FileInfo>('on-file-click', {\n detail: {\n file: this.file,\n },\n });\n\n this.dispatchEvent(event);\n }\n\n private onDelete(): void {\n const event = new CustomEvent<FileInfo>('on-file-delete', {\n detail: {\n file: this.file,\n },\n });\n\n this.dispatchEvent(event);\n }\n\n protected render(): TemplateResult<1> {\n return html`<li class=\"file-chip\">\n <span @click=${this.onClick}> ${this.file?.name} </span>\n\n <ix-icon-button\n @click=${this.onDelete}\n name=\"delete-button\"\n appearance=\"text\"\n icon=\"delete\"\n >\n </ix-icon-button>\n </li>`;\n }\n}\n"]}
|
package/dist/IxFileUploader.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { LitElement, PropertyValues, TemplateResult } from 'lit';
|
|
|
3
3
|
import { Ref } from 'lit/directives/ref.js';
|
|
4
4
|
import './ix-file-chip.js';
|
|
5
5
|
import DataStorageUnit from './data-storage-unit.js';
|
|
6
|
+
import UploaderFile from './internal/uploader-file.js';
|
|
6
7
|
export declare class IxFileUploader extends LitElement {
|
|
7
8
|
static readonly styles: import("lit").CSSResult[];
|
|
8
9
|
/** @nocollapse */
|
|
@@ -11,6 +12,7 @@ export declare class IxFileUploader extends LitElement {
|
|
|
11
12
|
dropzoneRef: Ref<HTMLInputElement>;
|
|
12
13
|
fileRef: Ref<HTMLInputElement>;
|
|
13
14
|
allowMultipleFiles: boolean;
|
|
15
|
+
allowDuplicates: boolean;
|
|
14
16
|
bodyText: string;
|
|
15
17
|
extensions: string[];
|
|
16
18
|
headerText: string;
|
|
@@ -18,7 +20,7 @@ export declare class IxFileUploader extends LitElement {
|
|
|
18
20
|
maxFileSizeUnit: DataStorageUnit;
|
|
19
21
|
maxFileSizeValue: number;
|
|
20
22
|
name: string;
|
|
21
|
-
files: Array<
|
|
23
|
+
files: Array<UploaderFile>;
|
|
22
24
|
private maxFileSizeInBytes;
|
|
23
25
|
/**
|
|
24
26
|
* The associated form element with which this element's value will submit.
|
package/dist/IxFileUploader.js
CHANGED
|
@@ -16,6 +16,7 @@ export class IxFileUploader extends LitElement {
|
|
|
16
16
|
this.dropzoneRef = createRef();
|
|
17
17
|
this.fileRef = createRef();
|
|
18
18
|
this.allowMultipleFiles = false;
|
|
19
|
+
this.allowDuplicates = false;
|
|
19
20
|
this.bodyText = '';
|
|
20
21
|
this.extensions = [];
|
|
21
22
|
this.headerText = '';
|
|
@@ -57,6 +58,7 @@ export class IxFileUploader extends LitElement {
|
|
|
57
58
|
filesToProcess,
|
|
58
59
|
maxFileCount: this.allowMultipleFiles ? this.maxFileCount : 1,
|
|
59
60
|
maxFileSizeInBytes: this.maxFileSizeInBytes,
|
|
61
|
+
allowDuplicates: this.allowDuplicates,
|
|
60
62
|
});
|
|
61
63
|
this.updateState(results);
|
|
62
64
|
this.onFilesUploaded(results);
|
|
@@ -65,7 +67,7 @@ export class IxFileUploader extends LitElement {
|
|
|
65
67
|
const filesToUpload = [];
|
|
66
68
|
results.forEach(result => {
|
|
67
69
|
if (result.uploaded) {
|
|
68
|
-
filesToUpload.push(result.file);
|
|
70
|
+
filesToUpload.push(Object.assign(result.file, { id: result.id }));
|
|
69
71
|
}
|
|
70
72
|
});
|
|
71
73
|
// handle multiple file setting
|
|
@@ -97,8 +99,8 @@ export class IxFileUploader extends LitElement {
|
|
|
97
99
|
}
|
|
98
100
|
onFileDelete(e) {
|
|
99
101
|
var _a;
|
|
100
|
-
const
|
|
101
|
-
this.files = [...this.files].filter(file => file.
|
|
102
|
+
const fileIdToDelete = (_a = e.detail.file) === null || _a === void 0 ? void 0 : _a.id;
|
|
103
|
+
this.files = [...this.files].filter(file => file.id !== fileIdToDelete);
|
|
102
104
|
const event = new CustomEvent('on-file-removed', {
|
|
103
105
|
detail: { allFiles: this.files, file: e.detail.file },
|
|
104
106
|
});
|
|
@@ -176,6 +178,9 @@ IxFileUploader.formAssociated = true;
|
|
|
176
178
|
__decorate([
|
|
177
179
|
property({ type: Boolean })
|
|
178
180
|
], IxFileUploader.prototype, "allowMultipleFiles", void 0);
|
|
181
|
+
__decorate([
|
|
182
|
+
property({ type: Boolean })
|
|
183
|
+
], IxFileUploader.prototype, "allowDuplicates", void 0);
|
|
179
184
|
__decorate([
|
|
180
185
|
property()
|
|
181
186
|
], IxFileUploader.prototype, "bodyText", void 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IxFileUploader.js","sourceRoot":"","sources":["../src/IxFileUploader.ts"],"names":[],"mappings":"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","sourcesContent":["import '@digital-realty/theme';\nimport { html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { createRef, ref, Ref } from 'lit/directives/ref.js';\n\nimport './ix-file-chip.js';\nimport DataStorageUnit from './data-storage-unit.js';\nimport FileInfo from './internal/file-info.js';\nimport FileUploadResult from './internal/file-upload-result.js';\nimport FileChangeInfo from './internal/file-change-info.js';\nimport FilesUploadedInfo from './internal/files-uploaded-info.js';\nimport getTotalBytes from './internal/get-total-bytes.js';\nimport { processFiles } from './internal/process-files.js';\nimport sortFilesAscending from './internal/sort-files-ascending.js';\nimport IxFileUploaderStyles from './styles/ix-file-uploader-styles.js';\n\nexport class IxFileUploader extends LitElement {\n static readonly styles = [IxFileUploaderStyles];\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n private readonly internals = (this as HTMLElement).attachInternals();\n\n dropzoneRef: Ref<HTMLInputElement> = createRef();\n\n fileRef: Ref<HTMLInputElement> = createRef();\n\n @property({ type: Boolean }) allowMultipleFiles: boolean = false;\n\n @property() bodyText: string = '';\n\n @property({ type: Array }) extensions: string[] = [];\n\n @property() headerText: string = '';\n\n @property({ type: Number }) maxFileCount: number = 10;\n\n @property() maxFileSizeUnit: DataStorageUnit = DataStorageUnit.MB;\n\n @property({ type: Number }) maxFileSizeValue: number = 10;\n\n @property() name: string = 'ix-file-uploader';\n\n @state() files: Array<File> = [];\n\n private maxFileSizeInBytes: number = 0;\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this.internals.form;\n }\n\n // called when the user drops files on the dropzone\n private onDrop(e: DragEvent): void {\n e.preventDefault();\n\n if (!e.dataTransfer) {\n return; // no files dropped\n }\n\n const filesToProcess = Array.from(e.dataTransfer.files);\n\n this.process(filesToProcess);\n }\n\n // This is called when the user selects files from the file dialog\n private onFileChange(e: Event): void {\n const fileList = (e.currentTarget as any).files as FileList;\n\n const filesToProcess = Array.from(fileList);\n\n this.process(filesToProcess);\n\n // clear the files from the file input; we are tracking state at the component level, not in the file input\n this.fileRef.value!.files = new DataTransfer().files;\n }\n\n // common method for processing files which are dropped or selected from file input dialog\n private process(filesToProcess: Array<File>): void {\n const results = processFiles({\n currentFiles: this.files,\n extensions: this.extensions,\n filesToProcess,\n maxFileCount: this.allowMultipleFiles ? this.maxFileCount : 1,\n maxFileSizeInBytes: this.maxFileSizeInBytes,\n });\n\n this.updateState(results);\n\n this.onFilesUploaded(results);\n }\n\n private updateState(results: Array<FileUploadResult> = []): void {\n const filesToUpload: Array<File> = [];\n\n results.forEach(result => {\n if (result.uploaded) {\n filesToUpload.push(result.file);\n }\n });\n\n // handle multiple file setting\n if (this.allowMultipleFiles) {\n this.files = [...this.files, ...filesToUpload];\n return;\n }\n\n // handle single file setting\n if (filesToUpload.length) {\n const file = filesToUpload[0];\n this.files = [file];\n }\n }\n\n private onFilesUploaded(results: Array<FileUploadResult>): void {\n const event = new CustomEvent<FilesUploadedInfo>('on-files-uploaded', {\n detail: {\n allFiles: this.files,\n filesUploaded: results.filter(result => result.uploaded),\n filesNotUploaded: results.filter(result => !result.uploaded),\n },\n });\n\n this.dispatchEvent(event);\n }\n\n private onFileClick(e: CustomEvent<FileInfo>): void {\n const event = new CustomEvent<FileChangeInfo>('on-file-clicked', {\n detail: { allFiles: this.files, file: e.detail.file },\n });\n\n this.dispatchEvent(event);\n }\n\n private onFileDelete(e: CustomEvent<FileInfo>): void {\n const fileNameToDelete = e.detail.file?.name;\n\n this.files = [...this.files].filter(file => file.name !== fileNameToDelete);\n\n const event = new CustomEvent<FileChangeInfo>('on-file-removed', {\n detail: { allFiles: this.files, file: e.detail.file },\n });\n\n this.dispatchEvent(event);\n }\n\n private openFileUploadDialog(): void {\n this.fileRef.value?.click();\n }\n\n protected override firstUpdated(): void {\n // connect the dropzone\n const dropzone = this.dropzoneRef.value;\n if (dropzone) {\n dropzone.addEventListener('dragenter', e => e.preventDefault());\n dropzone.addEventListener('dragover', e => e.preventDefault());\n dropzone.addEventListener('drop', this.onDrop.bind(this));\n }\n\n // connect the file input\n const fileElem = this.fileRef.value;\n if (fileElem) {\n fileElem.addEventListener('change', this.onFileChange.bind(this));\n }\n\n // calculate the maxBytes based on props\n // Calculate the max file size in bytes to use for checking if files are too large\n const totalBytesForStorageUnit = getTotalBytes(this.maxFileSizeUnit);\n this.maxFileSizeInBytes = this.maxFileSizeValue * totalBytesForStorageUnit;\n }\n\n private renderFileList(files: Array<File> = []): TemplateResult<1> {\n const sortedFiles = sortFilesAscending(files);\n\n const chips = sortedFiles.map(\n (file: File) => html`<ix-file-chip\n .file=${file}\n @on-file-click=${this.onFileClick}\n @on-file-delete=${this.onFileDelete}\n ></ix-file-chip>`\n );\n\n return html`\n <ul class=\"uploaded-file-list\">\n ${chips}\n </ul>\n `;\n }\n\n protected override updated(_: PropertyValues) {\n const formData = new FormData();\n\n this.files.forEach(file => {\n formData.append(`${this.name}[]`, file);\n });\n\n this.internals.setFormValue(formData);\n }\n\n protected render(): TemplateResult<1> {\n const accept = this.extensions.map(ext => `.${ext}`).join(', ');\n\n return html`<div class=\"ix-file-uploader\">\n <div\n class=\"dropzone\"\n @click=${this.openFileUploadDialog}\n @keyup=${this.openFileUploadDialog}\n ${ref(this.dropzoneRef)}\n >\n <div class=\"ix-file-uploader__label\">${this.headerText}</div>\n <div class=\"ix-file-uploader__help-text\">${this.bodyText}</div>\n <input\n accept=${accept}\n class=\"file-input\"\n ?multiple=${this.allowMultipleFiles}\n onchange=${this.onFileChange}\n ${ref(this.fileRef)}\n type=\"file\"\n />\n </div>\n ${this.files.length ? this.renderFileList(this.files) : nothing}\n </div>`;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IxFileUploader.js","sourceRoot":"","sources":["../src/IxFileUploader.ts"],"names":[],"mappings":"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","sourcesContent":["import '@digital-realty/theme';\nimport { html, LitElement, nothing, PropertyValues, TemplateResult } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { createRef, ref, Ref } from 'lit/directives/ref.js';\n\nimport './ix-file-chip.js';\nimport DataStorageUnit from './data-storage-unit.js';\nimport FileInfo from './internal/file-info.js';\nimport FileUploadResult from './internal/file-upload-result.js';\nimport FileChangeInfo from './internal/file-change-info.js';\nimport FilesUploadedInfo from './internal/files-uploaded-info.js';\nimport getTotalBytes from './internal/get-total-bytes.js';\nimport { processFiles } from './internal/process-files.js';\nimport sortFilesAscending from './internal/sort-files-ascending.js';\nimport IxFileUploaderStyles from './styles/ix-file-uploader-styles.js';\nimport UploaderFile from './internal/uploader-file.js';\n\nexport class IxFileUploader extends LitElement {\n static readonly styles = [IxFileUploaderStyles];\n\n /** @nocollapse */\n static readonly formAssociated = true;\n\n private readonly internals = (this as HTMLElement).attachInternals();\n\n dropzoneRef: Ref<HTMLInputElement> = createRef();\n\n fileRef: Ref<HTMLInputElement> = createRef();\n\n @property({ type: Boolean }) allowMultipleFiles: boolean = false;\n\n @property({ type: Boolean }) allowDuplicates: boolean = false;\n\n @property() bodyText: string = '';\n\n @property({ type: Array }) extensions: string[] = [];\n\n @property() headerText: string = '';\n\n @property({ type: Number }) maxFileCount: number = 10;\n\n @property() maxFileSizeUnit: DataStorageUnit = DataStorageUnit.MB;\n\n @property({ type: Number }) maxFileSizeValue: number = 10;\n\n @property() name: string = 'ix-file-uploader';\n\n @state() files: Array<UploaderFile> = [];\n\n private maxFileSizeInBytes: number = 0;\n\n /**\n * The associated form element with which this element's value will submit.\n */\n get form() {\n return this.internals.form;\n }\n\n // called when the user drops files on the dropzone\n private onDrop(e: DragEvent): void {\n e.preventDefault();\n\n if (!e.dataTransfer) {\n return; // no files dropped\n }\n\n const filesToProcess = Array.from(e.dataTransfer.files);\n\n this.process(filesToProcess);\n }\n\n // This is called when the user selects files from the file dialog\n private onFileChange(e: Event): void {\n const fileList = (e.currentTarget as any).files as FileList;\n\n const filesToProcess = Array.from(fileList);\n\n this.process(filesToProcess);\n\n // clear the files from the file input; we are tracking state at the component level, not in the file input\n this.fileRef.value!.files = new DataTransfer().files;\n }\n\n // common method for processing files which are dropped or selected from file input dialog\n private process(filesToProcess: Array<File>): void {\n const results = processFiles({\n currentFiles: this.files,\n extensions: this.extensions,\n filesToProcess,\n maxFileCount: this.allowMultipleFiles ? this.maxFileCount : 1,\n maxFileSizeInBytes: this.maxFileSizeInBytes,\n allowDuplicates: this.allowDuplicates,\n });\n\n this.updateState(results);\n\n this.onFilesUploaded(results);\n }\n\n private updateState(results: Array<FileUploadResult> = []): void {\n const filesToUpload: Array<UploaderFile> = [];\n\n results.forEach(result => {\n if (result.uploaded) {\n filesToUpload.push(Object.assign(result.file, { id: result.id }));\n }\n });\n\n // handle multiple file setting\n if (this.allowMultipleFiles) {\n this.files = [...this.files, ...filesToUpload];\n return;\n }\n\n // handle single file setting\n if (filesToUpload.length) {\n const file = filesToUpload[0];\n this.files = [file];\n }\n }\n\n private onFilesUploaded(results: Array<FileUploadResult>): void {\n const event = new CustomEvent<FilesUploadedInfo>('on-files-uploaded', {\n detail: {\n allFiles: this.files,\n filesUploaded: results.filter(result => result.uploaded),\n filesNotUploaded: results.filter(result => !result.uploaded),\n },\n });\n\n this.dispatchEvent(event);\n }\n\n private onFileClick(e: CustomEvent<FileInfo>): void {\n const event = new CustomEvent<FileChangeInfo>('on-file-clicked', {\n detail: { allFiles: this.files, file: e.detail.file },\n });\n\n this.dispatchEvent(event);\n }\n\n private onFileDelete(e: CustomEvent<FileInfo>): void {\n const fileIdToDelete = e.detail.file?.id;\n\n this.files = [...this.files].filter(file => file.id !== fileIdToDelete);\n\n const event = new CustomEvent<FileChangeInfo>('on-file-removed', {\n detail: { allFiles: this.files, file: e.detail.file },\n });\n\n this.dispatchEvent(event);\n }\n\n private openFileUploadDialog(): void {\n this.fileRef.value?.click();\n }\n\n protected override firstUpdated(): void {\n // connect the dropzone\n const dropzone = this.dropzoneRef.value;\n if (dropzone) {\n dropzone.addEventListener('dragenter', e => e.preventDefault());\n dropzone.addEventListener('dragover', e => e.preventDefault());\n dropzone.addEventListener('drop', this.onDrop.bind(this));\n }\n\n // connect the file input\n const fileElem = this.fileRef.value;\n if (fileElem) {\n fileElem.addEventListener('change', this.onFileChange.bind(this));\n }\n\n // calculate the maxBytes based on props\n // Calculate the max file size in bytes to use for checking if files are too large\n const totalBytesForStorageUnit = getTotalBytes(this.maxFileSizeUnit);\n this.maxFileSizeInBytes = this.maxFileSizeValue * totalBytesForStorageUnit;\n }\n\n private renderFileList(files: Array<UploaderFile> = []): TemplateResult<1> {\n const sortedFiles = sortFilesAscending(files);\n const chips = sortedFiles.map(\n (file?: UploaderFile) => html`<ix-file-chip\n .file=${file}\n @on-file-click=${this.onFileClick}\n @on-file-delete=${this.onFileDelete}\n ></ix-file-chip>`\n );\n\n return html`\n <ul class=\"uploaded-file-list\">\n ${chips}\n </ul>\n `;\n }\n\n protected override updated(_: PropertyValues) {\n const formData = new FormData();\n\n this.files.forEach(file => {\n formData.append(`${this.name}[]`, file);\n });\n\n this.internals.setFormValue(formData);\n }\n\n protected render(): TemplateResult<1> {\n const accept = this.extensions.map(ext => `.${ext}`).join(', ');\n\n return html`<div class=\"ix-file-uploader\">\n <div\n class=\"dropzone\"\n @click=${this.openFileUploadDialog}\n @keyup=${this.openFileUploadDialog}\n ${ref(this.dropzoneRef)}\n >\n <div class=\"ix-file-uploader__label\">${this.headerText}</div>\n <div class=\"ix-file-uploader__help-text\">${this.bodyText}</div>\n <input\n accept=${accept}\n class=\"file-input\"\n ?multiple=${this.allowMultipleFiles}\n onchange=${this.onFileChange}\n ${ref(this.fileRef)}\n type=\"file\"\n />\n </div>\n ${this.files.length ? this.renderFileList(this.files) : nothing}\n </div>`;\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-change-info.js","sourceRoot":"","sources":["../../src/internal/file-change-info.ts"],"names":[],"mappings":"","sourcesContent":["import FileInfo from './file-info.js';\n\ninterface FileChangeInfo extends FileInfo {\n allFiles: Array<
|
|
1
|
+
{"version":3,"file":"file-change-info.js","sourceRoot":"","sources":["../../src/internal/file-change-info.ts"],"names":[],"mappings":"","sourcesContent":["import FileInfo from './file-info.js';\nimport UploaderFile from './uploader-file.js';\n\ninterface FileChangeInfo extends FileInfo {\n allFiles: Array<UploaderFile>;\n}\n\nexport default FileChangeInfo;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-info.js","sourceRoot":"","sources":["../../src/internal/file-info.ts"],"names":[],"mappings":"","sourcesContent":["
|
|
1
|
+
{"version":3,"file":"file-info.js","sourceRoot":"","sources":["../../src/internal/file-info.ts"],"names":[],"mappings":"","sourcesContent":["import UploaderFile from './uploader-file.js';\n\ninterface FileInfo {\n file?: UploaderFile;\n}\n\nexport default FileInfo;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-upload-result.js","sourceRoot":"","sources":["../../src/internal/file-upload-result.ts"],"names":[],"mappings":"","sourcesContent":["interface FileUploadResult {\n file: File;\n message: string;\n uploaded: boolean;\n}\n\nexport default FileUploadResult;\n"]}
|
|
1
|
+
{"version":3,"file":"file-upload-result.js","sourceRoot":"","sources":["../../src/internal/file-upload-result.ts"],"names":[],"mappings":"","sourcesContent":["interface FileUploadResult {\n id: string;\n file: File;\n message: string;\n uploaded: boolean;\n}\n\nexport default FileUploadResult;\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import FileUploadResult from './file-upload-result.js';
|
|
2
|
+
import UploaderFile from './uploader-file.js';
|
|
2
3
|
interface FilesUploadedInfo {
|
|
3
|
-
allFiles: Array<
|
|
4
|
+
allFiles: Array<UploaderFile>;
|
|
4
5
|
filesUploaded: Array<FileUploadResult>;
|
|
5
6
|
filesNotUploaded: Array<FileUploadResult>;
|
|
6
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files-uploaded-info.js","sourceRoot":"","sources":["../../src/internal/files-uploaded-info.ts"],"names":[],"mappings":"","sourcesContent":["import FileUploadResult from './file-upload-result.js';\n\ninterface FilesUploadedInfo {\n allFiles: Array<
|
|
1
|
+
{"version":3,"file":"files-uploaded-info.js","sourceRoot":"","sources":["../../src/internal/files-uploaded-info.ts"],"names":[],"mappings":"","sourcesContent":["import FileUploadResult from './file-upload-result.js';\nimport UploaderFile from './uploader-file.js';\n\ninterface FilesUploadedInfo {\n allFiles: Array<UploaderFile>;\n filesUploaded: Array<FileUploadResult>;\n filesNotUploaded: Array<FileUploadResult>;\n}\n\nexport default FilesUploadedInfo;\n"]}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import FileUploadResult from './file-upload-result.js';
|
|
2
|
+
import UploaderFile from './uploader-file.js';
|
|
2
3
|
export interface Config {
|
|
3
|
-
currentFiles: Array<
|
|
4
|
+
currentFiles: Array<UploaderFile>;
|
|
4
5
|
extensions: Array<string>;
|
|
5
6
|
filesToProcess: Array<File>;
|
|
6
7
|
maxFileCount: number;
|
|
7
8
|
maxFileSizeInBytes: number;
|
|
9
|
+
allowDuplicates: boolean;
|
|
8
10
|
}
|
|
9
11
|
export declare const processFiles: (config: Config) => Array<FileUploadResult>;
|
|
@@ -1,40 +1,63 @@
|
|
|
1
1
|
export const processFiles = (config) => {
|
|
2
|
-
const { currentFiles, extensions, filesToProcess, maxFileCount, maxFileSizeInBytes, } = config;
|
|
2
|
+
const { currentFiles, extensions, filesToProcess, maxFileCount, maxFileSizeInBytes, allowDuplicates, } = config;
|
|
3
3
|
const results = [];
|
|
4
4
|
let filesToUploadCount = 0; // counter for how many files we add in the "for" loop below; used to know when we reach the maximum number of files allowed
|
|
5
|
-
for (
|
|
5
|
+
for (let file of filesToProcess) {
|
|
6
6
|
// check file extension
|
|
7
7
|
const fileExtension = file.name.split('.').pop() || '';
|
|
8
8
|
const isAllowedExtension = extensions.includes(fileExtension);
|
|
9
|
+
file = mapBrowserContentTypes(fileExtension, file);
|
|
9
10
|
if (!isAllowedExtension) {
|
|
10
11
|
const message = `File extension for "${file.name}" is not allowed`;
|
|
11
|
-
results.push({ file, message, uploaded: false });
|
|
12
|
+
results.push({ file, message, uploaded: false, id: crypto.randomUUID() });
|
|
12
13
|
continue;
|
|
13
14
|
}
|
|
14
15
|
// check for max file size
|
|
15
16
|
if (file.size > maxFileSizeInBytes) {
|
|
16
17
|
const message = `File size ${file.size} bytes is too large; maximum allowed size is ${maxFileSizeInBytes} bytes`;
|
|
17
|
-
results.push({ file, message, uploaded: false });
|
|
18
|
+
results.push({ file, message, uploaded: false, id: crypto.randomUUID() });
|
|
18
19
|
continue;
|
|
19
20
|
}
|
|
20
21
|
// check for max file count
|
|
21
22
|
const noMoreFilesAllowed = currentFiles.length + filesToUploadCount >= maxFileCount;
|
|
22
23
|
if (noMoreFilesAllowed) {
|
|
23
24
|
const message = `File not uploaded; it would exceed the maximum number of files (${maxFileCount})`;
|
|
24
|
-
results.push({ file, message, uploaded: false });
|
|
25
|
+
results.push({ file, message, uploaded: false, id: crypto.randomUUID() });
|
|
25
26
|
continue;
|
|
26
27
|
}
|
|
27
28
|
// check for duplicate file names
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
if (!allowDuplicates) {
|
|
30
|
+
const isDuplicate = currentFiles.some((f) => f.name === file.name);
|
|
31
|
+
if (isDuplicate) {
|
|
32
|
+
const message = `File not uploaded; there is already a file named ${file.name}`;
|
|
33
|
+
results.push({
|
|
34
|
+
file,
|
|
35
|
+
message,
|
|
36
|
+
uploaded: false,
|
|
37
|
+
id: crypto.randomUUID(),
|
|
38
|
+
});
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
33
41
|
}
|
|
34
42
|
// The file passes all validation and can be added
|
|
35
|
-
results.push({
|
|
43
|
+
results.push({
|
|
44
|
+
file,
|
|
45
|
+
message: 'File uploaded',
|
|
46
|
+
uploaded: true,
|
|
47
|
+
id: crypto.randomUUID(),
|
|
48
|
+
});
|
|
36
49
|
filesToUploadCount += 1;
|
|
37
50
|
}
|
|
38
51
|
return results;
|
|
39
52
|
};
|
|
53
|
+
function mapBrowserContentTypes(fileExtension, file) {
|
|
54
|
+
if (mimeTypeMap[`${fileExtension}-${file.type}`]) {
|
|
55
|
+
return new File([file], file.name, { type: mimeTypeMap[`${fileExtension}-${file.type}`] });
|
|
56
|
+
}
|
|
57
|
+
return file;
|
|
58
|
+
}
|
|
59
|
+
// key is source file extension and browser infered content type
|
|
60
|
+
const mimeTypeMap = {
|
|
61
|
+
"csv-application/vnd.ms-excel": "text/csv"
|
|
62
|
+
};
|
|
40
63
|
//# sourceMappingURL=process-files.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-files.js","sourceRoot":"","sources":["../../src/internal/process-files.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process-files.js","sourceRoot":"","sources":["../../src/internal/process-files.ts"],"names":[],"mappings":"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","sourcesContent":["import FileUploadResult from './file-upload-result.js';\nimport UploaderFile from './uploader-file.js';\n\nexport interface Config {\n currentFiles: Array<UploaderFile>;\n extensions: Array<string>;\n filesToProcess: Array<File>;\n maxFileCount: number;\n maxFileSizeInBytes: number;\n allowDuplicates: boolean;\n}\n\nexport const processFiles = (config: Config): Array<FileUploadResult> => {\n const {\n currentFiles,\n extensions,\n filesToProcess,\n maxFileCount,\n maxFileSizeInBytes,\n allowDuplicates,\n } = config;\n\n const results: Array<FileUploadResult> = [];\n\n let filesToUploadCount = 0; // counter for how many files we add in the \"for\" loop below; used to know when we reach the maximum number of files allowed\n\n for (let file of filesToProcess) {\n // check file extension\n const fileExtension = file.name.split('.').pop() || '';\n const isAllowedExtension = extensions.includes(fileExtension);\n file = mapBrowserContentTypes(fileExtension, file);\n if (!isAllowedExtension) {\n const message = `File extension for \"${file.name}\" is not allowed`;\n results.push({ file, message, uploaded: false, id: crypto.randomUUID() });\n continue;\n }\n\n // check for max file size\n if (file.size > maxFileSizeInBytes) {\n const message = `File size ${file.size} bytes is too large; maximum allowed size is ${maxFileSizeInBytes} bytes`;\n results.push({ file, message, uploaded: false, id: crypto.randomUUID() });\n continue;\n }\n\n // check for max file count\n const noMoreFilesAllowed =\n currentFiles.length + filesToUploadCount >= maxFileCount;\n if (noMoreFilesAllowed) {\n const message = `File not uploaded; it would exceed the maximum number of files (${maxFileCount})`;\n results.push({ file, message, uploaded: false, id: crypto.randomUUID() });\n continue;\n }\n\n // check for duplicate file names\n if (!allowDuplicates) {\n const isDuplicate = currentFiles.some(\n (f: UploaderFile) => f.name === file.name\n );\n if (isDuplicate) {\n const message = `File not uploaded; there is already a file named ${file.name}`;\n results.push({\n file,\n message,\n uploaded: false,\n id: crypto.randomUUID(),\n });\n continue;\n }\n }\n\n // The file passes all validation and can be added\n results.push({\n file,\n message: 'File uploaded',\n uploaded: true,\n id: crypto.randomUUID(),\n });\n filesToUploadCount += 1;\n }\n\n return results;\n};\nfunction mapBrowserContentTypes(fileExtension: string, file: File) {\n if(mimeTypeMap[`${fileExtension}-${file.type}`]) {\n return new File([file], file.name, { type: mimeTypeMap[`${fileExtension}-${file.type}`]});\n }\n return file;\n}\n\n// key is source file extension and browser infered content type\nconst mimeTypeMap:{[key:string]: string} = {\n \"csv-application/vnd.ms-excel\": \"text/csv\"\n}"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sort-files-ascending.js","sourceRoot":"","sources":["../../src/internal/sort-files-ascending.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sort-files-ascending.js","sourceRoot":"","sources":["../../src/internal/sort-files-ascending.ts"],"names":[],"mappings":"AAEA,MAAM,kBAAkB,GAAG,CACzB,cAAmC,EAAE,EAChB,EAAE,CACvB,WAAW,CAAC,IAAI,CAAC,CAAC,KAAmB,EAAE,KAAmB,EAAE,EAAE;IAC5D,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAEjD,IAAI,SAAS,GAAG,SAAS,EAAE;QACzB,OAAO,CAAC,CAAC,CAAC;KACX;IACD,IAAI,SAAS,GAAG,SAAS,EAAE;QACzB,OAAO,CAAC,CAAC;KACV;IAED,OAAO,CAAC,CAAC;AACX,CAAC,CAAC,CAAC;AAEL,eAAe,kBAAkB,CAAC","sourcesContent":["import UploaderFile from './uploader-file.js';\n\nconst sortFilesAscending = (\n filesToSort: Array<UploaderFile> = []\n): Array<UploaderFile> =>\n filesToSort.sort((file1: UploaderFile, file2: UploaderFile) => {\n const file1Name = file1.name.toLocaleLowerCase();\n const file2Name = file2.name.toLocaleLowerCase();\n\n if (file1Name < file2Name) {\n return -1;\n }\n if (file2Name > file1Name) {\n return 1;\n }\n\n return 0;\n });\n\nexport default sortFilesAscending;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploader-file.js","sourceRoot":"","sources":["../../src/internal/uploader-file.ts"],"names":[],"mappings":"","sourcesContent":["interface UploaderFile extends File {\n id: string;\n}\n\nexport default UploaderFile;\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__decorate}from"tslib";import"@digital-realty/theme";import{css,LitElement,html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";const IxFileChipStyles=css`.file-chip{align-items:center;background:#f5f7ff;cursor:pointer;display:flex;flex:auto;padding:4px 8px}.file-chip span{margin-right:10px}`;class IxFileChip extends LitElement{onClick(){var e=new CustomEvent("on-file-click",{detail:{file:this.file}});this.dispatchEvent(e)}onDelete(){var e=new CustomEvent("on-file-delete",{detail:{file:this.file}});this.dispatchEvent(e)}render(){var e;return html`<li class="file-chip"><span @click="${this.onClick}">${null==(e=this.file)?void 0:e.name}</span><ix-icon-button @click="${this.onDelete}" name="delete-button" appearance="text" icon="delete"></ix-icon-button></li>`}}IxFileChip.styles=[IxFileChipStyles],__decorate([property({type:Object})],IxFileChip.prototype,"file",void 0),customElements.define("ix-file-chip",IxFileChip),function(e){e.B="B",e.KB="KB",e.MB="MB",e.GB="GB",e.TB="TB",e.PB="PB",e.EB="EB",e.ZB="ZB",e.YB="YB"}(DataStorageUnit=DataStorageUnit||{});var DataStorageUnit,DataStorageUnit$1=DataStorageUnit;const KB=1024,MB=1024*KB,GB=1024*MB,TB=1024*GB,PB=1024*TB,EB=1024*PB,ZB=1024*EB,YB=1024*ZB,getTotalBytes=e=>{switch(e){case DataStorageUnit$1.KB:return KB;case DataStorageUnit$1.MB:return MB;case DataStorageUnit$1.GB:return GB;case DataStorageUnit$1.TB:return TB;case DataStorageUnit$1.PB:return PB;case DataStorageUnit$1.EB:return EB;case DataStorageUnit$1.ZB:return ZB;case DataStorageUnit$1.YB:return YB;default:return 0}},processFiles=e=>{var{currentFiles:
|
|
1
|
+
import{__decorate}from"tslib";import"@digital-realty/theme";import{css,LitElement,html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";const IxFileChipStyles=css`.file-chip{align-items:center;background:#f5f7ff;cursor:pointer;display:flex;flex:auto;padding:4px 8px}.file-chip span{margin-right:10px}`;class IxFileChip extends LitElement{onClick(){var e=new CustomEvent("on-file-click",{detail:{file:this.file}});this.dispatchEvent(e)}onDelete(){var e=new CustomEvent("on-file-delete",{detail:{file:this.file}});this.dispatchEvent(e)}render(){var e;return html`<li class="file-chip"><span @click="${this.onClick}">${null==(e=this.file)?void 0:e.name}</span><ix-icon-button @click="${this.onDelete}" name="delete-button" appearance="text" icon="delete"></ix-icon-button></li>`}}IxFileChip.styles=[IxFileChipStyles],__decorate([property({type:Object})],IxFileChip.prototype,"file",void 0),customElements.define("ix-file-chip",IxFileChip),function(e){e.B="B",e.KB="KB",e.MB="MB",e.GB="GB",e.TB="TB",e.PB="PB",e.EB="EB",e.ZB="ZB",e.YB="YB"}(DataStorageUnit=DataStorageUnit||{});var DataStorageUnit,DataStorageUnit$1=DataStorageUnit;const KB=1024,MB=1024*KB,GB=1024*MB,TB=1024*GB,PB=1024*TB,EB=1024*PB,ZB=1024*EB,YB=1024*ZB,getTotalBytes=e=>{switch(e){case DataStorageUnit$1.KB:return KB;case DataStorageUnit$1.MB:return MB;case DataStorageUnit$1.GB:return GB;case DataStorageUnit$1.TB:return TB;case DataStorageUnit$1.PB:return PB;case DataStorageUnit$1.EB:return EB;case DataStorageUnit$1.ZB:return ZB;case DataStorageUnit$1.YB:return YB;default:return 0}},processFiles=e=>{var{currentFiles:t,extensions:l,filesToProcess:e,maxFileCount:a,maxFileSizeInBytes:o,allowDuplicates:s}=e,r=[];let n=0;for(let i of e){var p=i.name.split(".").pop()||"",d=l.includes(p);if(i=mapBrowserContentTypes(p,i),d)if(i.size>o){p=`File size ${i.size} bytes is too large; maximum allowed size is ${o} bytes`;r.push({file:i,message:p,uploaded:!1,id:crypto.randomUUID()})}else if(t.length+n>=a)r.push({file:i,message:`File not uploaded; it would exceed the maximum number of files (${a})`,uploaded:!1,id:crypto.randomUUID()});else{if(!s)if(t.some(e=>e.name===i.name)){d="File not uploaded; there is already a file named "+i.name;r.push({file:i,message:d,uploaded:!1,id:crypto.randomUUID()});continue}r.push({file:i,message:"File uploaded",uploaded:!0,id:crypto.randomUUID()}),n+=1}else{p=`File extension for "${i.name}" is not allowed`;r.push({file:i,message:p,uploaded:!1,id:crypto.randomUUID()})}}return r};function mapBrowserContentTypes(e,i){return mimeTypeMap[e+"-"+i.type]?new File([i],i.name,{type:mimeTypeMap[e+"-"+i.type]}):i}const mimeTypeMap={"csv-application/vnd.ms-excel":"text/csv"},sortFilesAscending=(e=[])=>e.sort((e,i)=>{e=e.name.toLocaleLowerCase(),i=i.name.toLocaleLowerCase();return e<i?-1:0}),IxFileUploaderStyles=css`.ix-file-uploader{display:flex;flex-direction:column;justify-content:center;min-width:320px}.dropzone{background:var(--Background,#f5f7ff);border:1px dashed var(--Secondary-Main,#378aca);border-radius:3px;cursor:pointer;display:flex;flex-direction:column;gap:4px;padding:16px}.ix-file-uploader__label{color:var(--Text-Dark,#092241);font-family:Red Hat Display;font-size:.75rem;font-style:normal;font-weight:700;line-height:16px;letter-spacing:1.25px;text-align:center;text-transform:uppercase}.ix-file-uploader__help-text{color:var(--Text-Dark,#092241);font-family:Red Hat Display;font-size:.75rem;text-align:center}.uploaded-file-list{display:flex;flex-wrap:wrap;gap:16px;list-style:none;margin:0;margin-top:32px;padding:0}.file-input{opacity:0;border-width:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;white-space:nowrap;width:1px}`;class IxFileUploader extends LitElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.dropzoneRef=createRef(),this.fileRef=createRef(),this.allowMultipleFiles=!1,this.allowDuplicates=!1,this.bodyText="",this.extensions=[],this.headerText="",this.maxFileCount=10,this.maxFileSizeUnit=DataStorageUnit$1.MB,this.maxFileSizeValue=10,this.name="ix-file-uploader",this.files=[],this.maxFileSizeInBytes=0}get form(){return this.internals.form}onDrop(e){e.preventDefault(),e.dataTransfer&&(e=Array.from(e.dataTransfer.files),this.process(e))}onFileChange(e){e=e.currentTarget.files,e=Array.from(e);this.process(e),this.fileRef.value.files=(new DataTransfer).files}process(e){e=processFiles({currentFiles:this.files,extensions:this.extensions,filesToProcess:e,maxFileCount:this.allowMultipleFiles?this.maxFileCount:1,maxFileSizeInBytes:this.maxFileSizeInBytes,allowDuplicates:this.allowDuplicates});this.updateState(e),this.onFilesUploaded(e)}updateState(e=[]){const i=[];e.forEach(e=>{e.uploaded&&i.push(Object.assign(e.file,{id:e.id}))}),this.allowMultipleFiles?this.files=[...this.files,...i]:i.length&&(e=i[0],this.files=[e])}onFilesUploaded(e){e=new CustomEvent("on-files-uploaded",{detail:{allFiles:this.files,filesUploaded:e.filter(e=>e.uploaded),filesNotUploaded:e.filter(e=>!e.uploaded)}});this.dispatchEvent(e)}onFileClick(e){e=new CustomEvent("on-file-clicked",{detail:{allFiles:this.files,file:e.detail.file}});this.dispatchEvent(e)}onFileDelete(e){const i=null==(t=e.detail.file)?void 0:t.id;this.files=[...this.files].filter(e=>e.id!==i);var t=new CustomEvent("on-file-removed",{detail:{allFiles:this.files,file:e.detail.file}});this.dispatchEvent(t)}openFileUploadDialog(){var e;null!=(e=this.fileRef.value)&&e.click()}firstUpdated(){var e=this.dropzoneRef.value,e=(e&&(e.addEventListener("dragenter",e=>e.preventDefault()),e.addEventListener("dragover",e=>e.preventDefault()),e.addEventListener("drop",this.onDrop.bind(this))),this.fileRef.value),e=(e&&e.addEventListener("change",this.onFileChange.bind(this)),getTotalBytes(this.maxFileSizeUnit));this.maxFileSizeInBytes=this.maxFileSizeValue*e}renderFileList(e=[]){e=sortFilesAscending(e).map(e=>html`<ix-file-chip .file="${e}" @on-file-click="${this.onFileClick}" @on-file-delete="${this.onFileDelete}"></ix-file-chip>`);return html`<ul class="uploaded-file-list">${e}</ul>`}updated(e){const i=new FormData;this.files.forEach(e=>{i.append(this.name+"[]",e)}),this.internals.setFormValue(i)}render(){var e=this.extensions.map(e=>"."+e).join(", ");return html`<div class="ix-file-uploader"><div class="dropzone" @click="${this.openFileUploadDialog}" @keyup="${this.openFileUploadDialog}" ${ref(this.dropzoneRef)}><div class="ix-file-uploader__label">${this.headerText}</div><div class="ix-file-uploader__help-text">${this.bodyText}</div><input accept="${e}" class="file-input" ?multiple="${this.allowMultipleFiles}" onchange="${this.onFileChange}" ${ref(this.fileRef)} type="file"></div>${this.files.length?this.renderFileList(this.files):nothing}</div>`}}IxFileUploader.styles=[IxFileUploaderStyles],IxFileUploader.formAssociated=!0,__decorate([property({type:Boolean})],IxFileUploader.prototype,"allowMultipleFiles",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"allowDuplicates",void 0),__decorate([property()],IxFileUploader.prototype,"bodyText",void 0),__decorate([property({type:Array})],IxFileUploader.prototype,"extensions",void 0),__decorate([property()],IxFileUploader.prototype,"headerText",void 0),__decorate([property({type:Number})],IxFileUploader.prototype,"maxFileCount",void 0),__decorate([property()],IxFileUploader.prototype,"maxFileSizeUnit",void 0),__decorate([property({type:Number})],IxFileUploader.prototype,"maxFileSizeValue",void 0),__decorate([property()],IxFileUploader.prototype,"name",void 0),__decorate([state()],IxFileUploader.prototype,"files",void 0),customElements.define("ix-file-uploader",IxFileUploader);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Webcomponent ix-file-uploader following open-wc recommendations",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Digital Realty",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.34",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/index.js",
|
|
9
9
|
"module": "dist/index.js",
|
|
@@ -113,5 +113,5 @@
|
|
|
113
113
|
"README.md",
|
|
114
114
|
"LICENSE"
|
|
115
115
|
],
|
|
116
|
-
"gitHead": "
|
|
116
|
+
"gitHead": "d1ae79d9416a388c31319d8b88bcafd610542736"
|
|
117
117
|
}
|