@progress/kendo-angular-buttons 16.3.1-develop.3 → 16.4.0-develop.2

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.
@@ -341,7 +341,6 @@ DropDownButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
341
341
  (blur)="onButtonBlur()"
342
342
  [attr.aria-disabled]="disabled"
343
343
  [attr.aria-expanded]="openState"
344
- [attr.aria-haspopup]="'true'"
345
344
  [attr.aria-controls]="listId"
346
345
  >
347
346
  <ng-content></ng-content>
@@ -402,7 +401,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
402
401
  (blur)="onButtonBlur()"
403
402
  [attr.aria-disabled]="disabled"
404
403
  [attr.aria-expanded]="openState"
405
- [attr.aria-haspopup]="'true'"
406
404
  [attr.aria-controls]="listId"
407
405
  >
408
406
  <ng-content></ng-content>
@@ -144,6 +144,7 @@ export class FloatingActionButtonComponent {
144
144
  this.rtl = false;
145
145
  this.animationEnd = new EventEmitter();
146
146
  this.initialSetup = true;
147
+ this.focusChangedProgrammatically = false;
147
148
  validatePackage(packageMetadata);
148
149
  this.subscribeNavigationEvents();
149
150
  this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
@@ -273,6 +274,7 @@ export class FloatingActionButtonComponent {
273
274
  }
274
275
  ngOnDestroy() {
275
276
  this.subscriptions.unsubscribe();
277
+ this.isOpen && this.toggleDial(false);
276
278
  }
277
279
  /**
278
280
  * Indicates whether the FloatingActionButton is currently open.
@@ -283,7 +285,9 @@ export class FloatingActionButtonComponent {
283
285
  */
284
286
  focus() {
285
287
  if (isDocumentAvailable()) {
288
+ this.focusChangedProgrammatically = true;
286
289
  this.button.nativeElement.focus();
290
+ this.focusChangedProgrammatically = false;
287
291
  }
288
292
  }
289
293
  /**
@@ -291,7 +295,9 @@ export class FloatingActionButtonComponent {
291
295
  */
292
296
  blur() {
293
297
  if (isDocumentAvailable()) {
298
+ this.focusChangedProgrammatically = true;
294
299
  this.button.nativeElement.blur();
300
+ this.focusChangedProgrammatically = false;
295
301
  }
296
302
  }
297
303
  /**
@@ -321,19 +327,19 @@ export class FloatingActionButtonComponent {
321
327
  * @hidden
322
328
  */
323
329
  get ariaExpanded() {
324
- return this.hasDialItems ? this.isOpen : null;
330
+ return this.hasDialItems ? this.isOpen : undefined;
325
331
  }
326
332
  /**
327
333
  * @hidden
328
334
  */
329
335
  get ariaHasPopup() {
330
- return this.hasDialItems ? 'menu' : null;
336
+ return this.hasDialItems ? 'menu' : undefined;
331
337
  }
332
338
  /**
333
339
  * @hidden
334
340
  */
335
341
  get ariaControls() {
336
- return this.hasDialItems ? this.dialListId : null;
342
+ return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
337
343
  }
338
344
  /**
339
345
  * @hidden
@@ -363,13 +369,16 @@ export class FloatingActionButtonComponent {
363
369
  /**
364
370
  * @hidden
365
371
  */
366
- keyDownHandler(event) {
367
- this.keyHandler(event);
372
+ pointerdownHandler(e) {
373
+ if (this.isOpen) {
374
+ e.preventDefault();
375
+ this.focus();
376
+ }
368
377
  }
369
378
  /**
370
379
  * @hidden
371
380
  */
372
- keyHandler(event, keyEvent) {
381
+ keyDownHandler(event) {
373
382
  if (this.disabled) {
374
383
  return;
375
384
  }
@@ -379,7 +388,6 @@ export class FloatingActionButtonComponent {
379
388
  altKey: event.altKey,
380
389
  current: focused,
381
390
  keyCode,
382
- keyEvent: keyEvent,
383
391
  max: this.dialItems ? this.dialItems.length - 1 : 0,
384
392
  min: 0,
385
393
  flipNavigation: this.align.vertical === 'bottom'
@@ -387,6 +395,9 @@ export class FloatingActionButtonComponent {
387
395
  if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
388
396
  event.preventDefault();
389
397
  }
398
+ if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
399
+ this.focus();
400
+ }
390
401
  if (action === NavigationAction.EnterUp && !this.hasDialItems) {
391
402
  this.button.nativeElement.click();
392
403
  }
@@ -412,17 +423,66 @@ export class FloatingActionButtonComponent {
412
423
  * @hidden
413
424
  */
414
425
  focusHandler() {
415
- if (!this.disabled) {
426
+ if (!this.disabled && !this.focusChangedProgrammatically) {
416
427
  this.onFocus.emit();
417
428
  }
418
429
  }
419
430
  /**
420
431
  * @hidden
421
432
  */
422
- blurHandler() {
423
- this.onBlur.emit();
433
+ blurHandler(e) {
434
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
435
+ if (focusInList) {
436
+ return;
437
+ }
438
+ !this.focusChangedProgrammatically && this.onBlur.emit();
424
439
  this.toggleDialWithEvents(false);
425
440
  }
441
+ /**
442
+ * @hidden
443
+ */
444
+ focusOutHandler(e) {
445
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
446
+ const focusOnButton = e.relatedTarget === this.button.nativeElement;
447
+ const shouldClose = !focusInList && !focusOnButton;
448
+ if (shouldClose) {
449
+ this.toggleDialWithEvents(false);
450
+ !this.focusChangedProgrammatically && this.onBlur.emit();
451
+ }
452
+ }
453
+ /**
454
+ * @hidden
455
+ */
456
+ onNavigationEnterPress() {
457
+ this.ngZone.run(() => {
458
+ if (this.isOpen) {
459
+ const focusedIndex = this.focusService.focused;
460
+ const focusedItem = this.dialItems[focusedIndex];
461
+ if (focusedItem && focusedItem.disabled) {
462
+ return;
463
+ }
464
+ if (isPresent(focusedIndex) && focusedIndex !== -1) {
465
+ this.onEnterPressed();
466
+ return;
467
+ }
468
+ }
469
+ if (!this.isOpen && isDocumentAvailable()) {
470
+ this.toggleDialWithEvents(true);
471
+ this.focus();
472
+ }
473
+ });
474
+ }
475
+ /**
476
+ * @hidden
477
+ */
478
+ onNavigationClose() {
479
+ if (this.isOpen) {
480
+ this.ngZone.run(() => {
481
+ this.toggleDialWithEvents(false);
482
+ this.focus();
483
+ });
484
+ }
485
+ }
426
486
  handleClasses(inputValue, input) {
427
487
  if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
428
488
  const button = this.button.nativeElement;
@@ -454,6 +514,7 @@ export class FloatingActionButtonComponent {
454
514
  this.toggleDialWithEvents(false);
455
515
  this.focusService.focused = index;
456
516
  }
517
+ this.focus();
457
518
  }
458
519
  subscribeNavigationEvents() {
459
520
  this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
@@ -463,35 +524,6 @@ export class FloatingActionButtonComponent {
463
524
  onArrowKeyNavigate({ index }) {
464
525
  this.focusService.focus(index);
465
526
  }
466
- onNavigationEnterPress() {
467
- this.ngZone.run(() => {
468
- if (this.isOpen) {
469
- const focusedIndex = this.focusService.focused;
470
- const focusedItem = this.dialItems[focusedIndex];
471
- if (focusedItem && focusedItem.disabled) {
472
- return;
473
- }
474
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
475
- this.onEnterPressed();
476
- return;
477
- }
478
- }
479
- if (!this.isOpen && isDocumentAvailable()) {
480
- this.toggleDialWithEvents(true);
481
- this.button.nativeElement.focus();
482
- }
483
- });
484
- }
485
- onNavigationClose() {
486
- if (this.isOpen) {
487
- this.ngZone.run(() => {
488
- this.toggleDialWithEvents(false);
489
- if (isDocumentAvailable()) {
490
- this.button.nativeElement.focus();
491
- }
492
- });
493
- }
494
- }
495
527
  alignClass() {
496
528
  return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
497
529
  }
@@ -569,6 +601,7 @@ export class FloatingActionButtonComponent {
569
601
  this.closePopup();
570
602
  }
571
603
  this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
604
+ this.focusService.resetFocus();
572
605
  }
573
606
  isValidAnimation() {
574
607
  const animation = this.dialItemAnimation;
@@ -714,10 +747,11 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
714
747
  [attr.aria-haspopup]="ariaHasPopup"
715
748
  [attr.aria-controls]="ariaControls"
716
749
  (focus)="focusHandler()"
717
- (blur)="blurHandler()"
750
+ (blur)="blurHandler($event)"
718
751
  [kendoEventsOutsideAngular]="{
719
752
  keydown: keyDownHandler,
720
- click: clickHandler
753
+ click: clickHandler,
754
+ pointerdown: pointerdownHandler
721
755
  }"
722
756
  [scope]="this"
723
757
  >
@@ -748,6 +782,10 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
748
782
  [align]="align"
749
783
  [attr.aria-labelledby]="id"
750
784
  (click)="onItemClick($event)"
785
+ [kendoEventsOutsideAngular]="{
786
+ keydown: keyDownHandler.bind(this),
787
+ focusout: focusOutHandler.bind(this)
788
+ }"
751
789
  >
752
790
  </ul>
753
791
  </ng-template>
@@ -781,10 +819,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
781
819
  [attr.aria-haspopup]="ariaHasPopup"
782
820
  [attr.aria-controls]="ariaControls"
783
821
  (focus)="focusHandler()"
784
- (blur)="blurHandler()"
822
+ (blur)="blurHandler($event)"
785
823
  [kendoEventsOutsideAngular]="{
786
824
  keydown: keyDownHandler,
787
- click: clickHandler
825
+ click: clickHandler,
826
+ pointerdown: pointerdownHandler
788
827
  }"
789
828
  [scope]="this"
790
829
  >
@@ -815,6 +854,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
815
854
  [align]="align"
816
855
  [attr.aria-labelledby]="id"
817
856
  (click)="onItemClick($event)"
857
+ [kendoEventsOutsideAngular]="{
858
+ keydown: keyDownHandler.bind(this),
859
+ focusout: focusOutHandler.bind(this)
860
+ }"
818
861
  >
819
862
  </ul>
820
863
  </ng-template>
@@ -40,11 +40,11 @@ export class FocusableDirective {
40
40
  this.subs.add(this.focusService.onFocus.subscribe((index) => {
41
41
  if (this.index === index) {
42
42
  this.renderer.addClass(this.element, 'k-focus');
43
- this.renderer.setAttribute(this.element, 'tabidnex', '0');
43
+ this.renderer.setAttribute(this.element, 'tabindex', '0');
44
44
  this.element.focus();
45
45
  }
46
46
  else {
47
- this.renderer.setAttribute(this.element, 'tabidnex', '-1');
47
+ this.renderer.setAttribute(this.element, 'tabindex', '-1');
48
48
  this.renderer.removeClass(this.element, 'k-focus');
49
49
  }
50
50
  }));
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-buttons',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1719822617,
13
- version: '16.3.1-develop.3',
12
+ publishDate: 1719935751,
13
+ version: '16.4.0-develop.2',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -599,7 +599,6 @@ SplitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
599
599
  (mousedown)="toggleButtonActiveState(true)"
600
600
  (mouseup)="toggleButtonActiveState(false)"
601
601
  [attr.aria-expanded]="openState"
602
- [attr.aria-haspopup]="'true'"
603
602
  [attr.aria-controls]="listId"
604
603
  [attr.aria-label]="ariaLabel"
605
604
  >
@@ -688,7 +687,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
688
687
  (mousedown)="toggleButtonActiveState(true)"
689
688
  (mouseup)="toggleButtonActiveState(false)"
690
689
  [attr.aria-expanded]="openState"
691
- [attr.aria-haspopup]="'true'"
692
690
  [attr.aria-controls]="listId"
693
691
  [attr.aria-label]="ariaLabel"
694
692
  >
@@ -29,8 +29,8 @@ const packageMetadata = {
29
29
  name: '@progress/kendo-angular-buttons',
30
30
  productName: 'Kendo UI for Angular',
31
31
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
32
- publishDate: 1719822617,
33
- version: '16.3.1-develop.3',
32
+ publishDate: 1719935751,
33
+ version: '16.4.0-develop.2',
34
34
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
35
35
  };
36
36
 
@@ -1157,11 +1157,11 @@ class FocusableDirective {
1157
1157
  this.subs.add(this.focusService.onFocus.subscribe((index) => {
1158
1158
  if (this.index === index) {
1159
1159
  this.renderer.addClass(this.element, 'k-focus');
1160
- this.renderer.setAttribute(this.element, 'tabidnex', '0');
1160
+ this.renderer.setAttribute(this.element, 'tabindex', '0');
1161
1161
  this.element.focus();
1162
1162
  }
1163
1163
  else {
1164
- this.renderer.setAttribute(this.element, 'tabidnex', '-1');
1164
+ this.renderer.setAttribute(this.element, 'tabindex', '-1');
1165
1165
  this.renderer.removeClass(this.element, 'k-focus');
1166
1166
  }
1167
1167
  }));
@@ -2607,7 +2607,6 @@ SplitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
2607
2607
  (mousedown)="toggleButtonActiveState(true)"
2608
2608
  (mouseup)="toggleButtonActiveState(false)"
2609
2609
  [attr.aria-expanded]="openState"
2610
- [attr.aria-haspopup]="'true'"
2611
2610
  [attr.aria-controls]="listId"
2612
2611
  [attr.aria-label]="ariaLabel"
2613
2612
  >
@@ -2696,7 +2695,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
2696
2695
  (mousedown)="toggleButtonActiveState(true)"
2697
2696
  (mouseup)="toggleButtonActiveState(false)"
2698
2697
  [attr.aria-expanded]="openState"
2699
- [attr.aria-haspopup]="'true'"
2700
2698
  [attr.aria-controls]="listId"
2701
2699
  [attr.aria-label]="ariaLabel"
2702
2700
  >
@@ -3199,7 +3197,6 @@ DropDownButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
3199
3197
  (blur)="onButtonBlur()"
3200
3198
  [attr.aria-disabled]="disabled"
3201
3199
  [attr.aria-expanded]="openState"
3202
- [attr.aria-haspopup]="'true'"
3203
3200
  [attr.aria-controls]="listId"
3204
3201
  >
3205
3202
  <ng-content></ng-content>
@@ -3260,7 +3257,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
3260
3257
  (blur)="onButtonBlur()"
3261
3258
  [attr.aria-disabled]="disabled"
3262
3259
  [attr.aria-expanded]="openState"
3263
- [attr.aria-haspopup]="'true'"
3264
3260
  [attr.aria-controls]="listId"
3265
3261
  >
3266
3262
  <ng-content></ng-content>
@@ -4662,6 +4658,7 @@ class FloatingActionButtonComponent {
4662
4658
  this.rtl = false;
4663
4659
  this.animationEnd = new EventEmitter();
4664
4660
  this.initialSetup = true;
4661
+ this.focusChangedProgrammatically = false;
4665
4662
  validatePackage(packageMetadata);
4666
4663
  this.subscribeNavigationEvents();
4667
4664
  this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
@@ -4791,6 +4788,7 @@ class FloatingActionButtonComponent {
4791
4788
  }
4792
4789
  ngOnDestroy() {
4793
4790
  this.subscriptions.unsubscribe();
4791
+ this.isOpen && this.toggleDial(false);
4794
4792
  }
4795
4793
  /**
4796
4794
  * Indicates whether the FloatingActionButton is currently open.
@@ -4801,7 +4799,9 @@ class FloatingActionButtonComponent {
4801
4799
  */
4802
4800
  focus() {
4803
4801
  if (isDocumentAvailable()) {
4802
+ this.focusChangedProgrammatically = true;
4804
4803
  this.button.nativeElement.focus();
4804
+ this.focusChangedProgrammatically = false;
4805
4805
  }
4806
4806
  }
4807
4807
  /**
@@ -4809,7 +4809,9 @@ class FloatingActionButtonComponent {
4809
4809
  */
4810
4810
  blur() {
4811
4811
  if (isDocumentAvailable()) {
4812
+ this.focusChangedProgrammatically = true;
4812
4813
  this.button.nativeElement.blur();
4814
+ this.focusChangedProgrammatically = false;
4813
4815
  }
4814
4816
  }
4815
4817
  /**
@@ -4839,19 +4841,19 @@ class FloatingActionButtonComponent {
4839
4841
  * @hidden
4840
4842
  */
4841
4843
  get ariaExpanded() {
4842
- return this.hasDialItems ? this.isOpen : null;
4844
+ return this.hasDialItems ? this.isOpen : undefined;
4843
4845
  }
4844
4846
  /**
4845
4847
  * @hidden
4846
4848
  */
4847
4849
  get ariaHasPopup() {
4848
- return this.hasDialItems ? 'menu' : null;
4850
+ return this.hasDialItems ? 'menu' : undefined;
4849
4851
  }
4850
4852
  /**
4851
4853
  * @hidden
4852
4854
  */
4853
4855
  get ariaControls() {
4854
- return this.hasDialItems ? this.dialListId : null;
4856
+ return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
4855
4857
  }
4856
4858
  /**
4857
4859
  * @hidden
@@ -4881,13 +4883,16 @@ class FloatingActionButtonComponent {
4881
4883
  /**
4882
4884
  * @hidden
4883
4885
  */
4884
- keyDownHandler(event) {
4885
- this.keyHandler(event);
4886
+ pointerdownHandler(e) {
4887
+ if (this.isOpen) {
4888
+ e.preventDefault();
4889
+ this.focus();
4890
+ }
4886
4891
  }
4887
4892
  /**
4888
4893
  * @hidden
4889
4894
  */
4890
- keyHandler(event, keyEvent) {
4895
+ keyDownHandler(event) {
4891
4896
  if (this.disabled) {
4892
4897
  return;
4893
4898
  }
@@ -4897,7 +4902,6 @@ class FloatingActionButtonComponent {
4897
4902
  altKey: event.altKey,
4898
4903
  current: focused,
4899
4904
  keyCode,
4900
- keyEvent: keyEvent,
4901
4905
  max: this.dialItems ? this.dialItems.length - 1 : 0,
4902
4906
  min: 0,
4903
4907
  flipNavigation: this.align.vertical === 'bottom'
@@ -4905,6 +4909,9 @@ class FloatingActionButtonComponent {
4905
4909
  if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
4906
4910
  event.preventDefault();
4907
4911
  }
4912
+ if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
4913
+ this.focus();
4914
+ }
4908
4915
  if (action === NavigationAction.EnterUp && !this.hasDialItems) {
4909
4916
  this.button.nativeElement.click();
4910
4917
  }
@@ -4930,17 +4937,66 @@ class FloatingActionButtonComponent {
4930
4937
  * @hidden
4931
4938
  */
4932
4939
  focusHandler() {
4933
- if (!this.disabled) {
4940
+ if (!this.disabled && !this.focusChangedProgrammatically) {
4934
4941
  this.onFocus.emit();
4935
4942
  }
4936
4943
  }
4937
4944
  /**
4938
4945
  * @hidden
4939
4946
  */
4940
- blurHandler() {
4941
- this.onBlur.emit();
4947
+ blurHandler(e) {
4948
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
4949
+ if (focusInList) {
4950
+ return;
4951
+ }
4952
+ !this.focusChangedProgrammatically && this.onBlur.emit();
4942
4953
  this.toggleDialWithEvents(false);
4943
4954
  }
4955
+ /**
4956
+ * @hidden
4957
+ */
4958
+ focusOutHandler(e) {
4959
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
4960
+ const focusOnButton = e.relatedTarget === this.button.nativeElement;
4961
+ const shouldClose = !focusInList && !focusOnButton;
4962
+ if (shouldClose) {
4963
+ this.toggleDialWithEvents(false);
4964
+ !this.focusChangedProgrammatically && this.onBlur.emit();
4965
+ }
4966
+ }
4967
+ /**
4968
+ * @hidden
4969
+ */
4970
+ onNavigationEnterPress() {
4971
+ this.ngZone.run(() => {
4972
+ if (this.isOpen) {
4973
+ const focusedIndex = this.focusService.focused;
4974
+ const focusedItem = this.dialItems[focusedIndex];
4975
+ if (focusedItem && focusedItem.disabled) {
4976
+ return;
4977
+ }
4978
+ if (isPresent(focusedIndex) && focusedIndex !== -1) {
4979
+ this.onEnterPressed();
4980
+ return;
4981
+ }
4982
+ }
4983
+ if (!this.isOpen && isDocumentAvailable()) {
4984
+ this.toggleDialWithEvents(true);
4985
+ this.focus();
4986
+ }
4987
+ });
4988
+ }
4989
+ /**
4990
+ * @hidden
4991
+ */
4992
+ onNavigationClose() {
4993
+ if (this.isOpen) {
4994
+ this.ngZone.run(() => {
4995
+ this.toggleDialWithEvents(false);
4996
+ this.focus();
4997
+ });
4998
+ }
4999
+ }
4944
5000
  handleClasses(inputValue, input) {
4945
5001
  if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
4946
5002
  const button = this.button.nativeElement;
@@ -4972,6 +5028,7 @@ class FloatingActionButtonComponent {
4972
5028
  this.toggleDialWithEvents(false);
4973
5029
  this.focusService.focused = index;
4974
5030
  }
5031
+ this.focus();
4975
5032
  }
4976
5033
  subscribeNavigationEvents() {
4977
5034
  this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
@@ -4981,35 +5038,6 @@ class FloatingActionButtonComponent {
4981
5038
  onArrowKeyNavigate({ index }) {
4982
5039
  this.focusService.focus(index);
4983
5040
  }
4984
- onNavigationEnterPress() {
4985
- this.ngZone.run(() => {
4986
- if (this.isOpen) {
4987
- const focusedIndex = this.focusService.focused;
4988
- const focusedItem = this.dialItems[focusedIndex];
4989
- if (focusedItem && focusedItem.disabled) {
4990
- return;
4991
- }
4992
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
4993
- this.onEnterPressed();
4994
- return;
4995
- }
4996
- }
4997
- if (!this.isOpen && isDocumentAvailable()) {
4998
- this.toggleDialWithEvents(true);
4999
- this.button.nativeElement.focus();
5000
- }
5001
- });
5002
- }
5003
- onNavigationClose() {
5004
- if (this.isOpen) {
5005
- this.ngZone.run(() => {
5006
- this.toggleDialWithEvents(false);
5007
- if (isDocumentAvailable()) {
5008
- this.button.nativeElement.focus();
5009
- }
5010
- });
5011
- }
5012
- }
5013
5041
  alignClass() {
5014
5042
  return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
5015
5043
  }
@@ -5087,6 +5115,7 @@ class FloatingActionButtonComponent {
5087
5115
  this.closePopup();
5088
5116
  }
5089
5117
  this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
5118
+ this.focusService.resetFocus();
5090
5119
  }
5091
5120
  isValidAnimation() {
5092
5121
  const animation = this.dialItemAnimation;
@@ -5232,10 +5261,11 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5232
5261
  [attr.aria-haspopup]="ariaHasPopup"
5233
5262
  [attr.aria-controls]="ariaControls"
5234
5263
  (focus)="focusHandler()"
5235
- (blur)="blurHandler()"
5264
+ (blur)="blurHandler($event)"
5236
5265
  [kendoEventsOutsideAngular]="{
5237
5266
  keydown: keyDownHandler,
5238
- click: clickHandler
5267
+ click: clickHandler,
5268
+ pointerdown: pointerdownHandler
5239
5269
  }"
5240
5270
  [scope]="this"
5241
5271
  >
@@ -5266,6 +5296,10 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5266
5296
  [align]="align"
5267
5297
  [attr.aria-labelledby]="id"
5268
5298
  (click)="onItemClick($event)"
5299
+ [kendoEventsOutsideAngular]="{
5300
+ keydown: keyDownHandler.bind(this),
5301
+ focusout: focusOutHandler.bind(this)
5302
+ }"
5269
5303
  >
5270
5304
  </ul>
5271
5305
  </ng-template>
@@ -5299,10 +5333,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5299
5333
  [attr.aria-haspopup]="ariaHasPopup"
5300
5334
  [attr.aria-controls]="ariaControls"
5301
5335
  (focus)="focusHandler()"
5302
- (blur)="blurHandler()"
5336
+ (blur)="blurHandler($event)"
5303
5337
  [kendoEventsOutsideAngular]="{
5304
5338
  keydown: keyDownHandler,
5305
- click: clickHandler
5339
+ click: clickHandler,
5340
+ pointerdown: pointerdownHandler
5306
5341
  }"
5307
5342
  [scope]="this"
5308
5343
  >
@@ -5333,6 +5368,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5333
5368
  [align]="align"
5334
5369
  [attr.aria-labelledby]="id"
5335
5370
  (click)="onItemClick($event)"
5371
+ [kendoEventsOutsideAngular]="{
5372
+ keydown: keyDownHandler.bind(this),
5373
+ focusout: focusOutHandler.bind(this)
5374
+ }"
5336
5375
  >
5337
5376
  </ul>
5338
5377
  </ng-template>
@@ -47,8 +47,8 @@ const packageMetadata = {
47
47
  name: '@progress/kendo-angular-buttons',
48
48
  productName: 'Kendo UI for Angular',
49
49
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
50
- publishDate: 1719822617,
51
- version: '16.3.1-develop.3',
50
+ publishDate: 1719935751,
51
+ version: '16.4.0-develop.2',
52
52
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
53
53
  };
54
54
 
@@ -1217,11 +1217,11 @@ class FocusableDirective {
1217
1217
  this.subs.add(this.focusService.onFocus.subscribe((index) => {
1218
1218
  if (this.index === index) {
1219
1219
  this.renderer.addClass(this.element, 'k-focus');
1220
- this.renderer.setAttribute(this.element, 'tabidnex', '0');
1220
+ this.renderer.setAttribute(this.element, 'tabindex', '0');
1221
1221
  this.element.focus();
1222
1222
  }
1223
1223
  else {
1224
- this.renderer.setAttribute(this.element, 'tabidnex', '-1');
1224
+ this.renderer.setAttribute(this.element, 'tabindex', '-1');
1225
1225
  this.renderer.removeClass(this.element, 'k-focus');
1226
1226
  }
1227
1227
  }));
@@ -2601,7 +2601,6 @@ SplitButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", v
2601
2601
  (mousedown)="toggleButtonActiveState(true)"
2602
2602
  (mouseup)="toggleButtonActiveState(false)"
2603
2603
  [attr.aria-expanded]="openState"
2604
- [attr.aria-haspopup]="'true'"
2605
2604
  [attr.aria-controls]="listId"
2606
2605
  [attr.aria-label]="ariaLabel"
2607
2606
  >
@@ -2690,7 +2689,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
2690
2689
  (mousedown)="toggleButtonActiveState(true)"
2691
2690
  (mouseup)="toggleButtonActiveState(false)"
2692
2691
  [attr.aria-expanded]="openState"
2693
- [attr.aria-haspopup]="'true'"
2694
2692
  [attr.aria-controls]="listId"
2695
2693
  [attr.aria-label]="ariaLabel"
2696
2694
  >
@@ -3192,7 +3190,6 @@ DropDownButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0"
3192
3190
  (blur)="onButtonBlur()"
3193
3191
  [attr.aria-disabled]="disabled"
3194
3192
  [attr.aria-expanded]="openState"
3195
- [attr.aria-haspopup]="'true'"
3196
3193
  [attr.aria-controls]="listId"
3197
3194
  >
3198
3195
  <ng-content></ng-content>
@@ -3253,7 +3250,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
3253
3250
  (blur)="onButtonBlur()"
3254
3251
  [attr.aria-disabled]="disabled"
3255
3252
  [attr.aria-expanded]="openState"
3256
- [attr.aria-haspopup]="'true'"
3257
3253
  [attr.aria-controls]="listId"
3258
3254
  >
3259
3255
  <ng-content></ng-content>
@@ -4649,6 +4645,7 @@ class FloatingActionButtonComponent {
4649
4645
  this.rtl = false;
4650
4646
  this.animationEnd = new EventEmitter();
4651
4647
  this.initialSetup = true;
4648
+ this.focusChangedProgrammatically = false;
4652
4649
  validatePackage(packageMetadata);
4653
4650
  this.subscribeNavigationEvents();
4654
4651
  this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
@@ -4778,6 +4775,7 @@ class FloatingActionButtonComponent {
4778
4775
  }
4779
4776
  ngOnDestroy() {
4780
4777
  this.subscriptions.unsubscribe();
4778
+ this.isOpen && this.toggleDial(false);
4781
4779
  }
4782
4780
  /**
4783
4781
  * Indicates whether the FloatingActionButton is currently open.
@@ -4788,7 +4786,9 @@ class FloatingActionButtonComponent {
4788
4786
  */
4789
4787
  focus() {
4790
4788
  if (isDocumentAvailable()) {
4789
+ this.focusChangedProgrammatically = true;
4791
4790
  this.button.nativeElement.focus();
4791
+ this.focusChangedProgrammatically = false;
4792
4792
  }
4793
4793
  }
4794
4794
  /**
@@ -4796,7 +4796,9 @@ class FloatingActionButtonComponent {
4796
4796
  */
4797
4797
  blur() {
4798
4798
  if (isDocumentAvailable()) {
4799
+ this.focusChangedProgrammatically = true;
4799
4800
  this.button.nativeElement.blur();
4801
+ this.focusChangedProgrammatically = false;
4800
4802
  }
4801
4803
  }
4802
4804
  /**
@@ -4826,19 +4828,19 @@ class FloatingActionButtonComponent {
4826
4828
  * @hidden
4827
4829
  */
4828
4830
  get ariaExpanded() {
4829
- return this.hasDialItems ? this.isOpen : null;
4831
+ return this.hasDialItems ? this.isOpen : undefined;
4830
4832
  }
4831
4833
  /**
4832
4834
  * @hidden
4833
4835
  */
4834
4836
  get ariaHasPopup() {
4835
- return this.hasDialItems ? 'menu' : null;
4837
+ return this.hasDialItems ? 'menu' : undefined;
4836
4838
  }
4837
4839
  /**
4838
4840
  * @hidden
4839
4841
  */
4840
4842
  get ariaControls() {
4841
- return this.hasDialItems ? this.dialListId : null;
4843
+ return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
4842
4844
  }
4843
4845
  /**
4844
4846
  * @hidden
@@ -4868,13 +4870,16 @@ class FloatingActionButtonComponent {
4868
4870
  /**
4869
4871
  * @hidden
4870
4872
  */
4871
- keyDownHandler(event) {
4872
- this.keyHandler(event);
4873
+ pointerdownHandler(e) {
4874
+ if (this.isOpen) {
4875
+ e.preventDefault();
4876
+ this.focus();
4877
+ }
4873
4878
  }
4874
4879
  /**
4875
4880
  * @hidden
4876
4881
  */
4877
- keyHandler(event, keyEvent) {
4882
+ keyDownHandler(event) {
4878
4883
  if (this.disabled) {
4879
4884
  return;
4880
4885
  }
@@ -4884,7 +4889,6 @@ class FloatingActionButtonComponent {
4884
4889
  altKey: event.altKey,
4885
4890
  current: focused,
4886
4891
  keyCode,
4887
- keyEvent: keyEvent,
4888
4892
  max: this.dialItems ? this.dialItems.length - 1 : 0,
4889
4893
  min: 0,
4890
4894
  flipNavigation: this.align.vertical === 'bottom'
@@ -4892,6 +4896,9 @@ class FloatingActionButtonComponent {
4892
4896
  if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
4893
4897
  event.preventDefault();
4894
4898
  }
4899
+ if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
4900
+ this.focus();
4901
+ }
4895
4902
  if (action === NavigationAction.EnterUp && !this.hasDialItems) {
4896
4903
  this.button.nativeElement.click();
4897
4904
  }
@@ -4917,17 +4924,66 @@ class FloatingActionButtonComponent {
4917
4924
  * @hidden
4918
4925
  */
4919
4926
  focusHandler() {
4920
- if (!this.disabled) {
4927
+ if (!this.disabled && !this.focusChangedProgrammatically) {
4921
4928
  this.onFocus.emit();
4922
4929
  }
4923
4930
  }
4924
4931
  /**
4925
4932
  * @hidden
4926
4933
  */
4927
- blurHandler() {
4928
- this.onBlur.emit();
4934
+ blurHandler(e) {
4935
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
4936
+ if (focusInList) {
4937
+ return;
4938
+ }
4939
+ !this.focusChangedProgrammatically && this.onBlur.emit();
4929
4940
  this.toggleDialWithEvents(false);
4930
4941
  }
4942
+ /**
4943
+ * @hidden
4944
+ */
4945
+ focusOutHandler(e) {
4946
+ const focusInList = e.relatedTarget && (e.relatedTarget.closest(`#${this.dialListId}`));
4947
+ const focusOnButton = e.relatedTarget === this.button.nativeElement;
4948
+ const shouldClose = !focusInList && !focusOnButton;
4949
+ if (shouldClose) {
4950
+ this.toggleDialWithEvents(false);
4951
+ !this.focusChangedProgrammatically && this.onBlur.emit();
4952
+ }
4953
+ }
4954
+ /**
4955
+ * @hidden
4956
+ */
4957
+ onNavigationEnterPress() {
4958
+ this.ngZone.run(() => {
4959
+ if (this.isOpen) {
4960
+ const focusedIndex = this.focusService.focused;
4961
+ const focusedItem = this.dialItems[focusedIndex];
4962
+ if (focusedItem && focusedItem.disabled) {
4963
+ return;
4964
+ }
4965
+ if (isPresent(focusedIndex) && focusedIndex !== -1) {
4966
+ this.onEnterPressed();
4967
+ return;
4968
+ }
4969
+ }
4970
+ if (!this.isOpen && isDocumentAvailable()) {
4971
+ this.toggleDialWithEvents(true);
4972
+ this.focus();
4973
+ }
4974
+ });
4975
+ }
4976
+ /**
4977
+ * @hidden
4978
+ */
4979
+ onNavigationClose() {
4980
+ if (this.isOpen) {
4981
+ this.ngZone.run(() => {
4982
+ this.toggleDialWithEvents(false);
4983
+ this.focus();
4984
+ });
4985
+ }
4986
+ }
4931
4987
  handleClasses(inputValue, input) {
4932
4988
  if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
4933
4989
  const button = this.button.nativeElement;
@@ -4959,6 +5015,7 @@ class FloatingActionButtonComponent {
4959
5015
  this.toggleDialWithEvents(false);
4960
5016
  this.focusService.focused = index;
4961
5017
  }
5018
+ this.focus();
4962
5019
  }
4963
5020
  subscribeNavigationEvents() {
4964
5021
  this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
@@ -4968,35 +5025,6 @@ class FloatingActionButtonComponent {
4968
5025
  onArrowKeyNavigate({ index }) {
4969
5026
  this.focusService.focus(index);
4970
5027
  }
4971
- onNavigationEnterPress() {
4972
- this.ngZone.run(() => {
4973
- if (this.isOpen) {
4974
- const focusedIndex = this.focusService.focused;
4975
- const focusedItem = this.dialItems[focusedIndex];
4976
- if (focusedItem && focusedItem.disabled) {
4977
- return;
4978
- }
4979
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
4980
- this.onEnterPressed();
4981
- return;
4982
- }
4983
- }
4984
- if (!this.isOpen && isDocumentAvailable()) {
4985
- this.toggleDialWithEvents(true);
4986
- this.button.nativeElement.focus();
4987
- }
4988
- });
4989
- }
4990
- onNavigationClose() {
4991
- if (this.isOpen) {
4992
- this.ngZone.run(() => {
4993
- this.toggleDialWithEvents(false);
4994
- if (isDocumentAvailable()) {
4995
- this.button.nativeElement.focus();
4996
- }
4997
- });
4998
- }
4999
- }
5000
5028
  alignClass() {
5001
5029
  return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
5002
5030
  }
@@ -5074,6 +5102,7 @@ class FloatingActionButtonComponent {
5074
5102
  this.closePopup();
5075
5103
  }
5076
5104
  this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
5105
+ this.focusService.resetFocus();
5077
5106
  }
5078
5107
  isValidAnimation() {
5079
5108
  const animation = this.dialItemAnimation;
@@ -5219,10 +5248,11 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5219
5248
  [attr.aria-haspopup]="ariaHasPopup"
5220
5249
  [attr.aria-controls]="ariaControls"
5221
5250
  (focus)="focusHandler()"
5222
- (blur)="blurHandler()"
5251
+ (blur)="blurHandler($event)"
5223
5252
  [kendoEventsOutsideAngular]="{
5224
5253
  keydown: keyDownHandler,
5225
- click: clickHandler
5254
+ click: clickHandler,
5255
+ pointerdown: pointerdownHandler
5226
5256
  }"
5227
5257
  [scope]="this"
5228
5258
  >
@@ -5253,6 +5283,10 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5253
5283
  [align]="align"
5254
5284
  [attr.aria-labelledby]="id"
5255
5285
  (click)="onItemClick($event)"
5286
+ [kendoEventsOutsideAngular]="{
5287
+ keydown: keyDownHandler.bind(this),
5288
+ focusout: focusOutHandler.bind(this)
5289
+ }"
5256
5290
  >
5257
5291
  </ul>
5258
5292
  </ng-template>
@@ -5286,10 +5320,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5286
5320
  [attr.aria-haspopup]="ariaHasPopup"
5287
5321
  [attr.aria-controls]="ariaControls"
5288
5322
  (focus)="focusHandler()"
5289
- (blur)="blurHandler()"
5323
+ (blur)="blurHandler($event)"
5290
5324
  [kendoEventsOutsideAngular]="{
5291
5325
  keydown: keyDownHandler,
5292
- click: clickHandler
5326
+ click: clickHandler,
5327
+ pointerdown: pointerdownHandler
5293
5328
  }"
5294
5329
  [scope]="this"
5295
5330
  >
@@ -5320,6 +5355,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5320
5355
  [align]="align"
5321
5356
  [attr.aria-labelledby]="id"
5322
5357
  (click)="onItemClick($event)"
5358
+ [kendoEventsOutsideAngular]="{
5359
+ keydown: keyDownHandler.bind(this),
5360
+ focusout: focusOutHandler.bind(this)
5361
+ }"
5323
5362
  >
5324
5363
  </ul>
5325
5364
  </ng-template>
@@ -7,7 +7,6 @@ import { AfterViewInit, ElementRef, EventEmitter, NgZone, Renderer2, OnDestroy,
7
7
  import { LocalizationService } from '@progress/kendo-angular-l10n';
8
8
  import { PopupService } from '@progress/kendo-angular-popup';
9
9
  import { FocusService } from '../focusable/focus.service';
10
- import { KeyEvents } from '../navigation/key-events';
11
10
  import { NavigationService } from '../navigation/navigation.service';
12
11
  import { FabAlign } from './models/align';
13
12
  import { FabOffset } from './models/offset';
@@ -222,6 +221,7 @@ export declare class FloatingActionButtonComponent implements AfterViewInit, OnD
222
221
  private animationEnd;
223
222
  private popupRef;
224
223
  private initialSetup;
224
+ private focusChangedProgrammatically;
225
225
  constructor(renderer: Renderer2, element: ElementRef, focusService: FocusService, navigationService: NavigationService, ngZone: NgZone, popupService: PopupService, builder: AnimationBuilder, localizationService: LocalizationService);
226
226
  ngAfterViewInit(): void;
227
227
  ngOnDestroy(): void;
@@ -269,11 +269,11 @@ export declare class FloatingActionButtonComponent implements AfterViewInit, OnD
269
269
  /**
270
270
  * @hidden
271
271
  */
272
- keyDownHandler(event: any): void;
272
+ pointerdownHandler(e: PointerEvent): void;
273
273
  /**
274
274
  * @hidden
275
275
  */
276
- keyHandler(event: KeyboardEvent, keyEvent?: KeyEvents): void;
276
+ keyDownHandler(event: any): void;
277
277
  /**
278
278
  * @hidden
279
279
  */
@@ -285,14 +285,24 @@ export declare class FloatingActionButtonComponent implements AfterViewInit, OnD
285
285
  /**
286
286
  * @hidden
287
287
  */
288
- blurHandler(): void;
288
+ blurHandler(e: FocusEvent): void;
289
+ /**
290
+ * @hidden
291
+ */
292
+ focusOutHandler(e: FocusEvent): void;
293
+ /**
294
+ * @hidden
295
+ */
296
+ onNavigationEnterPress(): void;
297
+ /**
298
+ * @hidden
299
+ */
300
+ onNavigationClose(): void;
289
301
  private handleClasses;
290
302
  private onEnterPressed;
291
303
  private emitItemClick;
292
304
  private subscribeNavigationEvents;
293
305
  private onArrowKeyNavigate;
294
- private onNavigationEnterPress;
295
- private onNavigationClose;
296
306
  private alignClass;
297
307
  private toggleDialWithEvents;
298
308
  private openPopup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-buttons",
3
- "version": "16.3.1-develop.3",
3
+ "version": "16.4.0-develop.2",
4
4
  "description": "Buttons Package for Angular",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -25,15 +25,15 @@
25
25
  "@angular/core": "15 - 18",
26
26
  "@angular/platform-browser": "15 - 18",
27
27
  "@progress/kendo-licensing": "^1.0.2",
28
- "@progress/kendo-angular-common": "16.3.1-develop.3",
29
- "@progress/kendo-angular-l10n": "16.3.1-develop.3",
30
- "@progress/kendo-angular-popup": "16.3.1-develop.3",
31
- "@progress/kendo-angular-icons": "16.3.1-develop.3",
28
+ "@progress/kendo-angular-common": "16.4.0-develop.2",
29
+ "@progress/kendo-angular-l10n": "16.4.0-develop.2",
30
+ "@progress/kendo-angular-popup": "16.4.0-develop.2",
31
+ "@progress/kendo-angular-icons": "16.4.0-develop.2",
32
32
  "rxjs": "^6.5.3 || ^7.0.0"
33
33
  },
34
34
  "dependencies": {
35
35
  "tslib": "^2.3.1",
36
- "@progress/kendo-angular-schematics": "16.3.1-develop.3",
36
+ "@progress/kendo-angular-schematics": "16.4.0-develop.2",
37
37
  "@progress/kendo-common": "^0.2.1"
38
38
  },
39
39
  "schematics": "./schematics/collection.json",