Skip to content

Commit 883b86c

Browse files
committed
feat(toolbar): support dense mode
* Adds support for the dense mode that is being shown in the Material Design specifications. Closes #11878
1 parent e1fd13a commit 883b86c

File tree

5 files changed

+69
-21
lines changed

5 files changed

+69
-21
lines changed

src/demo-app/toolbar/toolbar-demo.html

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
<div class="demo-toolbar">
22
<p>
3-
<mat-toolbar>
3+
<mat-checkbox [(ngModel)]="dense">Toggle Dense Mode</mat-checkbox>
4+
</p>
5+
<p>
6+
<mat-toolbar [dense]="dense">
47
<button mat-icon-button>
58
<mat-icon>menu</mat-icon>
69
</button>
@@ -20,7 +23,7 @@
2023
</p>
2124

2225
<p>
23-
<mat-toolbar color="primary">
26+
<mat-toolbar color="primary" [dense]="dense">
2427
<button mat-icon-button>
2528
<mat-icon>menu</mat-icon>
2629
</button>
@@ -35,7 +38,7 @@
3538
</p>
3639

3740
<p>
38-
<mat-toolbar color="accent">
41+
<mat-toolbar color="accent" [dense]="dense">
3942
<button mat-icon-button>
4043
<mat-icon>menu</mat-icon>
4144
</button>
@@ -55,7 +58,7 @@
5558
</p>
5659

5760
<p>
58-
<mat-toolbar>
61+
<mat-toolbar [dense]="dense">
5962
<mat-toolbar-row>First Row</mat-toolbar-row>
6063
<mat-toolbar-row>Second Row</mat-toolbar-row>
6164
</mat-toolbar>

src/demo-app/toolbar/toolbar-demo.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ import {Component} from '@angular/core';
1515
templateUrl: 'toolbar-demo.html',
1616
styleUrls: ['toolbar-demo.css'],
1717
})
18-
export class ToolbarDemo {}
18+
export class ToolbarDemo {
19+
dense = false;
20+
}

src/lib/toolbar/toolbar.scss

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,31 @@
22
@import '../../cdk/a11y/a11y';
33

44
$mat-toolbar-height-desktop: 64px !default;
5-
$mat-toolbar-height-mobile-portrait: 56px !default;
6-
$mat-toolbar-height-mobile-landscape: 48px !default;
5+
$mat-toolbar-height-mobile: 56px !default;
6+
$mat-toolbar-height-dense: 48px !default;
77

88
$mat-toolbar-row-padding: 16px !default;
99

10+
/** @deprecated @deletion-target 8.0.0 */
11+
$mat-toolbar-height-mobile-portrait: 56px !default;
12+
13+
/** @deprecated @deletion-target 8.0.0 */
14+
$mat-toolbar-height-mobile-landscape: 48px !default;
15+
1016

