@uploadcare/file-uploader 1.15.0-alpha.1 → 1.15.0-alpha.11

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.
Files changed (68) hide show
  1. package/abstract/ActivityBlock.js +1 -1
  2. package/abstract/Block.js +1 -1
  3. package/abstract/ModalManager.d.ts +23 -9
  4. package/abstract/ModalManager.d.ts.map +1 -1
  5. package/abstract/ModalManager.js +14 -9
  6. package/abstract/UploaderBlock.js +1 -1
  7. package/abstract/UploaderPublicApi.d.ts.map +1 -1
  8. package/abstract/UploaderPublicApi.js +1 -0
  9. package/blocks/Config/Config.d.ts +1 -1
  10. package/blocks/Config/Config.d.ts.map +1 -1
  11. package/blocks/Config/initialConfig.js +3 -3
  12. package/blocks/Config/normalizeConfigValue.d.ts +2 -1
  13. package/blocks/Config/normalizeConfigValue.d.ts.map +1 -1
  14. package/blocks/Config/normalizeConfigValue.js +18 -109
  15. package/blocks/Config/validatorsType.d.ts +37 -0
  16. package/blocks/Config/validatorsType.d.ts.map +1 -0
  17. package/blocks/Config/validatorsType.js +134 -0
  18. package/blocks/DropArea/DropArea.d.ts +1 -0
  19. package/blocks/DropArea/DropArea.d.ts.map +1 -1
  20. package/blocks/DropArea/DropArea.js +20 -2
  21. package/blocks/ExternalSource/ExternalSource.d.ts.map +1 -1
  22. package/blocks/ExternalSource/ExternalSource.js +0 -1
  23. package/blocks/FileItem/FileItem.d.ts +2 -5
  24. package/blocks/FileItem/FileItem.d.ts.map +1 -1
  25. package/blocks/FileItem/FileItem.js +27 -44
  26. package/blocks/FileItem/file-item.css +30 -0
  27. package/blocks/Modal/Modal.d.ts +21 -2
  28. package/blocks/Modal/Modal.d.ts.map +1 -1
  29. package/blocks/Modal/Modal.js +37 -18
  30. package/blocks/ProgressBar/ProgressBar.d.ts.map +1 -1
  31. package/blocks/ProgressBar/ProgressBar.js +1 -0
  32. package/blocks/ProgressBar/progress-bar.css +1 -0
  33. package/blocks/SimpleBtn/SimpleBtn.js +1 -1
  34. package/blocks/Thumb/Thumb.d.ts +48 -0
  35. package/blocks/Thumb/Thumb.d.ts.map +1 -0
  36. package/blocks/Thumb/Thumb.js +169 -0
  37. package/blocks/Thumb/thumb.css +4 -0
  38. package/blocks/UploadList/UploadList.d.ts +2 -0
  39. package/blocks/UploadList/UploadList.d.ts.map +1 -1
  40. package/blocks/UploadList/UploadList.js +3 -1
  41. package/blocks/themes/uc-basic/common.css +1 -1
  42. package/blocks/themes/uc-basic/index.css +1 -0
  43. package/index.d.ts +2 -0
  44. package/index.js +2 -0
  45. package/index.ssr.d.ts +59 -0
  46. package/index.ssr.d.ts.map +1 -1
  47. package/index.ssr.js +79 -13
  48. package/package.json +1 -1
  49. package/solutions/file-uploader/minimal/FileUploaderMinimal.d.ts +20 -1
  50. package/solutions/file-uploader/minimal/FileUploaderMinimal.d.ts.map +1 -1
  51. package/solutions/file-uploader/minimal/FileUploaderMinimal.js +102 -23
  52. package/solutions/file-uploader/minimal/index.css +6 -28
  53. package/solutions/file-uploader/minimal/index.d.ts +1 -16
  54. package/solutions/file-uploader/minimal/index.js +1 -18
  55. package/solutions/file-uploader/regular/FileUploaderRegular.d.ts +1 -3
  56. package/solutions/file-uploader/regular/FileUploaderRegular.d.ts.map +1 -1
  57. package/solutions/file-uploader/regular/FileUploaderRegular.js +1 -15
  58. package/types/exported.d.ts +4 -3
  59. package/web/file-uploader.iife.min.js +4 -4
  60. package/web/file-uploader.min.js +4 -4
  61. package/web/uc-basic.min.css +1 -1
  62. package/web/uc-cloud-image-editor.min.js +4 -4
  63. package/web/uc-file-uploader-inline.min.css +1 -1
  64. package/web/uc-file-uploader-inline.min.js +4 -4
  65. package/web/uc-file-uploader-minimal.min.css +1 -1
  66. package/web/uc-file-uploader-minimal.min.js +4 -4
  67. package/web/uc-file-uploader-regular.min.css +1 -1
  68. package/web/uc-file-uploader-regular.min.js +4 -4
