Skip to content

Commit 3779395

Browse files
devversionandrewseguin
authored andcommitted
refactor: replace color getters and setters with mixin (#4974)
* refactor: replace color getters and setters with mixin * Replaces the color getters and setters with a Mixin function (similar as for the disabled property) * This should reduce payload and also should make it way easier to maintain the color functionality. * Address comments * Updates
1 parent 28d2ddd commit 3779395

File tree

14 files changed

+268
-252
lines changed

14 files changed

+268
-252
lines changed

src/lib/button/button.spec.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ describe('MdButton', () => {
3838
fixture.detectChanges();
3939
expect(buttonDebugElement.nativeElement.classList.contains('mat-accent')).toBe(true);
4040
expect(aDebugElement.nativeElement.classList.contains('mat-accent')).toBe(true);
41+
42+
testComponent.buttonColor = null;
43+
fixture.detectChanges();
44+
45+
expect(buttonDebugElement.nativeElement.classList).not.toContain('mat-accent');
46+
expect(aDebugElement.nativeElement.classList).not.toContain('mat-accent');
4147
});
4248

4349
it('should should not clear previous defined classes', () => {
@@ -59,7 +65,6 @@ describe('MdButton', () => {
5965
expect(buttonDebugElement.nativeElement.classList.contains('mat-primary')).toBe(false);
6066
expect(buttonDebugElement.nativeElement.classList.contains('mat-accent')).toBe(true);
6167
expect(buttonDebugElement.nativeElement.classList.contains('custom-class')).toBe(true);
62-
6368
});
6469

6570
// Regular button tests

src/lib/button/button.ts

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
} from '@angular/core';
1212
import {coerceBooleanProperty, FocusOriginMonitor, Platform} from '../core';
1313
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
14+
import {CanColor, mixinColor} from '../core/common-behaviors/color';
1415

1516

1617
// TODO(kara): Convert attribute selectors to classes when attr maps become available
@@ -71,8 +72,10 @@ export class MdMiniFabCssMatStyler {}
7172

7273

7374
// Boilerplate for applying mixins to MdButton.
74-
export class MdButtonBase { }
75-
export const _MdButtonMixinBase = mixinDisabled(MdButtonBase);
75+
export class MdButtonBase {
76+
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
77+
}
78+
export const _MdButtonMixinBase = mixinColor(mixinDisabled(MdButtonBase));
7679

7780

7881
/**
@@ -89,13 +92,11 @@ export const _MdButtonMixinBase = mixinDisabled(MdButtonBase);
8992
},
9093
templateUrl: 'button.html',
9194
styleUrls: ['button.css'],
92-
inputs: ['disabled'],
95+
inputs: ['disabled', 'color'],
9396
encapsulation: ViewEncapsulation.None,
9497
changeDetection: ChangeDetectionStrategy.OnPush,
9598
})
96-
export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisable {
97-
private _color: string;
98-
99+
export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisable, CanColor {
99100
/** Whether the button is round. */
100101
_isRoundButton: boolean = this._hasAttributeWithPrefix('fab', 'mini-fab');
101102

@@ -110,40 +111,18 @@ export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisabl
110111
get disableRipple() { return this._disableRipple; }
111112
set disableRipple(v) { this._disableRipple = coerceBooleanProperty(v); }
112113

113-
constructor(
114-
private _elementRef: ElementRef,
115-
private _renderer: Renderer2,
116-
private _platform: Platform,
117-
private _focusOriginMonitor: FocusOriginMonitor) {
118-
super();
114+
constructor(renderer: Renderer2,
115+
elementRef: ElementRef,
116+
private _platform: Platform,
117+
private _focusOriginMonitor: FocusOriginMonitor) {
118+
super(renderer, elementRef);
119119
this._focusOriginMonitor.monitor(this._elementRef.nativeElement, this._renderer, true);
120120
}
121121

122122
ngOnDestroy() {
123123
this._focusOriginMonitor.stopMonitoring(this._elementRef.nativeElement);
124124
}
125125

126-
/** The color of the button. Can be `primary`, `accent`, or `warn`. */
127-
@Input()
128-
get color(): string { return this._color; }
129-
set color(value: string) { this._updateColor(value); }
130-
131-
_updateColor(newColor: string) {
132-
this._setElementColor(this._color, false);
133-
this._setElementColor(newColor, true);
134-
this._color = newColor;
135-
}
136-
137-
_setElementColor(color: string, isAdd: boolean) {
138-
if (color != null && color != '') {
139-
if (isAdd) {
140-
this._renderer.addClass(this._getHostElement(), `mat-${color}`);
141-
} else {
142-
this._renderer.removeClass(this._getHostElement(), `mat-${color}`);
143-
}
144-
}
145-
}
146-
147126
/** Focuses the button. */
148127
focus(): void {
149128
this._getHostElement().focus();
@@ -189,18 +168,18 @@ export class MdButton extends _MdButtonMixinBase implements OnDestroy, CanDisabl
189168
'[attr.aria-disabled]': '_isAriaDisabled',
190169
'(click)': '_haltDisabledEvents($event)',
191170
},
192-
inputs: ['disabled'],
171+
inputs: ['disabled', 'color'],
193172
templateUrl: 'button.html',
194173
styleUrls: ['button.css'],
195174
encapsulation: ViewEncapsulation.None
196175
})
197176
export class MdAnchor extends MdButton {
198177
constructor(
199-
elementRef: ElementRef,
200-
renderer: Renderer2,
201178
platform: Platform,
202-
focusOriginMonitor: FocusOriginMonitor) {
203-
super(elementRef, renderer, platform, focusOriginMonitor);
179+
focusOriginMonitor: FocusOriginMonitor,
180+
elementRef: ElementRef,
181+
renderer: Renderer2) {
182+
super(renderer, elementRef, platform, focusOriginMonitor);
204183
}
205184

206185
/** @docs-private */

src/lib/checkbox/checkbox.ts

Lines changed: 10 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
1717
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
1818
import {FocusOrigin, FocusOriginMonitor, MdRipple, RippleRef} from '../core';
1919
import {mixinDisabled, CanDisable} from '../core/common-behaviors/disabled';
20+
import {CanColor, mixinColor} from '../core/common-behaviors/color';
2021

2122

2223
/** Monotonically increasing integer used to auto-generate unique ids for checkbox components. */
@@ -57,8 +58,10 @@ export class MdCheckboxChange {
5758
}
5859

5960
// Boilerplate for applying mixins to MdCheckbox.
60-
export class MdCheckboxBase { }
61-
export const _MdCheckboxMixinBase = mixinDisabled(MdCheckboxBase);
61+
export class MdCheckboxBase {
62+
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
63+
}
64+
export const _MdCheckboxMixinBase = mixinColor(mixinDisabled(MdCheckboxBase), 'accent');
6265

6366

6467
/**
@@ -82,12 +85,12 @@ export const _MdCheckboxMixinBase = mixinDisabled(MdCheckboxBase);
8285
'[class.mat-checkbox-label-before]': 'labelPosition == "before"',
8386
},
8487
providers: [MD_CHECKBOX_CONTROL_VALUE_ACCESSOR],
85-
inputs: ['disabled'],
88+
inputs: ['disabled', 'color'],
8689
encapsulation: ViewEncapsulation.None,
8790
changeDetection: ChangeDetectionStrategy.OnPush
8891
})
8992
export class MdCheckbox extends _MdCheckboxMixinBase
90-
implements ControlValueAccessor, AfterViewInit, OnDestroy, CanDisable {
93+
implements ControlValueAccessor, AfterViewInit, OnDestroy, CanColor, CanDisable {
9194
/**
9295
* Attached to the aria-label attribute of the host element. In most cases, arial-labelledby will
9396
* take precedence so this may be omitted.
@@ -183,19 +186,16 @@ export class MdCheckbox extends _MdCheckboxMixinBase
183186

184187
private _indeterminate: boolean = false;
185188

186-
private _color: string;
187-
188189
private _controlValueAccessorChangeFn: (value: any) => void = (value) => {};
189190

190191
/** Reference to the focused state ripple. */
191192
private _focusRipple: RippleRef;
192193

193-
constructor(private _renderer: Renderer2,
194-
private _elementRef: ElementRef,
194+
constructor(renderer: Renderer2,
195+
elementRef: ElementRef,
195196
private _changeDetectorRef: ChangeDetectorRef,
196197
private _focusOriginMonitor: FocusOriginMonitor) {
197-
super();
198-
this.color = 'accent';
198+
super(renderer, elementRef);
199199
}
200200

201201
ngAfterViewInit() {
@@ -247,27 +247,6 @@ export class MdCheckbox extends _MdCheckboxMixinBase
247247
}
248248
}
249249

250-
/** The color of the button. Can be `primary`, `accent`, or `warn`. */
251-
@Input()
252-
get color(): string { return this._color; }
253-
set color(value: string) { this._updateColor(value); }
254-
255-
_updateColor(newColor: string) {
256-
this._setElementColor(this._color, false);
257-
this._setElementColor(newColor, true);
258-
this._color = newColor;
259-
}
260-
261-
_setElementColor(color: string, isAdd: boolean) {
262-
if (color != null && color != '') {
263-
if (isAdd) {
264-
this._renderer.addClass(this._elementRef.nativeElement, `mat-${color}`);
265-
} else {
266-
this._renderer.removeClass(this._elementRef.nativeElement, `mat-${color}`);
267-
}
268-
}
269-
}
270-
271250
_isRippleDisabled() {
272251
return this.disableRipple || this.disabled;
273252
}

src/lib/chips/chip.ts

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,27 @@ import {
1111

1212
import {Focusable} from '../core/a11y/focus-key-manager';
1313
import {coerceBooleanProperty} from '../core/coercion/boolean-property';
14+
import {CanColor, mixinColor} from '../core/common-behaviors/color';
1415

1516
export interface MdChipEvent {
1617
chip: MdChip;
1718
}
1819

20+
// Boilerplate for applying mixins to MdChip.
21+
export class MdChipBase {
22+
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
23+
}
24+
export const _MdChipMixinBase = mixinColor(MdChipBase, 'primary');
25+
26+
1927
/**
2028
* Material design styled Chip component. Used inside the MdChipList component.
2129
*/
2230
@Component({
2331
selector: `md-basic-chip, [md-basic-chip], md-chip, [md-chip],
2432
mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]`,
2533
template: `<ng-content></ng-content>`,
34+
inputs: ['color'],
2635
host: {
2736
'[class.mat-chip]': 'true',
2837
'tabindex': '-1',
@@ -35,17 +44,14 @@ export interface MdChipEvent {
3544
'(click)': '_handleClick($event)'
3645
}
3746
})
38-
export class MdChip implements Focusable, OnInit, OnDestroy {
47+
export class MdChip extends _MdChipMixinBase implements Focusable, OnInit, OnDestroy, CanColor {
3948

4049
/** Whether or not the chip is disabled. Disabled chips cannot be focused. */
4150
protected _disabled: boolean = null;
4251

4352
/** Whether or not the chip is selected. */
4453
protected _selected: boolean = false;
4554

46-
/** The palette color of selected chips. */
47-
protected _color: string = 'primary';
48-
4955
/** Emitted when the chip is focused. */
5056
onFocus = new EventEmitter<MdChipEvent>();
5157

@@ -58,11 +64,12 @@ export class MdChip implements Focusable, OnInit, OnDestroy {
5864
/** Emitted when the chip is destroyed. */
5965
@Output() destroy = new EventEmitter<MdChipEvent>();
6066

61-
constructor(protected _renderer: Renderer2, protected _elementRef: ElementRef) { }
67+
constructor(renderer: Renderer2, elementRef: ElementRef) {
68+
super(renderer, elementRef);
69+
}
6270

6371
ngOnInit(): void {
6472
this._addDefaultCSSClass();
65-
this._updateColor(this._color);
6673
}
6774

6875
ngOnDestroy(): void {
@@ -108,15 +115,6 @@ export class MdChip implements Focusable, OnInit, OnDestroy {
108115
return this.selected;
109116
}
110117

111-
/** The color of the chip. Can be `primary`, `accent`, or `warn`. */
112-
@Input() get color(): string {
113-
return this._color;
114-
}
115-
116-
set color(value: string) {
117-
this._updateColor(value);
118-
}
119-
120118
/** Allows for programmatic focusing of the chip. */
121119
focus(): void {
122120
this._elementRef.nativeElement.focus();
@@ -147,22 +145,4 @@ export class MdChip implements Focusable, OnInit, OnDestroy {
147145
this._renderer.addClass(el, 'mat-basic-chip');
148146
}
149147
}
150-
151-
/** Updates the private _color variable and the native element. */
152-
private _updateColor(newColor: string) {
153-
this._setElementColor(this._color, false);
154-
this._setElementColor(newColor, true);
155-
this._color = newColor;
156-
}
157-
158-
/** Sets the mat-color on the native element. */
159-
private _setElementColor(color: string, isAdd: boolean) {
160-
if (color != null && color != '') {
161-
if (isAdd) {
162-
this._renderer.addClass(this._elementRef.nativeElement, `mat-${color}`);
163-
} else {
164-
this._renderer.removeClass(this._elementRef.nativeElement, `mat-${color}`);
165-
}
166-
}
167-
}
168148
}

0 commit comments

Comments
 (0)