@progress/kendo-angular-upload 16.3.0-develop.3 → 16.3.0-develop.4

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.
@@ -2,10 +2,10 @@
2
2
  * Copyright © 2024 Progress Software Corporation. All rights reserved.
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
- import { Component, Input, HostBinding, forwardRef, Renderer2, ViewChild, ElementRef, Output, EventEmitter, NgZone, ContentChild, ChangeDetectorRef, Injector } from "@angular/core";
6
- import { NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
5
+ import { Component, HostBinding, forwardRef, Renderer2, ViewChild, ElementRef, NgZone, ChangeDetectorRef, Injector, Input, Output, EventEmitter } from "@angular/core";
6
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
7
7
  import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
8
- import { KendoInput, guid, Keys, isDocumentAvailable, isControlRequired } from '@progress/kendo-angular-common';
8
+ import { KendoInput, Keys, isDocumentAvailable } from '@progress/kendo-angular-common';
9
9
  import { fromEvent, merge } from 'rxjs';
10
10
  import { filter } from 'rxjs/operators';
11
11
  import { validatePackage } from '@progress/kendo-licensing';
@@ -13,10 +13,9 @@ import { packageMetadata } from './package-metadata';
13
13
  import { UploadService } from './upload.service';
14
14
  import { NavigationService } from './navigation.service';
15
15
  import { UPLOAD_CLASSES, hasClasses, isFocusable, IGNORE_TARGET_CLASSES, validateInitialFileSelectFile } from './common/util';
16
- import { FileTemplateDirective } from './templates/file-template.directive';
17
16
  import { FileState } from './types/file-state';
18
17
  import { DropZoneService } from './dropzone.service';
19
- import { FileInfoTemplateDirective } from './templates/file-info-template.directive';
18
+ import { UploadFileSelectBase } from "./common/base";
20
19
  import * as i0 from "@angular/core";
21
20
  import * as i1 from "./upload.service";
22
21
  import * as i2 from "@progress/kendo-angular-l10n";
@@ -37,8 +36,9 @@ export const FILESELECT_VALUE_ACCESSOR = {
37
36
  useExisting: forwardRef(() => FileSelectComponent)
38
37
  };
39
38
  let idx = 0;
40
- export class FileSelectComponent {
39
+ export class FileSelectComponent extends UploadFileSelectBase {
41
40
  constructor(uploadService, localization, navigation, dropZoneService, ngZone, renderer, cdr, wrapper, injector) {
41
+ super(uploadService, navigation, cdr, injector, ngZone);
42
42
  this.uploadService = uploadService;
43
43
  this.localization = localization;
44
44
  this.navigation = navigation;
@@ -47,54 +47,10 @@ export class FileSelectComponent {
47
47
  this.renderer = renderer;
48
48
  this.cdr = cdr;
49
49
  this.injector = injector;
50
- /**
51
- * Disables the FileSelect.
52
- * To learn how to disable the component in reactive forms, refer to the article on [Forms Support](slug:formssupport_fileselect#toc-managing-the-fileselect-disabled-state-in-reactive-forms).
53
- * @default false
54
- */
55
- this.disabled = false;
56
- /**
57
- * Enables the selection of multiple files
58
- * ([see example]({% slug fileprocessing_upload %}#toc-upload-of-sinlge-or-multiple-files)).
59
- * If set to `false`, only one file can be selected at a time.
60
- * @default true
61
- */
62
- this.multiple = true;
63
- /**
64
- * Toggles the visibility of the file list.
65
- * @default true
66
- */
67
- this.showFileList = true;
68
- /**
69
- * Specifies the [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the FileSelect.
70
- * @default 0
71
- */
72
- this.tabindex = 0;
73
- /**
74
- * @hidden
75
- */
76
- this.focusableId = `k-${guid()}`;
77
- /**
78
- * Fires when the user navigates outside the component.
79
- */
80
- this.onBlur = new EventEmitter();
81
- /**
82
- * Fires when the component is focused.
83
- */
84
- this.onFocus = new EventEmitter();
85
- /**
86
- * Fires when files are selected. If prevented, the selected files will not be added to the list.
87
- */
88
- this.select = new EventEmitter();
89
- /**
90
- * Fires when a file is about to be removed. If prevented, the file will remain in the list.
91
- */
92
- this.remove = new EventEmitter();
93
50
  /**
94
51
  * Fires when the value of the component has changed as a result of a successful `select` or `remove` operation.
95
52
  */
96
53
  this.valueChange = new EventEmitter();
97
- this.hostDefaultClasses = true;
98
54
  /**
99
55
  * @hidden
100
56
  */
@@ -103,13 +59,10 @@ export class FileSelectComponent {
103
59
  maxFileSize: 0,
104
60
  minFileSize: 0
105
61
  };
106
- this.onTouchedCallback = (_) => { };
107
- this.onChangeCallback = (_) => { };
108
62
  validatePackage(packageMetadata);
109
63
  this.wrapper = wrapper.nativeElement;
110
64
  this.direction = localization.rtl ? 'rtl' : 'ltr';
111
65
  this.navigation.computeKeys();
112
- this.fileList = this.uploadService.files;
113
66
  this.localizationChangeSubscription = localization.changes.subscribe(({ rtl }) => {
114
67
  this.direction = rtl ? 'rtl' : 'ltr';
115
68
  });
@@ -118,6 +71,9 @@ export class FileSelectComponent {
118
71
  this.attachEventHandlers();
119
72
  this.setDefaultSettings();
120
73
  }
74
+ get dir() {
75
+ return this.direction;
76
+ }
121
77
  /**
122
78
  * Sets the `name` attribute of the `input` element of the FileSelect.
123
79
  */
@@ -127,42 +83,10 @@ export class FileSelectComponent {
127
83
  get name() {
128
84
  return this.uploadService.async.saveField;
129
85
  }
130
- /**
131
- * Sets the restrictions for selected files.
132
- */
133
- set restrictions(restrictions) {
134
- const parsedRestrictions = Object.assign({}, this._restrictions, restrictions);
135
- this._restrictions = parsedRestrictions;
136
- }
137
- get restrictions() {
138
- return this._restrictions;
139
- }
140
- get hostDisabledClass() {
141
- return this.disabled;
142
- }
143
- get dir() {
144
- return this.direction;
145
- }
146
- get hostRole() {
147
- return 'application';
148
- }
149
- /**
150
- * @hidden
151
- */
152
- get formControl() {
153
- const ngControl = this.injector.get(NgControl, null);
154
- return ngControl?.control || null;
155
- }
156
- /**
157
- * @hidden
158
- */
159
- get isControlRequired() {
160
- return isControlRequired(this.formControl);
161
- }
162
86
  ngOnInit() {
163
- const { buttonId, inputId } = this.getIds();
87
+ const { buttonId, fileListId } = this.getIds();
164
88
  this.focusableId = buttonId;
165
- this.inputElementId = inputId;
89
+ this.fileListId = fileListId;
166
90
  if (this.zoneId) {
167
91
  this.dropZoneService.addComponent(this, this.zoneId);
168
92
  }
@@ -182,16 +106,6 @@ export class FileSelectComponent {
182
106
  textFor(key) {
183
107
  return this.localization.get(key);
184
108
  }
185
- /**
186
- * Focuses the underlying input element.
187
- */
188
- focus() {
189
- setTimeout(() => {
190
- this.fileSelectButton.nativeElement.focus();
191
- this.navigation.focused = true;
192
- this.onFocus.emit();
193
- });
194
- }
195
109
  ngOnDestroy() {
196
110
  this.fileList.clear();
197
111
  if (this.blurSubscription) {
@@ -210,52 +124,6 @@ export class FileSelectComponent {
210
124
  this.subs.unsubscribe();
211
125
  }
212
126
  }
213
- /**
214
- * @hidden
215
- */
216
- writeValue(newValue) {
217
- let isValid = true;
218
- if (newValue instanceof Array) {
219
- newValue.forEach((file) => {
220
- if (!validateInitialFileSelectFile(file)) {
221
- isValid = false;
222
- }
223
- });
224
- if (isValid) {
225
- this.uploadService.addInitialFileSelectFiles(newValue);
226
- }
227
- }
228
- if (newValue === null) {
229
- this.fileList.clear();
230
- }
231
- this.cdr.markForCheck();
232
- }
233
- /**
234
- * @hidden
235
- */
236
- registerOnChange(fn) {
237
- this.onChangeCallback = fn;
238
- }
239
- /**
240
- * @hidden
241
- */
242
- registerOnTouched(fn) {
243
- this.onTouchedCallback = fn;
244
- }
245
- /**
246
- * @hidden
247
- */
248
- setDisabledState(isDisabled) {
249
- this.disabled = isDisabled;
250
- }
251
- /**
252
- * @hidden
253
- */
254
- onFileSelectButtonFocus() {
255
- if (!this.navigation.focused) {
256
- this.navigation.focusedIndex = -1;
257
- }
258
- }
259
127
  /**
260
128
  * Removes specific file from the file list.
261
129
  */
@@ -294,8 +162,14 @@ export class FileSelectComponent {
294
162
  getIds() {
295
163
  const id = ++idx;
296
164
  const buttonId = `k-fileselect-button-${id}`;
297
- const inputId = `k-fileselect-input-${id}`;
298
- return { buttonId, inputId };
165
+ const fileListId = `k-fileselect-file-list-${id}`;
166
+ return { buttonId, fileListId };
167
+ }
168
+ /**
169
+ * @hidden
170
+ */
171
+ writeValue(newValue) {
172
+ super.writeValue(newValue, validateInitialFileSelectFile, 'addInitialFileSelectFiles');
299
173
  }
300
174
  subscribeBlur() {
301
175
  if (!isDocumentAvailable()) {
@@ -370,7 +244,7 @@ export class FileSelectComponent {
370
244
  }
371
245
  }
372
246
  FileSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectComponent, deps: [{ token: i1.UploadService }, { token: i2.LocalizationService }, { token: i3.NavigationService }, { token: i4.DropZoneService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
373
- FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileSelectComponent, selector: "kendo-fileselect", inputs: { accept: "accept", disabled: "disabled", multiple: "multiple", name: "name", showFileList: "showFileList", tabindex: "tabindex", restrictions: "restrictions", zoneId: "zoneId", focusableId: "focusableId" }, outputs: { onBlur: "blur", onFocus: "focus", select: "select", remove: "remove", valueChange: "valueChange" }, host: { properties: { "class.k-upload": "this.hostDefaultClasses", "class.k-disabled": "this.hostDisabledClass", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
247
+ FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileSelectComponent, selector: "kendo-fileselect", inputs: { name: "name" }, outputs: { valueChange: "valueChange" }, host: { properties: { "attr.dir": "this.dir" } }, providers: [
374
248
  LocalizationService,
375
249
  NavigationService,
376
250
  UploadService,
@@ -384,7 +258,7 @@ FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ve
384
258
  provide: KendoInput,
385
259
  useExisting: forwardRef(() => FileSelectComponent)
386
260
  }
387
- ], queries: [{ propertyName: "fileTemplate", first: true, predicate: FileTemplateDirective, descendants: true }, { propertyName: "fileInfoTemplate", first: true, predicate: FileInfoTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "fileSelectInput", first: true, predicate: ["fileSelectInput"], descendants: true, static: true }, { propertyName: "fileSelectButton", first: true, predicate: ["fileSelectButton"], descendants: true, read: ElementRef, static: true }], exportAs: ["kendoFileSelect"], ngImport: i0, template: `
261
+ ], viewQueries: [{ propertyName: "fileSelectInput", first: true, predicate: ["fileSelectInput"], descendants: true, static: true }], exportAs: ["kendoFileSelect"], usesInheritance: true, ngImport: i0, template: `
388
262
  <ng-container kendoFileSelectLocalizedMessages
389
263
  i18n-dropFilesHere="kendo.fileselect.dropFilesHere|The drop zone hint"
390
264
  dropFilesHere="Drop files here to select"
@@ -421,12 +295,12 @@ FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ve
421
295
  [id]="focusableId"
422
296
  [attr.aria-label]="textFor('select')"
423
297
  [attr.tabindex]="tabindex"
424
- [attr.aria-controls]="inputElementId"
298
+ [attr.aria-expanded]="hasFileList"
299
+ [attr.aria-controls]="hasFileList ? fileListId : undefined"
425
300
  >
426
301
  {{textFor('select')}}
427
302
  </button>
428
303
  <input kendoFileSelect #fileSelectInput
429
- [id]="inputElementId"
430
304
  [dir]="direction"
431
305
  [accept]="accept"
432
306
  [restrictions]="restrictions"
@@ -439,11 +313,12 @@ FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", ve
439
313
  </div>
440
314
  <ul kendo-upload-file-list
441
315
  class="k-upload-files k-reset"
442
- *ngIf="showFileList && fileList.count > 0"
316
+ *ngIf="hasFileList"
443
317
  [disabled]="disabled"
444
318
  [fileList]="fileList.files"
445
319
  [fileTemplate]="fileTemplate"
446
- [fileInfoTemplate]="fileInfoTemplate">
320
+ [fileInfoTemplate]="fileInfoTemplate"
321
+ [id]="fileListId">
447
322
  </ul>
448
323
  `, isInline: true, dependencies: [{ kind: "directive", type: i5.DropZoneInternalDirective, selector: "\n [kendoUploadInternalDropZone],\n [kendoFileSelectInternalDropZone]\n ", inputs: ["disabled", "multiple", "restrictions"] }, { kind: "component", type: i6.FileListComponent, selector: "[kendo-upload-file-list]", inputs: ["disabled", "fileList", "fileTemplate", "fileInfoTemplate"] }, { kind: "directive", type: i7.FileSelectDirective, selector: "[kendoFileSelect]", inputs: ["dir", "disabled", "multiple", "restrictions", "accept", "required"] }, { kind: "directive", type: i8.LocalizedMessagesDirective, selector: "\n [kendoUploadLocalizedMessages],\n [kendoFileSelectLocalizedMessages],\n [kendoUploadDropZoneLocalizedMessages]\n " }, { kind: "directive", type: i9.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i10.ButtonComponent, selector: "button[kendoButton], span[kendoButton], kendo-button", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "role", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
449
324
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectComponent, decorators: [{
@@ -503,12 +378,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
503
378
  [id]="focusableId"
504
379
  [attr.aria-label]="textFor('select')"
505
380
  [attr.tabindex]="tabindex"
506
- [attr.aria-controls]="inputElementId"
381
+ [attr.aria-expanded]="hasFileList"
382
+ [attr.aria-controls]="hasFileList ? fileListId : undefined"
507
383
  >
508
384
  {{textFor('select')}}
509
385
  </button>
510
386
  <input kendoFileSelect #fileSelectInput
511
- [id]="inputElementId"
512
387
  [dir]="direction"
513
388
  [accept]="accept"
514
389
  [restrictions]="restrictions"
@@ -521,66 +396,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
521
396
  </div>
522
397
  <ul kendo-upload-file-list
523
398
  class="k-upload-files k-reset"
524
- *ngIf="showFileList && fileList.count > 0"
399
+ *ngIf="hasFileList"
525
400
  [disabled]="disabled"
526
401
  [fileList]="fileList.files"
527
402
  [fileTemplate]="fileTemplate"
528
- [fileInfoTemplate]="fileInfoTemplate">
403
+ [fileInfoTemplate]="fileInfoTemplate"
404
+ [id]="fileListId">
529
405
  </ul>
530
406
  `
531
407
  }]
532
- }], ctorParameters: function () { return [{ type: i1.UploadService }, { type: i2.LocalizationService }, { type: i3.NavigationService }, { type: i4.DropZoneService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { accept: [{
533
- type: Input
534
- }], disabled: [{
535
- type: Input
536
- }], multiple: [{
537
- type: Input
538
- }], name: [{
539
- type: Input
540
- }], showFileList: [{
541
- type: Input
542
- }], tabindex: [{
543
- type: Input
544
- }], restrictions: [{
545
- type: Input
546
- }], zoneId: [{
547
- type: Input
548
- }], focusableId: [{
549
- type: Input
550
- }], fileTemplate: [{
551
- type: ContentChild,
552
- args: [FileTemplateDirective]
553
- }], fileInfoTemplate: [{
554
- type: ContentChild,
555
- args: [FileInfoTemplateDirective]
556
- }], fileSelectInput: [{
408
+ }], ctorParameters: function () { return [{ type: i1.UploadService }, { type: i2.LocalizationService }, { type: i3.NavigationService }, { type: i4.DropZoneService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { fileSelectInput: [{
557
409
  type: ViewChild,
558
410
  args: ['fileSelectInput', { static: true }]
559
- }], fileSelectButton: [{
560
- type: ViewChild,
561
- args: ['fileSelectButton', { static: true, read: ElementRef }]
562
- }], onBlur: [{
563
- type: Output,
564
- args: ['blur']
565
- }], onFocus: [{
566
- type: Output,
567
- args: ['focus']
568
- }], select: [{
569
- type: Output
570
- }], remove: [{
571
- type: Output
572
- }], valueChange: [{
573
- type: Output
574
- }], hostDefaultClasses: [{
575
- type: HostBinding,
576
- args: ['class.k-upload']
577
- }], hostDisabledClass: [{
578
- type: HostBinding,
579
- args: ['class.k-disabled']
580
411
  }], dir: [{
581
412
  type: HostBinding,
582
413
  args: ['attr.dir']
583
- }], hostRole: [{
584
- type: HostBinding,
585
- args: ['attr.role']
414
+ }], name: [{
415
+ type: Input
416
+ }], valueChange: [{
417
+ type: Output
586
418
  }] } });
@@ -21,7 +21,9 @@ export class NavigationService {
21
21
  this.onWrapperFocus = new EventEmitter();
22
22
  this.onSelectButtonFocus = new EventEmitter();
23
23
  this.actionButtonsVisible = false;
24
+ this.fileListVisible = false;
24
25
  this.focused = false;
26
+ this.focusedFileIndex = 0;
25
27
  this._focusedIndex = -1;
26
28
  }
27
29
  action(event) {
@@ -40,9 +42,9 @@ export class NavigationService {
40
42
  [Keys.Enter]: () => this.handleEnter(),
41
43
  [Keys.Escape]: () => this.handleEscape(),
42
44
  [Keys.Delete]: () => this.handleDelete(),
43
- [Keys.Tab]: (event, component) => this.handleTab(event.shiftKey, component),
44
- [Keys.ArrowUp]: (event) => this.handleUp(event),
45
- [Keys.ArrowDown]: (event) => this.handleDown(event)
45
+ [Keys.Tab]: (event, component) => this.handleTab(event, component),
46
+ [Keys.ArrowUp]: (event) => this.handleUpDown(event, -1),
47
+ [Keys.ArrowDown]: (event) => this.handleUpDown(event, 1)
46
48
  };
47
49
  }
48
50
  focusSelectButton() {
@@ -70,10 +72,13 @@ export class NavigationService {
70
72
  this.zone.run(() => this.onFileAction.emit(Keys.Escape));
71
73
  }
72
74
  }
73
- handleTab(shifted, component) {
75
+ handleTab(event, component) {
76
+ const shifted = event.shiftKey;
74
77
  /* Select Files button is focused */
75
- if (this.focusedIndex === -1 && this.actionButtonsVisible && !shifted) {
76
- this.focusedIndex = this.lastFileIndex + 1;
78
+ if (this.focusedIndex === -1 && this.fileListVisible && !shifted) {
79
+ this.focusedIndex = this.focusedFileIndex;
80
+ event.preventDefault();
81
+ this.onFileFocus.emit(this.focusedFileIndex);
77
82
  return;
78
83
  }
79
84
  /* File in the list is focused */
@@ -88,7 +93,11 @@ export class NavigationService {
88
93
  }
89
94
  /* Clear button is focused */
90
95
  if (this.focusedIndex === this.lastFileIndex + 1) {
91
- this.focusedIndex = shifted ? -1 : this.lastIndex;
96
+ this.focusedIndex = shifted ? this.focusedFileIndex : this.lastIndex;
97
+ if (shifted) {
98
+ event.preventDefault();
99
+ this.onFileFocus.emit(this.focusedFileIndex);
100
+ }
92
101
  return;
93
102
  }
94
103
  /* Upload button is focused */
@@ -98,35 +107,15 @@ export class NavigationService {
98
107
  }
99
108
  this.onTabOut.emit();
100
109
  }
101
- handleDown(event) {
102
- if (this.lastIndex >= 0 && this.focusedIndex < this.lastIndex) {
103
- event.preventDefault();
104
- this.zone.run(() => {
105
- if (this.focusedIndex < this.lastFileIndex) {
106
- this.focusedIndex += 1;
107
- this.onFileFocus.emit(this.focusedIndex);
108
- return;
109
- }
110
- });
111
- }
112
- }
113
- handleUp(event) {
114
- if (this.lastIndex >= 0 && this.focusedIndex > -1) {
110
+ handleUpDown(event, direction) {
111
+ const focusOnFileList = this.focusedIndex > -1 && this.uploadService.files.count >= 0;
112
+ const nextFocusableIndexInBoundaries = direction > 0 ? this.focusedFileIndex < this.lastFileIndex : this.focusedFileIndex > 0;
113
+ const focusNextFile = focusOnFileList && nextFocusableIndexInBoundaries;
114
+ if (focusNextFile) {
115
115
  event.preventDefault();
116
116
  this.zone.run(() => {
117
- this.focusedIndex -= 1;
118
- if (this.focusedIndex === -1) {
119
- this.onSelectButtonFocus.emit();
120
- return;
121
- }
122
- if (this.focusedIndex <= this.lastFileIndex) {
123
- this.onFileFocus.emit(this.focusedIndex);
124
- return;
125
- }
126
- if (this.actionButtonsVisible && this.focusedIndex <= this.lastIndex) {
127
- this.focusedIndex = this.lastFileIndex;
128
- this.onFileFocus.emit(this.focusedIndex);
129
- }
117
+ this.focusedIndex += direction;
118
+ this.focusedFileIndex += direction;
130
119
  });
131
120
  }
132
121
  }
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-upload',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1718186280,
13
- version: '16.3.0-develop.3',
12
+ publishDate: 1718190520,
13
+ version: '16.3.0-develop.4',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };