Skip to content

Commit 0806b29

Browse files
committed
fix(button): no color set for flat and icon buttons
* Currently for flat buttons and icon buttons, the font color is not set by the theme. This can cause the text to be invisible on those buttons in a dark theme. From now on, those buttons will also receive a font color by the theme. * Flat buttons and icon buttons inside of a `<mat-toolbar>` will inherit the font color from the toolbar row. This ensures that those buttons are looking as expected in themed toolbars (e.g. primary, accent, warn) Fixes #4614. Fixes #9231. Fixes #9634
1 parent 3352201 commit 0806b29

File tree

7 files changed

+78
-14
lines changed

7 files changed

+78
-14
lines changed

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

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,58 @@
11
<div class="demo-toolbar">
2-
32
<p>
43
<mat-toolbar>
5-
<mat-icon class="demo-toolbar-icon">menu</mat-icon>
6-
<span>Default Toolbar</span>
4+
<button mat-icon-button>
5+
<mat-icon>menu</mat-icon>
6+
</button>
77

8+
<span>Default Toolbar</span>
89
<span class="demo-fill-remaining"></span>
910

10-
<mat-icon>code</mat-icon>
11+
<button mat-icon-button>
12+
<mat-icon>code</mat-icon>
13+
</button>
14+
15+
<button mat-icon-button color="warn">
16+
<mat-icon>code</mat-icon>
17+
</button>
1118
</mat-toolbar>
1219
</p>
1320

1421
<p>
1522
<mat-toolbar color="primary">
16-
<mat-icon class="demo-toolbar-icon">menu</mat-icon>
17-
<span>Primary Toolbar</span>
23+
<button mat-icon-button>
24+
<mat-icon>menu</mat-icon>
25+
</button>
1826

27+
<span>Primary Toolbar</span>
1928
<span class="demo-fill-remaining"></span>
2029

21-
<mat-icon>code</mat-icon>
30+
<button mat-raised-button>Text</button>
31+
<button mat-raised-button color="accent">Accent</button>
2232
</mat-toolbar>
2333
</p>
2434

2535
<p>
2636
<mat-toolbar color="accent">
27-
<mat-icon class="demo-toolbar-icon">menu</mat-icon>
28-
<span>Accent Toolbar</span>
37+
<button mat-icon-button>
38+
<mat-icon>menu</mat-icon>
39+
</button>
2940

41+
<span>Accent Toolbar</span>
3042
<span class="demo-fill-remaining"></span>
3143

32-
<mat-icon>code</mat-icon>
44+
<button mat-raised-button>Text</button>
45+
<button mat-mini-fab color="">
46+
<mat-icon>done</mat-icon>
47+
</button>
48+
<button mat-mini-fab color="primary">
49+
<mat-icon>done</mat-icon>
50+
</button>
3351
</mat-toolbar>
3452
</p>
3553

3654
<p>
37-
<mat-toolbar color="accent">
55+
<mat-toolbar>
3856
<mat-toolbar-row>First Row</mat-toolbar-row>
3957
<mat-toolbar-row>Second Row</mat-toolbar-row>
4058
</mat-toolbar>

src/demo-app/toolbar/toolbar-demo.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@
99
flex: 1 1 auto;
1010
}
1111

12+
button {
13+
margin: 0 4px;
14+
}
1215
}

src/lib/button/_button-theme.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@
7676
$foreground: map-get($theme, foreground);
7777

