diff --git a/src/lib/toolbar/index.ts b/src/lib/toolbar/index.ts
index eb66854ca316..2b8be90eca30 100644
--- a/src/lib/toolbar/index.ts
+++ b/src/lib/toolbar/index.ts
@@ -7,12 +7,13 @@
*/
import {NgModule} from '@angular/core';
+import {PlatformModule} from '@angular/cdk/platform';
import {MdCommonModule} from '../core';
import {MdToolbar, MdToolbarRow} from './toolbar';
@NgModule({
- imports: [MdCommonModule],
+ imports: [MdCommonModule, PlatformModule],
exports: [MdToolbar, MdToolbarRow, MdCommonModule],
declarations: [MdToolbar, MdToolbarRow],
})
diff --git a/src/lib/toolbar/toolbar.html b/src/lib/toolbar/toolbar.html
index e81e16e5d708..208f30d2edaa 100644
--- a/src/lib/toolbar/toolbar.html
+++ b/src/lib/toolbar/toolbar.html
@@ -1,5 +1,5 @@
-
+
diff --git a/src/lib/toolbar/toolbar.md b/src/lib/toolbar/toolbar.md
index eb7189923d0f..11826b4f6c76 100644
--- a/src/lib/toolbar/toolbar.md
+++ b/src/lib/toolbar/toolbar.md
@@ -21,6 +21,19 @@ Each toolbar row is a `display: flex` container.
```
+In some situations, developers need full control over all `` elements
+(e.g. for use with flex-layout).
+
+To have full control over the first ``, which is usually auto-generated,
+there should be only row elements in the ``.
+
+```html
+
+ First Row
+ Second Row
+
+```
+
### Positioning toolbar content
The toolbar does not perform any positioning of its content. This gives the user full power to
position the content as it suits their application.
diff --git a/src/lib/toolbar/toolbar.spec.ts b/src/lib/toolbar/toolbar.spec.ts
index 6e0c6d4da7cd..681b6ed12457 100644
--- a/src/lib/toolbar/toolbar.spec.ts
+++ b/src/lib/toolbar/toolbar.spec.ts
@@ -3,55 +3,86 @@ import {TestBed, async, ComponentFixture} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
import {MdToolbarModule} from './index';
-
describe('MdToolbar', () => {
- let fixture: ComponentFixture;
- let testComponent: TestApp;
- let toolbarElement: HTMLElement;
-
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdToolbarModule],
- declarations: [TestApp],
+ declarations: [ToolbarWithDefaultFirstRow, ToolbarWithoutDefaultFirstRow],
});
TestBed.compileComponents();
}));
- beforeEach(() => {
- fixture = TestBed.createComponent(TestApp);
- testComponent = fixture.debugElement.componentInstance;
- toolbarElement = fixture.debugElement.query(By.css('md-toolbar')).nativeElement;
- });
+ describe('with default first row', () => {
+ let fixture: ComponentFixture;
+ let testComponent: ToolbarWithDefaultFirstRow;
+ let toolbarElement: HTMLElement;
+ let toolbarRowElements: HTMLElement[];
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(ToolbarWithDefaultFirstRow);
+ testComponent = fixture.debugElement.componentInstance;
+ toolbarElement = fixture.debugElement.query(By.css('.mat-toolbar')).nativeElement;
+ toolbarRowElements = fixture.debugElement.queryAll(By.css('.mat-toolbar-row'))
+ .map(rowDebugElement => rowDebugElement.nativeElement);
+ });
- it('should apply class based on color attribute', () => {
- testComponent.toolbarColor = 'primary';
- fixture.detectChanges();
+ it('should apply class based on color attribute', () => {
+ testComponent.toolbarColor = 'primary';
+ fixture.detectChanges();
- expect(toolbarElement.classList.contains('mat-primary')).toBe(true);
+ expect(toolbarElement.classList.contains('mat-primary')).toBe(true);
- testComponent.toolbarColor = 'accent';
- fixture.detectChanges();
+ testComponent.toolbarColor = 'accent';
+ fixture.detectChanges();
- expect(toolbarElement.classList.contains('mat-primary')).toBe(false);
- expect(toolbarElement.classList.contains('mat-accent')).toBe(true);
+ expect(toolbarElement.classList.contains('mat-primary')).toBe(false);
+ expect(toolbarElement.classList.contains('mat-accent')).toBe(true);
+
+ testComponent.toolbarColor = 'warn';
+ fixture.detectChanges();
+
+ expect(toolbarElement.classList.contains('mat-accent')).toBe(false);
+ expect(toolbarElement.classList.contains('mat-warn')).toBe(true);
+ });
- testComponent.toolbarColor = 'warn';
- fixture.detectChanges();
+ it('should set the toolbar role on the host', () => {
+ expect(toolbarElement.getAttribute('role')).toBe('toolbar');
+ });
- expect(toolbarElement.classList.contains('mat-accent')).toBe(false);
- expect(toolbarElement.classList.contains('mat-warn')).toBe(true);
+ it('should generate a default first row if content is projected', () => {
+ expect(toolbarRowElements.length)
+ .toBe(2, 'Expected a default first row and a second row to be present.');
+ });
});
- it('should set the toolbar role on the host', () => {
- expect(toolbarElement.getAttribute('role')).toBe('toolbar');
+ describe('without default first row', () => {
+
+ it('should not generate a default first row if no content is projected', () => {
+ const fixture = TestBed.createComponent(ToolbarWithoutDefaultFirstRow);
+
+ expect(fixture.debugElement.queryAll(By.css('.mat-toolbar-row')).length)
+ .toBe(2, 'Expected one toolbar row to be present while no content is projected.');
+ });
});
+
});
-@Component({template: `Test Toolbar`})
-class TestApp {
+@Component({template: `
+
+ First Row
+ Second Row
+ `})
+class ToolbarWithDefaultFirstRow {
toolbarColor: string;
}
+
+@Component({template: `
+
+ First Row
+
+`})
+class ToolbarWithoutDefaultFirstRow {}
diff --git a/src/lib/toolbar/toolbar.ts b/src/lib/toolbar/toolbar.ts
index 772869c8fadb..c98f9b6fb052 100644
--- a/src/lib/toolbar/toolbar.ts
+++ b/src/lib/toolbar/toolbar.ts
@@ -13,15 +13,11 @@ import {
Directive,
ElementRef,
Renderer2,
+ ViewChild,
+ AfterViewInit,
} from '@angular/core';
import {CanColor, mixinColor} from '../core/common-behaviors/color';
-
-
-@Directive({
- selector: 'md-toolbar-row, mat-toolbar-row',
- host: {'class': 'mat-toolbar-row'},
-})
-export class MdToolbarRow {}
+import {Platform} from '@angular/cdk/platform';
// Boilerplate for applying mixins to MdToolbar.
/** @docs-private */
@@ -30,7 +26,6 @@ export class MdToolbarBase {
}
export const _MdToolbarMixinBase = mixinColor(MdToolbarBase);
-
@Component({
moduleId: module.id,
selector: 'md-toolbar, mat-toolbar',
@@ -44,10 +39,35 @@ export const _MdToolbarMixinBase = mixinColor(MdToolbarBase);
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
})
-export class MdToolbar extends _MdToolbarMixinBase implements CanColor {
+export class MdToolbar extends _MdToolbarMixinBase implements CanColor, AfterViewInit {
- constructor(renderer: Renderer2, elementRef: ElementRef) {
+ /** Element reference to the default first row of the toolbar. */
+ @ViewChild('defaultFirstRow', { read: ElementRef }) _defaultFirstRow: ElementRef;
+
+ constructor(renderer: Renderer2, elementRef: ElementRef, private _platform: Platform) {
super(renderer, elementRef);
}
+ ngAfterViewInit() {
+ // Do nothing if we're not on the browser platform.
+ if (!this._platform.isBrowser) {
+ return;
+ }
+
+ const firstRowElement = this._defaultFirstRow.nativeElement;
+
+ // If the first toolbar row, which will be auto-generated, does not have any projected content,
+ // then the auto-generated first toolbar row should be removed. This gives developers
+ // full control over the first toolbar row (e.g. for use with flex-layout).
+ if (!firstRowElement.innerHTML.trim()) {
+ firstRowElement.parentNode.removeChild(firstRowElement);
+ }
+ }
}
+
+@Directive({
+ selector: 'md-toolbar-row, mat-toolbar-row',
+ host: {'class': 'mat-toolbar-row'},
+})
+export class MdToolbarRow {}
+