@progress/kendo-angular-buttons 16.4.0-develop.1 → 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.
@@ -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: 1719845805,
13
- version: '16.4.0-develop.1',
12
+ publishDate: 1719935751,
13
+ version: '16.4.0-develop.2',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -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: 1719845805,
33
- version: '16.4.0-develop.1',
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
  }));
@@ -4658,6 +4658,7 @@ class FloatingActionButtonComponent {
4658
4658
  this.rtl = false;
4659
4659
  this.animationEnd = new EventEmitter();
4660
4660
  this.initialSetup = true;
4661
+ this.focusChangedProgrammatically = false;
4661
4662
  validatePackage(packageMetadata);
4662
4663
  this.subscribeNavigationEvents();
4663
4664
  this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
@@ -4787,6 +4788,7 @@ class FloatingActionButtonComponent {
4787
4788
  }
4788
4789
  ngOnDestroy() {
4789
4790
  this.subscriptions.unsubscribe();
4791
+ this.isOpen && this.toggleDial(false);
4790
4792
  }
4791
4793
  /**
4792
4794
  * Indicates whether the FloatingActionButton is currently open.
@@ -4797,7 +4799,9 @@ class FloatingActionButtonComponent {
4797
4799
  */
4798
4800
  focus() {
4799
4801
  if (isDocumentAvailable()) {
4802
+ this.focusChangedProgrammatically = true;
4800
4803
  this.button.nativeElement.focus();
4804
+ this.focusChangedProgrammatically = false;
4801
4805
  }
4802
4806
  }
4803
4807
  /**
@@ -4805,7 +4809,9 @@ class FloatingActionButtonComponent {
4805
4809
  */
4806
4810
  blur() {
4807
4811
  if (isDocumentAvailable()) {
4812
+ this.focusChangedProgrammatically = true;
4808
4813
  this.button.nativeElement.blur();
4814
+ this.focusChangedProgrammatically = false;
4809
4815
  }
4810
4816
  }
4811
4817
  /**
@@ -4835,19 +4841,19 @@ class FloatingActionButtonComponent {
4835
4841
  * @hidden
4836
4842
  */
4837
4843
  get ariaExpanded() {
4838
- return this.hasDialItems ? this.isOpen : null;
4844
+ return this.hasDialItems ? this.isOpen : undefined;
4839
4845
  }
4840
4846
  /**
4841
4847
  * @hidden
4842
4848
  */
4843
4849
  get ariaHasPopup() {
4844
- return this.hasDialItems ? 'menu' : null;
4850
+ return this.hasDialItems ? 'menu' : undefined;
4845
4851
  }
4846
4852
  /**
4847
4853
  * @hidden
4848
4854
  */
4849
4855
  get ariaControls() {
4850
- return this.hasDialItems ? this.dialListId : null;
4856
+ return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
4851
4857
  }
4852
4858
  /**
4853
4859
  * @hidden
@@ -4877,13 +4883,16 @@ class FloatingActionButtonComponent {
4877
4883
  /**
4878
4884
  * @hidden
4879
4885
  */
4880
- keyDownHandler(event) {
4881
- this.keyHandler(event);
4886
+ pointerdownHandler(e) {
4887
+ if (this.isOpen) {
4888
+ e.preventDefault();
4889
+ this.focus();
4890
+ }
4882
4891
  }
4883
4892
  /**
4884
4893
  * @hidden
4885
4894
  */
4886
- keyHandler(event, keyEvent) {
4895
+ keyDownHandler(event) {
4887
4896
  if (this.disabled) {
4888
4897
  return;
4889
4898
  }
@@ -4893,7 +4902,6 @@ class FloatingActionButtonComponent {
4893
4902
  altKey: event.altKey,
4894
4903
  current: focused,
4895
4904
  keyCode,
4896
- keyEvent: keyEvent,
4897
4905
  max: this.dialItems ? this.dialItems.length - 1 : 0,
4898
4906
  min: 0,
4899
4907
  flipNavigation: this.align.vertical === 'bottom'
@@ -4901,6 +4909,9 @@ class FloatingActionButtonComponent {
4901
4909
  if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
4902
4910
  event.preventDefault();
4903
4911
  }
4912
+ if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
4913
+ this.focus();
4914
+ }
4904
4915
  if (action === NavigationAction.EnterUp && !this.hasDialItems) {
4905
4916
  this.button.nativeElement.click();
4906
4917
  }
@@ -4926,17 +4937,66 @@ class FloatingActionButtonComponent {
4926
4937
  * @hidden
4927
4938
  */
4928
4939
  focusHandler() {
4929
- if (!this.disabled) {
4940
+ if (!this.disabled && !this.focusChangedProgrammatically) {
4930
4941
  this.onFocus.emit();
4931
4942
  }
4932
4943
  }
4933
4944
  /**
4934
4945
  * @hidden
4935
4946
  */
4936
- blurHandler() {
4937
- 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();
4938
4953
  this.toggleDialWithEvents(false);
4939
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
+ }
4940
5000
  handleClasses(inputValue, input) {
4941
5001
  if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
4942
5002
  const button = this.button.nativeElement;
@@ -4968,6 +5028,7 @@ class FloatingActionButtonComponent {
4968
5028
  this.toggleDialWithEvents(false);
4969
5029
  this.focusService.focused = index;
4970
5030
  }
5031
+ this.focus();
4971
5032
  }
4972
5033
  subscribeNavigationEvents() {
4973
5034
  this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
@@ -4977,35 +5038,6 @@ class FloatingActionButtonComponent {
4977
5038
  onArrowKeyNavigate({ index }) {
4978
5039
  this.focusService.focus(index);
4979
5040
  }
4980
- onNavigationEnterPress() {
4981
- this.ngZone.run(() => {
4982
- if (this.isOpen) {
4983
- const focusedIndex = this.focusService.focused;
4984
- const focusedItem = this.dialItems[focusedIndex];
4985
- if (focusedItem && focusedItem.disabled) {
4986
- return;
4987
- }
4988
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
4989
- this.onEnterPressed();
4990
- return;
4991
- }
4992
- }
4993
- if (!this.isOpen && isDocumentAvailable()) {
4994
- this.toggleDialWithEvents(true);
4995
- this.button.nativeElement.focus();
4996
- }
4997
- });
4998
- }
4999
- onNavigationClose() {
5000
- if (this.isOpen) {
5001
- this.ngZone.run(() => {
5002
- this.toggleDialWithEvents(false);
5003
- if (isDocumentAvailable()) {
5004
- this.button.nativeElement.focus();
5005
- }
5006
- });
5007
- }
5008
- }
5009
5041
  alignClass() {
5010
5042
  return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
5011
5043
  }
@@ -5083,6 +5115,7 @@ class FloatingActionButtonComponent {
5083
5115
  this.closePopup();
5084
5116
  }
5085
5117
  this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
5118
+ this.focusService.resetFocus();
5086
5119
  }
5087
5120
  isValidAnimation() {
5088
5121
  const animation = this.dialItemAnimation;
@@ -5228,10 +5261,11 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5228
5261
  [attr.aria-haspopup]="ariaHasPopup"
5229
5262
  [attr.aria-controls]="ariaControls"
5230
5263
  (focus)="focusHandler()"
5231
- (blur)="blurHandler()"
5264
+ (blur)="blurHandler($event)"
5232
5265
  [kendoEventsOutsideAngular]="{
5233
5266
  keydown: keyDownHandler,
5234
- click: clickHandler
5267
+ click: clickHandler,
5268
+ pointerdown: pointerdownHandler
5235
5269
  }"
5236
5270
  [scope]="this"
5237
5271
  >
@@ -5262,6 +5296,10 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5262
5296
  [align]="align"
5263
5297
  [attr.aria-labelledby]="id"
5264
5298
  (click)="onItemClick($event)"
5299
+ [kendoEventsOutsideAngular]="{
5300
+ keydown: keyDownHandler.bind(this),
5301
+ focusout: focusOutHandler.bind(this)
5302
+ }"
5265
5303
  >
5266
5304
  </ul>
5267
5305
  </ng-template>
@@ -5295,10 +5333,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5295
5333
  [attr.aria-haspopup]="ariaHasPopup"
5296
5334
  [attr.aria-controls]="ariaControls"
5297
5335
  (focus)="focusHandler()"
5298
- (blur)="blurHandler()"
5336
+ (blur)="blurHandler($event)"
5299
5337
  [kendoEventsOutsideAngular]="{
5300
5338
  keydown: keyDownHandler,
5301
- click: clickHandler
5339
+ click: clickHandler,
5340
+ pointerdown: pointerdownHandler
5302
5341
  }"
5303
5342
  [scope]="this"
5304
5343
  >
@@ -5329,6 +5368,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5329
5368
  [align]="align"
5330
5369
  [attr.aria-labelledby]="id"
5331
5370
  (click)="onItemClick($event)"
5371
+ [kendoEventsOutsideAngular]="{
5372
+ keydown: keyDownHandler.bind(this),
5373
+ focusout: focusOutHandler.bind(this)
5374
+ }"
5332
5375
  >
5333
5376
  </ul>
5334
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: 1719845805,
51
- version: '16.4.0-develop.1',
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
  }));
