From c1d153c897e95a2dee3a4c5f9fb7d02be3ad2e51 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Mon, 3 Jul 2017 20:07:19 +0200 Subject: [PATCH 1/2] feat(menu): add injection token for overriding the default options Adds a new injection token that allows the consumer to override the default values for the `xPosition`, `yPosition` and `overlapTrigger` options. Fixes #5479. --- src/lib/menu/index.ts | 14 ++++++++++++-- src/lib/menu/menu-directive.ts | 22 ++++++++++++++++++---- src/lib/menu/menu.spec.ts | 28 ++++++++++++++++++++++++++++ src/lib/menu/menu.ts | 2 +- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/src/lib/menu/index.ts b/src/lib/menu/index.ts index e2a8fae18c6d..1545666e8449 100644 --- a/src/lib/menu/index.ts +++ b/src/lib/menu/index.ts @@ -9,7 +9,7 @@ import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {OverlayModule, MdCommonModule} from '../core'; -import {MdMenu} from './menu-directive'; +import {MdMenu, MD_MENU_DEFAULT_OPTIONS} from './menu-directive'; import {MdMenuItem} from './menu-item'; import {MdMenuTrigger, MD_MENU_SCROLL_STRATEGY_PROVIDER} from './menu-trigger'; import {MdRippleModule} from '../core/ripple/index'; @@ -24,7 +24,17 @@ import {MdRippleModule} from '../core/ripple/index'; ], exports: [MdMenu, MdMenuItem, MdMenuTrigger, MdCommonModule], declarations: [MdMenu, MdMenuItem, MdMenuTrigger], - providers: [MD_MENU_SCROLL_STRATEGY_PROVIDER], + providers: [ + MD_MENU_SCROLL_STRATEGY_PROVIDER, + { + provide: MD_MENU_DEFAULT_OPTIONS, + useValue: { + overlapTrigger: true, + xPosition: 'after', + yPosition: 'below', + }, + } + ], }) export class MdMenuModule {} diff --git a/src/lib/menu/menu-directive.ts b/src/lib/menu/menu-directive.ts index cd9c102da34f..c83dc7fb0c90 100644 --- a/src/lib/menu/menu-directive.ts +++ b/src/lib/menu/menu-directive.ts @@ -20,6 +20,8 @@ import { ViewEncapsulation, ElementRef, ChangeDetectionStrategy, + InjectionToken, + Inject, } from '@angular/core'; import {AnimationEvent} from '@angular/animations'; import {MenuPositionX, MenuPositionY} from './menu-positions'; @@ -34,6 +36,16 @@ import {merge} from 'rxjs/observable/merge'; import {Observable} from 'rxjs/Observable'; import {Direction} from '../core'; +/** Default `md-menu` options that can be overriden. */ +export interface MdMenuDefaultOptions { + xPosition: MenuPositionX; + yPosition: MenuPositionY; + overlapTrigger: boolean; +} + +/** Injection token to be used to override the default options for `md-menu`. */ +export const MD_MENU_DEFAULT_OPTIONS = + new InjectionToken('md-menu-default-options'); @Component({ moduleId: module.id, @@ -50,8 +62,8 @@ import {Direction} from '../core'; }) export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy { private _keyManager: FocusKeyManager; - private _xPosition: MenuPositionX = 'after'; - private _yPosition: MenuPositionY = 'below'; + private _xPosition: MenuPositionX = this._defaultOptions.xPosition; + private _yPosition: MenuPositionY = this._defaultOptions.yPosition; /** Subscription to tab events on the menu panel */ private _tabSubscription: Subscription; @@ -96,7 +108,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy { @ContentChildren(MdMenuItem) items: QueryList; /** Whether the menu should overlap its trigger. */ - @Input() overlapTrigger = true; + @Input() overlapTrigger = this._defaultOptions.overlapTrigger; /** * This method takes classes set on the host md-menu element and applies them on the @@ -120,7 +132,9 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy { /** Event emitted when the menu is closed. */ @Output() close = new EventEmitter(); - constructor(private _elementRef: ElementRef) { } + constructor( + private _elementRef: ElementRef, + @Inject(MD_MENU_DEFAULT_OPTIONS) private _defaultOptions: MdMenuDefaultOptions) { } ngAfterContentInit() { this._keyManager = new FocusKeyManager(this.items).withWrap(); diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index 4e6f0a1882b6..0c8fdc857360 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -25,6 +25,7 @@ import { MenuPositionX, MenuPositionY, MdMenu, + MD_MENU_DEFAULT_OPTIONS, } from './index'; import {MENU_PANEL_TOP_PADDING} from './menu-trigger'; import {extendObject} from '../core/util/object-extend'; @@ -875,6 +876,29 @@ describe('MdMenu', () => { }); +describe('MdMenu default overrides', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [MdMenuModule, NoopAnimationsModule], + declarations: [SimpleMenu], + providers: [{ + provide: MD_MENU_DEFAULT_OPTIONS, + useValue: {overlapTrigger: false, xPosition: 'before', yPosition: 'above'}, + }], + }).compileComponents(); + })); + + it('should allow for the default menu options to be overriden', () => { + const fixture = TestBed.createComponent(SimpleMenu); + fixture.detectChanges(); + const menu = fixture.componentInstance.menu; + + expect(menu.overlapTrigger).toBe(false); + expect(menu.xPosition).toBe('before'); + expect(menu.yPosition).toBe('above'); + }); +}); + @Component({ template: ` @@ -887,7 +911,11 @@ describe('MdMenu', () => { class SimpleMenu { @ViewChild(MdMenuTrigger) trigger: MdMenuTrigger; @ViewChild('triggerEl') triggerEl: ElementRef; +<<<<<<< HEAD @ViewChild(MdMenu) menu: MdMenu; +======= + @ViewChild('menu') menu: MdMenu; +>>>>>>> feat(menu): add injection token for overriding the default options closeCallback = jasmine.createSpy('menu closed callback'); } diff --git a/src/lib/menu/menu.ts b/src/lib/menu/menu.ts index ac3ee4140b25..1eff665c413b 100644 --- a/src/lib/menu/menu.ts +++ b/src/lib/menu/menu.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -export {MdMenu} from './menu-directive'; +export {MdMenu, MdMenuDefaultOptions, MD_MENU_DEFAULT_OPTIONS} from './menu-directive'; export {MdMenuItem} from './menu-item'; export {MdMenuTrigger} from './menu-trigger'; export {MdMenuPanel} from './menu-panel'; From b15c577fc6004f941f8214d29c101eb598b3b7d8 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 25 Jul 2017 10:51:19 +0300 Subject: [PATCH 2/2] fix: unresolved merge conflict and pr feedback --- src/lib/menu/menu-directive.ts | 2 +- src/lib/menu/menu.spec.ts | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/menu/menu-directive.ts b/src/lib/menu/menu-directive.ts index c83dc7fb0c90..425e66547ec1 100644 --- a/src/lib/menu/menu-directive.ts +++ b/src/lib/menu/menu-directive.ts @@ -36,7 +36,7 @@ import {merge} from 'rxjs/observable/merge'; import {Observable} from 'rxjs/Observable'; import {Direction} from '../core'; -/** Default `md-menu` options that can be overriden. */ +/** Default `md-menu` options that can be overridden. */ export interface MdMenuDefaultOptions { xPosition: MenuPositionX; yPosition: MenuPositionY; diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts index 0c8fdc857360..22914dae3630 100644 --- a/src/lib/menu/menu.spec.ts +++ b/src/lib/menu/menu.spec.ts @@ -888,7 +888,7 @@ describe('MdMenu default overrides', () => { }).compileComponents(); })); - it('should allow for the default menu options to be overriden', () => { + it('should allow for the default menu options to be overridden', () => { const fixture = TestBed.createComponent(SimpleMenu); fixture.detectChanges(); const menu = fixture.componentInstance.menu; @@ -911,11 +911,7 @@ describe('MdMenu default overrides', () => { class SimpleMenu { @ViewChild(MdMenuTrigger) trigger: MdMenuTrigger; @ViewChild('triggerEl') triggerEl: ElementRef; -<<<<<<< HEAD @ViewChild(MdMenu) menu: MdMenu; -======= - @ViewChild('menu') menu: MdMenu; ->>>>>>> feat(menu): add injection token for overriding the default options closeCallback = jasmine.createSpy('menu closed callback'); }