menu.es5.js 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039
  1. /**
  2. * @license
  3. * Copyright Google LLC All Rights Reserved.
  4. *
  5. * Use of this source code is governed by an MIT-style license that can be
  6. * found in the LICENSE file at https://angular.io/license
  7. */
  8. import { trigger, state, style, animate, transition, query, group } from '@angular/animations';
  9. import { DomPortalOutlet, TemplatePortal } from '@angular/cdk/portal';
  10. import { DOCUMENT, CommonModule } from '@angular/common';
  11. import { ApplicationRef, ChangeDetectorRef, ComponentFactoryResolver, Directive, Inject, Injector, TemplateRef, ViewContainerRef, InjectionToken, ChangeDetectionStrategy, Component, ElementRef, ViewEncapsulation, Optional, Input, HostListener, ContentChild, ContentChildren, EventEmitter, NgZone, Output, QueryList, ViewChild, Self, NgModule } from '@angular/core';
  12. import { Subject, merge, Subscription, asapScheduler, of } from 'rxjs';
  13. import { __extends } from 'tslib';
  14. import { FocusMonitor, FocusKeyManager, isFakeMousedownFromScreenReader } from '@angular/cdk/a11y';
  15. import { mixinDisabled, mixinDisableRipple, MatCommonModule, MatRippleModule } from '@angular/material/core';
  16. import { coerceBooleanProperty } from '@angular/cdk/coercion';
  17. import { ESCAPE, LEFT_ARROW, RIGHT_ARROW, DOWN_ARROW, UP_ARROW, HOME, END, hasModifierKey } from '@angular/cdk/keycodes';
  18. import { startWith, switchMap, take, delay, filter, takeUntil } from 'rxjs/operators';
  19. import { Directionality } from '@angular/cdk/bidi';
  20. import { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
  21. import { normalizePassiveListenerOptions } from '@angular/cdk/platform';
  22. /**
  23. * @fileoverview added by tsickle
  24. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  25. */
  26. /**
  27. * Animations used by the mat-menu component.
  28. * Animation duration and timing values are based on:
  29. * https://material.io/guidelines/components/menus.html#menus-usage
  30. * \@docs-private
  31. * @type {?}
  32. */
  33. var matMenuAnimations = {
  34. /**
  35. * This animation controls the menu panel's entry and exit from the page.
  36. *
  37. * When the menu panel is added to the DOM, it scales in and fades in its border.
  38. *
  39. * When the menu panel is removed from the DOM, it simply fades out after a brief
  40. * delay to display the ripple.
  41. */
  42. transformMenu: trigger('transformMenu', [
  43. state('void', style({
  44. opacity: 0,
  45. transform: 'scale(0.8)'
  46. })),
  47. transition('void => enter', group([
  48. query('.mat-menu-content, .mat-mdc-menu-content', animate('100ms linear', style({
  49. opacity: 1
  50. }))),
  51. animate('120ms cubic-bezier(0, 0, 0.2, 1)', style({ transform: 'scale(1)' })),
  52. ])),
  53. transition('* => void', animate('100ms 25ms linear', style({ opacity: 0 })))
  54. ]),
  55. /**
  56. * This animation fades in the background color and content of the menu panel
  57. * after its containing element is scaled in.
  58. */
  59. fadeInItems: trigger('fadeInItems', [
  60. // TODO(crisbeto): this is inside the `transformMenu`
  61. // now. Remove next time we do breaking changes.
  62. state('showing', style({ opacity: 1 })),
  63. transition('void => *', [
  64. style({ opacity: 0 }),
  65. animate('400ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)')
  66. ])
  67. ])
  68. };
  69. /**
  70. * @deprecated
  71. * \@breaking-change 8.0.0
  72. * \@docs-private
  73. * @type {?}
  74. */
  75. var fadeInItems = matMenuAnimations.fadeInItems;
  76. /**
  77. * @deprecated
  78. * \@breaking-change 8.0.0
  79. * \@docs-private
  80. * @type {?}
  81. */
  82. var transformMenu = matMenuAnimations.transformMenu;
  83. /**
  84. * @fileoverview added by tsickle
  85. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  86. */
  87. /**
  88. * Menu content that will be rendered lazily once the menu is opened.
  89. */
  90. var MatMenuContent = /** @class */ (function () {
  91. function MatMenuContent(_template, _componentFactoryResolver, _appRef, _injector, _viewContainerRef, _document, _changeDetectorRef) {
  92. this._template = _template;
  93. this._componentFactoryResolver = _componentFactoryResolver;
  94. this._appRef = _appRef;
  95. this._injector = _injector;
  96. this._viewContainerRef = _viewContainerRef;
  97. this._document = _document;
  98. this._changeDetectorRef = _changeDetectorRef;
  99. /**
  100. * Emits when the menu content has been attached.
  101. */
  102. this._attached = new Subject();
  103. }
  104. /**
  105. * Attaches the content with a particular context.
  106. * @docs-private
  107. */
  108. /**
  109. * Attaches the content with a particular context.
  110. * \@docs-private
  111. * @param {?=} context
  112. * @return {?}
  113. */
  114. MatMenuContent.prototype.attach = /**
  115. * Attaches the content with a particular context.
  116. * \@docs-private
  117. * @param {?=} context
  118. * @return {?}
  119. */
  120. function (context) {
  121. if (context === void 0) { context = {}; }
  122. if (!this._portal) {
  123. this._portal = new TemplatePortal(this._template, this._viewContainerRef);
  124. }
  125. this.detach();
  126. if (!this._outlet) {
  127. this._outlet = new DomPortalOutlet(this._document.createElement('div'), this._componentFactoryResolver, this._appRef, this._injector);
  128. }
  129. /** @type {?} */
  130. var element = this._template.elementRef.nativeElement;
  131. // Because we support opening the same menu from different triggers (which in turn have their
  132. // own `OverlayRef` panel), we have to re-insert the host element every time, otherwise we
  133. // risk it staying attached to a pane that's no longer in the DOM.
  134. (/** @type {?} */ (element.parentNode)).insertBefore(this._outlet.outletElement, element);
  135. // When `MatMenuContent` is used in an `OnPush` component, the insertion of the menu
  136. // content via `createEmbeddedView` does not cause the content to be seen as "dirty"
  137. // by Angular. This causes the `@ContentChildren` for menu items within the menu to
  138. // not be updated by Angular. By explicitly marking for check here, we tell Angular that
  139. // it needs to check for new menu items and update the `@ContentChild` in `MatMenu`.
  140. // @breaking-change 9.0.0 Make change detector ref required
  141. if (this._changeDetectorRef) {
  142. this._changeDetectorRef.markForCheck();
  143. }
  144. this._portal.attach(this._outlet, context);
  145. this._attached.next();
  146. };
  147. /**
  148. * Detaches the content.
  149. * @docs-private
  150. */
  151. /**
  152. * Detaches the content.
  153. * \@docs-private
  154. * @return {?}
  155. */
  156. MatMenuContent.prototype.detach = /**
  157. * Detaches the content.
  158. * \@docs-private
  159. * @return {?}
  160. */
  161. function () {
  162. if (this._portal.isAttached) {
  163. this._portal.detach();
  164. }
  165. };
  166. /**
  167. * @return {?}
  168. */
  169. MatMenuContent.prototype.ngOnDestroy = /**
  170. * @return {?}
  171. */
  172. function () {
  173. if (this._outlet) {
  174. this._outlet.dispose();
  175. }
  176. };
  177. MatMenuContent.decorators = [
  178. { type: Directive, args: [{
  179. selector: 'ng-template[matMenuContent]'
  180. },] },
  181. ];
  182. /** @nocollapse */
  183. MatMenuContent.ctorParameters = function () { return [
  184. { type: TemplateRef },
  185. { type: ComponentFactoryResolver },
  186. { type: ApplicationRef },
  187. { type: Injector },
  188. { type: ViewContainerRef },
  189. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
  190. { type: ChangeDetectorRef }
  191. ]; };
  192. return MatMenuContent;
  193. }());
  194. /**
  195. * @fileoverview added by tsickle
  196. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  197. */
  198. /**
  199. * Throws an exception for the case when menu trigger doesn't have a valid mat-menu instance
  200. * \@docs-private
  201. * @return {?}
  202. */
  203. function throwMatMenuMissingError() {
  204. throw Error("matMenuTriggerFor: must pass in an mat-menu instance.\n\n Example:\n <mat-menu #menu=\"matMenu\"></mat-menu>\n <button [matMenuTriggerFor]=\"menu\"></button>");
  205. }
  206. /**
  207. * Throws an exception for the case when menu's x-position value isn't valid.
  208. * In other words, it doesn't match 'before' or 'after'.
  209. * \@docs-private
  210. * @return {?}
  211. */
  212. function throwMatMenuInvalidPositionX() {
  213. throw Error("xPosition value must be either 'before' or after'.\n Example: <mat-menu xPosition=\"before\" #menu=\"matMenu\"></mat-menu>");
  214. }
  215. /**
  216. * Throws an exception for the case when menu's y-position value isn't valid.
  217. * In other words, it doesn't match 'above' or 'below'.
  218. * \@docs-private
  219. * @return {?}
  220. */
  221. function throwMatMenuInvalidPositionY() {
  222. throw Error("yPosition value must be either 'above' or below'.\n Example: <mat-menu yPosition=\"above\" #menu=\"matMenu\"></mat-menu>");
  223. }
  224. /**
  225. * @fileoverview added by tsickle
  226. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  227. */
  228. /**
  229. * Injection token used to provide the parent menu to menu-specific components.
  230. * \@docs-private
  231. * @type {?}
  232. */
  233. var MAT_MENU_PANEL = new InjectionToken('MAT_MENU_PANEL');
  234. /**
  235. * @fileoverview added by tsickle
  236. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  237. */
  238. // Boilerplate for applying mixins to MatMenuItem.
  239. /**
  240. * \@docs-private
  241. */
  242. var
  243. // Boilerplate for applying mixins to MatMenuItem.
  244. /**
  245. * \@docs-private
  246. */
  247. MatMenuItemBase = /** @class */ (function () {
  248. function MatMenuItemBase() {
  249. }
  250. return MatMenuItemBase;
  251. }());
  252. /** @type {?} */
  253. var _MatMenuItemMixinBase = mixinDisableRipple(mixinDisabled(MatMenuItemBase));
  254. /**
  255. * This directive is intended to be used inside an mat-menu tag.
  256. * It exists mostly to set the role attribute.
  257. */
  258. var MatMenuItem = /** @class */ (function (_super) {
  259. __extends(MatMenuItem, _super);
  260. function MatMenuItem(_elementRef, document, _focusMonitor, _parentMenu) {
  261. var _this =
  262. // @breaking-change 8.0.0 make `_focusMonitor` and `document` required params.
  263. _super.call(this) || this;
  264. _this._elementRef = _elementRef;
  265. _this._focusMonitor = _focusMonitor;
  266. _this._parentMenu = _parentMenu;
  267. /**
  268. * ARIA role for the menu item.
  269. */
  270. _this.role = 'menuitem';
  271. /**
  272. * Stream that emits when the menu item is hovered.
  273. */
  274. _this._hovered = new Subject();
  275. /**
  276. * Whether the menu item is highlighted.
  277. */
  278. _this._highlighted = false;
  279. /**
  280. * Whether the menu item acts as a trigger for a sub-menu.
  281. */
  282. _this._triggersSubmenu = false;
  283. if (_focusMonitor) {
  284. // Start monitoring the element so it gets the appropriate focused classes. We want
  285. // to show the focus style for menu items only when the focus was not caused by a
  286. // mouse or touch interaction.
  287. _focusMonitor.monitor(_this._elementRef, false);
  288. }
  289. if (_parentMenu && _parentMenu.addItem) {
  290. _parentMenu.addItem(_this);
  291. }
  292. _this._document = document;
  293. return _this;
  294. }
  295. /** Focuses the menu item. */
  296. /**
  297. * Focuses the menu item.
  298. * @param {?=} origin
  299. * @param {?=} options
  300. * @return {?}
  301. */
  302. MatMenuItem.prototype.focus = /**
  303. * Focuses the menu item.
  304. * @param {?=} origin
  305. * @param {?=} options
  306. * @return {?}
  307. */
  308. function (origin, options) {
  309. if (origin === void 0) { origin = 'program'; }
  310. if (this._focusMonitor) {
  311. this._focusMonitor.focusVia(this._getHostElement(), origin, options);
  312. }
  313. else {
  314. this._getHostElement().focus(options);
  315. }
  316. };
  317. /**
  318. * @return {?}
  319. */
  320. MatMenuItem.prototype.ngOnDestroy = /**
  321. * @return {?}
  322. */
  323. function () {
  324. if (this._focusMonitor) {
  325. this._focusMonitor.stopMonitoring(this._elementRef);
  326. }
  327. if (this._parentMenu && this._parentMenu.removeItem) {
  328. this._parentMenu.removeItem(this);
  329. }
  330. this._hovered.complete();
  331. };
  332. /** Used to set the `tabindex`. */
  333. /**
  334. * Used to set the `tabindex`.
  335. * @return {?}
  336. */
  337. MatMenuItem.prototype._getTabIndex = /**
  338. * Used to set the `tabindex`.
  339. * @return {?}
  340. */
  341. function () {
  342. return this.disabled ? '-1' : '0';
  343. };
  344. /** Returns the host DOM element. */
  345. /**
  346. * Returns the host DOM element.
  347. * @return {?}
  348. */
  349. MatMenuItem.prototype._getHostElement = /**
  350. * Returns the host DOM element.
  351. * @return {?}
  352. */
  353. function () {
  354. return this._elementRef.nativeElement;
  355. };
  356. /** Prevents the default element actions if it is disabled. */
  357. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  358. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  359. // ViewEngine they're overwritten.
  360. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  361. // tslint:disable-next-line:no-host-decorator-in-concrete
  362. /**
  363. * Prevents the default element actions if it is disabled.
  364. * @param {?} event
  365. * @return {?}
  366. */
  367. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  368. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  369. // ViewEngine they're overwritten.
  370. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  371. // tslint:disable-next-line:no-host-decorator-in-concrete
  372. MatMenuItem.prototype._checkDisabled = /**
  373. * Prevents the default element actions if it is disabled.
  374. * @param {?} event
  375. * @return {?}
  376. */
  377. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  378. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  379. // ViewEngine they're overwritten.
  380. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  381. // tslint:disable-next-line:no-host-decorator-in-concrete
  382. function (event) {
  383. if (this.disabled) {
  384. event.preventDefault();
  385. event.stopPropagation();
  386. }
  387. };
  388. /** Emits to the hover stream. */
  389. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  390. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  391. // ViewEngine they're overwritten.
  392. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  393. // tslint:disable-next-line:no-host-decorator-in-concrete
  394. /**
  395. * Emits to the hover stream.
  396. * @return {?}
  397. */
  398. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  399. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  400. // ViewEngine they're overwritten.
  401. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  402. // tslint:disable-next-line:no-host-decorator-in-concrete
  403. MatMenuItem.prototype._handleMouseEnter = /**
  404. * Emits to the hover stream.
  405. * @return {?}
  406. */
  407. // We have to use a `HostListener` here in order to support both Ivy and ViewEngine.
  408. // In Ivy the `host` bindings will be merged when this class is extended, whereas in
  409. // ViewEngine they're overwritten.
  410. // TODO(crisbeto): we move this back into `host` once Ivy is turned on by default.
  411. // tslint:disable-next-line:no-host-decorator-in-concrete
  412. function () {
  413. this._hovered.next(this);
  414. };
  415. /** Gets the label to be used when determining whether the option should be focused. */
  416. /**
  417. * Gets the label to be used when determining whether the option should be focused.
  418. * @return {?}
  419. */
  420. MatMenuItem.prototype.getLabel = /**
  421. * Gets the label to be used when determining whether the option should be focused.
  422. * @return {?}
  423. */
  424. function () {
  425. /** @type {?} */
  426. var element = this._elementRef.nativeElement;
  427. /** @type {?} */
  428. var textNodeType = this._document ? this._document.TEXT_NODE : 3;
  429. /** @type {?} */
  430. var output = '';
  431. if (element.childNodes) {
  432. /** @type {?} */
  433. var length_1 = element.childNodes.length;
  434. // Go through all the top-level text nodes and extract their text.
  435. // We skip anything that's not a text node to prevent the text from
  436. // being thrown off by something like an icon.
  437. for (var i = 0; i < length_1; i++) {
  438. if (element.childNodes[i].nodeType === textNodeType) {
  439. output += element.childNodes[i].textContent;
  440. }
  441. }
  442. }
  443. return output.trim();
  444. };
  445. MatMenuItem.decorators = [
  446. { type: Component, args: [{selector: '[mat-menu-item]',
  447. exportAs: 'matMenuItem',
  448. inputs: ['disabled', 'disableRipple'],
  449. host: {
  450. '[attr.role]': 'role',
  451. 'class': 'mat-menu-item',
  452. '[class.mat-menu-item-highlighted]': '_highlighted',
  453. '[class.mat-menu-item-submenu-trigger]': '_triggersSubmenu',
  454. '[attr.tabindex]': '_getTabIndex()',
  455. '[attr.aria-disabled]': 'disabled.toString()',
  456. '[attr.disabled]': 'disabled || null',
  457. },
  458. changeDetection: ChangeDetectionStrategy.OnPush,
  459. encapsulation: ViewEncapsulation.None,
  460. template: "<ng-content></ng-content><div class=\"mat-menu-ripple\" matRipple [matRippleDisabled]=\"disableRipple || disabled\" [matRippleTrigger]=\"_getHostElement()\"></div>",
  461. },] },
  462. ];
  463. /** @nocollapse */
  464. MatMenuItem.ctorParameters = function () { return [
  465. { type: ElementRef },
  466. { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
  467. { type: FocusMonitor },
  468. { type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_PANEL,] }, { type: Optional }] }
  469. ]; };
  470. MatMenuItem.propDecorators = {
  471. role: [{ type: Input }],
  472. _checkDisabled: [{ type: HostListener, args: ['click', ['$event'],] }],
  473. _handleMouseEnter: [{ type: HostListener, args: ['mouseenter',] }]
  474. };
  475. return MatMenuItem;
  476. }(_MatMenuItemMixinBase));
  477. /**
  478. * @fileoverview added by tsickle
  479. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  480. */
  481. /**
  482. * Injection token to be used to override the default options for `mat-menu`.
  483. * @type {?}
  484. */
  485. var MAT_MENU_DEFAULT_OPTIONS = new InjectionToken('mat-menu-default-options', {
  486. providedIn: 'root',
  487. factory: MAT_MENU_DEFAULT_OPTIONS_FACTORY
  488. });
  489. /**
  490. * \@docs-private
  491. * @return {?}
  492. */
  493. function MAT_MENU_DEFAULT_OPTIONS_FACTORY() {
  494. return {
  495. overlapTrigger: false,
  496. xPosition: 'after',
  497. yPosition: 'below',
  498. backdropClass: 'cdk-overlay-transparent-backdrop',
  499. };
  500. }
  501. /**
  502. * Start elevation for the menu panel.
  503. * \@docs-private
  504. * @type {?}
  505. */
  506. var MAT_MENU_BASE_ELEVATION = 4;
  507. /**
  508. * Base class with all of the `MatMenu` functionality.
  509. */
  510. // tslint:disable-next-line:class-name
  511. var _MatMenuBase = /** @class */ (function () {
  512. function _MatMenuBase(_elementRef, _ngZone, _defaultOptions) {
  513. this._elementRef = _elementRef;
  514. this._ngZone = _ngZone;
  515. this._defaultOptions = _defaultOptions;
  516. this._xPosition = this._defaultOptions.xPosition;
  517. this._yPosition = this._defaultOptions.yPosition;
  518. /**
  519. * Only the direct descendant menu items.
  520. */
  521. this._directDescendantItems = new QueryList();
  522. /**
  523. * Subscription to tab events on the menu panel
  524. */
  525. this._tabSubscription = Subscription.EMPTY;
  526. /**
  527. * Config object to be passed into the menu's ngClass
  528. */
  529. this._classList = {};
  530. /**
  531. * Current state of the panel animation.
  532. */
  533. this._panelAnimationState = 'void';
  534. /**
  535. * Emits whenever an animation on the menu completes.
  536. */
  537. this._animationDone = new Subject();
  538. /**
  539. * Class to be added to the backdrop element.
  540. */
  541. this.backdropClass = this._defaultOptions.backdropClass;
  542. this._overlapTrigger = this._defaultOptions.overlapTrigger;
  543. this._hasBackdrop = this._defaultOptions.hasBackdrop;
  544. /**
  545. * Event emitted when the menu is closed.
  546. */
  547. this.closed = new EventEmitter();
  548. /**
  549. * Event emitted when the menu is closed.
  550. * @deprecated Switch to `closed` instead
  551. * \@breaking-change 8.0.0
  552. */
  553. this.close = this.closed;
  554. }
  555. Object.defineProperty(_MatMenuBase.prototype, "xPosition", {
  556. /** Position of the menu in the X axis. */
  557. get: /**
  558. * Position of the menu in the X axis.
  559. * @return {?}
  560. */
  561. function () { return this._xPosition; },
  562. set: /**
  563. * @param {?} value
  564. * @return {?}
  565. */
  566. function (value) {
  567. if (value !== 'before' && value !== 'after') {
  568. throwMatMenuInvalidPositionX();
  569. }
  570. this._xPosition = value;
  571. this.setPositionClasses();
  572. },
  573. enumerable: true,
  574. configurable: true
  575. });
  576. Object.defineProperty(_MatMenuBase.prototype, "yPosition", {
  577. /** Position of the menu in the Y axis. */
  578. get: /**
  579. * Position of the menu in the Y axis.
  580. * @return {?}
  581. */
  582. function () { return this._yPosition; },
  583. set: /**
  584. * @param {?} value
  585. * @return {?}
  586. */
  587. function (value) {
  588. if (value !== 'above' && value !== 'below') {
  589. throwMatMenuInvalidPositionY();
  590. }
  591. this._yPosition = value;
  592. this.setPositionClasses();
  593. },
  594. enumerable: true,
  595. configurable: true
  596. });
  597. Object.defineProperty(_MatMenuBase.prototype, "overlapTrigger", {
  598. /** Whether the menu should overlap its trigger. */
  599. get: /**
  600. * Whether the menu should overlap its trigger.
  601. * @return {?}
  602. */
  603. function () { return this._overlapTrigger; },
  604. set: /**
  605. * @param {?} value
  606. * @return {?}
  607. */
  608. function (value) {
  609. this._overlapTrigger = coerceBooleanProperty(value);
  610. },
  611. enumerable: true,
  612. configurable: true
  613. });
  614. Object.defineProperty(_MatMenuBase.prototype, "hasBackdrop", {
  615. /** Whether the menu has a backdrop. */
  616. get: /**
  617. * Whether the menu has a backdrop.
  618. * @return {?}
  619. */
  620. function () { return this._hasBackdrop; },
  621. set: /**
  622. * @param {?} value
  623. * @return {?}
  624. */
  625. function (value) {
  626. this._hasBackdrop = coerceBooleanProperty(value);
  627. },
  628. enumerable: true,
  629. configurable: true
  630. });
  631. Object.defineProperty(_MatMenuBase.prototype, "panelClass", {
  632. /**
  633. * This method takes classes set on the host mat-menu element and applies them on the
  634. * menu template that displays in the overlay container. Otherwise, it's difficult
  635. * to style the containing menu from outside the component.
  636. * @param classes list of class names
  637. */
  638. set: /**
  639. * This method takes classes set on the host mat-menu element and applies them on the
  640. * menu template that displays in the overlay container. Otherwise, it's difficult
  641. * to style the containing menu from outside the component.
  642. * @param {?} classes list of class names
  643. * @return {?}
  644. */
  645. function (classes) {
  646. var _this = this;
  647. /** @type {?} */
  648. var previousPanelClass = this._previousPanelClass;
  649. if (previousPanelClass && previousPanelClass.length) {
  650. previousPanelClass.split(' ').forEach((/**
  651. * @param {?} className
  652. * @return {?}
  653. */
  654. function (className) {
  655. _this._classList[className] = false;
  656. }));
  657. }
  658. this._previousPanelClass = classes;
  659. if (classes && classes.length) {
  660. classes.split(' ').forEach((/**
  661. * @param {?} className
  662. * @return {?}
  663. */
  664. function (className) {
  665. _this._classList[className] = true;
  666. }));
  667. this._elementRef.nativeElement.className = '';
  668. }
  669. },
  670. enumerable: true,
  671. configurable: true
  672. });
  673. Object.defineProperty(_MatMenuBase.prototype, "classList", {
  674. /**
  675. * This method takes classes set on the host mat-menu element and applies them on the
  676. * menu template that displays in the overlay container. Otherwise, it's difficult
  677. * to style the containing menu from outside the component.
  678. * @deprecated Use `panelClass` instead.
  679. * @breaking-change 8.0.0
  680. */
  681. get: /**
  682. * This method takes classes set on the host mat-menu element and applies them on the
  683. * menu template that displays in the overlay container. Otherwise, it's difficult
  684. * to style the containing menu from outside the component.
  685. * @deprecated Use `panelClass` instead.
  686. * \@breaking-change 8.0.0
  687. * @return {?}
  688. */
  689. function () { return this.panelClass; },
  690. set: /**
  691. * @param {?} classes
  692. * @return {?}
  693. */
  694. function (classes) { this.panelClass = classes; },
  695. enumerable: true,
  696. configurable: true
  697. });
  698. /**
  699. * @return {?}
  700. */
  701. _MatMenuBase.prototype.ngOnInit = /**
  702. * @return {?}
  703. */
  704. function () {
  705. this.setPositionClasses();
  706. };
  707. /**
  708. * @return {?}
  709. */
  710. _MatMenuBase.prototype.ngAfterContentInit = /**
  711. * @return {?}
  712. */
  713. function () {
  714. var _this = this;
  715. this._updateDirectDescendants();
  716. this._keyManager = new FocusKeyManager(this._directDescendantItems).withWrap().withTypeAhead();
  717. this._tabSubscription = this._keyManager.tabOut.subscribe((/**
  718. * @return {?}
  719. */
  720. function () { return _this.closed.emit('tab'); }));
  721. };
  722. /**
  723. * @return {?}
  724. */
  725. _MatMenuBase.prototype.ngOnDestroy = /**
  726. * @return {?}
  727. */
  728. function () {
  729. this._directDescendantItems.destroy();
  730. this._tabSubscription.unsubscribe();
  731. this.closed.complete();
  732. };
  733. /** Stream that emits whenever the hovered menu item changes. */
  734. /**
  735. * Stream that emits whenever the hovered menu item changes.
  736. * @return {?}
  737. */
  738. _MatMenuBase.prototype._hovered = /**
  739. * Stream that emits whenever the hovered menu item changes.
  740. * @return {?}
  741. */
  742. function () {
  743. // Coerce the `changes` property because Angular types it as `Observable<any>`
  744. /** @type {?} */
  745. var itemChanges = (/** @type {?} */ (this._directDescendantItems.changes));
  746. return itemChanges.pipe(startWith(this._directDescendantItems), switchMap((/**
  747. * @param {?} items
  748. * @return {?}
  749. */
  750. function (items) { return merge.apply(void 0, items.map((/**
  751. * @param {?} item
  752. * @return {?}
  753. */
  754. function (item) { return item._hovered; }))); })));
  755. };
  756. /*
  757. * Registers a menu item with the menu.
  758. * @docs-private
  759. * @deprecated No longer being used. To be removed.
  760. * @breaking-change 9.0.0
  761. */
  762. /*
  763. * Registers a menu item with the menu.
  764. * @docs-private
  765. * @deprecated No longer being used. To be removed.
  766. * @breaking-change 9.0.0
  767. */
  768. /**
  769. * @param {?} _item
  770. * @return {?}
  771. */
  772. _MatMenuBase.prototype.addItem = /*
  773. * Registers a menu item with the menu.
  774. * @docs-private
  775. * @deprecated No longer being used. To be removed.
  776. * @breaking-change 9.0.0
  777. */
  778. /**
  779. * @param {?} _item
  780. * @return {?}
  781. */
  782. function (_item) { };
  783. /**
  784. * Removes an item from the menu.
  785. * @docs-private
  786. * @deprecated No longer being used. To be removed.
  787. * @breaking-change 9.0.0
  788. */
  789. /**
  790. * Removes an item from the menu.
  791. * \@docs-private
  792. * @deprecated No longer being used. To be removed.
  793. * \@breaking-change 9.0.0
  794. * @param {?} _item
  795. * @return {?}
  796. */
  797. _MatMenuBase.prototype.removeItem = /**
  798. * Removes an item from the menu.
  799. * \@docs-private
  800. * @deprecated No longer being used. To be removed.
  801. * \@breaking-change 9.0.0
  802. * @param {?} _item
  803. * @return {?}
  804. */
  805. function (_item) { };
  806. /** Handle a keyboard event from the menu, delegating to the appropriate action. */
  807. /**
  808. * Handle a keyboard event from the menu, delegating to the appropriate action.
  809. * @param {?} event
  810. * @return {?}
  811. */
  812. _MatMenuBase.prototype._handleKeydown = /**
  813. * Handle a keyboard event from the menu, delegating to the appropriate action.
  814. * @param {?} event
  815. * @return {?}
  816. */
  817. function (event) {
  818. /** @type {?} */
  819. var keyCode = event.keyCode;
  820. /** @type {?} */
  821. var manager = this._keyManager;
  822. switch (keyCode) {
  823. case ESCAPE:
  824. if (!hasModifierKey(event)) {
  825. event.preventDefault();
  826. this.closed.emit('keydown');
  827. }
  828. break;
  829. case LEFT_ARROW:
  830. if (this.parentMenu && this.direction === 'ltr') {
  831. this.closed.emit('keydown');
  832. }
  833. break;
  834. case RIGHT_ARROW:
  835. if (this.parentMenu && this.direction === 'rtl') {
  836. this.closed.emit('keydown');
  837. }
  838. break;
  839. case HOME:
  840. case END:
  841. if (!hasModifierKey(event)) {
  842. keyCode === HOME ? manager.setFirstItemActive() : manager.setLastItemActive();
  843. event.preventDefault();
  844. }
  845. break;
  846. default:
  847. if (keyCode === UP_ARROW || keyCode === DOWN_ARROW) {
  848. manager.setFocusOrigin('keyboard');
  849. }
  850. manager.onKeydown(event);
  851. }
  852. };
  853. /**
  854. * Focus the first item in the menu.
  855. * @param origin Action from which the focus originated. Used to set the correct styling.
  856. */
  857. /**
  858. * Focus the first item in the menu.
  859. * @param {?=} origin Action from which the focus originated. Used to set the correct styling.
  860. * @return {?}
  861. */
  862. _MatMenuBase.prototype.focusFirstItem = /**
  863. * Focus the first item in the menu.
  864. * @param {?=} origin Action from which the focus originated. Used to set the correct styling.
  865. * @return {?}
  866. */
  867. function (origin) {
  868. var _this = this;
  869. if (origin === void 0) { origin = 'program'; }
  870. // When the content is rendered lazily, it takes a bit before the items are inside the DOM.
  871. if (this.lazyContent) {
  872. this._ngZone.onStable.asObservable()
  873. .pipe(take(1))
  874. .subscribe((/**
  875. * @return {?}
  876. */
  877. function () { return _this._keyManager.setFocusOrigin(origin).setFirstItemActive(); }));
  878. }
  879. else {
  880. this._keyManager.setFocusOrigin(origin).setFirstItemActive();
  881. }
  882. };
  883. /**
  884. * Resets the active item in the menu. This is used when the menu is opened, allowing
  885. * the user to start from the first option when pressing the down arrow.
  886. */
  887. /**
  888. * Resets the active item in the menu. This is used when the menu is opened, allowing
  889. * the user to start from the first option when pressing the down arrow.
  890. * @return {?}
  891. */
  892. _MatMenuBase.prototype.resetActiveItem = /**
  893. * Resets the active item in the menu. This is used when the menu is opened, allowing
  894. * the user to start from the first option when pressing the down arrow.
  895. * @return {?}
  896. */
  897. function () {
  898. this._keyManager.setActiveItem(-1);
  899. };
  900. /**
  901. * Sets the menu panel elevation.
  902. * @param depth Number of parent menus that come before the menu.
  903. */
  904. /**
  905. * Sets the menu panel elevation.
  906. * @param {?} depth Number of parent menus that come before the menu.
  907. * @return {?}
  908. */
  909. _MatMenuBase.prototype.setElevation = /**
  910. * Sets the menu panel elevation.
  911. * @param {?} depth Number of parent menus that come before the menu.
  912. * @return {?}
  913. */
  914. function (depth) {
  915. // The elevation starts at the base and increases by one for each level.
  916. /** @type {?} */
  917. var newElevation = "mat-elevation-z" + (MAT_MENU_BASE_ELEVATION + depth);
  918. /** @type {?} */
  919. var customElevation = Object.keys(this._classList).find((/**
  920. * @param {?} c
  921. * @return {?}
  922. */
  923. function (c) { return c.startsWith('mat-elevation-z'); }));
  924. if (!customElevation || customElevation === this._previousElevation) {
  925. if (this._previousElevation) {
  926. this._classList[this._previousElevation] = false;
  927. }
  928. this._classList[newElevation] = true;
  929. this._previousElevation = newElevation;
  930. }
  931. };
  932. /**
  933. * Adds classes to the menu panel based on its position. Can be used by
  934. * consumers to add specific styling based on the position.
  935. * @param posX Position of the menu along the x axis.
  936. * @param posY Position of the menu along the y axis.
  937. * @docs-private
  938. */
  939. /**
  940. * Adds classes to the menu panel based on its position. Can be used by
  941. * consumers to add specific styling based on the position.
  942. * \@docs-private
  943. * @param {?=} posX Position of the menu along the x axis.
  944. * @param {?=} posY Position of the menu along the y axis.
  945. * @return {?}
  946. */
  947. _MatMenuBase.prototype.setPositionClasses = /**
  948. * Adds classes to the menu panel based on its position. Can be used by
  949. * consumers to add specific styling based on the position.
  950. * \@docs-private
  951. * @param {?=} posX Position of the menu along the x axis.
  952. * @param {?=} posY Position of the menu along the y axis.
  953. * @return {?}
  954. */
  955. function (posX, posY) {
  956. if (posX === void 0) { posX = this.xPosition; }
  957. if (posY === void 0) { posY = this.yPosition; }
  958. /** @type {?} */
  959. var classes = this._classList;
  960. classes['mat-menu-before'] = posX === 'before';
  961. classes['mat-menu-after'] = posX === 'after';
  962. classes['mat-menu-above'] = posY === 'above';
  963. classes['mat-menu-below'] = posY === 'below';
  964. };
  965. /** Starts the enter animation. */
  966. /**
  967. * Starts the enter animation.
  968. * @return {?}
  969. */
  970. _MatMenuBase.prototype._startAnimation = /**
  971. * Starts the enter animation.
  972. * @return {?}
  973. */
  974. function () {
  975. // @breaking-change 8.0.0 Combine with _resetAnimation.
  976. this._panelAnimationState = 'enter';
  977. };
  978. /** Resets the panel animation to its initial state. */
  979. /**
  980. * Resets the panel animation to its initial state.
  981. * @return {?}
  982. */
  983. _MatMenuBase.prototype._resetAnimation = /**
  984. * Resets the panel animation to its initial state.
  985. * @return {?}
  986. */
  987. function () {
  988. // @breaking-change 8.0.0 Combine with _startAnimation.
  989. this._panelAnimationState = 'void';
  990. };
  991. /** Callback that is invoked when the panel animation completes. */
  992. /**
  993. * Callback that is invoked when the panel animation completes.
  994. * @param {?} event
  995. * @return {?}
  996. */
  997. _MatMenuBase.prototype._onAnimationDone = /**
  998. * Callback that is invoked when the panel animation completes.
  999. * @param {?} event
  1000. * @return {?}
  1001. */
  1002. function (event) {
  1003. this._animationDone.next(event);
  1004. this._isAnimating = false;
  1005. };
  1006. /**
  1007. * @param {?} event
  1008. * @return {?}
  1009. */
  1010. _MatMenuBase.prototype._onAnimationStart = /**
  1011. * @param {?} event
  1012. * @return {?}
  1013. */
  1014. function (event) {
  1015. this._isAnimating = true;
  1016. // Scroll the content element to the top as soon as the animation starts. This is necessary,
  1017. // because we move focus to the first item while it's still being animated, which can throw
  1018. // the browser off when it determines the scroll position. Alternatively we can move focus
  1019. // when the animation is done, however moving focus asynchronously will interrupt screen
  1020. // readers which are in the process of reading out the menu already. We take the `element`
  1021. // from the `event` since we can't use a `ViewChild` to access the pane.
  1022. if (event.toState === 'enter' && this._keyManager.activeItemIndex === 0) {
  1023. event.element.scrollTop = 0;
  1024. }
  1025. };
  1026. /**
  1027. * Sets up a stream that will keep track of any newly-added menu items and will update the list
  1028. * of direct descendants. We collect the descendants this way, because `_allItems` can include
  1029. * items that are part of child menus, and using a custom way of registering items is unreliable
  1030. * when it comes to maintaining the item order.
  1031. */
  1032. /**
  1033. * Sets up a stream that will keep track of any newly-added menu items and will update the list
  1034. * of direct descendants. We collect the descendants this way, because `_allItems` can include
  1035. * items that are part of child menus, and using a custom way of registering items is unreliable
  1036. * when it comes to maintaining the item order.
  1037. * @private
  1038. * @return {?}
  1039. */
  1040. _MatMenuBase.prototype._updateDirectDescendants = /**
  1041. * Sets up a stream that will keep track of any newly-added menu items and will update the list
  1042. * of direct descendants. We collect the descendants this way, because `_allItems` can include
  1043. * items that are part of child menus, and using a custom way of registering items is unreliable
  1044. * when it comes to maintaining the item order.
  1045. * @private
  1046. * @return {?}
  1047. */
  1048. function () {
  1049. var _this = this;
  1050. this._allItems.changes
  1051. .pipe(startWith(this._allItems))
  1052. .subscribe((/**
  1053. * @param {?} items
  1054. * @return {?}
  1055. */
  1056. function (items) {
  1057. _this._directDescendantItems.reset(items.filter((/**
  1058. * @param {?} item
  1059. * @return {?}
  1060. */
  1061. function (item) { return item._parentMenu === _this; })));
  1062. _this._directDescendantItems.notifyOnChanges();
  1063. }));
  1064. };
  1065. /** @nocollapse */
  1066. _MatMenuBase.ctorParameters = function () { return [
  1067. { type: ElementRef },
  1068. { type: NgZone },
  1069. { type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_DEFAULT_OPTIONS,] }] }
  1070. ]; };
  1071. _MatMenuBase.propDecorators = {
  1072. _allItems: [{ type: ContentChildren, args: [MatMenuItem, { descendants: true },] }],
  1073. backdropClass: [{ type: Input }],
  1074. xPosition: [{ type: Input }],
  1075. yPosition: [{ type: Input }],
  1076. templateRef: [{ type: ViewChild, args: [TemplateRef, { static: false },] }],
  1077. items: [{ type: ContentChildren, args: [MatMenuItem,] }],
  1078. lazyContent: [{ type: ContentChild, args: [MatMenuContent, { static: false },] }],
  1079. overlapTrigger: [{ type: Input }],
  1080. hasBackdrop: [{ type: Input }],
  1081. panelClass: [{ type: Input, args: ['class',] }],
  1082. classList: [{ type: Input }],
  1083. closed: [{ type: Output }],
  1084. close: [{ type: Output }]
  1085. };
  1086. return _MatMenuBase;
  1087. }());
  1088. /**
  1089. * \@docs-private We show the "_MatMenu" class as "MatMenu" in the docs.
  1090. */
  1091. var /**
  1092. * \@docs-private We show the "_MatMenu" class as "MatMenu" in the docs.
  1093. */
  1094. MatMenu = /** @class */ (function (_super) {
  1095. __extends(MatMenu, _super);
  1096. function MatMenu() {
  1097. return _super !== null && _super.apply(this, arguments) || this;
  1098. }
  1099. return MatMenu;
  1100. }(_MatMenuBase));
  1101. // Note on the weird inheritance setup: we need three classes, because the MDC-based menu has to
  1102. // extend `MatMenu`, however keeping a reference to it will cause the inlined template and styles
  1103. // to be retained as well. The MDC menu also has to provide itself as a `MatMenu` in order for
  1104. // queries and DI to work correctly, while still not referencing the actual menu class.
  1105. // Class responsibility is split up as follows:
  1106. // * _MatMenuBase - provides all the functionality without any of the Angular metadata.
  1107. // * MatMenu - keeps the same name symbol name as the current menu and
  1108. // is used as a provider for DI and query purposes.
  1109. // * _MatMenu - the actual menu component implementation with the Angular metadata that should
  1110. // be tree shaken away for MDC.
  1111. /**
  1112. * \@docs-public MatMenu
  1113. */
  1114. var _MatMenu = /** @class */ (function (_super) {
  1115. __extends(_MatMenu, _super);
  1116. function _MatMenu(elementRef, ngZone, defaultOptions) {
  1117. return _super.call(this, elementRef, ngZone, defaultOptions) || this;
  1118. }
  1119. _MatMenu.decorators = [
  1120. { type: Component, args: [{selector: 'mat-menu',
  1121. template: "<ng-template><div class=\"mat-menu-panel\" [ngClass]=\"_classList\" (keydown)=\"_handleKeydown($event)\" (click)=\"closed.emit('click')\" [@transformMenu]=\"_panelAnimationState\" (@transformMenu.start)=\"_onAnimationStart($event)\" (@transformMenu.done)=\"_onAnimationDone($event)\" tabindex=\"-1\" role=\"menu\"><div class=\"mat-menu-content\"><ng-content></ng-content></div></div></ng-template>",
  1122. styles: [".mat-menu-panel{min-width:112px;max-width:280px;overflow:auto;-webkit-overflow-scrolling:touch;max-height:calc(100vh - 48px);border-radius:4px;outline:0;min-height:64px}.mat-menu-panel.ng-animating{pointer-events:none}@media (-ms-high-contrast:active){.mat-menu-panel{outline:solid 1px}}.mat-menu-content:not(:empty){padding-top:8px;padding-bottom:8px}.mat-menu-item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;line-height:48px;height:48px;padding:0 16px;text-align:left;text-decoration:none;max-width:100%;position:relative}.mat-menu-item::-moz-focus-inner{border:0}.mat-menu-item[disabled]{cursor:default}[dir=rtl] .mat-menu-item{text-align:right}.mat-menu-item .mat-icon{margin-right:16px;vertical-align:middle}.mat-menu-item .mat-icon svg{vertical-align:top}[dir=rtl] .mat-menu-item .mat-icon{margin-left:16px;margin-right:0}.mat-menu-item[disabled]{pointer-events:none}@media (-ms-high-contrast:active){.mat-menu-item-highlighted,.mat-menu-item.cdk-keyboard-focused,.mat-menu-item.cdk-program-focused{outline:dotted 1px}}.mat-menu-item-submenu-trigger{padding-right:32px}.mat-menu-item-submenu-trigger::after{width:0;height:0;border-style:solid;border-width:5px 0 5px 5px;border-color:transparent transparent transparent currentColor;content:'';display:inline-block;position:absolute;top:50%;right:16px;transform:translateY(-50%)}[dir=rtl] .mat-menu-item-submenu-trigger{padding-right:16px;padding-left:32px}[dir=rtl] .mat-menu-item-submenu-trigger::after{right:auto;left:16px;transform:rotateY(180deg) translateY(-50%)}button.mat-menu-item{width:100%}.mat-menu-item .mat-menu-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}"],
  1123. changeDetection: ChangeDetectionStrategy.OnPush,
  1124. encapsulation: ViewEncapsulation.None,
  1125. exportAs: 'matMenu',
  1126. animations: [
  1127. matMenuAnimations.transformMenu,
  1128. matMenuAnimations.fadeInItems
  1129. ],
  1130. providers: [
  1131. { provide: MAT_MENU_PANEL, useExisting: MatMenu },
  1132. { provide: MatMenu, useExisting: _MatMenu }
  1133. ]
  1134. },] },
  1135. ];
  1136. /** @nocollapse */
  1137. _MatMenu.ctorParameters = function () { return [
  1138. { type: ElementRef },
  1139. { type: NgZone },
  1140. { type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_DEFAULT_OPTIONS,] }] }
  1141. ]; };
  1142. return _MatMenu;
  1143. }(MatMenu));
  1144. /**
  1145. * @fileoverview added by tsickle
  1146. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1147. */
  1148. /**
  1149. * Injection token that determines the scroll handling while the menu is open.
  1150. * @type {?}
  1151. */
  1152. var MAT_MENU_SCROLL_STRATEGY = new InjectionToken('mat-menu-scroll-strategy');
  1153. /**
  1154. * \@docs-private
  1155. * @param {?} overlay
  1156. * @return {?}
  1157. */
  1158. function MAT_MENU_SCROLL_STRATEGY_FACTORY(overlay) {
  1159. return (/**
  1160. * @return {?}
  1161. */
  1162. function () { return overlay.scrollStrategies.reposition(); });
  1163. }
  1164. /**
  1165. * \@docs-private
  1166. * @type {?}
  1167. */
  1168. var MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER = {
  1169. provide: MAT_MENU_SCROLL_STRATEGY,
  1170. deps: [Overlay],
  1171. useFactory: MAT_MENU_SCROLL_STRATEGY_FACTORY,
  1172. };
  1173. /**
  1174. * Default top padding of the menu panel.
  1175. * @type {?}
  1176. */
  1177. var MENU_PANEL_TOP_PADDING = 8;
  1178. /**
  1179. * Options for binding a passive event listener.
  1180. * @type {?}
  1181. */
  1182. var passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
  1183. // TODO(andrewseguin): Remove the kebab versions in favor of camelCased attribute selectors
  1184. /**
  1185. * This directive is intended to be used in conjunction with an mat-menu tag. It is
  1186. * responsible for toggling the display of the provided menu instance.
  1187. */
  1188. var MatMenuTrigger = /** @class */ (function () {
  1189. function MatMenuTrigger(_overlay, _element, _viewContainerRef, scrollStrategy, _parentMenu, _menuItemInstance, _dir, _focusMonitor) {
  1190. var _this = this;
  1191. this._overlay = _overlay;
  1192. this._element = _element;
  1193. this._viewContainerRef = _viewContainerRef;
  1194. this._parentMenu = _parentMenu;
  1195. this._menuItemInstance = _menuItemInstance;
  1196. this._dir = _dir;
  1197. this._focusMonitor = _focusMonitor;
  1198. this._overlayRef = null;
  1199. this._menuOpen = false;
  1200. this._closingActionsSubscription = Subscription.EMPTY;
  1201. this._hoverSubscription = Subscription.EMPTY;
  1202. this._menuCloseSubscription = Subscription.EMPTY;
  1203. /**
  1204. * Handles touch start events on the trigger.
  1205. * Needs to be an arrow function so we can easily use addEventListener and removeEventListener.
  1206. */
  1207. this._handleTouchStart = (/**
  1208. * @return {?}
  1209. */
  1210. function () { return _this._openedBy = 'touch'; });
  1211. // Tracking input type is necessary so it's possible to only auto-focus
  1212. // the first item of the list when the menu is opened via the keyboard
  1213. this._openedBy = null;
  1214. /**
  1215. * Whether focus should be restored when the menu is closed.
  1216. * Note that disabling this option can have accessibility implications
  1217. * and it's up to you to manage focus, if you decide to turn it off.
  1218. */
  1219. this.restoreFocus = true;
  1220. /**
  1221. * Event emitted when the associated menu is opened.
  1222. */
  1223. this.menuOpened = new EventEmitter();
  1224. /**
  1225. * Event emitted when the associated menu is opened.
  1226. * @deprecated Switch to `menuOpened` instead
  1227. * \@breaking-change 8.0.0
  1228. */
  1229. // tslint:disable-next-line:no-output-on-prefix
  1230. this.onMenuOpen = this.menuOpened;
  1231. /**
  1232. * Event emitted when the associated menu is closed.
  1233. */
  1234. this.menuClosed = new EventEmitter();
  1235. /**
  1236. * Event emitted when the associated menu is closed.
  1237. * @deprecated Switch to `menuClosed` instead
  1238. * \@breaking-change 8.0.0
  1239. */
  1240. // tslint:disable-next-line:no-output-on-prefix
  1241. this.onMenuClose = this.menuClosed;
  1242. _element.nativeElement.addEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
  1243. if (_menuItemInstance) {
  1244. _menuItemInstance._triggersSubmenu = this.triggersSubmenu();
  1245. }
  1246. this._scrollStrategy = scrollStrategy;
  1247. }
  1248. Object.defineProperty(MatMenuTrigger.prototype, "_deprecatedMatMenuTriggerFor", {
  1249. /**
  1250. * @deprecated
  1251. * @breaking-change 8.0.0
  1252. */
  1253. get: /**
  1254. * @deprecated
  1255. * \@breaking-change 8.0.0
  1256. * @return {?}
  1257. */
  1258. function () { return this.menu; },
  1259. set: /**
  1260. * @param {?} v
  1261. * @return {?}
  1262. */
  1263. function (v) {
  1264. this.menu = v;
  1265. },
  1266. enumerable: true,
  1267. configurable: true
  1268. });
  1269. Object.defineProperty(MatMenuTrigger.prototype, "menu", {
  1270. /** References the menu instance that the trigger is associated with. */
  1271. get: /**
  1272. * References the menu instance that the trigger is associated with.
  1273. * @return {?}
  1274. */
  1275. function () { return this._menu; },
  1276. set: /**
  1277. * @param {?} menu
  1278. * @return {?}
  1279. */
  1280. function (menu) {
  1281. var _this = this;
  1282. if (menu === this._menu) {
  1283. return;
  1284. }
  1285. this._menu = menu;
  1286. this._menuCloseSubscription.unsubscribe();
  1287. if (menu) {
  1288. this._menuCloseSubscription = menu.close.asObservable().subscribe((/**
  1289. * @param {?} reason
  1290. * @return {?}
  1291. */
  1292. function (reason) {
  1293. _this._destroyMenu();
  1294. // If a click closed the menu, we should close the entire chain of nested menus.
  1295. if ((reason === 'click' || reason === 'tab') && _this._parentMenu) {
  1296. _this._parentMenu.closed.emit(reason);
  1297. }
  1298. }));
  1299. }
  1300. },
  1301. enumerable: true,
  1302. configurable: true
  1303. });
  1304. /**
  1305. * @return {?}
  1306. */
  1307. MatMenuTrigger.prototype.ngAfterContentInit = /**
  1308. * @return {?}
  1309. */
  1310. function () {
  1311. this._checkMenu();
  1312. this._handleHover();
  1313. };
  1314. /**
  1315. * @return {?}
  1316. */
  1317. MatMenuTrigger.prototype.ngOnDestroy = /**
  1318. * @return {?}
  1319. */
  1320. function () {
  1321. if (this._overlayRef) {
  1322. this._overlayRef.dispose();
  1323. this._overlayRef = null;
  1324. }
  1325. this._element.nativeElement.removeEventListener('touchstart', this._handleTouchStart, passiveEventListenerOptions);
  1326. this._menuCloseSubscription.unsubscribe();
  1327. this._closingActionsSubscription.unsubscribe();
  1328. this._hoverSubscription.unsubscribe();
  1329. };
  1330. Object.defineProperty(MatMenuTrigger.prototype, "menuOpen", {
  1331. /** Whether the menu is open. */
  1332. get: /**
  1333. * Whether the menu is open.
  1334. * @return {?}
  1335. */
  1336. function () {
  1337. return this._menuOpen;
  1338. },
  1339. enumerable: true,
  1340. configurable: true
  1341. });
  1342. Object.defineProperty(MatMenuTrigger.prototype, "dir", {
  1343. /** The text direction of the containing app. */
  1344. get: /**
  1345. * The text direction of the containing app.
  1346. * @return {?}
  1347. */
  1348. function () {
  1349. return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
  1350. },
  1351. enumerable: true,
  1352. configurable: true
  1353. });
  1354. /** Whether the menu triggers a sub-menu or a top-level one. */
  1355. /**
  1356. * Whether the menu triggers a sub-menu or a top-level one.
  1357. * @return {?}
  1358. */
  1359. MatMenuTrigger.prototype.triggersSubmenu = /**
  1360. * Whether the menu triggers a sub-menu or a top-level one.
  1361. * @return {?}
  1362. */
  1363. function () {
  1364. return !!(this._menuItemInstance && this._parentMenu);
  1365. };
  1366. /** Toggles the menu between the open and closed states. */
  1367. /**
  1368. * Toggles the menu between the open and closed states.
  1369. * @return {?}
  1370. */
  1371. MatMenuTrigger.prototype.toggleMenu = /**
  1372. * Toggles the menu between the open and closed states.
  1373. * @return {?}
  1374. */
  1375. function () {
  1376. return this._menuOpen ? this.closeMenu() : this.openMenu();
  1377. };
  1378. /** Opens the menu. */
  1379. /**
  1380. * Opens the menu.
  1381. * @return {?}
  1382. */
  1383. MatMenuTrigger.prototype.openMenu = /**
  1384. * Opens the menu.
  1385. * @return {?}
  1386. */
  1387. function () {
  1388. var _this = this;
  1389. if (this._menuOpen) {
  1390. return;
  1391. }
  1392. this._checkMenu();
  1393. /** @type {?} */
  1394. var overlayRef = this._createOverlay();
  1395. /** @type {?} */
  1396. var overlayConfig = overlayRef.getConfig();
  1397. this._setPosition((/** @type {?} */ (overlayConfig.positionStrategy)));
  1398. overlayConfig.hasBackdrop = this.menu.hasBackdrop == null ? !this.triggersSubmenu() :
  1399. this.menu.hasBackdrop;
  1400. overlayRef.attach(this._getPortal());
  1401. if (this.menu.lazyContent) {
  1402. this.menu.lazyContent.attach(this.menuData);
  1403. }
  1404. this._closingActionsSubscription = this._menuClosingActions().subscribe((/**
  1405. * @return {?}
  1406. */
  1407. function () { return _this.closeMenu(); }));
  1408. this._initMenu();
  1409. if (this.menu instanceof MatMenu) {
  1410. this.menu._startAnimation();
  1411. }
  1412. };
  1413. /** Closes the menu. */
  1414. /**
  1415. * Closes the menu.
  1416. * @return {?}
  1417. */
  1418. MatMenuTrigger.prototype.closeMenu = /**
  1419. * Closes the menu.
  1420. * @return {?}
  1421. */
  1422. function () {
  1423. this.menu.close.emit();
  1424. };
  1425. /**
  1426. * Focuses the menu trigger.
  1427. * @param origin Source of the menu trigger's focus.
  1428. */
  1429. /**
  1430. * Focuses the menu trigger.
  1431. * @param {?=} origin Source of the menu trigger's focus.
  1432. * @param {?=} options
  1433. * @return {?}
  1434. */
  1435. MatMenuTrigger.prototype.focus = /**
  1436. * Focuses the menu trigger.
  1437. * @param {?=} origin Source of the menu trigger's focus.
  1438. * @param {?=} options
  1439. * @return {?}
  1440. */
  1441. function (origin, options) {
  1442. if (origin === void 0) { origin = 'program'; }
  1443. if (this._focusMonitor) {
  1444. this._focusMonitor.focusVia(this._element, origin, options);
  1445. }
  1446. else {
  1447. this._element.nativeElement.focus(options);
  1448. }
  1449. };
  1450. /** Closes the menu and does the necessary cleanup. */
  1451. /**
  1452. * Closes the menu and does the necessary cleanup.
  1453. * @private
  1454. * @return {?}
  1455. */
  1456. MatMenuTrigger.prototype._destroyMenu = /**
  1457. * Closes the menu and does the necessary cleanup.
  1458. * @private
  1459. * @return {?}
  1460. */
  1461. function () {
  1462. var _this = this;
  1463. if (!this._overlayRef || !this.menuOpen) {
  1464. return;
  1465. }
  1466. /** @type {?} */
  1467. var menu = this.menu;
  1468. this._closingActionsSubscription.unsubscribe();
  1469. this._overlayRef.detach();
  1470. if (menu instanceof MatMenu) {
  1471. menu._resetAnimation();
  1472. if (menu.lazyContent) {
  1473. // Wait for the exit animation to finish before detaching the content.
  1474. menu._animationDone
  1475. .pipe(filter((/**
  1476. * @param {?} event
  1477. * @return {?}
  1478. */
  1479. function (event) { return event.toState === 'void'; })), take(1),
  1480. // Interrupt if the content got re-attached.
  1481. takeUntil(menu.lazyContent._attached))
  1482. .subscribe({
  1483. next: (/**
  1484. * @return {?}
  1485. */
  1486. function () { return (/** @type {?} */ (menu.lazyContent)).detach(); }),
  1487. // No matter whether the content got re-attached, reset the menu.
  1488. complete: (/**
  1489. * @return {?}
  1490. */
  1491. function () { return _this._resetMenu(); })
  1492. });
  1493. }
  1494. else {
  1495. this._resetMenu();
  1496. }
  1497. }
  1498. else {
  1499. this._resetMenu();
  1500. if (menu.lazyContent) {
  1501. menu.lazyContent.detach();
  1502. }
  1503. }
  1504. };
  1505. /**
  1506. * This method sets the menu state to open and focuses the first item if
  1507. * the menu was opened via the keyboard.
  1508. */
  1509. /**
  1510. * This method sets the menu state to open and focuses the first item if
  1511. * the menu was opened via the keyboard.
  1512. * @private
  1513. * @return {?}
  1514. */
  1515. MatMenuTrigger.prototype._initMenu = /**
  1516. * This method sets the menu state to open and focuses the first item if
  1517. * the menu was opened via the keyboard.
  1518. * @private
  1519. * @return {?}
  1520. */
  1521. function () {
  1522. this.menu.parentMenu = this.triggersSubmenu() ? this._parentMenu : undefined;
  1523. this.menu.direction = this.dir;
  1524. this._setMenuElevation();
  1525. this._setIsMenuOpen(true);
  1526. this.menu.focusFirstItem(this._openedBy || 'program');
  1527. };
  1528. /** Updates the menu elevation based on the amount of parent menus that it has. */
  1529. /**
  1530. * Updates the menu elevation based on the amount of parent menus that it has.
  1531. * @private
  1532. * @return {?}
  1533. */
  1534. MatMenuTrigger.prototype._setMenuElevation = /**
  1535. * Updates the menu elevation based on the amount of parent menus that it has.
  1536. * @private
  1537. * @return {?}
  1538. */
  1539. function () {
  1540. if (this.menu.setElevation) {
  1541. /** @type {?} */
  1542. var depth = 0;
  1543. /** @type {?} */
  1544. var parentMenu = this.menu.parentMenu;
  1545. while (parentMenu) {
  1546. depth++;
  1547. parentMenu = parentMenu.parentMenu;
  1548. }
  1549. this.menu.setElevation(depth);
  1550. }
  1551. };
  1552. /**
  1553. * This method resets the menu when it's closed, most importantly restoring
  1554. * focus to the menu trigger if the menu was opened via the keyboard.
  1555. */
  1556. /**
  1557. * This method resets the menu when it's closed, most importantly restoring
  1558. * focus to the menu trigger if the menu was opened via the keyboard.
  1559. * @private
  1560. * @return {?}
  1561. */
  1562. MatMenuTrigger.prototype._resetMenu = /**
  1563. * This method resets the menu when it's closed, most importantly restoring
  1564. * focus to the menu trigger if the menu was opened via the keyboard.
  1565. * @private
  1566. * @return {?}
  1567. */
  1568. function () {
  1569. this._setIsMenuOpen(false);
  1570. // We should reset focus if the user is navigating using a keyboard or
  1571. // if we have a top-level trigger which might cause focus to be lost
  1572. // when clicking on the backdrop.
  1573. if (this.restoreFocus) {
  1574. if (!this._openedBy) {
  1575. // Note that the focus style will show up both for `program` and
  1576. // `keyboard` so we don't have to specify which one it is.
  1577. this.focus();
  1578. }
  1579. else if (!this.triggersSubmenu()) {
  1580. this.focus(this._openedBy);
  1581. }
  1582. }
  1583. this._openedBy = null;
  1584. };
  1585. // set state rather than toggle to support triggers sharing a menu
  1586. // set state rather than toggle to support triggers sharing a menu
  1587. /**
  1588. * @private
  1589. * @param {?} isOpen
  1590. * @return {?}
  1591. */
  1592. MatMenuTrigger.prototype._setIsMenuOpen =
  1593. // set state rather than toggle to support triggers sharing a menu
  1594. /**
  1595. * @private
  1596. * @param {?} isOpen
  1597. * @return {?}
  1598. */
  1599. function (isOpen) {
  1600. this._menuOpen = isOpen;
  1601. this._menuOpen ? this.menuOpened.emit() : this.menuClosed.emit();
  1602. if (this.triggersSubmenu()) {
  1603. this._menuItemInstance._highlighted = isOpen;
  1604. }
  1605. };
  1606. /**
  1607. * This method checks that a valid instance of MatMenu has been passed into
  1608. * matMenuTriggerFor. If not, an exception is thrown.
  1609. */
  1610. /**
  1611. * This method checks that a valid instance of MatMenu has been passed into
  1612. * matMenuTriggerFor. If not, an exception is thrown.
  1613. * @private
  1614. * @return {?}
  1615. */
  1616. MatMenuTrigger.prototype._checkMenu = /**
  1617. * This method checks that a valid instance of MatMenu has been passed into
  1618. * matMenuTriggerFor. If not, an exception is thrown.
  1619. * @private
  1620. * @return {?}
  1621. */
  1622. function () {
  1623. if (!this.menu) {
  1624. throwMatMenuMissingError();
  1625. }
  1626. };
  1627. /**
  1628. * This method creates the overlay from the provided menu's template and saves its
  1629. * OverlayRef so that it can be attached to the DOM when openMenu is called.
  1630. */
  1631. /**
  1632. * This method creates the overlay from the provided menu's template and saves its
  1633. * OverlayRef so that it can be attached to the DOM when openMenu is called.
  1634. * @private
  1635. * @return {?}
  1636. */
  1637. MatMenuTrigger.prototype._createOverlay = /**
  1638. * This method creates the overlay from the provided menu's template and saves its
  1639. * OverlayRef so that it can be attached to the DOM when openMenu is called.
  1640. * @private
  1641. * @return {?}
  1642. */
  1643. function () {
  1644. if (!this._overlayRef) {
  1645. /** @type {?} */
  1646. var config = this._getOverlayConfig();
  1647. this._subscribeToPositions((/** @type {?} */ (config.positionStrategy)));
  1648. this._overlayRef = this._overlay.create(config);
  1649. // Consume the `keydownEvents` in order to prevent them from going to another overlay.
  1650. // Ideally we'd also have our keyboard event logic in here, however doing so will
  1651. // break anybody that may have implemented the `MatMenuPanel` themselves.
  1652. this._overlayRef.keydownEvents().subscribe();
  1653. }
  1654. return this._overlayRef;
  1655. };
  1656. /**
  1657. * This method builds the configuration object needed to create the overlay, the OverlayState.
  1658. * @returns OverlayConfig
  1659. */
  1660. /**
  1661. * This method builds the configuration object needed to create the overlay, the OverlayState.
  1662. * @private
  1663. * @return {?} OverlayConfig
  1664. */
  1665. MatMenuTrigger.prototype._getOverlayConfig = /**
  1666. * This method builds the configuration object needed to create the overlay, the OverlayState.
  1667. * @private
  1668. * @return {?} OverlayConfig
  1669. */
  1670. function () {
  1671. return new OverlayConfig({
  1672. positionStrategy: this._overlay.position()
  1673. .flexibleConnectedTo(this._element)
  1674. .withLockedPosition()
  1675. .withTransformOriginOn('.mat-menu-panel, .mat-mdc-menu-panel'),
  1676. backdropClass: this.menu.backdropClass || 'cdk-overlay-transparent-backdrop',
  1677. scrollStrategy: this._scrollStrategy(),
  1678. direction: this._dir
  1679. });
  1680. };
  1681. /**
  1682. * Listens to changes in the position of the overlay and sets the correct classes
  1683. * on the menu based on the new position. This ensures the animation origin is always
  1684. * correct, even if a fallback position is used for the overlay.
  1685. */
  1686. /**
  1687. * Listens to changes in the position of the overlay and sets the correct classes
  1688. * on the menu based on the new position. This ensures the animation origin is always
  1689. * correct, even if a fallback position is used for the overlay.
  1690. * @private
  1691. * @param {?} position
  1692. * @return {?}
  1693. */
  1694. MatMenuTrigger.prototype._subscribeToPositions = /**
  1695. * Listens to changes in the position of the overlay and sets the correct classes
  1696. * on the menu based on the new position. This ensures the animation origin is always
  1697. * correct, even if a fallback position is used for the overlay.
  1698. * @private
  1699. * @param {?} position
  1700. * @return {?}
  1701. */
  1702. function (position) {
  1703. var _this = this;
  1704. if (this.menu.setPositionClasses) {
  1705. position.positionChanges.subscribe((/**
  1706. * @param {?} change
  1707. * @return {?}
  1708. */
  1709. function (change) {
  1710. /** @type {?} */
  1711. var posX = change.connectionPair.overlayX === 'start' ? 'after' : 'before';
  1712. /** @type {?} */
  1713. var posY = change.connectionPair.overlayY === 'top' ? 'below' : 'above';
  1714. (/** @type {?} */ (_this.menu.setPositionClasses))(posX, posY);
  1715. }));
  1716. }
  1717. };
  1718. /**
  1719. * Sets the appropriate positions on a position strategy
  1720. * so the overlay connects with the trigger correctly.
  1721. * @param positionStrategy Strategy whose position to update.
  1722. */
  1723. /**
  1724. * Sets the appropriate positions on a position strategy
  1725. * so the overlay connects with the trigger correctly.
  1726. * @private
  1727. * @param {?} positionStrategy Strategy whose position to update.
  1728. * @return {?}
  1729. */
  1730. MatMenuTrigger.prototype._setPosition = /**
  1731. * Sets the appropriate positions on a position strategy
  1732. * so the overlay connects with the trigger correctly.
  1733. * @private
  1734. * @param {?} positionStrategy Strategy whose position to update.
  1735. * @return {?}
  1736. */
  1737. function (positionStrategy) {
  1738. var _a = this.menu.xPosition === 'before' ? ['end', 'start'] : ['start', 'end'], originX = _a[0], originFallbackX = _a[1];
  1739. var _b = this.menu.yPosition === 'above' ? ['bottom', 'top'] : ['top', 'bottom'], overlayY = _b[0], overlayFallbackY = _b[1];
  1740. var _c = [overlayY, overlayFallbackY], originY = _c[0], originFallbackY = _c[1];
  1741. var _d = [originX, originFallbackX], overlayX = _d[0], overlayFallbackX = _d[1];
  1742. /** @type {?} */
  1743. var offsetY = 0;
  1744. if (this.triggersSubmenu()) {
  1745. // When the menu is a sub-menu, it should always align itself
  1746. // to the edges of the trigger, instead of overlapping it.
  1747. overlayFallbackX = originX = this.menu.xPosition === 'before' ? 'start' : 'end';
  1748. originFallbackX = overlayX = originX === 'end' ? 'start' : 'end';
  1749. offsetY = overlayY === 'bottom' ? MENU_PANEL_TOP_PADDING : -MENU_PANEL_TOP_PADDING;
  1750. }
  1751. else if (!this.menu.overlapTrigger) {
  1752. originY = overlayY === 'top' ? 'bottom' : 'top';
  1753. originFallbackY = overlayFallbackY === 'top' ? 'bottom' : 'top';
  1754. }
  1755. positionStrategy.withPositions([
  1756. { originX: originX, originY: originY, overlayX: overlayX, overlayY: overlayY, offsetY: offsetY },
  1757. { originX: originFallbackX, originY: originY, overlayX: overlayFallbackX, overlayY: overlayY, offsetY: offsetY },
  1758. {
  1759. originX: originX,
  1760. originY: originFallbackY,
  1761. overlayX: overlayX,
  1762. overlayY: overlayFallbackY,
  1763. offsetY: -offsetY
  1764. },
  1765. {
  1766. originX: originFallbackX,
  1767. originY: originFallbackY,
  1768. overlayX: overlayFallbackX,
  1769. overlayY: overlayFallbackY,
  1770. offsetY: -offsetY
  1771. }
  1772. ]);
  1773. };
  1774. /** Returns a stream that emits whenever an action that should close the menu occurs. */
  1775. /**
  1776. * Returns a stream that emits whenever an action that should close the menu occurs.
  1777. * @private
  1778. * @return {?}
  1779. */
  1780. MatMenuTrigger.prototype._menuClosingActions = /**
  1781. * Returns a stream that emits whenever an action that should close the menu occurs.
  1782. * @private
  1783. * @return {?}
  1784. */
  1785. function () {
  1786. var _this = this;
  1787. /** @type {?} */
  1788. var backdrop = (/** @type {?} */ (this._overlayRef)).backdropClick();
  1789. /** @type {?} */
  1790. var detachments = (/** @type {?} */ (this._overlayRef)).detachments();
  1791. /** @type {?} */
  1792. var parentClose = this._parentMenu ? this._parentMenu.closed : of();
  1793. /** @type {?} */
  1794. var hover = this._parentMenu ? this._parentMenu._hovered().pipe(filter((/**
  1795. * @param {?} active
  1796. * @return {?}
  1797. */
  1798. function (active) { return active !== _this._menuItemInstance; })), filter((/**
  1799. * @return {?}
  1800. */
  1801. function () { return _this._menuOpen; }))) : of();
  1802. return merge(backdrop, parentClose, hover, detachments);
  1803. };
  1804. /** Handles mouse presses on the trigger. */
  1805. /**
  1806. * Handles mouse presses on the trigger.
  1807. * @param {?} event
  1808. * @return {?}
  1809. */
  1810. MatMenuTrigger.prototype._handleMousedown = /**
  1811. * Handles mouse presses on the trigger.
  1812. * @param {?} event
  1813. * @return {?}
  1814. */
  1815. function (event) {
  1816. if (!isFakeMousedownFromScreenReader(event)) {
  1817. // Since right or middle button clicks won't trigger the `click` event,
  1818. // we shouldn't consider the menu as opened by mouse in those cases.
  1819. this._openedBy = event.button === 0 ? 'mouse' : null;
  1820. // Since clicking on the trigger won't close the menu if it opens a sub-menu,
  1821. // we should prevent focus from moving onto it via click to avoid the
  1822. // highlight from lingering on the menu item.
  1823. if (this.triggersSubmenu()) {
  1824. event.preventDefault();
  1825. }
  1826. }
  1827. };
  1828. /** Handles key presses on the trigger. */
  1829. /**
  1830. * Handles key presses on the trigger.
  1831. * @param {?} event
  1832. * @return {?}
  1833. */
  1834. MatMenuTrigger.prototype._handleKeydown = /**
  1835. * Handles key presses on the trigger.
  1836. * @param {?} event
  1837. * @return {?}
  1838. */
  1839. function (event) {
  1840. /** @type {?} */
  1841. var keyCode = event.keyCode;
  1842. if (this.triggersSubmenu() && ((keyCode === RIGHT_ARROW && this.dir === 'ltr') ||
  1843. (keyCode === LEFT_ARROW && this.dir === 'rtl'))) {
  1844. this.openMenu();
  1845. }
  1846. };
  1847. /** Handles click events on the trigger. */
  1848. /**
  1849. * Handles click events on the trigger.
  1850. * @param {?} event
  1851. * @return {?}
  1852. */
  1853. MatMenuTrigger.prototype._handleClick = /**
  1854. * Handles click events on the trigger.
  1855. * @param {?} event
  1856. * @return {?}
  1857. */
  1858. function (event) {
  1859. if (this.triggersSubmenu()) {
  1860. // Stop event propagation to avoid closing the parent menu.
  1861. event.stopPropagation();
  1862. this.openMenu();
  1863. }
  1864. else {
  1865. this.toggleMenu();
  1866. }
  1867. };
  1868. /** Handles the cases where the user hovers over the trigger. */
  1869. /**
  1870. * Handles the cases where the user hovers over the trigger.
  1871. * @private
  1872. * @return {?}
  1873. */
  1874. MatMenuTrigger.prototype._handleHover = /**
  1875. * Handles the cases where the user hovers over the trigger.
  1876. * @private
  1877. * @return {?}
  1878. */
  1879. function () {
  1880. var _this = this;
  1881. // Subscribe to changes in the hovered item in order to toggle the panel.
  1882. if (!this.triggersSubmenu()) {
  1883. return;
  1884. }
  1885. this._hoverSubscription = this._parentMenu._hovered()
  1886. // Since we might have multiple competing triggers for the same menu (e.g. a sub-menu
  1887. // with different data and triggers), we have to delay it by a tick to ensure that
  1888. // it won't be closed immediately after it is opened.
  1889. .pipe(filter((/**
  1890. * @param {?} active
  1891. * @return {?}
  1892. */
  1893. function (active) { return active === _this._menuItemInstance && !active.disabled; })), delay(0, asapScheduler))
  1894. .subscribe((/**
  1895. * @return {?}
  1896. */
  1897. function () {
  1898. _this._openedBy = 'mouse';
  1899. // If the same menu is used between multiple triggers, it might still be animating
  1900. // while the new trigger tries to re-open it. Wait for the animation to finish
  1901. // before doing so. Also interrupt if the user moves to another item.
  1902. if (_this.menu instanceof MatMenu && _this.menu._isAnimating) {
  1903. // We need the `delay(0)` here in order to avoid
  1904. // 'changed after checked' errors in some cases. See #12194.
  1905. _this.menu._animationDone
  1906. .pipe(take(1), delay(0, asapScheduler), takeUntil(_this._parentMenu._hovered()))
  1907. .subscribe((/**
  1908. * @return {?}
  1909. */
  1910. function () { return _this.openMenu(); }));
  1911. }
  1912. else {
  1913. _this.openMenu();
  1914. }
  1915. }));
  1916. };
  1917. /** Gets the portal that should be attached to the overlay. */
  1918. /**
  1919. * Gets the portal that should be attached to the overlay.
  1920. * @private
  1921. * @return {?}
  1922. */
  1923. MatMenuTrigger.prototype._getPortal = /**
  1924. * Gets the portal that should be attached to the overlay.
  1925. * @private
  1926. * @return {?}
  1927. */
  1928. function () {
  1929. // Note that we can avoid this check by keeping the portal on the menu panel.
  1930. // While it would be cleaner, we'd have to introduce another required method on
  1931. // `MatMenuPanel`, making it harder to consume.
  1932. if (!this._portal || this._portal.templateRef !== this.menu.templateRef) {
  1933. this._portal = new TemplatePortal(this.menu.templateRef, this._viewContainerRef);
  1934. }
  1935. return this._portal;
  1936. };
  1937. MatMenuTrigger.decorators = [
  1938. { type: Directive, args: [{
  1939. selector: "[mat-menu-trigger-for], [matMenuTriggerFor]",
  1940. host: {
  1941. 'class': 'mat-menu-trigger',
  1942. 'aria-haspopup': 'true',
  1943. '[attr.aria-expanded]': 'menuOpen || null',
  1944. '(mousedown)': '_handleMousedown($event)',
  1945. '(keydown)': '_handleKeydown($event)',
  1946. '(click)': '_handleClick($event)',
  1947. },
  1948. exportAs: 'matMenuTrigger'
  1949. },] },
  1950. ];
  1951. /** @nocollapse */
  1952. MatMenuTrigger.ctorParameters = function () { return [
  1953. { type: Overlay },
  1954. { type: ElementRef },
  1955. { type: ViewContainerRef },
  1956. { type: undefined, decorators: [{ type: Inject, args: [MAT_MENU_SCROLL_STRATEGY,] }] },
  1957. { type: MatMenu, decorators: [{ type: Optional }] },
  1958. { type: MatMenuItem, decorators: [{ type: Optional }, { type: Self }] },
  1959. { type: Directionality, decorators: [{ type: Optional }] },
  1960. { type: FocusMonitor }
  1961. ]; };
  1962. MatMenuTrigger.propDecorators = {
  1963. _deprecatedMatMenuTriggerFor: [{ type: Input, args: ['mat-menu-trigger-for',] }],
  1964. menu: [{ type: Input, args: ['matMenuTriggerFor',] }],
  1965. menuData: [{ type: Input, args: ['matMenuTriggerData',] }],
  1966. restoreFocus: [{ type: Input, args: ['matMenuTriggerRestoreFocus',] }],
  1967. menuOpened: [{ type: Output }],
  1968. onMenuOpen: [{ type: Output }],
  1969. menuClosed: [{ type: Output }],
  1970. onMenuClose: [{ type: Output }]
  1971. };
  1972. return MatMenuTrigger;
  1973. }());
  1974. /**
  1975. * @fileoverview added by tsickle
  1976. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1977. */
  1978. /**
  1979. * Used by both the current `MatMenuModule` and the MDC `MatMenuModule`
  1980. * to declare the menu-related directives.
  1981. */
  1982. var _MatMenuDirectivesModule = /** @class */ (function () {
  1983. function _MatMenuDirectivesModule() {
  1984. }
  1985. _MatMenuDirectivesModule.decorators = [
  1986. { type: NgModule, args: [{
  1987. exports: [MatMenuTrigger, MatMenuContent, MatCommonModule],
  1988. declarations: [MatMenuTrigger, MatMenuContent],
  1989. providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
  1990. },] },
  1991. ];
  1992. return _MatMenuDirectivesModule;
  1993. }());
  1994. var MatMenuModule = /** @class */ (function () {
  1995. function MatMenuModule() {
  1996. }
  1997. MatMenuModule.decorators = [
  1998. { type: NgModule, args: [{
  1999. imports: [
  2000. CommonModule,
  2001. MatCommonModule,
  2002. MatRippleModule,
  2003. OverlayModule,
  2004. _MatMenuDirectivesModule,
  2005. ],
  2006. exports: [_MatMenu, MatMenuItem, _MatMenuDirectivesModule],
  2007. declarations: [_MatMenu, MatMenuItem],
  2008. providers: [MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER]
  2009. },] },
  2010. ];
  2011. return MatMenuModule;
  2012. }());
  2013. /**
  2014. * @fileoverview added by tsickle
  2015. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2016. */
  2017. /**
  2018. * @fileoverview added by tsickle
  2019. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2020. */
  2021. /**
  2022. * @fileoverview added by tsickle
  2023. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2024. */
  2025. export { MatMenu, MAT_MENU_DEFAULT_OPTIONS, _MatMenu, _MatMenuBase, MatMenuItem, MatMenuTrigger, MAT_MENU_SCROLL_STRATEGY, MAT_MENU_PANEL, _MatMenuDirectivesModule, MatMenuModule, matMenuAnimations, fadeInItems, transformMenu, MatMenuContent, MAT_MENU_DEFAULT_OPTIONS_FACTORY as ɵa24, MAT_MENU_SCROLL_STRATEGY_FACTORY as ɵb24, MAT_MENU_SCROLL_STRATEGY_FACTORY_PROVIDER as ɵc24 };
  2026. //# sourceMappingURL=menu.es5.js.map