@@ -4645,6 +4645,7 @@ class FloatingActionButtonComponent {
4645
4645
  this.rtl = false;
4646
4646
  this.animationEnd = new EventEmitter();
4647
4647
  this.initialSetup = true;
4648
+ this.focusChangedProgrammatically = false;
4648
4649
  validatePackage(packageMetadata);
4649
4650
  this.subscribeNavigationEvents();
4650
4651
  this.subscriptions.add(this.localizationService.changes.subscribe(({ rtl }) => {
@@ -4774,6 +4775,7 @@ class FloatingActionButtonComponent {
4774
4775
  }
4775
4776
  ngOnDestroy() {
4776
4777
  this.subscriptions.unsubscribe();
4778
+ this.isOpen && this.toggleDial(false);
4777
4779
  }
4778
4780
  /**
4779
4781
  * Indicates whether the FloatingActionButton is currently open.
@@ -4784,7 +4786,9 @@ class FloatingActionButtonComponent {
4784
4786
  */
4785
4787
  focus() {
4786
4788
  if (isDocumentAvailable()) {
4789
+ this.focusChangedProgrammatically = true;
4787
4790
  this.button.nativeElement.focus();
4791
+ this.focusChangedProgrammatically = false;
4788
4792
  }
4789
4793
  }
4790
4794
  /**
@@ -4792,7 +4796,9 @@ class FloatingActionButtonComponent {
4792
4796
  */
4793
4797
  blur() {
4794
4798
  if (isDocumentAvailable()) {
4799
+ this.focusChangedProgrammatically = true;
4795
4800
  this.button.nativeElement.blur();
4801
+ this.focusChangedProgrammatically = false;
4796
4802
  }
4797
4803
  }
4798
4804
  /**
@@ -4822,19 +4828,19 @@ class FloatingActionButtonComponent {
4822
4828
  * @hidden
4823
4829
  */
4824
4830
  get ariaExpanded() {
4825
- return this.hasDialItems ? this.isOpen : null;
4831
+ return this.hasDialItems ? this.isOpen : undefined;
4826
4832
  }
4827
4833
  /**
4828
4834
  * @hidden
4829
4835
  */
4830
4836
  get ariaHasPopup() {
4831
- return this.hasDialItems ? 'menu' : null;
4837
+ return this.hasDialItems ? 'menu' : undefined;
4832
4838
  }
4833
4839
  /**
4834
4840
  * @hidden
4835
4841
  */
4836
4842
  get ariaControls() {
4837
- return this.hasDialItems ? this.dialListId : null;
4843
+ return this.hasDialItems ? this.isOpen ? this.dialListId : undefined : undefined;
4838
4844
  }
4839
4845
  /**
4840
4846
  * @hidden
@@ -4864,13 +4870,16 @@ class FloatingActionButtonComponent {
4864
4870
  /**
4865
4871
  * @hidden
4866
4872
  */
4867
- keyDownHandler(event) {
4868
- this.keyHandler(event);
4873
+ pointerdownHandler(e) {
4874
+ if (this.isOpen) {
4875
+ e.preventDefault();
4876
+ this.focus();
4877
+ }
4869
4878
  }
4870
4879
  /**
4871
4880
  * @hidden
4872
4881
  */
4873
- keyHandler(event, keyEvent) {
4882
+ keyDownHandler(event) {
4874
4883
  if (this.disabled) {
4875
4884
  return;
4876
4885
  }
@@ -4880,7 +4889,6 @@ class FloatingActionButtonComponent {
4880
4889
  altKey: event.altKey,
4881
4890
  current: focused,
4882
4891
  keyCode,
4883
- keyEvent: keyEvent,
4884
4892
  max: this.dialItems ? this.dialItems.length - 1 : 0,
4885
4893
  min: 0,
4886
4894
  flipNavigation: this.align.vertical === 'bottom'
@@ -4888,6 +4896,9 @@ class FloatingActionButtonComponent {
4888
4896
  if (action !== NavigationAction.Undefined && action !== NavigationAction.Tab) {
4889
4897
  event.preventDefault();
4890
4898
  }
4899
+ if (action === NavigationAction.Tab && event.target.closest(`#${this.dialListId}`)) {
4900
+ this.focus();
4901
+ }
4891
4902
  if (action === NavigationAction.EnterUp && !this.hasDialItems) {
4892
4903
  this.button.nativeElement.click();
4893
4904
  }
@@ -4913,17 +4924,66 @@ class FloatingActionButtonComponent {
4913
4924
  * @hidden
4914
4925
  */
4915
4926
  focusHandler() {
4916
- if (!this.disabled) {
4927
+ if (!this.disabled && !this.focusChangedProgrammatically) {
4917
4928
  this.onFocus.emit();
4918
4929
  }
4919
4930
  }
4920
4931
  /**
4921
4932
  * @hidden
4922
4933
  */
4923
- blurHandler() {
4924
- 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();
4925
4940
  this.toggleDialWithEvents(false);
4926
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
+ }
4927
4987
  handleClasses(inputValue, input) {
4928
4988
  if (isPresent(this.button) && (this[input] !== inputValue || this.initialSetup)) {
4929
4989
  const button = this.button.nativeElement;
@@ -4955,6 +5015,7 @@ class FloatingActionButtonComponent {
4955
5015
  this.toggleDialWithEvents(false);
4956
5016
  this.focusService.focused = index;
4957
5017
  }
5018
+ this.focus();
4958
5019
  }
4959
5020
  subscribeNavigationEvents() {
4960
5021
  this.subscriptions.add(this.navigationService.navigate.subscribe(this.onArrowKeyNavigate.bind(this)));
@@ -4964,35 +5025,6 @@ class FloatingActionButtonComponent {
4964
5025
  onArrowKeyNavigate({ index }) {
4965
5026
  this.focusService.focus(index);
4966
5027
  }
4967
- onNavigationEnterPress() {
4968
- this.ngZone.run(() => {
4969
- if (this.isOpen) {
4970
- const focusedIndex = this.focusService.focused;
4971
- const focusedItem = this.dialItems[focusedIndex];
4972
- if (focusedItem && focusedItem.disabled) {
4973
- return;
4974
- }
4975
- if (isPresent(focusedIndex) && focusedIndex !== -1) {
4976
- this.onEnterPressed();
4977
- return;
4978
- }
4979
- }
4980
- if (!this.isOpen && isDocumentAvailable()) {
4981
- this.toggleDialWithEvents(true);
4982
- this.button.nativeElement.focus();
4983
- }
4984
- });
4985
- }
4986
- onNavigationClose() {
4987
- if (this.isOpen) {
4988
- this.ngZone.run(() => {
4989
- this.toggleDialWithEvents(false);
4990
- if (isDocumentAvailable()) {
4991
- this.button.nativeElement.focus();
4992
- }
4993
- });
4994
- }
4995
- }
4996
5028
  alignClass() {
4997
5029
  return `k-pos-${this.align.vertical}-${this.align.horizontal}`;
4998
5030
  }
@@ -5070,6 +5102,7 @@ class FloatingActionButtonComponent {
5070
5102
  this.closePopup();
5071
5103
  }
5072
5104
  this.renderer.setAttribute(this.button.nativeElement, 'aria-expanded', 'false');
5105
+ this.focusService.resetFocus();
5073
5106
  }
5074
5107
  isValidAnimation() {
5075
5108
  const animation = this.dialItemAnimation;
@@ -5215,10 +5248,11 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5215
5248
  [attr.aria-haspopup]="ariaHasPopup"
5216
5249
  [attr.aria-controls]="ariaControls"
5217
5250
  (focus)="focusHandler()"
5218
- (blur)="blurHandler()"
5251
+ (blur)="blurHandler($event)"
5219
5252
  [kendoEventsOutsideAngular]="{
5220
5253
  keydown: keyDownHandler,
5221
- click: clickHandler
5254
+ click: clickHandler,
5255
+ pointerdown: pointerdownHandler
5222
5256
  }"
5223
5257
  [scope]="this"
5224
5258
  >
@@ -5249,6 +5283,10 @@ FloatingActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "1
5249
5283
  [align]="align"
5250
5284
  [attr.aria-labelledby]="id"
5251
5285
  (click)="onItemClick($event)"
5286
+ [kendoEventsOutsideAngular]="{
5287
+ keydown: keyDownHandler.bind(this),
5288
+ focusout: focusOutHandler.bind(this)
5289
+ }"
5252
5290
  >
5253
5291
  </ul>
5254
5292
  </ng-template>
@@ -5282,10 +5320,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5282
5320
  [attr.aria-haspopup]="ariaHasPopup"
5283
5321
  [attr.aria-controls]="ariaControls"
5284
5322
  (focus)="focusHandler()"
5285
- (blur)="blurHandler()"
5323
+ (blur)="blurHandler($event)"
5286
5324
  [kendoEventsOutsideAngular]="{
5287
5325
  keydown: keyDownHandler,
5288
- click: clickHandler
5326
+ click: clickHandler,
5327
+ pointerdown: pointerdownHandler
5289
5328
  }"
5290
5329
  [scope]="this"
5291
5330
  >
@@ -5316,6 +5355,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
5316
5355
  [align]="align"
5317
5356
  [attr.aria-labelledby]="id"
5318
5357
  (click)="onItemClick($event)"
5358
+ [kendoEventsOutsideAngular]="{
5359
+ keydown: keyDownHandler.bind(this),
5360
+ focusout: focusOutHandler.bind(this)
5361
+ }"
5319
5362
  >
5320
5363
  </ul>
5321
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.4.0-develop.1",
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.4.0-develop.1",
29
- "@progress/kendo-angular-l10n": "16.4.0-develop.1",
30
- "@progress/kendo-angular-popup": "16.4.0-develop.1",
31
- "@progress/kendo-angular-icons": "16.4.0-develop.1",
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.4.0-develop.1",
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",