@progress/kendo-angular-dialog 5.1.1 → 5.2.0

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 (33) hide show
  1. package/dist/cdn/js/kendo-angular-dialog.js +1 -1
  2. package/dist/cdn/main.js +1 -1
  3. package/dist/es/common/util.js +66 -1
  4. package/dist/es/dialog/dialog-titlebar.component.js +1 -1
  5. package/dist/es/dialog/dialog.component.js +93 -26
  6. package/dist/es/dialog/dialog.service.js +2 -0
  7. package/dist/es/package-metadata.js +1 -1
  8. package/dist/es/window/window.component.js +52 -2
  9. package/dist/es/window/window.service.js +6 -0
  10. package/dist/es2015/common/util.d.ts +21 -0
  11. package/dist/es2015/common/util.js +66 -1
  12. package/dist/es2015/dialog/dialog-settings.d.ts +12 -0
  13. package/dist/es2015/dialog/dialog-titlebar.component.js +1 -1
  14. package/dist/es2015/dialog/dialog.component.d.ts +26 -6
  15. package/dist/es2015/dialog/dialog.component.js +84 -26
  16. package/dist/es2015/dialog/dialog.service.js +2 -0
  17. package/dist/es2015/index.metadata.json +1 -1
  18. package/dist/es2015/package-metadata.js +1 -1
  19. package/dist/es2015/window/window-settings.d.ts +12 -0
  20. package/dist/es2015/window/window.component.d.ts +13 -0
  21. package/dist/es2015/window/window.component.js +43 -2
  22. package/dist/es2015/window/window.service.js +6 -0
  23. package/dist/fesm2015/index.js +197 -28
  24. package/dist/fesm5/index.js +215 -28
  25. package/dist/npm/common/util.js +68 -0
  26. package/dist/npm/dialog/dialog-titlebar.component.js +1 -1
  27. package/dist/npm/dialog/dialog.component.js +91 -24
  28. package/dist/npm/dialog/dialog.service.js +2 -0
  29. package/dist/npm/package-metadata.js +1 -1
  30. package/dist/npm/window/window.component.js +51 -1
  31. package/dist/npm/window/window.service.js +6 -0
  32. package/dist/systemjs/kendo-angular-dialog.js +1 -1
  33. package/package.json +1 -1
@@ -3,7 +3,7 @@
3
3
  * Licensed under commercial license. See LICENSE.md in the project root for more information
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { __decorate, __metadata, __param } from 'tslib';
6
- import { EventEmitter, TemplateRef, Input, Output, HostBinding, Component, ElementRef, InjectionToken, Inject, Optional, NgZone, ContentChildren, QueryList, ViewChild, HostListener, Renderer2, ChangeDetectorRef, Injectable, isDevMode, ComponentFactoryResolver, Directive, Host, ContentChild, ViewChildren, ViewContainerRef, forwardRef, NgModule } from '@angular/core';
6
+ import { EventEmitter, TemplateRef, Input, Output, HostBinding, Component, ElementRef, InjectionToken, Inject, Optional, NgZone, ContentChildren, QueryList, ViewChildren, ViewChild, HostListener, Renderer2, ChangeDetectorRef, Injectable, isDevMode, ComponentFactoryResolver, Directive, Host, ContentChild, ViewContainerRef, forwardRef, NgModule } from '@angular/core';
7
7
  import { trigger, state, style, transition, animate } from '@angular/animations';
8
8
  import { LocalizationService, L10N_PREFIX, RTL, MessageService, ComponentMessages } from '@progress/kendo-angular-l10n';
9
9
  import { take, filter, map, share, tap, switchMap, takeUntil } from 'rxjs/operators';
@@ -176,7 +176,7 @@ let DialogTitleBarComponent = class DialogTitleBarComponent {
176
176
  }
177
177
  ngAfterViewInit() {
178
178
  this.zone.onStable.pipe(take(1)).subscribe(() => {
179
- const element = this.hostElement.nativeElement;
179
+ const element = this.hostElement.nativeElement.querySelector('.k-dialog-title');
180
180
  element.setAttribute('id', this.id);
181
181
  });
182
182
  }
