material-menu.umd.js 78 KB

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