@@ -7,10 +7,6 @@ export class FileItem extends UploaderBlock {
7
7
  */
8
8
  private _entry;
9
9
  /** @private */
10
- private _isIntersecting;
11
- /** @private */
12
- private _debouncedGenerateThumb;
13
- /** @private */
14
10
  private _debouncedCalculateState;
15
11
  /** @private */
16
12
  private _renderedOnce;
@@ -28,7 +24,7 @@ export class FileItem extends UploaderBlock {
28
24
  isUploading: boolean;
29
25
  isFocused: boolean;
30
26
  isEditable: boolean;
31
- isFileName: boolean;
27
+ showFileNames: boolean;
32
28
  state: symbol;
33
29
  ariaLabelStatusFile: string;
34
30
  onEdit: () => void;
@@ -54,6 +50,7 @@ export class FileItem extends UploaderBlock {
54
50
  * @param {IntersectionObserverEntry[]} entries
55
51
  */
56
52
  private _observerCallback;
53
+ _isIntersecting: boolean | undefined;
57
54
  _thumbRect: DOMRectReadOnly | undefined;
58
55
  /** @private */
59
56
  private _calculateState;
@@ -1 +1 @@
1
- {"version":3,"file":"FileItem.d.ts","sourceRoot":"","sources":["FileItem.js"],"names":[],"mappings":"AAoBA;IAIE,eAAe;IACf,mBAAuB;IACvB;;;OAGG;IACH,eAAc;IACd,eAAe;IACf,wBAAwB;IACxB,eAAe;IACf,gCAA4E;IAC5E,eAAe;IACf,iCAA0E;IAE1E,eAAe;IACf,sBAAsB;IAKpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+BC;IAGH,eASC;IAED;;;OAGG;IACH,0BAcC;IAXC,wCAA0C;IAa5C,eAAe;IACf,wBAgBC;IAED,eAAe;IACf,2BA2CC;IAED;;;;OAIG;IACH,kBAUC;IAED;;MAaQ;IAER;;;OAGG;IACH,uBAmDC;IA6CD,wEAAwE;IACxE,oBADY,CAAC,oBAAoB,CAAC,CAAC,MAAM,oBAAoB,CAAC,QA0B7D;IAaC,eAAe;IACf,kBAEE;IAWJ;;;MAEC;IAED;;;OAGG;IACH,uBAEC;IAED,wBAsFC;CACF;;;;;8BAtc6B,iCAAiC;AAS/D;;;;;GAKG"}
1
+ {"version":3,"file":"FileItem.d.ts","sourceRoot":"","sources":["FileItem.js"],"names":[],"mappings":"AAoBA;IAIE,eAAe;IACf,mBAAuB;IACvB;;;OAGG;IACH,eAAc;IAEd,eAAe;IACf,iCAA0E;IAE1E,eAAe;IACf,sBAAsB;IAKpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA+BC;IAGH,eAQC;IAED;;;OAGG;IACH,0BAUC;IAPC,qCAA2C;IAC3C,wCAA0C;IAQ5C,eAAe;IACf,wBAgBC;IAED,eAAe;IACf,2BAuCC;IAED;;;;OAIG;IACH,kBAUC;IAED;;MAaQ;IAER;;;OAGG;IACH,uBAkCC;IAyDD,wEAAwE;IACxE,oBADY,CAAC,oBAAoB,CAAC,CAAC,MAAM,oBAAoB,CAAC,QA0B7D;IAaC,eAAe;IACf,kBAEE;IAUJ;;;MAEC;IAED;;;OAGG;IACH,uBAEC;IAED,wBAsFC;CACF;;;;;8BApb6B,iCAAiC;AAS/D;;;;;GAKG"}
@@ -29,10 +29,7 @@ export class FileItem extends UploaderBlock {
29
29
  * @type {any} TODO: Add types for upload entry
30
30
  */
31
31
  _entry = null;
32
- /** @private */
33
- _isIntersecting = false;
34
- /** @private */
35
- _debouncedGenerateThumb = debounce(this._generateThumbnail.bind(this), 100);
32
+
36
33
  /** @private */
37
34
  _debouncedCalculateState = debounce(this._calculateState.bind(this), 100);
38
35
 
@@ -57,7 +54,7 @@ export class FileItem extends UploaderBlock {
57
54
  isUploading: false,
58
55
  isFocused: false,
59
56
  isEditable: false,
60
- isFileName: false,
57
+ showFileNames: false,
61
58
  state: FileItemState.IDLE,
62
59
  ariaLabelStatusFile: '',
63
60
  onEdit: () => {
@@ -81,7 +78,6 @@ export class FileItem extends UploaderBlock {
81
78
  sub.remove();
82
79
  }
83
80
 
84
- this._debouncedGenerateThumb.cancel();
85
81
  this._debouncedCalculateState.cancel();
86
82
  this._entrySubs = new Set();
87
83
  this._entry = null;
@@ -93,6 +89,7 @@ export class FileItem extends UploaderBlock {
93
89
  */
94
90
  _observerCallback(entries) {
95
91
  let [entry] = entries;
92
+
96
93
  this._isIntersecting = entry.isIntersecting;
97
94
  this._thumbRect = entry.boundingClientRect;
98
95
 
@@ -100,11 +97,6 @@ export class FileItem extends UploaderBlock {
100
97
  this.render();
101
98
  this._renderedOnce = true;
102
99
  }
103
- if (entry.intersectionRatio === 0) {
104
- this._debouncedGenerateThumb.cancel();
105
- } else {
106
- this._debouncedGenerateThumb();
107
- }
108
100
  }
109
101
 
110
102
  /** @private */
@@ -154,10 +146,6 @@ export class FileItem extends UploaderBlock {
154
146
  return;
155
147
  }
156
148
 
157
- if (entry.getValue('thumbUrl')) {
158
- return;
159
- }
160
-
161
149
  if (entry.getValue('file')?.type.includes('image')) {
162
150
  try {
163
151
  let thumbUrl = await generateThumb(entry.getValue('file'), this.cfg.thumbSize);
@@ -233,21 +221,8 @@ export class FileItem extends UploaderBlock {
233
221
  this.$.itemName = entry.getValue('fileName') || externalUrl || this.l10n('file-no-name');
234
222
  });
235
223
 
236
- this._subEntry('fileInfo', (fileInfo) => {
224
+ this._subEntry('fileInfo', () => {
237
225
  this._debouncedCalculateState();
238
- if (fileInfo && this._isIntersecting) {
239
- this._debouncedGenerateThumb();
240
- }
241
- });
242
-
243
- this._subEntry('cdnUrlModifiers', () => {
244
- if (this._isIntersecting) {
245
- this._debouncedGenerateThumb();
246
- }
247
- });
248
-
249
- this._subEntry('thumbUrl', (thumbUrl) => {
250
- this.$.thumbUrl = thumbUrl ? `url(${thumbUrl})` : '';
251
226
  });
252
227
 
253
228
  this._subEntry('errors', () => this._debouncedCalculateState());
@@ -255,10 +230,6 @@ export class FileItem extends UploaderBlock {
255
230
  this._subEntry('fileSize', () => this._debouncedCalculateState());
256
231
  this._subEntry('mimeType', () => this._debouncedCalculateState());
257
232
  this._subEntry('isImage', () => this._debouncedCalculateState());
258
-
259
- if (this._isIntersecting) {
260
- this._debouncedGenerateThumb();
261
- }
262
233
  }
263
234
 
264
235
  initCallback() {
@@ -273,14 +244,26 @@ export class FileItem extends UploaderBlock {
273
244
  });
274
245
 
275
246
  this.subConfigValue('useCloudImageEditor', () => this._debouncedCalculateState());
276
- this.subConfigValue('displayUploadList', (mode) => {
277
- if (mode === 'grid') {
278
- this.subConfigValue('enableFileName', (value) => (this.$.isFileName = !value));
247
+ this.subConfigValue('filesViewMode', (mode) => {
248
+ if (this.cfg.filesViewMode === 'list') {
249
+ this.$.showFileNames = true;
250
+ }
251
+ if (this.cfg.filesViewMode === 'grid') {
252
+ this.$.showFileNames = this.cfg.gridShowFileNames;
279
253
  }
280
254
 
281
255
  this.setAttribute('mode', mode);
282
256
  });
283
257
 
258
+ this.subConfigValue('gridShowFileNames', (value) => {
259
+ if (this.cfg.filesViewMode === 'grid') {
260
+ this.$.showFileNames = value;
261
+ }
262
+ if (this.cfg.filesViewMode === 'list') {
263
+ this.$.showFileNames = true;
264
+ }
265
+ });
266
+
284
267
  this.onclick = () => {
285
268
  FileItem.activeInstances.forEach((inst) => {
286
269
  if (inst === this) {
@@ -353,7 +336,6 @@ export class FileItem extends UploaderBlock {
353
336
  disconnectedCallback() {
354
337
  super.disconnectedCallback();
355
338
 
356
- this._debouncedGenerateThumb.cancel();
357
339
  this._observer?.disconnect();
358
340
  }
359
341
 
@@ -460,13 +442,10 @@ export class FileItem extends UploaderBlock {
460
442
 
461
443
  FileItem.template = /* HTML */ `
462
444
  <div class="uc-inner" set="@finished: isFinished; @uploading: isUploading; @failed: isFailed; @focused: isFocused">
463
- <div class="uc-thumb" set="style.backgroundImage: thumbUrl">
464
- <div class="uc-badge">
465
- <uc-icon set="@name: badgeIcon"></uc-icon>
466
- </div>
467
- </div>
445
+ <uc-thumb set="uid:uid;badgeIcon:badgeIcon"></uc-thumb>
446
+
468
447
  <div aria-atomic="true" aria-live="polite" class="uc-file-name-wrapper" set="@aria-label:ariaLabelStatusFile;">
469
- <span class="uc-file-name" set="@hidden: isFileName">{{itemName}}</span>
448
+ <span class="uc-file-name" set="@hidden: !showFileNames">{{itemName}}</span>
470
449
  <span class="uc-file-error" set="@hidden: !errorText;">{{errorText}}</span>
471
450
  <span class="uc-file-hint" set="@hidden: !hint">{{hint}}</span>
472
451
  </div>
@@ -491,7 +470,11 @@ FileItem.template = /* HTML */ `
491
470
  <uc-icon name="upload"></uc-icon>
492
471
  </button>
493
472
  </div>
494
- <uc-progress-bar class="uc-progress-bar" set="value: progressValue; visible: progressVisible;"> </uc-progress-bar>
473
+ <uc-progress-bar
474
+ class="uc-progress-bar"
475
+ set="value: progressValue; visible: progressVisible; @hasFileName: showFileNames"
476
+ >
477
+ </uc-progress-bar>
495
478
  </div>
496
479
  `;
497
480
  FileItem.activeInstances = new Set();
@@ -202,3 +202,33 @@ uc-file-item[mode='grid'] .uc-file-actions {
202
202
  uc-file-item[mode='grid'] button {
203
203
  background-color: var(--uc-background);
204
204
  }
205
+
206
+ uc-file-item[mode='grid'] button:hover {
207
+ background-color: var(--uc-muted);
208
+ }
209
+
210
+ uc-file-item[mode='grid'] .uc-progress-bar {
211
+ width: initial;
212
+ height: 4px !important;
213
+ opacity: 1;
214
+ top: initial !important;
215
+ bottom: var(--uc-padding);
216
+ left: var(--uc-padding);
217
+ right: var(--uc-padding);
218
+ border-radius: var(--uc-radius);
219
+ background-color: var(--uc-background);
220
+ z-index: 1;
221
+ }
222
+
223
+ uc-file-item[mode='grid'] .uc-progress-bar.uc-progress-bar--hidden {
224
+ opacity: 0;
225
+ }
226
+
227
+ uc-file-item[mode='grid'] .uc-progress-bar[hasfilename] {
228
+ bottom: calc(var(--uc-padding) + var(--uc-font-size));
229
+ }
230
+
231
+ uc-file-item[mode='grid'] .uc-progress-bar .uc-progress {
232
+ background-color: var(--uc-primary);
233
+ opacity: 0.7;
234
+ }
@@ -1,8 +1,6 @@
1
1
  export class Modal extends Block {
2
2
  static StateConsumerScope: string;
3
3
  init$: {
4
- '*modalActive': boolean;
5
- isOpen: boolean;
6
4
  closeClicked: () => void;
7
5
  };
8
6
  _handleBackdropClick: () => void;
@@ -16,6 +14,27 @@ export class Modal extends Block {
16
14
  _handleDialogMouseUp: (e: Event) => void;
17
15
  show(): void;
18
16
  hide(): void;
17
+ /**
18
+ * @private
19
+ * @type {import('../../abstract/ModalManager.js').ModalCb}
20
+ */
21
+ private _handleModalOpen;
22
+ /**
23
+ * @private
24
+ * @type {import('../../abstract/ModalManager.js').ModalCb}
25
+ */
26
+ private _handleModalClose;
27
+ /** @private */
28
+ private _handleModalCloseAll;
29
+ handleModalOpen: ((data: {
30
+ id: string;
31
+ modal?: Modal | undefined;
32
+ }) => void) | undefined;
33
+ handleModalClose: ((data: {
34
+ id: string;
35
+ modal?: Modal | undefined;
36
+ }) => void) | undefined;
37
+ handleModalCloseAll: (() => void) | undefined;
19
38
  }
20
39
  export namespace Modal {
21
40
  let template: string;
@@ -1 +1 @@
1
- {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["Modal.js"],"names":[],"mappings":"AAIA;IAEE,kCAAoC;IAIlC;;;;MAKC;IAGH,iCAEE;IAEF,yBAME;IAEF,+BAEE;IAEF,uBAAuB;IACvB,4BADY,KAAK,UAIf;IAFA,eAAe;IACf,yBAAgC;IAGlC,uBAAuB;IACvB,0BADY,KAAK,UAKf;IAEF,aAWC;IAED,aAOC;CA8CF;;;;sBAhHqB,yBAAyB"}
1
+ {"version":3,"file":"Modal.d.ts","sourceRoot":"","sources":["Modal.js"],"names":[],"mappings":"AAIA;IAEE,kCAAoC;IAIlC;;MAGC;IAGH,iCAEE;IAEF,yBAME;IAEF,+BAEE;IAEF,uBAAuB;IACvB,4BADY,KAAK,UAIf;IAFA,eAAe;IACf,yBAAgC;IAGlC,uBAAuB;IACvB,0BADY,KAAK,UAKf;IAEF,aAWC;IAED,aAOC;IAED;;;OAGG;IACH,yBAMC;IAED;;;OAGG;IACH,0BAIC;IAED,eAAe;IACf,6BAEC;IAmBC;;;4BAAuD;IACvD;;;4BAAyD;IACzD,8CAA+D;CAmBlE;;;;sBAnIqB,yBAAyB"}
@@ -10,8 +10,6 @@ export class Modal extends Block {
10
10
  super();
11
11
  this.init$ = {
12
12
  ...this.init$,
13
- '*modalActive': false,
14
- isOpen: false,
15
13
  closeClicked: this._handleDialogClose,
16
14
  };
17
15
  }
@@ -67,6 +65,33 @@ export class Modal extends Block {
67
65
  }
68
66
  }
69
67
 
68
+ /**
69
+ * @private
70
+ * @type {import('../../abstract/ModalManager.js').ModalCb}
71
+ */
72
+ _handleModalOpen({ id }) {
73
+ if (id === this.id) {
74
+ this.show();
75
+ } else {
76
+ this.hide();
77
+ }
78
+ }
79
+
80
+ /**
81
+ * @private
82
+ * @type {import('../../abstract/ModalManager.js').ModalCb}
83
+ */
84
+ _handleModalClose({ id }) {
85
+ if (id === this.id) {
86
+ this.hide();
87
+ }
88
+ }
89
+
90
+ /** @private */
91
+ _handleModalCloseAll() {
92
+ this.hide();
93
+ }
94
+
70
95
  initCallback() {
71
96
  super.initCallback();
72
97
 
@@ -84,23 +109,13 @@ export class Modal extends Block {
84
109
  }
85
110
  });
86
111
 
87
- this.modalManager.subscribe(ModalEvents.OPEN, (/** @type {{ id: string }} */ { id }) => {
88
- if (id === this.id) {
89
- this.show();
90
- } else {
91
- this.hide();
92
- }
93
- });
94
-
95
- this.modalManager.subscribe(ModalEvents.CLOSE, (/** @type {{ id: string }} */ { id }) => {
96
- if (id === this.id) {
97
- this.hide();
98
- }
99
- });
112
+ this.handleModalOpen = this._handleModalOpen.bind(this);
113
+ this.handleModalClose = this._handleModalClose.bind(this);
114
+ this.handleModalCloseAll = this._handleModalCloseAll.bind(this);
100
115
 
101
- this.modalManager.subscribe(ModalEvents.CLOSE_ALL, () => {
102
- this.hide();
103
- });
116
+ this.modalManager.subscribe(ModalEvents.OPEN, this.handleModalOpen);
117
+ this.modalManager.subscribe(ModalEvents.CLOSE, this.handleModalClose);
118
+ this.modalManager.subscribe(ModalEvents.CLOSE_ALL, this.handleModalCloseAll);
104
119
  }
105
120
 
106
121
  destroyCallback() {
@@ -110,6 +125,10 @@ export class Modal extends Block {
110
125
  this.ref.dialog.removeEventListener('close', this._handleDialogClose);
111
126
  this.ref.dialog.removeEventListener('mousedown', this._handleDialogMouseDown);
112
127
  this.ref.dialog.removeEventListener('mouseup', this._handleDialogMouseUp);
128
+
129
+ this.modalManager.unsubscribe(ModalEvents.OPEN, this.handleModalOpen);
130
+ this.modalManager.unsubscribe(ModalEvents.CLOSE, this.handleModalClose);
131
+ this.modalManager.unsubscribe(ModalEvents.CLOSE_ALL, this.handleModalCloseAll);
113
132
  }
114
133
  }
115
134
 
@@ -1 +1 @@
1
- {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["ProgressBar.js"],"names":[],"mappings":"AAEA;IACE,qBAAqB;IACrB,eAAW;IAEX,sBAAsB;IACtB,kBAAgB;IAEhB,WAIE;CA8CH;;;;sBA3DqB,yBAAyB"}
1
+ {"version":3,"file":"ProgressBar.d.ts","sourceRoot":"","sources":["ProgressBar.js"],"names":[],"mappings":"AAEA;IACE,qBAAqB;IACrB,eAAW;IAEX,sBAAsB;IACtB,kBAAgB;IAEhB,WAIE;CA+CH;;;;sBA5DqB,yBAAyB"}
@@ -24,6 +24,7 @@ export class ProgressBar extends Block {
24
24
  this.ref.realProgressLine.addEventListener(
25
25
  'transitionend',
26
26
  () => {
27
+ this.classList.add('uc-progress-bar--hidden');
27
28
  this.ref.realProgressLine.classList.toggle('uc-progress--hidden', true);
28
29
  },
29
30
  {
@@ -41,6 +41,7 @@ uc-progress-bar .uc-fake-progress {
41
41
  display 1s;
42
42
  /* stylelint-disable-next-line property-no-unknown */
43
43
  transition-behavior: allow-discrete;
44
+ z-index: 1;
44
45
  }
45
46
 
46
47
  uc-progress-bar .uc-fake-progress--hidden {
@@ -1,6 +1,6 @@
1
1
  // @ts-check
2
2
  import { UploaderBlock } from '../../abstract/UploaderBlock.js';
3
- import { asBoolean } from '../Config/normalizeConfigValue.js';
3
+ import { asBoolean } from '../Config/validatorsType.js';
4
4
 
5
5
  export class SimpleBtn extends UploaderBlock {
6
6
  static styleAttrs = [...super.styleAttrs, 'uc-simple-btn'];
@@ -0,0 +1,48 @@
1
+ export class Thumb extends UploaderBlock {
2
+ /**
3
+ * @private
4
+ * @type {any} TODO: Add types for upload entry
5
+ */
6
+ private _entry;
7
+ /**
8
+ * @private
9
+ * @type {IntersectionObserverEntry['boundingClientRect'] | null}
10
+ */
11
+ private _thumbRect;
12
+ _debouncedGenerateThumb: (() => Promise<void>) & {
13
+ cancel: () => void;
14
+ };
15
+ _isIntersecting: boolean;
16
+ init$: {
17
+ thumbUrl: string;
18
+ badgeIcon: string;
19
+ uid: string;
20
+ '*commonProgress': number;
21
+ '*uploadList': never[];
22
+ '*uploadQueue': import("@uploadcare/upload-client").Queue;
23
+ '*collectionErrors': any[];
24
+ '*collectionState': import("../../index.js").OutputCollectionState<import("../../index.js").OutputCollectionStatus, "maybe-has-group"> | null;
25
+ '*groupInfo': import("@uploadcare/upload-client").UploadcareGroup | null;
26
+ '*uploadTrigger': Set<string>;
27
+ '*secureUploadsManager': import("../../abstract/SecureUploadsManager.js").SecureUploadsManager | null;
28
+ '*currentActivity': null;
29
+ '*currentActivityParams': {};
30
+ '*history': never[];
31
+ '*historyBack': null;
32
+ '*closeModal': () => void;
33
+ };
34
+ _calculateThumbSize(): number;
35
+ /** @private */
36
+ private _generateThumbnail;
37
+ /**
38
+ * @private
39
+ * @param {IntersectionObserverEntry[]} entries
40
+ */
41
+ private _observerCallback;
42
+ _observer: IntersectionObserver | undefined;
43
+ }
44
+ export namespace Thumb {
45
+ let template: string;
46
+ }
47
+ import { UploaderBlock } from '../../abstract/UploaderBlock.js';
48
+ //# sourceMappingURL=Thumb.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Thumb.d.ts","sourceRoot":"","sources":["Thumb.js"],"names":[],"mappings":"AAMA;IACE;;;OAGG;IACH,eAAc;IAEd;;;OAGG;IACH,mBAAkB;IAElB;;MAA4E;IAE5E,yBAAwB;IAKtB;;;;;;;;;;;;;;;;;MAKC;IAGH,8BAYC;IAED,eAAe;IACf,2BAqCC;IAED;;;OAGG;IACH,0BAaC;IAqCC,4CAAuG;CAW1G;;;;8BAzJ6B,iCAAiC"}
@@ -0,0 +1,169 @@
1
+ import { UploaderBlock } from '../../abstract/UploaderBlock.js';
2
+ import { createCdnUrl, createCdnUrlModifiers, createOriginalUrl } from '../../utils/cdn-utils.js';
3
+ import { fileCssBg } from '../svg-backgrounds/svg-backgrounds.js';
4
+ import { debounce } from '../utils/debounce.js';
5
+ import { generateThumb } from '../utils/resizeImage.js';
6
+
7
+ export class Thumb extends UploaderBlock {
8
+ /**
9
+ * @private
10
+ * @type {any} TODO: Add types for upload entry
11
+ */
12
+ _entry = null;
13
+
14
+ /**
15
+ * @private
16
+ * @type {IntersectionObserverEntry['boundingClientRect'] | null}
17
+ */
18
+ _thumbRect = null;
19
+
20
+ _debouncedGenerateThumb = debounce(this._generateThumbnail.bind(this), 100);
21
+
22
+ _isIntersecting = false;
23
+
24
+ constructor() {
25
+ super();
26
+
27
+ this.init$ = {
28
+ ...this.init$,
29
+ thumbUrl: '',
30
+ badgeIcon: '',
31
+ uid: '',
32
+ };
33
+ }
34
+
35
+ _calculateThumbSize() {
36
+ let size = Math.max(
37
+ parseInt(String(this?._thumbRect?.height || 0)),
38
+ parseInt(String(this?._thumbRect?.width || 0)),
39
+ this.cfg.thumbSize,
40
+ );
41
+
42
+ if (window.devicePixelRatio > 1) {
43
+ size *= window.devicePixelRatio;
44
+ }
45
+
46
+ return size;
47
+ }
48
+
49
+ /** @private */
50
+ async _generateThumbnail() {
51
+ if (!this._entry) {
52
+ return;
53
+ }
54
+ let entry = this._entry;
55
+
56
+ if (entry.getValue('fileInfo') && entry.getValue('isImage')) {
57
+ let size = this._calculateThumbSize();
58
+
59
+ let thumbUrl = await this.proxyUrl(
60
+ createCdnUrl(
61
+ createOriginalUrl(this.cfg.cdnCname, this._entry.getValue('uuid')),
62
+ createCdnUrlModifiers(entry.getValue('cdnUrlModifiers'), `scale_crop/${size}x${size}/center/-/preview/`),
63
+ ),
64
+ );
65
+ let currentThumbUrl = entry.getValue('thumbUrl');
66
+ if (currentThumbUrl !== thumbUrl) {
67
+ entry.setValue('thumbUrl', thumbUrl);
68
+ currentThumbUrl?.startsWith('blob:') && URL.revokeObjectURL(currentThumbUrl);
69
+ }
70
+ return;
71
+ }
72
+
73
+ if (entry.getValue('file')?.type.includes('image')) {
74
+ try {
75
+ let size = this._calculateThumbSize();
76
+
77
+ let thumbUrl = await generateThumb(entry.getValue('file'), size);
78
+ entry.setValue('thumbUrl', thumbUrl);
79
+ } catch (err) {
80
+ let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground');
81
+ entry.setValue('thumbUrl', fileCssBg(color));
82
+ }
83
+ } else {
84
+ let color = window.getComputedStyle(this).getPropertyValue('--uc-muted-foreground');
85
+ entry.setValue('thumbUrl', fileCssBg(color));
86
+ }
87
+ }
88
+
89
+ /**
90
+ * @private
91
+ * @param {IntersectionObserverEntry[]} entries
92
+ */
93
+ _observerCallback(entries) {
94
+ const [entry] = entries;
95
+ this._isIntersecting = entry.isIntersecting;
96
+
97
+ if (entry.isIntersecting) {
98
+ this._thumbRect = entry.boundingClientRect;
99
+ this._debouncedGenerateThumb();
100
+ this._observer?.disconnect();
101
+ }
102
+
103
+ if (entry.intersectionRatio === 0) {
104
+ this._debouncedGenerateThumb.cancel();
105
+ }
106
+ }
107
+
108
+ initCallback() {
109
+ super.initCallback();
110
+
111
+ this.defineAccessor('badgeIcon', (/** @type {string} */ val) => (this.$.badgeIcon = val));
112
+
113
+ this.defineAccessor('uid', (/** @type {string} */ value) => {
114
+ this.set$({ uid: value });
115
+ });
116
+
117
+ this.sub('uid', (value) => {
118
+ this._entry = this.uploadCollection.read(value);
119
+ });
120
+
121
+ this._entry?.subscribe('fileInfo', (fileInfo) => {
122
+ if (fileInfo?.isImage && this._isIntersecting) {
123
+ this._debouncedGenerateThumb();
124
+ }
125
+ });
126
+
127
+ this._entry?.subscribe('thumbUrl', (thumbUrl) => {
128
+ this.$.thumbUrl = thumbUrl ? `url(${thumbUrl})` : '';
129
+ });
130
+
131
+ this._entry?.subscribe('cdnUrlModifiers', () => {
132
+ if (this._isIntersecting) {
133
+ this._debouncedGenerateThumb();
134
+ }
135
+ });
136
+
137
+ this.setAttribute('role', 'img');
138
+ }
139
+
140
+ connectedCallback() {
141
+ super.connectedCallback();
142
+
143
+ this._observer = new window.IntersectionObserver(this._observerCallback.bind(this), { threshold: 0.1 });
144
+
145
+ this._observer.observe(this);
146
+ }
147
+
148
+ disconnectedCallback() {
149
+ super.disconnectedCallback();
150
+
151
+ this._debouncedGenerateThumb.cancel();
152
+ this._observer?.disconnect();
153
+ }
154
+ }
155
+
156
+ Thumb.template = /* html */ `
157
+ <div class="uc-thumb" set="style.backgroundImage: thumbUrl">
158
+ <div class="uc-badge">
159
+ <uc-icon set="@name: badgeIcon"></uc-icon>
160
+ </div>
161
+ </div>
162
+ `;
163
+
164
+ Thumb.bindAttributes({
165
+ // @ts-expect-error TODO: fix types inside symbiote
166
+ badgeIcon: null,
167
+ // @ts-expect-error TODO: fix types inside symbiote
168
+ uid: null,
169
+ });
@@ -0,0 +1,4 @@
1
+ uc-thumb {
2
+ width: 100%;
3
+ height: 100%;
4
+ }
@@ -1,3 +1,4 @@
1
+ /** @typedef {'grid' | 'list'} FilesViewMode */
1
2
  /**
2
3
  * @typedef {{
3
4
  * total: number;
@@ -48,6 +49,7 @@ export class UploadList extends UploaderBlock {
48
49
  export namespace UploadList {
49
50
  let template: string;
50
51
  }
52
+ export type FilesViewMode = 'grid' | 'list';
51
53
  export type Summary = {
52
54
  total: number;
53
55
  succeed: number;
@@ -1 +1 @@
1
- {"version":3,"file":"UploadList.d.ts","sourceRoot":"","sources":["UploadList.js"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AAEH;IAKE,4BAAoD;IAKlD;;;;;;;;;;;;;;;;;;;;;;;;;;MA0BC;IAGH,eAAe;IACf,yCASQ;IAER,eAAe;IACf,4BAuCC;IAED;;;OAGG;IACH,uBAmBC;CAwEF;;;;sBApMY;IACZ,KAAS,EAAE,MAAM,CAAC;IAClB,OAAW,EAAE,MAAM,CAAC;IACpB,SAAa,EAAE,MAAM,CAAC;IACtB,MAAU,EAAE,MAAM,CAAC;CAChB;8BAV0B,iCAAiC"}
1
+ {"version":3,"file":"UploadList.d.ts","sourceRoot":"","sources":["UploadList.js"],"names":[],"mappings":"AAMA,+CAA+C;AAE/C;;;;;;;GAOG;AAEH;IAKE,4BAAoD;IAKlD;;;;;;;;;;;;;;;;;;;;;;;;;;MA0BC;IAGH,eAAe;IACf,yCASQ;IAER,eAAe;IACf,4BAuCC;IAED;;;OAGG;IACH,uBAmBC;CAwEF;;;;4BAvMa,MAAM,GAAG,MAAM;sBAGhB;IACZ,KAAS,EAAE,MAAM,CAAC;IAClB,OAAW,EAAE,MAAM,CAAC;IACpB,SAAa,EAAE,MAAM,CAAC;IACtB,MAAU,EAAE,MAAM,CAAC;CAChB;8BAZ0B,iCAAiC"}
@@ -4,6 +4,8 @@ import { UploaderBlock } from '../../abstract/UploaderBlock.js';
4
4
  import { EventType } from '../UploadCtxProvider/EventEmitter.js';
5
5
  import { throttle } from '../utils/throttle.js';
6
6
 
7
+ /** @typedef {'grid' | 'list'} FilesViewMode */
8
+
7
9
  /**
8
10
  * @typedef {{
9
11
  * total: number;
@@ -149,7 +151,7 @@ export class UploadList extends UploaderBlock {
149
151
  }
150
152
  });
151
153
 
152
- this.subConfigValue('displayUploadList', (mode) => {
154
+ this.subConfigValue('filesViewMode', (mode) => {
153
155
  this.setAttribute('mode', mode);
154
156
  });
155
157
 
@@ -13,7 +13,7 @@
13
13
  display: none !important;
14
14
  }
15
15
 
16
- :where([uc-wgt-common]) [activity]:not([active]) {
16
+ :where([uc-wgt-common]) [activity]:not([active], .active) {
17
17
  display: none;
18
18
  }
19
19
 
@@ -31,6 +31,7 @@
31
31
  @import url('../../CloudImageEditorActivity/index.css');
32
32
  @import url('../../Select/select.css');
33
33
  @import url('../../Spinner/spinner.css');
34
+ @import url('../../Thumb/thumb.css');
34
35
 
35
36
  /* POST RESET */
36
37
  @import url('post-reset.css');