7878
.mat-button, .mat-icon-button {
79-
background: transparent;
79+
color: mat-color($foreground, text);
80+
background-color: transparent;
8081

8182
@include _mat-button-focus-color($theme);
8283
@include _mat-button-theme-color($theme, 'color');

src/lib/button/button.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252

5353
// The text and icon should be vertical aligned inside a button
5454
.mat-button, .mat-raised-button, .mat-icon-button, .mat-fab, .mat-mini-fab {
55-
color: currentColor;
5655
.mat-button-wrapper > * {
5756
vertical-align: middle;
5857
}

src/lib/button/button.spec.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing';
22
import {Component, DebugElement} from '@angular/core';
33
import {By} from '@angular/platform-browser';
44
import {MatButtonModule, MatButton} from './index';
5-
import {MatRipple} from '@angular/material/core';
5+
import {MatRipple, ThemePalette} from '@angular/material/core';
66

77

88
describe('MatButton', () => {
@@ -41,6 +41,29 @@ describe('MatButton', () => {
4141
expect(aDebugElement.nativeElement.classList).not.toContain('mat-accent');
4242
});
4343

44+
it('should mark buttons without a background color and theme as plain buttons', () => {
45+
const fixture = TestBed.createComponent(TestApp);
46+
const buttonDebugEl = fixture.debugElement.query(By.css('button'));
47+
const anchorDebugEl = fixture.debugElement.query(By.css('a'));
48+
const fabDebugEl = fixture.debugElement.query(By.css('[mat-fab]'));
49+
50+
fixture.detectChanges();
51+
52+
// Buttons that have no background color and theme palette are considered as plain buttons.
53+
expect(buttonDebugEl.nativeElement.classList).toContain('mat-plain-button');
54+
expect(anchorDebugEl.nativeElement.classList).toContain('mat-plain-button');
55+
expect(fabDebugEl.nativeElement.classList).not.toContain('mat-plain-button');
56+
57+
fixture.componentInstance.buttonColor = 'primary';
58+
fixture.detectChanges();
59+
60+
// Buttons that have no background color, but use an explicit theme palette, are not
61+
// considered as plain buttons.
62+
expect(buttonDebugEl.nativeElement.classList).not.toContain('mat-plain-button');
63+
expect(anchorDebugEl.nativeElement.classList).not.toContain('mat-plain-button');
64+
expect(fabDebugEl.nativeElement.classList).not.toContain('mat-plain-button');
65+
});
66+
4467
it('should expose the ripple instance', () => {
4568
const fixture = TestBed.createComponent(TestApp);
4669
const button = fixture.debugElement.query(By.css('button')).componentInstance as MatButton;
@@ -259,6 +282,7 @@ class TestApp {
259282
clickCount: number = 0;
260283
isDisabled: boolean = false;
261284
rippleDisabled: boolean = false;
285+
buttonColor: ThemePalette;
262286

263287
increment() {
264288
this.clickCount++;

src/lib/button/button.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export const _MatButtonMixinBase = mixinColor(mixinDisabled(mixinDisableRipple(M
103103
exportAs: 'matButton',
104104
host: {
105105
'[disabled]': 'disabled || null',
106+
'[class.mat-plain-button]': '_isPlainButton()',
106107
},
107108
templateUrl: 'button.html',
108109
styleUrls: ['button.css'],
@@ -120,6 +121,9 @@ export class MatButton extends _MatButtonMixinBase
120121
/** Whether the button is icon button. */
121122
_isIconButton: boolean = this._hasHostAttributes('mat-icon-button');
122123

124+
/** Whether the button is a flat button. */
125+
_isFlatButton: boolean = this._hasHostAttributes('mat-button');
126+
123127
/** Reference to the MatRipple instance of the button. */
124128
@ViewChild(MatRipple) ripple: MatRipple;
125129

@@ -152,6 +156,14 @@ export class MatButton extends _MatButtonMixinBase
152156
return this.disableRipple || this.disabled;
153157
}
154158

159+
/**
160+
* Whether the button is a plain button. Plain buttons are buttons without a background
161+
* color and theme color set.
162+
*/
163+
_isPlainButton() {
164+
return !this.color && (this._isIconButton || this._isFlatButton);
165+
}
166+
155167
/** Gets whether the button has one of the given attributes. */
156168
_hasHostAttributes(...attributes: string[]) {
157169
// If not on the browser, say that there are none of the attributes present.
@@ -176,6 +188,7 @@ export class MatButton extends _MatButtonMixinBase
176188
'[attr.tabindex]': 'disabled ? -1 : 0',
177189
'[attr.disabled]': 'disabled || null',
178190
'[attr.aria-disabled]': 'disabled.toString()',
191+
'[class.mat-plain-button]': '_isPlainButton()',
179192
'(click)': '_haltDisabledEvents($event)',
180193
},
181194
inputs: ['disabled', 'disableRipple', 'color'],

src/lib/toolbar/toolbar.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ $mat-toolbar-row-padding: 16px !default;
3030
// Per Material specs a toolbar cannot have multiple lines inside of a single row.
3131
// Disable text wrapping inside of the toolbar. Developers are still able to overwrite it.
3232
white-space: nowrap;
33+
34+
// Plain buttons (buttons without a background color and color palette) should inherit the color
35+
// from the toolbar row, because otherwise the text will be unreadable on themed toolbars.
36+
.mat-plain-button {
37+
color: inherit;
38+
}
3339
}
3440

3541
.mat-toolbar-multiple-rows {

0 commit comments

Comments
 (0)