@angular/cdk 16.2.0-next.2 → 16.2.0-next.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.
package/fesm2022/menu.mjs CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { Directive, InjectionToken, Optional, SkipSelf, Inject, Injectable, inject, Injector, ViewContainerRef, EventEmitter, NgZone, ElementRef, Input, Output, ContentChildren, NgModule } from '@angular/core';
3
3
  import { Overlay, OverlayConfig, STANDARD_DROPDOWN_BELOW_POSITIONS, STANDARD_DROPDOWN_ADJACENT_POSITIONS, OverlayModule } from '@angular/cdk/overlay';
4
- import { UP_ARROW, hasModifierKey, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, ENTER, SPACE, TAB, ESCAPE } from '@angular/cdk/keycodes';
4
+ import { ENTER, SPACE, UP_ARROW, hasModifierKey, DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, TAB, ESCAPE } from '@angular/cdk/keycodes';
5
5
  import { startWith, debounceTime, distinctUntilChanged, filter, takeUntil, mergeMap, mapTo, mergeAll, switchMap, skip } from 'rxjs/operators';
6
6
  import { UniqueSelectionDispatcher } from '@angular/cdk/collections';
7
7
  import { Subject, merge, fromEvent, defer, partition } from 'rxjs';
8
8
  import { TemplatePortal } from '@angular/cdk/portal';
9
- import { InputModalityDetector, FocusKeyManager } from '@angular/cdk/a11y';
9
+ import { FocusKeyManager } from '@angular/cdk/a11y';
10
10
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
11
11
  import { Directionality } from '@angular/cdk/bidi';
12
12
  import { _getEventTarget } from '@angular/cdk/platform';
@@ -482,6 +482,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.1", ngImpor
482
482
  }]
483
483
  }] });
484
484
 
485
+ /** Checks whether a keyboard event will trigger a native `click` event on an element. */
486
+ function eventDispatchesNativeClick(elementRef, event) {
487
+ // Synthetic events won't trigger clicks.
488
+ if (!event.isTrusted) {
489
+ return false;
490
+ }
491
+ const el = elementRef.nativeElement;
492
+ const keyCode = event.keyCode;
493
+ // Buttons trigger clicks both on space and enter events.
494
+ if (el.nodeName === 'BUTTON' && !el.disabled) {
495
+ return keyCode === ENTER || keyCode === SPACE;
496
+ }
497
+ // Links only trigger clicks on enter.
498
+ if (el.nodeName === 'A') {
499
+ return keyCode === ENTER;
500
+ }
501
+ // Any other elements won't dispatch clicks from keyboard events.
502
+ return false;
503
+ }
504
+
485
505
  /**
486
506
  * A directive that turns its host element into a trigger for a popup menu.
487
507
  * It can be combined with cdkMenuItem to create sub-menus. If the element is in a top level
@@ -496,7 +516,6 @@ class CdkMenuTrigger extends CdkMenuTriggerBase {
496
516
  this._overlay = inject(Overlay);
497
517
  this._ngZone = inject(NgZone);
498
518
  this._directionality = inject(Directionality, { optional: true });
499
- this._inputModalityDetector = inject(InputModalityDetector);
500
519
  /** The parent menu this trigger belongs to. */
501
520
  this._parentMenu = inject(CDK_MENU, { optional: true });
502
521
  /** The menu aim service used by this menu. */