@@ -257,7 +257,7 @@ const packageMetadata = {
257
257
  name: '@progress/kendo-angular-dialog',
258
258
  productName: 'Kendo UI for Angular',
259
259
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
260
- publishDate: 1631198413,
260
+ publishDate: 1634903940,
261
261
  version: '',
262
262
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
263
263
  };
@@ -333,6 +333,60 @@ const isFocusable = (element, checkVisibility = true) => {
333
333
  }
334
334
  return false;
335
335
  };
336
+ /**
337
+ * @hidden
338
+ */
339
+ const setHTMLAttributes = (attributes, renderer, element) => {
340
+ for (const attribute in attributes) {
341
+ if (attribute) {
342
+ renderer.setAttribute(element, attribute, attributes[attribute]);
343
+ }
344
+ }
345
+ };
346
+ /**
347
+ * Receives CSS class declarations either as an object, string or array and returns an array of the class names.
348
+ *
349
+ * @hidden
350
+ */
351
+ const parseCSSClassNames = (value) => {
352
+ if (isObject(value)) {
353
+ return parseObjectClassNames(value);
354
+ }
355
+ if (isString(value)) {
356
+ return parseStringClassNames(value);
357
+ }
358
+ if (Array.isArray(value)) {
359
+ return parseArrayClassNames(value);
360
+ }
361
+ };
362
+ const parseObjectClassNames = (value) => {
363
+ const classes = [];
364
+ Object.keys(value).forEach(className => {
365
+ const currentClassName = splitStringToArray(className);
366
+ if (value[className] && currentClassName[0]) {
367
+ classes.push(...currentClassName);
368
+ }
369
+ });
370
+ return classes;
371
+ };
372
+ const parseStringClassNames = (value) => {
373
+ const classes = [];
374
+ const classesArray = splitStringToArray(value);
375
+ classesArray.forEach(className => {
376
+ classes.push(className);
377
+ });
378
+ return classes;
379
+ };
380
+ const parseArrayClassNames = (value) => {
381
+ const classes = [];
382
+ value.forEach((className) => {
383
+ const current = splitStringToArray(className);
384
+ if (current[0]) {
385
+ classes.push(...current);
386
+ }
387
+ });
388
+ return classes;
389
+ };
336
390
  /**
337
391
  * @hidden
338
392
  */
@@ -368,6 +422,10 @@ const OFFSET_STYLES = ['top', 'left', 'width', 'height'];
368
422
  * @hidden
369
423
  */
370
424
  const isString = (value) => value instanceof String || typeof value === 'string';
425
+ /**
426
+ * @hidden
427
+ */
428
+ const isObject = (value) => isPresent(value) && !Array.isArray(value) && typeof value === 'object';
371
429
  /**
372
430
  * @hidden
373
431
  */
@@ -376,6 +434,10 @@ const isNumber = (value) => typeof value === 'number' && isFinite(value);
376
434
  * @hidden
377
435
  */
378
436
  const createValueWithUnit = (value) => value + (isNumber(value) ? 'px' : '');
437
+ /**
438
+ * @hidden
439
+ */
440
+ const splitStringToArray = (value) => value.trim().replace(/\s+/g, " ").split(' ');
379
441
 
380
442
  /**
381
443
  * The settings for the Dialog actions when the Dialog is opened through `DialogService`
@@ -424,13 +486,17 @@ let DialogComponent = class DialogComponent {
424
486
  * @hidden
425
487
  */
426
488
  this.titleId = null;
489
+ /**
490
+ * @hidden
491
+ */
492
+ this.contentId = null;
427
493
  /**
428
494
  * Fires when the user clicks an action button of the Dialog.
429
495
  * The event is fired only when the action buttons are specified through the `actions` options.
430
496
  */
431
497
  this.action = new EventEmitter();
432
498
  /**
433
- * Fires when the user clicks the **Close** button of the Dialog.
499
+ * Fires when the user clicks the **Close** button of the Dialog or the **ESC** key.
434
500
  */
435
501
  this.close = new EventEmitter();
436
502
  this.tabIndex = 0;
