Skip to content

Commit 3cb3945

Browse files
crisbetoandrewseguin
authored andcommitted
feat(menu): add injection token for overriding the default options (#5483)
* 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. * fix: unresolved merge conflict and pr feedback
1 parent 92d8368 commit 3cb3945

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

src/lib/menu/index.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {NgModule} from '@angular/core';
1010
import {CommonModule} from '@angular/common';
1111
import {OverlayModule, MdCommonModule} from '../core';
12-
import {MdMenu} from './menu-directive';
12+
import {MdMenu, MD_MENU_DEFAULT_OPTIONS} from './menu-directive';
1313
import {MdMenuItem} from './menu-item';
1414
import {MdMenuTrigger, MD_MENU_SCROLL_STRATEGY_PROVIDER} from './menu-trigger';
1515
import {MdRippleModule} from '../core/ripple/index';
@@ -24,7 +24,17 @@ import {MdRippleModule} from '../core/ripple/index';
2424
],
2525
exports: [MdMenu, MdMenuItem, MdMenuTrigger, MdCommonModule],
2626
declarations: [MdMenu, MdMenuItem, MdMenuTrigger],
27-
providers: [MD_MENU_SCROLL_STRATEGY_PROVIDER],
27+
providers: [
28+
MD_MENU_SCROLL_STRATEGY_PROVIDER,
29+
{
30+
provide: MD_MENU_DEFAULT_OPTIONS,
31+
useValue: {
32+
overlapTrigger: true,
33+
xPosition: 'after',
34+
yPosition: 'below',
35+
},
36+
}
37+
],
2838
})
2939
export class MdMenuModule {}
3040

src/lib/menu/menu-directive.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import {
2020
ViewEncapsulation,
2121
ElementRef,
2222
ChangeDetectionStrategy,
23+
InjectionToken,
24+
Inject,
2325
} from '@angular/core';
2426
import {AnimationEvent} from '@angular/animations';
2527
import {MenuPositionX, MenuPositionY} from './menu-positions';
@@ -34,6 +36,16 @@ import {merge} from 'rxjs/observable/merge';
3436
import {Observable} from 'rxjs/Observable';
3537
import {Direction} from '../core';
3638

39+
/** Default `md-menu` options that can be overridden. */
40+
export interface MdMenuDefaultOptions {
41+
xPosition: MenuPositionX;
42+
yPosition: MenuPositionY;
43+
overlapTrigger: boolean;
44+
}
45+
46+
/** Injection token to be used to override the default options for `md-menu`. */
47+
export const MD_MENU_DEFAULT_OPTIONS =
48+
new InjectionToken<MdMenuDefaultOptions>('md-menu-default-options');
3749

3850
@Component({
3951
moduleId: module.id,
@@ -50,8 +62,8 @@ import {Direction} from '../core';
5062
})
5163
export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
5264
private _keyManager: FocusKeyManager;
53-
private _xPosition: MenuPositionX = 'after';
54-
private _yPosition: MenuPositionY = 'below';
65+
private _xPosition: MenuPositionX = this._defaultOptions.xPosition;
66+
private _yPosition: MenuPositionY = this._defaultOptions.yPosition;
5567

5668
/** Subscription to tab events on the menu panel */
5769
private _tabSubscription: Subscription;
@@ -96,7 +108,7 @@ export class MdMenu implements AfterContentInit, MdMenuPanel, OnDestroy {
96108
@ContentChildren(MdMenuItem) items: QueryList<MdMenuItem>;
97109

98110
/** Whether the menu should overlap its trigger. */
99-
@Input() overlapTrigger = true;
111+
@Input() overlapTrigger = this._defaultOptions.overlapTrigger;
100112

101113
/**
102114
* 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 {
120132
/** Event emitted when the menu is closed. */
121133
@Output() close = new EventEmitter<void | 'click' | 'keydown'>();
122134

123-
constructor(private _elementRef: ElementRef) { }
135+
constructor(
136+
private _elementRef: ElementRef,
137+
@Inject(MD_MENU_DEFAULT_OPTIONS) private _defaultOptions: MdMenuDefaultOptions) { }
124138

125139
ngAfterContentInit() {
126140
this._keyManager = new FocusKeyManager(this.items).withWrap();

src/lib/menu/menu.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
MenuPositionX,
2626
MenuPositionY,
2727
MdMenu,
28+
MD_MENU_DEFAULT_OPTIONS,
2829
} from './index';
2930
import {MENU_PANEL_TOP_PADDING} from './menu-trigger';
3031
import {extendObject} from '../core/util/object-extend';
@@ -875,6 +876,29 @@ describe('MdMenu', () => {
875876

876877
});
877878

879+
describe('MdMenu default overrides', () => {
880+
beforeEach(async(() => {
881+
TestBed.configureTestingModule({
882+
imports: [MdMenuModule, NoopAnimationsModule],
883+
declarations: [SimpleMenu],
884+
providers: [{
885+
provide: MD_MENU_DEFAULT_OPTIONS,
886+
useValue: {overlapTrigger: false, xPosition: 'before', yPosition: 'above'},
887+
}],
888+
}).compileComponents();
889+
}));
890+
891+
it('should allow for the default menu options to be overridden', () => {
892+
const fixture = TestBed.createComponent(SimpleMenu);
893+
fixture.detectChanges();
894+
const menu = fixture.componentInstance.menu;
895+
896+
expect(menu.overlapTrigger).toBe(false);
897+
expect(menu.xPosition).toBe('before');
898+
expect(menu.yPosition).toBe('above');
899+
});
900+
});
901+
878902
@Component({
879903
template: `
880904
<button [mdMenuTriggerFor]="menu" #triggerEl>Toggle menu</button>

src/lib/menu/menu.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
export {MdMenu} from './menu-directive';
9+
export {MdMenu, MdMenuDefaultOptions, MD_MENU_DEFAULT_OPTIONS} from './menu-directive';
1010
export {MdMenuItem} from './menu-item';
1111
export {MdMenuTrigger} from './menu-trigger';
1212
export {MdMenuPanel} from './menu-panel';

0 commit comments

Comments
 (0)