@digital-realty/ix-file-uploader 1.2.21 → 1.3.1

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.
@@ -1,10 +1,249 @@
1
- import{__decorate}from"tslib";import{css,svg,LitElement,nothing,html}from"lit";import{property,state}from"lit/decorators.js";import{createRef,ref}from"lit/directives/ref.js";import{classMap}from"lit/directives/class-map.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";import"@digital-realty/ix-dialog/ix-dialog.js";let IxFileChipStyles=css`.file-chip{align-items:center;background:#f5f7ff;cursor:pointer;display:flex;flex:auto;padding:4px 8px;height:40px}.file-chip span{margin-right:10px;font-size:var(--ix-file-chip-font-size,var(--text-small-size,1rem));line-height:var(--ix-file-chip-line-height,var(--text-small-line-height,1.3rem));letter-spacing:var(--ix-file-chip-letter-spacing,var(--text-small-letter-spacing,.15px));color:var(--ix-file-chip-color, var(--clr-on-surface, 'inherit'))}.delete-icon{color:var(--md-sys-color-error)}`,trash=svg`<svg viewBox="0 0 24 24"><path d="M15.5 4H19V6H5V4H8.5L9.5 3H14.5L15.5 4ZM8 21C6.9 21 6 20.1 6 19V7H18V19C18 20.1 17.1 21 16 21H8Z"/></svg>`;class IxFileChip extends LitElement{constructor(){super(...arguments),this.deletable=!0}onClick(){var e=new CustomEvent("on-file-click",{detail:{file:this.file}});this.dispatchEvent(e)}onDelete(){var e;this.deletable&&(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>${this.deletable?html`<ix-icon-button @click="${this.onDelete}" name="delete-button"><ix-icon slot="default" class="delete-icon">${trash}</ix-icon></ix-icon-button>`:nothing}</li>`}}IxFileChip.styles=[IxFileChipStyles],__decorate([property({type:Object})],IxFileChip.prototype,"file",void 0),__decorate([property({type:Boolean})],IxFileChip.prototype,"deletable",void 0),customElements.define("ix-file-chip",IxFileChip),(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;let 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}},mimeTypeMap={"csv-application/vnd.ms-excel":"text/csv"};function mapBrowserContentTypes(e,i){return mimeTypeMap[e+"-"+i.type]?new File([i],i.name,{type:mimeTypeMap[e+"-"+i.type]}):i}let processFiles=e=>{var{currentFiles:t,extensions:l,filesToProcess:e,maxFileCount:o,maxFileSizeInBytes:a,allowDuplicates:r}=e,s=[];let n=0;for(let i of e){var p=i.name.split(".").pop()||"",d=l.includes(p.toLocaleLowerCase());if(i=mapBrowserContentTypes(p,i),d)if(i.size>a)s.push({file:i,message:"The file you are attempting to upload exceeds the maximum size allowed.",uploaded:!1,id:crypto.randomUUID()});else if(t.length+n>=o)s.push({file:i,message:`File not uploaded; it would exceed the maximum number of files (${o})`,uploaded:!1,id:crypto.randomUUID()});else{if(!r)if(t.some(e=>e.name===i.name)){p="File not uploaded; there is already a file named "+i.name;s.push({file:i,message:p,uploaded:!1,id:crypto.randomUUID()});continue}s.push({file:i,message:"File uploaded",uploaded:!0,id:crypto.randomUUID()}),n+=1}else{d=`File extension for "${i.name}" is not allowed`;s.push({file:i,message:d,uploaded:!1,id:crypto.randomUUID()})}}return s},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}.ix-file-uploader--hide-body{display:none}.dropzone{background:var(--clr-surface,#f5f7ff);border:1px dashed var(--clr-info,#2196f3);border-radius:3px;cursor:pointer;display:flex;flex-direction:column;gap:4px;padding:16px}.ix-file-uploader__label{color:var(
1
+ import{__decorate as e}from"tslib";import{css as i,svg as t,LitElement as l,nothing as o,html as s}from"lit";import{property as a,state as r}from"lit/decorators.js";import{createRef as n,ref as d}from"lit/directives/ref.js";import{classMap as p}from"lit/directives/class-map.js";import"@digital-realty/ix-icon-button/ix-icon-button.js";import"@digital-realty/ix-dialog/ix-dialog.js";const h=i`
2
+ .file-chip {
3
+ align-items: center;
4
+ background: #f5f7ff;
5
+ cursor: pointer;
6
+ display: flex;
7
+ flex: auto;
8
+ padding: 4px 8px;
9
+ height: 40px;
10
+ }
11
+
12
+ .file-chip span {
13
+ margin-right: 10px;
14
+
15
+ font-size: var(--ix-file-chip-font-size, var(--text-small-size, 1rem));
16
+ line-height: var(
17
+ --ix-file-chip-line-height,
18
+ var(--text-small-line-height, 1.3rem)
19
+ );
20
+ letter-spacing: var(
21
+ --ix-file-chip-letter-spacing,
22
+ var(--text-small-letter-spacing, 0.15px)
23
+ );
24
+ color: var(--ix-file-chip-color, var(--clr-on-surface, 'inherit'));
25
+ }
26
+
27
+ .delete-icon {
28
+ color: var(--md-sys-color-error);
29
+ }
30
+ `,f=t`<svg viewBox="0 0 24 24"><path d="M15.5 4H19V6H5V4H8.5L9.5 3H14.5L15.5 4ZM8 21C6.9 21 6 20.1 6 19V7H18V19C18 20.1 17.1 21 16 21H8Z" /></svg>`;class c extends l{constructor(){super(...arguments),this.deletable=!0}onClick(){const e=new CustomEvent("on-file-click",{detail:{file:this.file}});this.dispatchEvent(e)}onDelete(){if(this.deletable){const e=new CustomEvent("on-file-delete",{detail:{file:this.file}});this.dispatchEvent(e)}}render(){var e;return s`<li class="file-chip">
31
+ <span @click=${this.onClick}> ${null===(e=this.file)||void 0===e?void 0:e.name} </span>
32
+
33
+ ${this.deletable?s`<ix-icon-button @click=${this.onDelete} name="delete-button">
34
+ <ix-icon slot="default" class="delete-icon"> ${f} </ix-icon>
35
+ </ix-icon-button>`:o}
36
+ </li>`}}var u;c.styles=[h],e([a({type:Object})],c.prototype,"file",void 0),e([a({type:Boolean})],c.prototype,"deletable",void 0),customElements.define("ix-file-chip",c),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"}(u||(u={}));var m=u;const x=1048576,v=1024*x,g=1024*v,y=1024*g,F=1024*y,D=1024*F,B=1024*D,b={"csv-application/vnd.ms-excel":"text/csv"};function w(e,i){return b[`${e}-${i.type}`]?new File([i],i.name,{type:b[`${e}-${i.type}`]}):i}const $=i`
37
+ .ix-file-uploader {
38
+ display: flex;
39
+ flex-direction: column;
40
+ justify-content: center;
41
+ min-width: 320px;
42
+ }
43
+ .ix-file-uploader--hide-body {
44
+ display: none;
45
+ }
46
+ .dropzone {
47
+ background: var(--clr-surface, #f5f7ff);
48
+ border: 1px dashed var(--clr-info, #2196f3);
49
+ border-radius: 3px;
50
+ cursor: pointer;
51
+ display: flex;
52
+ flex-direction: column;
53
+ gap: 4px;
54
+ padding: 16px;
55
+ }
56
+ .ix-file-uploader__label {
57
+ color: var(
2
58
  --ix-file-uploader-label-color,
3
59
  var(--clr-on-surface, 'inherit')
4
- );font-family:var(
60
+ );
61
+ font-family: var(
5
62
  --ix-file-uploader-label-font-family,
6
63
  var(--root-secondary-font, 'inherit')
7
- );font-size:var(--ix-file-uploader-label-font-size,var(--text-small-size,.75rem));font-style:normal;font-weight:var(--ix-file-uploader-label-font-weight,700);line-height:var(--ix-file-uploader-label-line-height,var(--text-small-line-height,16px));letter-spacing:var(--ix-file-uploader-label-letter-spacing,var(--text-small-letter-spacing,1.25px));text-align:center;text-transform:var(--ix-file-uploader-label-text-transform,uppercase);margin:auto;width:var(--ix-file-uploader-label-width,100%)}.ix-file-uploader__help-text{color:var(--ix-file-uploader-help-color, var(--clr-on-surface, 'inherit'));font-family:var(
64
+ );
65
+ font-size: var(
66
+ --ix-file-uploader-label-font-size,
67
+ var(--text-small-size, 0.75rem)
68
+ );
69
+ font-style: normal;
70
+ font-weight: var(--ix-file-uploader-label-font-weight, 700);
71
+ line-height: var(
72
+ --ix-file-uploader-label-line-height,
73
+ var(--text-small-line-height, 16px)
74
+ );
75
+ letter-spacing: var(
76
+ --ix-file-uploader-label-letter-spacing,
77
+ var(--text-small-letter-spacing, 1.25px)
78
+ );
79
+ text-align: center;
80
+ text-transform: var(--ix-file-uploader-label-text-transform, uppercase);
81
+ margin: auto;
82
+ width: var(--ix-file-uploader-label-width, 100%);
83
+ }
84
+ .ix-file-uploader__help-text {
85
+ color: var(--ix-file-uploader-help-color, var(--clr-on-surface, 'inherit'));
86
+ font-family: var(
8
87
  --ix-file-uploader-help-font-family,
9
88
  var(--root-secondary-font, 'inherit')
10
- );font-size:var(--ix-file-uploader-help-font-size,var(--text-small-size,.75rem));line-height:var(--ix-file-uploader-help-line-height,var(--text-small-line-height,16px));letter-spacing:var(--ix-file-uploader-help-letter-spacing,var(--text-small-letter-spacing,1.25px));text-align:center}.uploaded-file-list{display:flex;flex-wrap:wrap;gap:16px;list-style:none;margin:0;padding:0}.uploaded-file-list--spaced{margin-top:32px}.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}.error .dropzone{border-color:var(--md-sys-color-error)}.error .error-text{color:var(--md-sys-color-error);padding-left:.75rem;font-size:.75rem;font-weight:400;display:flex;flex-direction:column;margin-top:.5rem;line-height:.75rem}.ix-file-uploader__hint-text{font-family:var(--root-primary-font, 'inherit') font-weight: 400;font-size:12px;line-height:16px;letter-spacing:.4px;padding-top:.5rem;color:var(--clr-on-surface, 'inherit')}.ix-file-uploader__template-file{display:flex;align-items:center}.delete-file-confirmation-dialog{max-width:560px;font-family:var(--root-secondary-font, 'Red Hat Display');font-weight:700;font-size:20px;leading-trim:NONE;line-height:24px;letter-spacing:.15px}`;class IxFileUploader extends LitElement{constructor(){super(...arguments),this.internals=this.attachInternals(),this.dropzoneRef=createRef(),this.fileRef=createRef(),this.showTemplateFileLink=!1,this.allowMultipleFiles=!1,this.allowDuplicates=!1,this.headerText="",this.bodyText="",this.hintText=void 0,this.defaultFiles=[],this.allowDeleteDefaultFiles=!1,this.hideBody=!1,this.extensions=[],this.maxFileCount=10,this.maxFileSizeUnit=DataStorageUnit$1.MB,this.maxFileSizeValue=10,this.name="ix-file-uploader",this.error=!1,this.askConfirmationOnDeleteFile=!1,this.deleteConfirmationDialogLabel="Are you sure you want to delete your upload file?",this.isDeleteBulkFileDialogOpen=!1,this.pendingFileDeletion=void 0,this.files=[],this.errors=[],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}get allowedMaxFileCount(){return this.allowMultipleFiles?this.maxFileCount:1}process(e){e=processFiles({currentFiles:this.files,extensions:this.extensions,filesToProcess:e,maxFileCount:this.allowedMaxFileCount,maxFileSizeInBytes:this.maxFileSizeInBytes,allowDuplicates:this.allowDuplicates});this.updateState(e),this.onFilesUploaded(e)}updateState(e=[]){let 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){this.errors=[];var i=e.filter(e=>!e.uploaded),e=new CustomEvent("on-files-uploaded",{detail:{allFiles:this.files,filesUploaded:e.filter(e=>e.uploaded),filesNotUploaded:i}}),i=null==i?void 0:i.map(e=>e.message).filter((e,i,t)=>t.indexOf(e)===i);this.errors=[...i],this.dispatchEvent(e)}onFileClick(e){e=new CustomEvent("on-file-clicked",{detail:{allFiles:this.files,file:e.detail.file}});this.dispatchEvent(e)}onFileDelete(e){this.pendingFileDeletion=e.detail.file,this.askConfirmationOnDeleteFile?this.isDeleteBulkFileDialogOpen=!0:this.handleDeleteBulkFile()}handleDeleteBulkFile(){this.files=[...this.files].filter(e=>e.id!==(null==(e=this.pendingFileDeletion)?void 0:e.id));var e=new CustomEvent("on-file-removed",{detail:{allFiles:this.files,file:this.pendingFileDeletion}});this.isDeleteBulkFileDialogOpen=!1,this.dispatchEvent(e)}deleteLastFileWithoutConfirmation(){0!==this.files.length&&(this.pendingFileDeletion=this.files[this.files.length-1],this.handleDeleteBulkFile())}openFileUploadDialog(){var e;null!=(e=this.fileRef.value)&&e.click()}firstUpdated(){this.files=[...this.defaultFiles];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}update(e){super.update(e),e.has("defaultFiles")&&(this.files=[...this.files.filter(i=>!this.defaultFiles.some(e=>e.name===i.name)),...this.defaultFiles])}isFileDeletable(i){return!this.defaultFiles.some(e=>e.name===i.name)||this.allowDeleteDefaultFiles}renderFileList(e=[]){var e=sortFilesAscending(e).map(e=>html`<ix-file-chip .file="${e}" .deletable="${this.isFileDeletable(e)}" @on-file-click="${this.onFileClick}" @on-file-delete="${this.onFileDelete}"></ix-file-chip>`),i={"uploaded-file-list":!0,"uploaded-file-list--spaced":!this.hideBody};return html`<ul class="${classMap(i)}">${e} ${this.showTemplateFileLink?html`<li class="ix-file-uploader__template-file"><slot name="template-file"></slot></li>`:nothing}</ul>${this.renderDeleteBulkFileConfirmationDialog()}`}updated(e){let i=new FormData;this.files.forEach(e=>{i.append(this.name+"[]",e)}),this.internals.setFormValue(i)}renderDeleteBulkFileConfirmationDialog(){return this.askConfirmationOnDeleteFile?html`<ix-dialog id="deleteFileConfirmationDialog" ?open="${this.isDeleteBulkFileDialogOpen}" preventCloseOnScrimClick="true" @closed="${()=>{this.isDeleteBulkFileDialogOpen=!1}}" @close="${()=>{this.isDeleteBulkFileDialogOpen=!1}}"><form slot="content" id="delete-file-id" method="dialog" class="delete-file-confirmation-dialog">${this.deleteConfirmationDialogLabel}</form><div slot="actions"><ix-button appearance="text" @click="${()=>{this.isDeleteBulkFileDialogOpen=!1}}"><span class="button-label">NO</span></ix-button><ix-button appearance="text" name="submitBtn" @click="${()=>this.handleDeleteBulkFile()}"><span class="button-label">YES</span></ix-button></div></ix-dialog>`:nothing}renderHintText(){return this.hintText?html`<div class="ix-file-uploader__hint-text">${this.hintText}</div>`:nothing}renderErrors(){return html`<div class="error-text">${this.errors.map(e=>html`<span>* ${e}</span>`)}</div>`}renderBody(){var e=this.extensions.map(e=>"."+e).join(", "),i={"ix-file-uploader--hide-body":this.hideBody};return html`<div class="${classMap(i)}"><div class="dropzone" @click="${this.openFileUploadDialog}" @keyup="${this.openFileUploadDialog}" ${ref(this.dropzoneRef)}><label class="ix-file-uploader__label" for="fileUploader">${this.headerText}</label><div class="ix-file-uploader__help-text" id="fileUploaderDesc">${this.bodyText}</div><input id="fileUploader" accept="${e}" class="file-input" ?multiple="${this.allowMultipleFiles}" onchange="${e=>this.onFileChange(e)}" ${ref(this.fileRef)} aria-describedby="fileUploaderDesc" type="file"></div>${this.renderErrors()} ${this.renderHintText()}</div>`}render(){return html`<div class="${classMap({"ix-file-uploader":!0,error:this.errors.length||this.error})}">${this.renderBody()} ${this.files.length?this.renderFileList(this.files):nothing}</div>`}}IxFileUploader.styles=[IxFileUploaderStyles],IxFileUploader.formAssociated=!0,__decorate([property({type:Boolean})],IxFileUploader.prototype,"showTemplateFileLink",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"allowMultipleFiles",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"allowDuplicates",void 0),__decorate([property()],IxFileUploader.prototype,"headerText",void 0),__decorate([property()],IxFileUploader.prototype,"bodyText",void 0),__decorate([property()],IxFileUploader.prototype,"hintText",void 0),__decorate([property({type:Array})],IxFileUploader.prototype,"defaultFiles",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"allowDeleteDefaultFiles",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"hideBody",void 0),__decorate([property({type:Array})],IxFileUploader.prototype,"extensions",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([property({type:Boolean})],IxFileUploader.prototype,"error",void 0),__decorate([property({type:Boolean})],IxFileUploader.prototype,"askConfirmationOnDeleteFile",void 0),__decorate([property()],IxFileUploader.prototype,"deleteConfirmationDialogLabel",void 0),__decorate([state()],IxFileUploader.prototype,"isDeleteBulkFileDialogOpen",void 0),__decorate([state()],IxFileUploader.prototype,"pendingFileDeletion",void 0),__decorate([state()],IxFileUploader.prototype,"files",void 0),__decorate([state()],IxFileUploader.prototype,"errors",void 0),customElements.define("ix-file-uploader",IxFileUploader);
89
+ );
90
+ font-size: var(
91
+ --ix-file-uploader-help-font-size,
92
+ var(--text-small-size, 0.75rem)
93
+ );
94
+ line-height: var(
95
+ --ix-file-uploader-help-line-height,
96
+ var(--text-small-line-height, 16px)
97
+ );
98
+ letter-spacing: var(
99
+ --ix-file-uploader-help-letter-spacing,
100
+ var(--text-small-letter-spacing, 1.25px)
101
+ );
102
+ text-align: center;
103
+ }
104
+ .uploaded-file-list {
105
+ display: flex;
106
+ flex-wrap: wrap;
107
+ gap: 16px;
108
+ list-style: none;
109
+ margin: 0;
110
+ padding: 0;
111
+ }
112
+ .uploaded-file-list--spaced {
113
+ margin-top: 32px;
114
+ }
115
+ .file-input {
116
+ /*
117
+ Per MDN -> https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file
118
+ "Note: opacity is used to hide the file input instead of visibility: hidden or display: none, because assistive technology interprets the latter two styles to mean the file input isn't interactive."
119
+ */
120
+ opacity: 0;
121
+
122
+ /*
123
+ Adapted styles from https://tailwindcss.com/docs/screen-readers
124
+ */
125
+ border-width: 0;
126
+ clip: rect(0, 0, 0, 0);
127
+ height: 1px;
128
+ margin: -1px;
129
+ overflow: hidden;
130
+ padding: 0;
131
+ white-space: nowrap;
132
+ width: 1px;
133
+ }
134
+ .error .dropzone {
135
+ border-color: var(--md-sys-color-error);
136
+ }
137
+
138
+ .error .error-text {
139
+ color: var(--md-sys-color-error);
140
+ padding-left: 0.75rem;
141
+ font-size: 0.75rem;
142
+ font-weight: 400;
143
+ display: flex;
144
+ flex-direction: column;
145
+ margin-top: 0.5rem;
146
+ line-height: 0.75rem;
147
+ }
148
+
149
+ .ix-file-uploader__hint-text{
150
+ font-family: var(--root-primary-font, 'inherit')
151
+ font-weight: 400;
152
+ font-size: 12px;
153
+ line-height: 16px;
154
+ letter-spacing: 0.4px;
155
+ padding-top: 0.5rem;
156
+ color: var(--clr-on-surface, 'inherit');
157
+ }
158
+
159
+ .ix-file-uploader__template-file {
160
+ display: flex;
161
+ align-items: center;
162
+ }
163
+ .delete-file-confirmation-dialog {
164
+ max-width: 560px;
165
+ font-family: var(--root-secondary-font, 'Red Hat Display');
166
+ font-weight: 700;
167
+ font-size: 20px;
168
+ leading-trim: NONE;
169
+ line-height: 24px;
170
+ letter-spacing: 0.15px;
171
+ }
172
+ `;class k extends l{constructor(){super(...arguments),this.internals=this.attachInternals(),this.dropzoneRef=n(),this.fileRef=n(),this.showTemplateFileLink=!1,this.allowMultipleFiles=!1,this.allowDuplicates=!1,this.headerText="",this.bodyText="",this.hintText=void 0,this.defaultFiles=[],this.allowDeleteDefaultFiles=!1,this.hideBody=!1,this.extensions=[],this.maxFileCount=10,this.maxFileSizeUnit=m.MB,this.maxFileSizeValue=10,this.name="ix-file-uploader",this.error=!1,this.askConfirmationOnDeleteFile=!1,this.deleteConfirmationDialogLabel="Are you sure you want to delete your upload file?",this.isDeleteBulkFileDialogOpen=!1,this.pendingFileDeletion=void 0,this.files=[],this.errors=[],this.maxFileSizeInBytes=0}get form(){return this.internals.form}onDrop(e){if(e.preventDefault(),!e.dataTransfer)return;const i=Array.from(e.dataTransfer.files);this.process(i)}onFileChange(e){const i=e.currentTarget.files,t=Array.from(i);this.process(t),this.fileRef.value.files=(new DataTransfer).files}get allowedMaxFileCount(){return this.allowMultipleFiles?this.maxFileCount:1}process(e){const i=(e=>{const{currentFiles:i,extensions:t,filesToProcess:l,maxFileCount:o,maxFileSizeInBytes:s,allowDuplicates:a}=e,r=[];let n=0;for(let e of l){const l=e.name.split(".").pop()||"",d=t.includes(l.toLocaleLowerCase());if(e=w(l,e),!d){const i=`File extension for "${e.name}" is not allowed`;r.push({file:e,message:i,uploaded:!1,id:crypto.randomUUID()});continue}if(e.size>s){const i="The file you are attempting to upload exceeds the maximum size allowed.";r.push({file:e,message:i,uploaded:!1,id:crypto.randomUUID()});continue}if(i.length+n>=o){const i=`File not uploaded; it would exceed the maximum number of files (${o})`;r.push({file:e,message:i,uploaded:!1,id:crypto.randomUUID()});continue}if(!a&&i.some(i=>i.name===e.name)){const i=`File not uploaded; there is already a file named ${e.name}`;r.push({file:e,message:i,uploaded:!1,id:crypto.randomUUID()});continue}r.push({file:e,message:"File uploaded",uploaded:!0,id:crypto.randomUUID()}),n+=1}return r})({currentFiles:this.files,extensions:this.extensions,filesToProcess:e,maxFileCount:this.allowedMaxFileCount,maxFileSizeInBytes:this.maxFileSizeInBytes,allowDuplicates:this.allowDuplicates});this.updateState(i),this.onFilesUploaded(i)}updateState(e=[]){const i=[];if(e.forEach(e=>{e.uploaded&&i.push(Object.assign(e.file,{id:e.id}))}),this.allowMultipleFiles)this.files=[...this.files,...i];else if(i.length){const e=i[0];this.files=[e]}}onFilesUploaded(e){this.errors=[];const i=e.filter(e=>!e.uploaded),t=new CustomEvent("on-files-uploaded",{detail:{allFiles:this.files,filesUploaded:e.filter(e=>e.uploaded),filesNotUploaded:i}}),l=null==i?void 0:i.map(e=>e.message).filter((e,i,t)=>t.indexOf(e)===i);this.errors=[...l],this.dispatchEvent(t)}onFileClick(e){const i=new CustomEvent("on-file-clicked",{detail:{allFiles:this.files,file:e.detail.file}});this.dispatchEvent(i)}onFileDelete(e){this.pendingFileDeletion=e.detail.file,this.askConfirmationOnDeleteFile?this.isDeleteBulkFileDialogOpen=!0:this.handleDeleteBulkFile()}handleDeleteBulkFile(){this.files=[...this.files].filter(e=>{var i;return e.id!==(null===(i=this.pendingFileDeletion)||void 0===i?void 0:i.id)});const e=new CustomEvent("on-file-removed",{detail:{allFiles:this.files,file:this.pendingFileDeletion}});this.isDeleteBulkFileDialogOpen=!1,this.dispatchEvent(e)}deleteLastFileWithoutConfirmation(){0!==this.files.length&&(this.pendingFileDeletion=this.files[this.files.length-1],this.handleDeleteBulkFile())}openFileUploadDialog(){var e;null===(e=this.fileRef.value)||void 0===e||e.click()}firstUpdated(){this.files=[...this.defaultFiles];const e=this.dropzoneRef.value;e&&(e.addEventListener("dragenter",e=>e.preventDefault()),e.addEventListener("dragover",e=>e.preventDefault()),e.addEventListener("drop",this.onDrop.bind(this)));const i=this.fileRef.value;i&&i.addEventListener("change",this.onFileChange.bind(this));const t=(e=>{switch(e){case m.KB:return 1024;case m.MB:return x;case m.GB:return v;case m.TB:return g;case m.PB:return y;case m.EB:return F;case m.ZB:return D;case m.YB:return B;default:return 0}})(this.maxFileSizeUnit);this.maxFileSizeInBytes=this.maxFileSizeValue*t}update(e){super.update(e),e.has("defaultFiles")&&(this.files=[...this.files.filter(e=>!this.defaultFiles.some(i=>i.name===e.name)),...this.defaultFiles])}isFileDeletable(e){return!this.defaultFiles.some(i=>i.name===e.name)||this.allowDeleteDefaultFiles}renderFileList(e=[]){const i=((e=[])=>e.sort((e,i)=>{const t=e.name.toLocaleLowerCase(),l=i.name.toLocaleLowerCase();return t<l?-1:l>t?1:0}))(e).map(e=>s`<ix-file-chip
173
+ .file=${e}
174
+ .deletable=${this.isFileDeletable(e)}
175
+ @on-file-click=${this.onFileClick}
176
+ @on-file-delete=${this.onFileDelete}
177
+ ></ix-file-chip>`),t={"uploaded-file-list":!0,"uploaded-file-list--spaced":!this.hideBody};return s`
178
+ <ul class="${p(t)}">
179
+ ${i}
180
+ ${this.showTemplateFileLink?s`<li class="ix-file-uploader__template-file">
181
+ <slot name="template-file"></slot>
182
+ </li>`:o}
183
+ </ul>
184
+ ${this.renderDeleteBulkFileConfirmationDialog()}
185
+ `}updated(e){const i=new FormData;this.files.forEach(e=>{i.append(`${this.name}[]`,e)}),this.internals.setFormValue(i)}renderDeleteBulkFileConfirmationDialog(){return this.askConfirmationOnDeleteFile?s`<ix-dialog
186
+ id="deleteFileConfirmationDialog"
187
+ ?open=${this.isDeleteBulkFileDialogOpen}
188
+ preventCloseOnScrimClick="true"
189
+ @closed=${()=>{this.isDeleteBulkFileDialogOpen=!1}}
190
+ @close=${()=>{this.isDeleteBulkFileDialogOpen=!1}}
191
+ >
192
+ <form
193
+ slot="content"
194
+ id="delete-file-id"
195
+ method="dialog"
196
+ class="delete-file-confirmation-dialog"
197
+ >
198
+ ${this.deleteConfirmationDialogLabel}
199
+ </form>
200
+ <div slot="actions">
201
+ <ix-button
202
+ appearance="text"
203
+ @click=${()=>{this.isDeleteBulkFileDialogOpen=!1}}
204
+ >
205
+ <span class="button-label">NO</span>
206
+ </ix-button>
207
+ <ix-button
208
+ appearance="text"
209
+ name="submitBtn"
210
+ @click=${()=>this.handleDeleteBulkFile()}
211
+ >
212
+ <span class="button-label">YES</span>
213
+ </ix-button>
214
+ </div>
215
+ </ix-dialog>`:o}renderHintText(){return this.hintText?s`<div class="ix-file-uploader__hint-text">
216
+ ${this.hintText}
217
+ </div>`:o}renderErrors(){return s` <div class="error-text">
218
+ ${this.errors.map(e=>s`<span>* ${e}</span>`)}
219
+ </div>`}renderBody(){const e=this.extensions.map(e=>`.${e}`).join(", "),i={"ix-file-uploader--hide-body":this.hideBody};return s`<div class=${p(i)}>
220
+ <div
221
+ class="dropzone"
222
+ @click=${this.openFileUploadDialog}
223
+ @keyup=${this.openFileUploadDialog}
224
+ ${d(this.dropzoneRef)}
225
+ >
226
+ <label class="ix-file-uploader__label" for="fileUploader"
227
+ >${this.headerText}</label
228
+ >
229
+ <div class="ix-file-uploader__help-text" id="fileUploaderDesc">
230
+ ${this.bodyText}
231
+ </div>
232
+ <input
233
+ id="fileUploader"
234
+ accept=${e}
235
+ class="file-input"
236
+ ?multiple=${this.allowMultipleFiles}
237
+ onchange=${e=>this.onFileChange(e)}
238
+ ${d(this.fileRef)}
239
+ aria-describedby="fileUploaderDesc"
240
+ type="file"
241
+ />
242
+ </div>
243
+ ${this.renderErrors()} ${this.renderHintText()}
244
+ </div>`}render(){return s`<div
245
+ class=${p({"ix-file-uploader":!0,error:this.errors.length||this.error})}
246
+ >
247
+ ${this.renderBody()}
248
+ ${this.files.length?this.renderFileList(this.files):o}
249
+ </div>`}}k.styles=[$],k.formAssociated=!0,e([a({type:Boolean})],k.prototype,"showTemplateFileLink",void 0),e([a({type:Boolean})],k.prototype,"allowMultipleFiles",void 0),e([a({type:Boolean})],k.prototype,"allowDuplicates",void 0),e([a()],k.prototype,"headerText",void 0),e([a()],k.prototype,"bodyText",void 0),e([a()],k.prototype,"hintText",void 0),e([a({type:Array})],k.prototype,"defaultFiles",void 0),e([a({type:Boolean})],k.prototype,"allowDeleteDefaultFiles",void 0),e([a({type:Boolean})],k.prototype,"hideBody",void 0),e([a({type:Array})],k.prototype,"extensions",void 0),e([a({type:Number})],k.prototype,"maxFileCount",void 0),e([a()],k.prototype,"maxFileSizeUnit",void 0),e([a({type:Number})],k.prototype,"maxFileSizeValue",void 0),e([a()],k.prototype,"name",void 0),e([a({type:Boolean})],k.prototype,"error",void 0),e([a({type:Boolean})],k.prototype,"askConfirmationOnDeleteFile",void 0),e([a()],k.prototype,"deleteConfirmationDialogLabel",void 0),e([r()],k.prototype,"isDeleteBulkFileDialogOpen",void 0),e([r()],k.prototype,"pendingFileDeletion",void 0),e([r()],k.prototype,"files",void 0),e([r()],k.prototype,"errors",void 0),customElements.define("ix-file-uploader",k);
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.2.21",
6
+ "version": "1.3.1",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
9
  "module": "dist/index.js",
@@ -21,17 +21,17 @@
21
21
  "scripts": {
22
22
  "analyze": "cem analyze --litelement",
23
23
  "build": "tsc && npm run analyze -- --exclude dist && rollup -c",
24
- "format": "eslint --ext .ts,.html . --fix --ignore-path .gitignore && prettier \"**/*.ts\" --write --ignore-path .gitignore",
25
- "lint": "eslint --ext .ts,.html . --ignore-path .gitignore && prettier \"**/*.ts\" --check --ignore-path .gitignore",
24
+ "format": "eslint --ext .ts,.html . --fix && prettier \"**/*.ts\" --write --ignore-path .gitignore",
25
+ "lint": "eslint --ext .ts,.html . && prettier \"**/*.ts\" --check --ignore-path .gitignore",
26
26
  "prepublish": "tsc && npm run analyze -- --exclude dist",
27
27
  "start": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wds\"",
28
28
  "test": "tsc && wtr --coverage",
29
29
  "test:watch": "tsc && concurrently -k -r \"tsc --watch --preserveWatchOutput\" \"wtr --watch\""
30
30
  },
31
31
  "dependencies": {
32
- "@digital-realty/ix-button": "^3.4.16",
33
- "@digital-realty/ix-dialog": "^1.2.20",
34
- "@digital-realty/ix-icon-button": "^1.2.15",
32
+ "@digital-realty/ix-button": "^3.5.1",
33
+ "@digital-realty/ix-dialog": "^1.3.1",
34
+ "@digital-realty/ix-icon-button": "^1.3.1",
35
35
  "@lit-labs/react": "^2.1.0",
36
36
  "@lit/react": "^1.0.2",
37
37
  "@material/web": "2.4.0",
@@ -40,32 +40,26 @@
40
40
  },
41
41
  "devDependencies": {
42
42
  "@custom-elements-manifest/analyzer": "^0.4.17",
43
- "@open-wc/eslint-config": "^9.2.1",
44
43
  "@open-wc/testing": "^3.1.6",
45
- "@typescript-eslint/eslint-plugin": "^5.48.0",
46
- "@typescript-eslint/parser": "^5.48.0",
44
+ "@rollup/plugin-terser": "^1.0.0",
45
+ "@typescript-eslint/eslint-plugin": "^8.58.2",
46
+ "@typescript-eslint/parser": "^8.58.2",
47
47
  "@web/dev-server": "^0.4.6",
48
48
  "@web/test-runner": "^0.20.2",
49
- "concurrently": "^9.1.0",
50
- "eslint": "^8.31.0",
49
+ "concurrently": "^9.2.1",
50
+ "eslint": "^9.39.4",
51
51
  "eslint-config-prettier": "^8.3.0",
52
52
  "husky": "^4.3.8",
53
53
  "lint-staged": "^10.5.4",
54
54
  "prettier": "^2.4.1",
55
55
  "rollup": "^4.29.1",
56
- "rollup-plugin-minify-html-literals": "^1.2.6",
57
56
  "rollup-plugin-summary": "^2.0.0",
58
- "rollup-plugin-uglify": "^6.0.4",
59
57
  "tslib": "^2.3.1",
60
58
  "typescript": "^4.5.2"
61
59
  },
62
60
  "customElements": "custom-elements.json",
63
61
  "eslintConfig": {
64
62
  "parser": "@typescript-eslint/parser",
65
- "extends": [
66
- "@open-wc",
67
- "prettier"
68
- ],
69
63
  "plugins": [
70
64
  "@typescript-eslint"
71
65
  ],
@@ -114,5 +108,5 @@
114
108
  "README.md",
115
109
  "LICENSE"
116
110
  ],
117
- "gitHead": "b47ba9e880c386ecf579ab21a118f94221cd1e1c"
111
+ "gitHead": "da06737d6707fd3d4ef898ba0fa632e7b3ed8019"
118
112
  }