@@ -439,6 +505,36 @@ let DialogComponent = class DialogComponent {
439
505
  this.direction = localization.rtl ? 'rtl' : 'ltr';
440
506
  this.subscriptions.push(localization.changes.subscribe(({ rtl }) => (this.direction = rtl ? 'rtl' : 'ltr')));
441
507
  this.titleId = this.generateTitleId();
508
+ this.contentId = this.generateContentId();
509
+ }
510
+ /**
511
+ * @hidden
512
+ */
513
+ set htmlAttributes(attributes) {
514
+ setHTMLAttributes(attributes, this._renderer, this._elRef.nativeElement);
515
+ const el = this._elRef.nativeElement;
516
+ const dir = el.getAttribute('dir');
517
+ const tIndex = el.getAttribute('tabindex');
518
+ if (this.direction !== dir) {
519
+ this.direction = dir;
520
+ }
521
+ if (this.tabIndex !== tIndex) {
522
+ this.tabIndex = tIndex;
523
+ }
524
+ this._htmlAttributes = attributes;
525
+ }
526
+ get htmlAttributes() {
527
+ return this._htmlAttributes;
528
+ }
529
+ /**
530
+ * @hidden
531
+ */
532
+ set cssClass(classes) {
533
+ this.setServiceClasses(this._cssClass, classes);
534
+ this._cssClass = classes;
535
+ }
536
+ get cssClass() {
537
+ return this._cssClass;
442
538
  }
443
539
  get dir() {
444
540
  return this.direction;
@@ -465,6 +561,7 @@ let DialogComponent = class DialogComponent {
465
561
  }
466
562
  ngAfterContentInit() {
467
563
  this.bubble('close', this.titlebarContent.first);
564
+ this._renderer.setAttribute(this._elRef.nativeElement.querySelector('.k-dialog'), 'aria-describedby', this.contentId);
468
565
  if (this.titlebarContent.first) {
469
566
  this.titlebarContent.first.id = this.titleId;
470
567
  }
@@ -480,22 +577,25 @@ let DialogComponent = class DialogComponent {
480
577
  }));
481
578
  }
482
579
  }
