Skip to content

Commit

Permalink
Updates
Browse files Browse the repository at this point in the history
  • Loading branch information
devversion committed May 23, 2017
1 parent d3f954f commit 6dfd6cc
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 16 deletions.
5 changes: 2 additions & 3 deletions src/lib/checkbox/checkbox.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<label class="mat-checkbox-layout" #label>
<div class="mat-checkbox-inner-container"
[class.mat-checkbox-inner-container-no-side-margin]="!_hasLabel">
[class.mat-checkbox-inner-container-no-side-margin]="!checkboxLabel.textContent.trim()">
<input #input
class="mat-checkbox-input cdk-visually-hidden" type="checkbox"
[id]="inputId"
Expand Down Expand Up @@ -35,8 +35,7 @@
<div class="mat-checkbox-mixedmark"></div>
</div>
</div>
<span class="mat-checkbox-label" #userLabel
(cdkObserveContent)="_hasLabel = !!userLabel.textContent.trim()">
<span class="mat-checkbox-label" #checkboxLabel (cdkObserveContent)="_onLabelTextChange()">
<ng-content></ng-content>
</span>
</label>
60 changes: 50 additions & 10 deletions src/lib/checkbox/checkbox.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,19 +765,57 @@ describe('MdCheckbox', () => {
});

describe('without label', () => {
let checkboxDebugElement: DebugElement;
let checkboxNativeElement: HTMLElement;
let testComponent: CheckboxWithoutLabel;
let checkboxElement: HTMLElement;
let checkboxInnerContainer: HTMLElement;

it('should add a css class to inner-container to remove side margin', () => {
beforeEach(() => {
fixture = TestBed.createComponent(CheckboxWithoutLabel);

const checkboxDebugEl = fixture.debugElement.query(By.directive(MdCheckbox));

testComponent = fixture.componentInstance;
checkboxElement = checkboxDebugEl.nativeElement;
checkboxInnerContainer = checkboxDebugEl
.query(By.css('.mat-checkbox-inner-container')).nativeElement;
});

it('should remove margin for checkbox without a label', () => {
fixture.detectChanges();
checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
checkboxNativeElement = checkboxDebugElement.nativeElement;

let checkboxInnerContainerWithoutMarginCount = checkboxNativeElement
.querySelectorAll('.mat-checkbox-inner-container-no-side-margin').length;
expect(checkboxInnerContainerWithoutMarginCount).toBe(1);
expect(checkboxInnerContainer.classList)
.toContain('mat-checkbox-inner-container-no-side-margin');
});

it('should not remove margin if initial label is set through binding', async(() => {
testComponent.label = 'Some content';
fixture.detectChanges();

expect(checkboxInnerContainer.classList)
.not.toContain('mat-checkbox-inner-container-no-side-margin');
}));

it('should re-add margin if label is added asynchronously', async(() => {
fixture.detectChanges();

expect(checkboxInnerContainer.classList)
.toContain('mat-checkbox-inner-container-no-side-margin');

testComponent.label = 'Some content';
fixture.detectChanges();

// Wait for the MutationObserver to detect the content change and for the cdkObserveContent
// to emit the change event to the checkbox.
setTimeout(() => {
// The MutationObserver from the cdkObserveContent directive detected the content change
// and notified the checkbox component. The checkbox then marks the component as dirty
// by calling `markForCheck()`. This needs to be reflected by the component template then.
fixture.detectChanges();

expect(checkboxInnerContainer.classList)
.not.toContain('mat-checkbox-inner-container-no-side-margin');
}, 1);
}));
});
});

Expand Down Expand Up @@ -891,6 +929,8 @@ class CheckboxWithFormControl {

/** Test component without label */
@Component({
template: `<md-checkbox></md-checkbox>`
template: `<md-checkbox>{{ label }}</md-checkbox>`
})
class CheckboxWithoutLabel {}
class CheckboxWithoutLabel {
label: string;
}
11 changes: 8 additions & 3 deletions src/lib/checkbox/checkbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,6 @@ export class MdCheckbox extends _MdCheckboxMixinBase
/** Called when the checkbox is blurred. Needed to properly implement ControlValueAccessor. */
@ViewChild(MdRipple) _ripple: MdRipple;

/** Whether the checkbox has a label set or not. */
_hasLabel: boolean = false;

/**
* Called when the checkbox is blurred. Needed to properly implement ControlValueAccessor.
* @docs-private
Expand Down Expand Up @@ -267,6 +264,14 @@ export class MdCheckbox extends _MdCheckboxMixinBase
return this.disableRipple || this.disabled;
}

/** Method being called whenever the label text changes. */
_onLabelTextChange() {
// This method is getting called whenever the label of the checkbox changes.
// Since the checkbox uses the OnPush strategy we need to notify it about the change
// that has been recognized by the cdkObserveContent directive.
this._changeDetectorRef.markForCheck();
}

/**
* Sets the model value. Implemented as part of ControlValueAccessor.
* @param value Value to be set to the model.
Expand Down

0 comments on commit 6dfd6cc

Please sign in to comment.