11-
@mixin mat-toolbar-height($height) {
12-
.mat-toolbar-multiple-rows {
17+
// In order to avoid breaking changes with an increase of specificity, we introduce the
18+
// `$target-selector` parameter. This allows us to target specific toolbars with a selector
19+
// (e.g. `.mat-toolbar-dense`), or just set the height for the default toolbar classes.
20+
@mixin mat-toolbar-height($height, $target-selector: '') {
21+
// If the toolbar has multiple rows, only set a minimum height to not limit the height of the
22+
// toolbar because it should grow based on the amount of rows.
23+
#{$target-selector}.mat-toolbar-multiple-rows {
1324
min-height: $height;
1425
}
15-
.mat-toolbar-row, .mat-toolbar-single-row {
26+
27+
// If the toolbar element itself acts as the first row, set the height to the same value
28+
// as an actual toolbar row would have.
29+
.mat-toolbar-row, #{$target-selector}.mat-toolbar-single-row {
1630
height: $height;
1731
}
1832
}
@@ -49,10 +63,12 @@ $mat-toolbar-row-padding: 16px !default;
4963
// Set the default height for the toolbar.
5064
@include mat-toolbar-height($mat-toolbar-height-desktop);
5165

52-
// As per specs, mobile devices will use a different height for toolbars than for desktop.
53-
// The height for mobile landscape devices has been ignored since relying on `@media orientation`
54-
// is causing issues on devices with a soft-keyboard.
55-
// See: https://material.io/guidelines/layout/structure.html#structure-app-bar
66+
// Set the toolbar height for toolbar's displaying in dense mode.
67+
@include mat-toolbar-height($mat-toolbar-height-dense, '.mat-toolbar-dense');
68+
69+
// As per specs, toolbars should have a different height in mobile devices. This has been
70+
// specified in the old guidelines and is still observable in the new specifications by looking at
71+
// the spec images. See: https://material.io/design/components/app-bars-top.html#anatomy
5672
@media ($mat-xsmall) {
57-
@include mat-toolbar-height($mat-toolbar-height-mobile-portrait);
73+
@include mat-toolbar-height($mat-toolbar-height-mobile);
5874
}

src/lib/toolbar/toolbar.spec.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,19 @@ describe('MatToolbar', () => {
4444
expect(toolbarElement.classList.contains('mat-warn')).toBe(true);
4545
});
4646

47+
it('should apply proper class based on dense input binding', () => {
48+
fixture.detectChanges();
49+
50+
expect(toolbarElement.classList)
51+
.not.toContain('mat-toolbar-dense', 'Expected the toolbar to not show in dense mode.');
52+
53+
testComponent.dense = true;
54+
fixture.detectChanges();
55+
56+
expect(toolbarElement.classList)
57+
.toContain('mat-toolbar-dense', 'Expected the toolbar to show in dense mode.');
58+
});
59+
4760
it('should not wrap the first row contents inside of a generated element', () => {
4861
expect(toolbarElement.firstElementChild!.tagName).toBe('SPAN',
4962
'Expected the <span> element of the first row to be a direct child of the toolbar');
@@ -91,13 +104,14 @@ describe('MatToolbar', () => {
91104

92105
@Component({
93106
template: `
94-
<mat-toolbar [color]="toolbarColor">
107+
<mat-toolbar [color]="toolbarColor" [dense]="dense">
95108
<span>First Row</span>
96109
</mat-toolbar>
97110
`
98111
})
99112
class ToolbarSingleRow {
100113
toolbarColor: string;
114+
dense = false;
101115
}
102116

103117
@Component({

src/lib/toolbar/toolbar.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,23 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {coerceBooleanProperty} from '@angular/cdk/coercion';
10+
import {Platform} from '@angular/cdk/platform';
11+
import {DOCUMENT} from '@angular/common';
912
import {
1013
AfterViewInit,
1114
ChangeDetectionStrategy,
1215
Component,
1316
ContentChildren,
1417
Directive,
1518
ElementRef,
19+
Inject,
20+
Input,
1621
isDevMode,
1722
QueryList,
1823
ViewEncapsulation,
19-
Inject,
2024
} from '@angular/core';
2125
import {CanColor, mixinColor} from '@angular/material/core';
22-
import {Platform} from '@angular/cdk/platform';
23-
import {DOCUMENT} from '@angular/common';
2426

2527
// Boilerplate for applying mixins to MatToolbar.
2628
/** @docs-private */
@@ -45,18 +47,29 @@ export class MatToolbarRow {}
4547
inputs: ['color'],
4648
host: {
4749
'class': 'mat-toolbar',
48-
'[class.mat-toolbar-multiple-rows]': 'this._toolbarRows.length',
49-
'[class.mat-toolbar-single-row]': '!this._toolbarRows.length'
50+
'[class.mat-toolbar-multiple-rows]': '_toolbarRows.length > 0',
51+
'[class.mat-toolbar-single-row]': '_toolbarRows.length === 0',
52+
'[class.mat-toolbar-dense]': 'dense'
5053
},
5154
changeDetection: ChangeDetectionStrategy.OnPush,
5255
encapsulation: ViewEncapsulation.None,
5356
})
5457
export class MatToolbar extends _MatToolbarMixinBase implements CanColor, AfterViewInit {
58+
5559
private _document: Document;
60+
private _dense: boolean = false;
5661

5762
/** Reference to all toolbar row elements that have been projected. */
5863
@ContentChildren(MatToolbarRow) _toolbarRows: QueryList<MatToolbarRow>;
5964

65+
/**
66+
* Whether the toolbar should display in dense mode. It is recommended to only enable
67+
* this mode on desktop devices.
68+
*/
69+
@Input()
70+
get dense(): boolean { return this._dense; }
71+
set dense(value: boolean) { this._dense = coerceBooleanProperty(value); }
72+
6073
constructor(
6174
elementRef: ElementRef,
6275
private _platform: Platform,

0 commit comments

Comments
 (0)