@@ -544,7 +563,8 @@ class CdkMenuTrigger extends CdkMenuTriggerBase {
544
563
  switch (event.keyCode) {
545
564
  case SPACE:
546
565
  case ENTER:
547
- if (!hasModifierKey(event)) {
566
+ // Skip events that will trigger clicks so the handler doesn't get triggered twice.
567
+ if (!hasModifierKey(event) && !eventDispatchesNativeClick(this._elementRef, event)) {
548
568
  this.toggle();
549
569
  this.childMenu?.focusFirstItem('keyboard');
550
570
  }
@@ -583,12 +603,8 @@ class CdkMenuTrigger extends CdkMenuTriggerBase {
583
603
  }
584
604
  /** Handles clicks on the menu trigger. */
585
605
  _handleClick() {
586
- // Don't handle clicks originating from the keyboard since we
587
- // already do the same on `keydown` events for enter and space.
588
- if (this._inputModalityDetector.mostRecentModality !== 'keyboard') {
589
- this.toggle();
590
- this.childMenu?.focusFirstItem('mouse');
591
- }
606
+ this.toggle();
607
+ this.childMenu?.focusFirstItem('mouse');
592
608
  }
593
609
  /**
594
610
  * Sets whether the trigger's menu stack has focus.
@@ -787,7 +803,6 @@ class CdkMenuItem {
787
803
  }
788
804
  constructor() {
789
805
  this._dir = inject(Directionality, { optional: true });
790
- this._inputModalityDetector = inject(InputModalityDetector);
791
806
  this._elementRef = inject(ElementRef);
792
807
  this._ngZone = inject(NgZone);
793
808
  /** The menu aim service used by this menu. */
@@ -890,7 +905,8 @@ class CdkMenuItem {
890
905
  switch (event.keyCode) {
891
906
  case SPACE:
892
907
  case ENTER:
893
- if (!hasModifierKey(event)) {
908
+ // Skip events that will trigger clicks so the handler doesn't get triggered twice.
909
+ if (!hasModifierKey(event) && !eventDispatchesNativeClick(this._elementRef, event)) {
894
910
  this.trigger({ keepOpen: event.keyCode === SPACE && !this.closeOnSpacebarTrigger });
895
911
  }
896
912
  break;
@@ -920,14 +936,6 @@ class CdkMenuItem {
920
936
  break;
921
937
  }
922
938
  }
923
- /** Handles clicks on the menu item. */
924
- _handleClick() {
925
- // Don't handle clicks originating from the keyboard since we
926
- // already do the same on `keydown` events for enter and space.
927
- if (this._inputModalityDetector.mostRecentModality !== 'keyboard') {
928
- this.trigger();
929
- }
930
- }
931
939
  /** Whether this menu item is standalone or within a menu or menu bar. */
932
940
  _isStandaloneItem() {
933
941
  return !this._parentMenu;
@@ -996,7 +1004,7 @@ class CdkMenuItem {
996
1004
  }
997
1005
  }
998
1006
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: CdkMenuItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
999
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.1", type: CdkMenuItem, isStandalone: true, selector: "[cdkMenuItem]", inputs: { disabled: ["cdkMenuItemDisabled", "disabled"], typeaheadLabel: ["cdkMenuitemTypeaheadLabel", "typeaheadLabel"] }, outputs: { triggered: "cdkMenuItemTriggered" }, host: { attributes: { "role": "menuitem" }, listeners: { "blur": "_resetTabIndex()", "focus": "_setTabIndex()", "click": "_handleClick()", "keydown": "_onKeydown($event)" }, properties: { "tabindex": "_tabindex", "attr.aria-disabled": "disabled || null" }, classAttribute: "cdk-menu-item" }, exportAs: ["cdkMenuItem"], ngImport: i0 }); }
1007
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.1", type: CdkMenuItem, isStandalone: true, selector: "[cdkMenuItem]", inputs: { disabled: ["cdkMenuItemDisabled", "disabled"], typeaheadLabel: ["cdkMenuitemTypeaheadLabel", "typeaheadLabel"] }, outputs: { triggered: "cdkMenuItemTriggered" }, host: { attributes: { "role": "menuitem" }, listeners: { "blur": "_resetTabIndex()", "focus": "_setTabIndex()", "click": "trigger()", "keydown": "_onKeydown($event)" }, properties: { "tabindex": "_tabindex", "attr.aria-disabled": "disabled || null" }, classAttribute: "cdk-menu-item" }, exportAs: ["cdkMenuItem"], ngImport: i0 }); }
1000
1008
  }
1001
1009
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.1", ngImport: i0, type: CdkMenuItem, decorators: [{
1002
1010
  type: Directive,
@@ -1011,7 +1019,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.1", ngImpor
1011
1019
  '[attr.aria-disabled]': 'disabled || null',
1012
1020
  '(blur)': '_resetTabIndex()',
1013
1021
  '(focus)': '_setTabIndex()',
1014
- '(click)': '_handleClick()',
1022
+ '(click)': 'trigger()',
1015
1023
  '(keydown)': '_onKeydown($event)',
1016
1024
  },
1017
1025
  }]