483
- ngOnChanges(changes) {
484
- if (changes.title && changes.title.currentValue && !changes.title.previousValue) {
485
- this.zone.onStable.pipe(take(1)).subscribe(() => {
486
- this.bubble('close', this.titlebarView);
487
- this._renderer.setAttribute(this._elRef.nativeElement.querySelector('.k-dialog'), 'aria-labelledby', this.titleId);
488
- });
489
- }
490
- }
491
580
  ngAfterViewInit() {
492
581
  this.handleInitialFocus();
493
- this.bubble('close', this.titlebarView);
582
+ this.bubble('close', this.titlebarView.first);
494
583
  this.bubble('action', this.actionsView);
495
- if (this.titlebarView || this.titlebarContent.first) {
584
+ if (this.titlebarView.first || this.titlebarContent.first) {
496
585
  //Needed for Dialogs created via service
497
586
  this._renderer.setAttribute(this._elRef.nativeElement.querySelector('.k-dialog'), 'aria-labelledby', this.titleId);
498
587
  }
588
+ else {
589
+ this.subscriptions.push(this.titlebarView.changes.subscribe(() => {
590
+ if (isPresent(this.titlebarView.first)) {
591
+ this.titlebarView.first.id = this.titleId;
592
+ this.zone.onStable.pipe(take(1)).subscribe(() => {
593
+ this.bubble('close', this.titlebarView.first);
594
+ this._renderer.setAttribute(this._elRef.nativeElement.querySelector('.k-dialog'), 'aria-labelledby', this.titleId);
595
+ });
596
+ }
597
+ }));
598
+ }
499
599
  }
500
600
  ngOnInit() {
501
601
  this._renderer.removeAttribute(this._elRef.nativeElement, 'title');
@@ -514,6 +614,19 @@ let DialogComponent = class DialogComponent {
514
614
  wrapper.focus();
515
615
  }
516
616
  }
617
+ setServiceClasses(prevValue, value) {
618
+ const el = this._elRef.nativeElement;
619
+ if (prevValue) {
620
+ parseCSSClassNames(prevValue).forEach(className => {
621
+ this._renderer.removeClass(el, className);
622
+ });
623
+ }
624
+ if (value) {
625
+ parseCSSClassNames(value).forEach(className => {
626
+ this._renderer.addClass(el, className);
627
+ });
628
+ }
629
+ }
517
630
  /**
518
631
  * @hidden
519
632
  */
@@ -556,16 +669,15 @@ let DialogComponent = class DialogComponent {
556
669
  * @hidden
557
670
  */
558
671
  keepFocusWithinComponent(target, event) {
559
- const firstFocusable = this._elRef.nativeElement;
560
- const lastFocusable = this.getLastFocusableElement(firstFocusable);
561
- const tabBeforeFirstFocusable = target === firstFocusable && event.shiftKey;
562
- const tabAfterLastFocusable = !event.shiftKey && isPresent(lastFocusable) && target === lastFocusable;
563
- const tabWithNoFocusable = !isPresent(lastFocusable) && !event.shiftKey;
564
- if (tabBeforeFirstFocusable || tabWithNoFocusable) {
672
+ const wrapper = this._elRef.nativeElement;
673
+ const [firstFocusable, lastFocusable] = this.getFirstAndLastFocusable(wrapper);
674
+ const tabAfterLastFocusable = !event.shiftKey && target === lastFocusable;
675
+ const shiftTabAfterFirstFocusable = event.shiftKey && target === firstFocusable;
676
+ if (tabAfterLastFocusable) {
565
677
  event.preventDefault();
566
678
  firstFocusable.focus();
567
679
  }
568
- if (tabAfterLastFocusable) {
680
+ if (shiftTabAfterFirstFocusable) {
569
681
  event.preventDefault();
570
682
  lastFocusable.focus();
571
683
  }
@@ -585,9 +697,11 @@ let DialogComponent = class DialogComponent {
585
697
  /**
586
698
  * @hidden
587
699
  */
588
- getLastFocusableElement(parent) {
700
+ getFirstAndLastFocusable(parent) {
589
701
  const all = this.getAllFocusableChildren(parent);
590
- return all.length > 0 ? all[all.length - 1] : null;
702
+ const firstFocusable = all.length > 0 ? all[0] : parent;
703
+ const lastFocusable = all.length > 0 ? all[all.length - 1] : parent;
704
+ return [firstFocusable, lastFocusable];
591
705
  }
592
706
  /**
593
707
  * @hidden
@@ -595,6 +709,12 @@ let DialogComponent = class DialogComponent {
595
709
  generateTitleId() {
596
710
  return 'kendo-dialog-title-' + Math.ceil(Math.random() * 1000000).toString();
597
711
  }
712
+ /**
713
+ * @hidden
714
+ */
715
+ generateContentId() {
716
+ return 'kendo-dialog-content-' + Math.ceil(Math.random() * 1000000).toString();
717
+ }
598
718
  get wrapperClass() {
599
719
  return true;
600
720
  }
@@ -690,8 +810,8 @@ __decorate([
690
810
  __metadata("design:type", QueryList)
691
811
  ], DialogComponent.prototype, "titlebarContent", void 0);
692
812
  __decorate([
693
- ViewChild(DialogTitleBarComponent, { static: false }),
694
- __metadata("design:type", DialogTitleBarComponent)
813
+ ViewChildren(DialogTitleBarComponent),
814
+ __metadata("design:type", QueryList)
695
815
  ], DialogComponent.prototype, "titlebarView", void 0);
696
816
  __decorate([
697
817
  ViewChild(DialogActionsComponent, { static: false }),
@@ -741,11 +861,11 @@ DialogComponent = __decorate([
741
861
  >
742
862
  <div class="k-overlay" @overlayAppear></div>
743
863
 
744
- <div class="k-widget k-window k-dialog" role="dialog" [ngStyle]="styles" @dialogSlideInAppear>
864
+ <div class="k-window k-dialog" role="dialog" aria-modal="true" [ngStyle]="styles" @dialogSlideInAppear>
745
865
  <kendo-dialog-titlebar *ngIf="title" [closeTitle]="closeTitle" [id]="titleId">{{ title }}</kendo-dialog-titlebar>
746
866
  <ng-content select="kendo-dialog-titlebar" *ngIf="!title"></ng-content>
747
867
 
748
- <div class="k-content k-window-content k-dialog-content">
868
+ <div [id]="contentId" class="k-content k-window-content k-dialog-content">
749
869
  <ng-content *ngIf="!contentTemplate"></ng-content>
750
870
  <ng-template [ngTemplateOutlet]="contentTemplate" *ngIf="contentTemplate"></ng-template>
751
871
  </div>
@@ -978,6 +1098,8 @@ See https://www.telerik.com/kendo-angular-ui/components/dialogs/dialog/service/.
978
1098
  instance.maxHeight = options.maxHeight;
979
1099
  instance.autoFocusedElement = options.autoFocusedElement;
980
1100
  instance.closeTitle = options.closeTitle;
1101
+ instance.cssClass = options.cssClass;
1102
+ instance.htmlAttributes = options.htmlAttributes;
981
1103
  if (options.content instanceof TemplateRef) {
982
1104
  instance.contentTemplate = options.content;
983
1105
  }
@@ -1752,6 +1874,35 @@ let WindowComponent = class WindowComponent {
1752
1874
  get resizable() {
1753
1875
  return this.options.resizable;
1754
1876
  }
1877
+ /**
1878
+ * @hidden
1879
+ */
1880
+ set cssClass(classes) {
1881
+ this.setServiceClasses(this._cssClass, classes);
1882
+ this._cssClass = classes;
1883
+ }
1884
+ get cssClass() {
1885
+ return this._cssClass;
1886
+ }
1887
+ /**
1888
+ * @hidden
1889
+ */
1890
+ set htmlAttributes(attributes) {
1891
+ setHTMLAttributes(attributes, this.renderer, this.el.nativeElement);
1892
+ const el = this.el.nativeElement;
1893
+ const dir = el.getAttribute('dir');
1894
+ const tIndex = el.getAttribute('tabindex');
1895
+ if (this.direction !== dir) {
1896
+ this.direction = dir;
1897
+ }
1898
+ if (this.tabIndex !== tIndex) {
1899
+ this.tabIndex = tIndex;
1900
+ }
1901
+ this._htmlAttributes = attributes;
1902
+ }
1903
+ get htmlAttributes() {
1904
+ return this._htmlAttributes;
1905
+ }
1755
1906
  /**
1756
1907
  * Specifies the initial state of the component.
1757
1908
  * If not specified, the value is set to `default`.
@@ -2039,6 +2190,19 @@ let WindowComponent = class WindowComponent {
2039
2190
  }
2040
2191
  }));
2041
2192
  }
2193
+ setServiceClasses(prevValue, value) {
2194
+ const el = this.el.nativeElement;
2195
+ if (prevValue) {
2196
+ parseCSSClassNames(prevValue).forEach(className => {
2197
+ this.renderer.removeClass(el, className);
2198
+ });
2199
+ }
2200
+ if (value) {
2201
+ parseCSSClassNames(value).forEach(className => {
2202
+ this.renderer.addClass(el, className);
2203
+ });
2204
+ }
2205
+ }
2042
2206
  setNextZIndex() {
2043
2207
  const currentZIndex = this.el.nativeElement.style['z-index'];
2044
2208
  const nextPossibleZIndex = this.service.nextPossibleZIndex;
@@ -2203,7 +2367,6 @@ __decorate([
2203
2367
  __metadata("design:type", Number)
2204
2368
  ], WindowComponent.prototype, "tabIndex", void 0);
2205
2369
  __decorate([
2206
- HostBinding('class.k-widget'),
2207
2370
  HostBinding('class.k-window'),
2208
2371
  __metadata("design:type", Boolean),
2209
2372
  __metadata("design:paramtypes", [])
@@ -2704,6 +2867,12 @@ let WindowService = class WindowService {
2704
2867
  return windowRef;
2705
2868
  }
2706
2869
  applyOptions(instance, options) {
2870
+ if (isPresent(options.htmlAttributes)) {
2871
+ instance.htmlAttributes = options.htmlAttributes;
2872
+ }
2873
+ if (isPresent(options.cssClass)) {
2874
+ instance.cssClass = options.cssClass;
2875
+ }
2707
2876
  if (isPresent(options.title)) {
2708
2877
  instance.title = options.title;
2709
2878
  }