Skip to content

fix(checkbox): not handling unknown color palette #18467

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 1 commit into from
Aug 21, 2020
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
1 change: 1 addition & 0 deletions src/material-experimental/mdc-checkbox/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ ng_test_library(
"//src/cdk/testing/private",
"//src/cdk/testing/testbed",
"//src/material/checkbox",
"//src/material/core",
"@npm//@angular/forms",
"@npm//@angular/platform-browser",
],
Expand Down
10 changes: 9 additions & 1 deletion src/material-experimental/mdc-checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
flushMicrotasks,
TestBed,
} from '@angular/core/testing';
import {ThemePalette} from '@angular/material/core';
import {FormControl, FormsModule, NgModel, ReactiveFormsModule} from '@angular/forms';
import {By} from '@angular/platform-browser';
import {
Expand Down Expand Up @@ -467,6 +468,13 @@ describe('MDC-based MatCheckbox', () => {
expect(checkboxNativeElement.classList.contains('mat-accent')).toBe(true);
expect(checkboxNativeElement.classList.contains('custom-class')).toBe(true);
}));

it('should default to accent if no color is passed in', fakeAsync(() => {
testComponent.checkboxColor = undefined;
fixture.detectChanges();
expect(checkboxNativeElement.classList).toContain('mat-accent');
}));

});

describe(`when MAT_CHECKBOX_CLICK_ACTION is set`, () => {
Expand Down Expand Up @@ -1078,7 +1086,7 @@ class SingleCheckbox {
parentElementClicked: boolean = false;
parentElementKeyedUp: boolean = false;
checkboxId: string|null = 'simple-check';
checkboxColor: string = 'primary';
checkboxColor: ThemePalette = 'primary';
checkboxValue: string = 'single_checkbox';

onCheckboxClick: (event?: Event) => void = () => {};
Expand Down
44 changes: 28 additions & 16 deletions src/material-experimental/mdc-checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ import {
MAT_CHECKBOX_DEFAULT_OPTIONS,
MatCheckboxClickAction, MatCheckboxDefaultOptions
} from '@angular/material/checkbox';
import {ThemePalette, RippleAnimationConfig} from '@angular/material/core';
import {
ThemePalette,
RippleAnimationConfig,
CanColorCtor,
CanDisableCtor,
mixinColor,
mixinDisabled,
CanColor,
CanDisable,
} from '@angular/material/core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {MDCCheckboxAdapter, MDCCheckboxFoundation} from '@material/checkbox';
import {numbers} from '@material/ripple';
Expand All @@ -51,6 +60,18 @@ export class MatCheckboxChange {
checked: boolean;
}

// Boilerplate for applying mixins to MatCheckbox.
/** @docs-private */
class MatCheckboxBase {
constructor(public _elementRef: ElementRef) {}
}
const _MatCheckboxMixinBase:
CanColorCtor &
CanDisableCtor &
typeof MatCheckboxBase =
mixinColor(mixinDisabled(MatCheckboxBase));


/** Configuration for the ripple animation. */
const RIPPLE_ANIMATION_CONFIG: RippleAnimationConfig = {
enterDuration: numbers.DEACTIVATION_TIMEOUT_MS,
Expand All @@ -61,12 +82,10 @@ const RIPPLE_ANIMATION_CONFIG: RippleAnimationConfig = {
selector: 'mat-checkbox',
templateUrl: 'checkbox.html',
styleUrls: ['checkbox.css'],
inputs: ['color', 'disabled'],
host: {
'class': 'mat-mdc-checkbox',
'[attr.tabindex]': 'null',
'[class.mat-primary]': 'color == "primary"',
'[class.mat-accent]': 'color == "accent"',
'[class.mat-warn]': 'color == "warn"',
'[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`,
'[class.mdc-checkbox--disabled]': 'disabled',
'[id]': 'id',
Expand All @@ -76,7 +95,8 @@ const RIPPLE_ANIMATION_CONFIG: RippleAnimationConfig = {
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class MatCheckbox implements AfterViewInit, OnDestroy, ControlValueAccessor {
export class MatCheckbox extends _MatCheckboxMixinBase implements AfterViewInit, OnDestroy,
ControlValueAccessor, CanColor, CanDisable {
/**
* The `aria-label` attribute to use for the input element. In most cases, `aria-labelledby` will
* take precedence so this may be omitted.
Expand Down Expand Up @@ -135,16 +155,6 @@ export class MatCheckbox implements AfterViewInit, OnDestroy, ControlValueAccess
}
private _indeterminate = false;

/** Whether the checkbox is disabled. */
@Input()
get disabled(): boolean {
return this._disabled;
}
set disabled(disabled) {
this._disabled = coerceBooleanProperty(disabled);
}
private _disabled = false;

/** Whether the checkbox is required. */
@Input()
get required(): boolean {
Expand Down Expand Up @@ -235,6 +245,7 @@ export class MatCheckbox implements AfterViewInit, OnDestroy, ControlValueAccess

constructor(
private _changeDetectorRef: ChangeDetectorRef,
elementRef: ElementRef<HTMLElement>,
@Attribute('tabindex') tabIndex: string,
/**
* @deprecated `_clickAction` parameter to be removed, use
Expand All @@ -245,6 +256,7 @@ export class MatCheckbox implements AfterViewInit, OnDestroy, ControlValueAccess
@Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string,
@Optional() @Inject(MAT_CHECKBOX_DEFAULT_OPTIONS)
private _options?: MatCheckboxDefaultOptions) {
super(elementRef);
// Note: We don't need to set up the MDCFormFieldFoundation. Its only purpose is to manage the
// ripple, which we do ourselves instead.
this.tabIndex = parseInt(tabIndex) || 0;
Expand All @@ -253,7 +265,7 @@ export class MatCheckbox implements AfterViewInit, OnDestroy, ControlValueAccess
this._options = this._options || {};

if (this._options.color) {
this.color = this._options.color;
this.color = this.defaultColor = this._options.color;
}

// @breaking-change 10.0.0: Remove this after the `_clickAction` parameter is removed as an
Expand Down
6 changes: 6 additions & 0 deletions src/material/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -465,8 +465,14 @@ describe('MatCheckbox', () => {
expect(checkboxNativeElement.classList.contains('mat-primary')).toBe(false);
expect(checkboxNativeElement.classList.contains('mat-accent')).toBe(true);
expect(checkboxNativeElement.classList.contains('custom-class')).toBe(true);
});

it('should default to accent if no color is passed in', () => {
testComponent.checkboxColor = undefined;
fixture.detectChanges();
expect(checkboxNativeElement.classList).toContain('mat-accent');
});

});

describe('state transition css classes', () => {
Expand Down