From da5febc921b2841cd04a953322c552fc0adfc698 Mon Sep 17 00:00:00 2001
From: tdawgy
Date: Thu, 17 Nov 2016 10:51:31 -0700
Subject: [PATCH] feat(icon): added color attribute to md-icon for icon theming
(#1896)
---
src/demo-app/icon/icon-demo.html | 7 +++++++
src/demo-app/icon/icon-demo.scss | 4 ----
src/lib/icon/_icon-theme.scss | 23 ++++++++++++++++++++--
src/lib/icon/icon.spec.ts | 22 +++++++++++++++++++++
src/lib/icon/icon.ts | 33 +++++++++++++++++++++++++++-----
5 files changed, 78 insertions(+), 11 deletions(-)
diff --git a/src/demo-app/icon/icon-demo.html b/src/demo-app/icon/icon-demo.html
index 8c766f50a481..9cf76fd440e8 100644
--- a/src/demo-app/icon/icon-demo.html
+++ b/src/demo-app/icon/icon-demo.html
@@ -26,6 +26,13 @@
home
+
+ Using a theme:
+ home
+ home
+ home
+
+
Custom icon font and CSS:
diff --git a/src/demo-app/icon/icon-demo.scss b/src/demo-app/icon/icon-demo.scss
index 7dddcd618e67..02af5f002624 100644
--- a/src/demo-app/icon/icon-demo.scss
+++ b/src/demo-app/icon/icon-demo.scss
@@ -1,7 +1,3 @@
-.demo-icon md-icon {
- color: purple;
-}
-
.demo-icon md-icon.green {
color: green;
}
diff --git a/src/lib/icon/_icon-theme.scss b/src/lib/icon/_icon-theme.scss
index 860538e4a6e4..2a656321676b 100644
--- a/src/lib/icon/_icon-theme.scss
+++ b/src/lib/icon/_icon-theme.scss
@@ -1,6 +1,25 @@
-@import '../core/theming/palette';
@import '../core/theming/theming';
// Include this empty mixin for consistency with the other components.
-@mixin md-icon-theme($theme) { }
+@mixin md-icon-theme($theme) {
+ $primary: map-get($theme, primary);
+ $accent: map-get($theme, accent);
+ $warn: map-get($theme, warn);
+ $background: map-get($theme, background);
+ $foreground: map-get($theme, foreground);
+
+ md-icon {
+ &.md-primary {
+ color: md-color($primary);
+ }
+
+ &.md-accent {
+ color: md-color($accent);
+ }
+
+ &.md-warn {
+ color: md-color($warn);
+ }
+ }
+}
diff --git a/src/lib/icon/icon.spec.ts b/src/lib/icon/icon.spec.ts
index d855a8888008..604770074555 100644
--- a/src/lib/icon/icon.spec.ts
+++ b/src/lib/icon/icon.spec.ts
@@ -41,6 +41,7 @@ describe('MdIcon', () => {
TestBed.configureTestingModule({
imports: [MdIconModule.forRoot()],
declarations: [
+ MdIconColorTestApp,
MdIconLigatureTestApp,
MdIconLigatureWithAriaBindingTestApp,
MdIconCustomFontCssTestApp,
@@ -72,6 +73,17 @@ describe('MdIcon', () => {
});
}));
+ it('should apply class based on color attribute', () => {
+ let fixture = TestBed.createComponent(MdIconColorTestApp);
+
+ const testComponent = fixture.debugElement.componentInstance;
+ const mdIconElement = fixture.debugElement.nativeElement.querySelector('md-icon');
+ testComponent.iconName = 'home';
+ testComponent.iconColor = 'primary';
+ fixture.detectChanges();
+ expect(sortedClassNames(mdIconElement)).toEqual(['material-icons', 'md-primary']);
+ });
+
describe('Ligature icons', () => {
it('should add material-icons class by default', () => {
let fixture = TestBed.createComponent(MdIconLigatureTestApp);
@@ -413,6 +425,16 @@ class MdIconLigatureTestApp {
iconName = '';
}
+@Component({
+ selector: 'test-app',
+ template: `{{iconName}}`,
+})
+class MdIconColorTestApp {
+ ariaLabel: string = null;
+ iconName = '';
+ iconColor = 'primary';
+}
+
@Component({
selector: 'test-app',
template: `{{iconName}}`,
diff --git a/src/lib/icon/icon.ts b/src/lib/icon/icon.ts
index c17749aca31a..17ef7f6801ed 100644
--- a/src/lib/icon/icon.ts
+++ b/src/lib/icon/icon.ts
@@ -70,6 +70,8 @@ export class MdIconInvalidNameError extends MdError {
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
+ private _color: string;
+
@Input() svgSrc: string;
@Input() svgIcon: string;
@Input() fontSet: string;
@@ -78,14 +80,35 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
@Input('aria-label') hostAriaLabel: string = '';
+ @Input()
+ get color(): string {
+ return this._color;
+ }
+
+ set color(value: string) {
+ this._updateColor(value);
+ }
+
private _previousFontSetClass: string;
private _previousFontIconClass: string;
constructor(
- private _element: ElementRef,
+ private _elementRef: ElementRef,
private _renderer: Renderer,
private _mdIconRegistry: MdIconRegistry) { }
+ _updateColor(newColor: string) {
+ this._setElementColor(this._color, false);
+ this._setElementColor(newColor, true);
+ this._color = newColor;
+ }
+
+ _setElementColor(color: string, isAdd: boolean) {
+ if (color != null && color != '') {
+ this._renderer.setElementClass(this._elementRef.nativeElement, `md-${color}`, isAdd);
+ }
+ }
+
/**
* Splits an svgIcon binding value into its icon set and icon name components.
* Returns a 2-element array of [(icon set), (icon name)].
@@ -156,7 +179,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
private _updateAriaLabel() {
const ariaLabel = this._getAriaLabel();
if (ariaLabel) {
- this._renderer.setElementAttribute(this._element.nativeElement, 'aria-label', ariaLabel);
+ this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-label', ariaLabel);
}
}
@@ -174,7 +197,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
}
// The "content" of an SVG icon is not a useful label.
if (this._usingFontIcon()) {
- const text = this._element.nativeElement.textContent;
+ const text = this._elementRef.nativeElement.textContent;
if (text) {
return text;
}
@@ -188,7 +211,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
}
private _setSvgElement(svg: SVGElement) {
- const layoutElement = this._element.nativeElement;
+ const layoutElement = this._elementRef.nativeElement;
// Remove existing child nodes and add the new SVG element.
// We would use renderer.detachView(Array.from(layoutElement.childNodes)) here,
// but it fails in IE11: https://github.com/angular/angular/issues/6327
@@ -200,7 +223,7 @@ export class MdIcon implements OnChanges, OnInit, AfterViewChecked {
if (!this._usingFontIcon()) {
return;
}
- const elem = this._element.nativeElement;
+ const elem = this._elementRef.nativeElement;
const fontSetClass = this.fontSet ?
this._mdIconRegistry.classNameForFontAlias(this.fontSet) :
this._mdIconRegistry.getDefaultFontSetClass();