Skip to content

feat(md-icon theming): added color attribute to md-icon for icon them… #1896

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 17, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/demo-app/icon/icon-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
<md-icon>home</md-icon>
</p>

<p>
Using a theme:
<md-icon color="primary">home</md-icon>
<md-icon color="accent">home</md-icon>
<md-icon color="warn">home</md-icon>
</p>

<p>
Custom icon font and CSS:
<md-icon fontSet="fontawesome" fontIcon="fa-birthday-cake"></md-icon>
Expand Down
4 changes: 0 additions & 4 deletions src/demo-app/icon/icon-demo.scss
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.demo-icon md-icon {
color: purple;
}

.demo-icon md-icon.green {
color: green;
}
23 changes: 21 additions & 2 deletions src/lib/icon/_icon-theme.scss
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
22 changes: 22 additions & 0 deletions src/lib/icon/icon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ describe('MdIcon', () => {
TestBed.configureTestingModule({
imports: [MdIconModule.forRoot()],
declarations: [
MdIconColorTestApp,
MdIconLigatureTestApp,
MdIconLigatureWithAriaBindingTestApp,
MdIconCustomFontCssTestApp,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -413,6 +425,16 @@ class MdIconLigatureTestApp {
iconName = '';
}

@Component({
selector: 'test-app',
template: `<md-icon [color]="iconColor">{{iconName}}</md-icon>`,
})
class MdIconColorTestApp {
ariaLabel: string = null;
iconName = '';
iconColor = 'primary';
}

@Component({
selector: 'test-app',
template: `<md-icon [aria-label]="ariaLabel" [alt]="altText">{{iconName}}</md-icon>`,
Expand Down
33 changes: 28 additions & 5 deletions src/lib/icon/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)].
Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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;
}
Expand All @@ -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
Expand All @@ -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();
Expand Down