Skip to content

Commit 7fd1e12

Browse files
committed
fix(checkbox): no side margin if label has no content
* Remove side margin in checkbox if label has no content. * Use `checkboxNativeElement` instead of `checkboxDebugElement.nativeElement` in expect statements. * Fix typo. Closes #2011
1 parent 84323a8 commit 7fd1e12

File tree

4 files changed

+56
-12
lines changed

4 files changed

+56
-12
lines changed

src/lib/checkbox/checkbox.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<label class="md-checkbox-layout">
2-
<div class="md-checkbox-inner-container">
2+
<div class="md-checkbox-inner-container"
3+
[class.md-checkbox-inner-container-no-side-margin]="!hasLabel">
34
<input #input
45
class="md-checkbox-input md-visually-hidden" type="checkbox"
56
[id]="inputId"
@@ -36,7 +37,7 @@
3637
<div class="md-checkbox-mixedmark"></div>
3738
</div>
3839
</div>
39-
<span class="md-checkbox-label">
40+
<span class="md-checkbox-label" #labelWrapper>
4041
<ng-content></ng-content>
4142
</span>
4243
</label>

src/lib/checkbox/checkbox.scss

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ md-checkbox {
227227
right: auto;
228228
}
229229
}
230+
231+
&.md-checkbox-inner-container-no-side-margin {
232+
margin: {
233+
left: 0;
234+
right: 0;
235+
}
236+
}
230237
}
231238

232239
// TODO(kara): Remove this style when fixing vertical baseline
@@ -292,6 +299,13 @@ md-checkbox {
292299
right: $md-checkbox-item-spacing;
293300
}
294301
}
302+
303+
&.md-checkbox-inner-container-no-side-margin {
304+
margin: {
305+
left: 0;
306+
right: 0;
307+
}
308+
}
295309
}
296310
}
297311

src/lib/checkbox/checkbox.spec.ts

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe('MdCheckbox', () => {
3636
CheckboxWithNameAttribute,
3737
CheckboxWithChangeEvent,
3838
CheckboxWithFormControl,
39+
CheckboxWithoutLabel,
3940
],
4041
providers: [
4142
{provide: ViewportRuler, useClass: FakeViewportRuler},
@@ -181,7 +182,7 @@ describe('MdCheckbox', () => {
181182
expect(rippleElement).toBeFalsy('Expected a disabled checkbox not to have a ripple');
182183
});
183184

184-
it('should not toggle `checked` state upon interation while disabled', () => {
185+
it('should not toggle `checked` state upon interaction while disabled', () => {
185186
testComponent.isDisabled = true;
186187
fixture.detectChanges();
187188

@@ -308,28 +309,28 @@ describe('MdCheckbox', () => {
308309
it('should apply class based on color attribute', () => {
309310
testComponent.checkboxColor = 'primary';
310311
fixture.detectChanges();
311-
expect(checkboxDebugElement.nativeElement.classList.contains('md-primary')).toBe(true);
312+
expect(checkboxNativeElement.classList.contains('md-primary')).toBe(true);
312313

313314
testComponent.checkboxColor = 'accent';
314315
fixture.detectChanges();
315-
expect(checkboxDebugElement.nativeElement.classList.contains('md-accent')).toBe(true);
316+
expect(checkboxNativeElement.classList.contains('md-accent')).toBe(true);
316317
});
317318

318319
it('should should not clear previous defined classes', () => {
319-
checkboxDebugElement.nativeElement.classList.add('custom-class');
320+
checkboxNativeElement.classList.add('custom-class');
320321

321322
testComponent.checkboxColor = 'primary';
322323
fixture.detectChanges();
323324

324-
expect(checkboxDebugElement.nativeElement.classList.contains('md-primary')).toBe(true);
325-
expect(checkboxDebugElement.nativeElement.classList.contains('custom-class')).toBe(true);
325+
expect(checkboxNativeElement.classList.contains('md-primary')).toBe(true);
326+
expect(checkboxNativeElement.classList.contains('custom-class')).toBe(true);
326327

327328
testComponent.checkboxColor = 'accent';
328329
fixture.detectChanges();
329330

330-
expect(checkboxDebugElement.nativeElement.classList.contains('md-primary')).toBe(false);
331-
expect(checkboxDebugElement.nativeElement.classList.contains('md-accent')).toBe(true);
332-
expect(checkboxDebugElement.nativeElement.classList.contains('custom-class')).toBe(true);
331+
expect(checkboxNativeElement.classList.contains('md-primary')).toBe(false);
332+
expect(checkboxNativeElement.classList.contains('md-accent')).toBe(true);
333+
expect(checkboxNativeElement.classList.contains('custom-class')).toBe(true);
333334

334335
});
335336
});
@@ -588,7 +589,6 @@ describe('MdCheckbox', () => {
588589
});
589590
});
590591

591-
592592
describe('with form control', () => {
593593
let checkboxDebugElement: DebugElement;
594594
let checkboxInstance: MdCheckbox;
@@ -617,6 +617,22 @@ describe('MdCheckbox', () => {
617617
expect(checkboxInstance.disabled).toBe(false);
618618
});
619619
});
620+
621+
describe('without label', () => {
622+
let checkboxDebugElement: DebugElement;
623+
let checkboxNativeElement: HTMLElement;
624+
625+
it('should add a css class to inner-container to remove side margin', () => {
626+
fixture = TestBed.createComponent(CheckboxWithoutLabel);
627+
fixture.detectChanges();
628+
checkboxDebugElement = fixture.debugElement.query(By.directive(MdCheckbox));
629+
checkboxNativeElement = checkboxDebugElement.nativeElement;
630+
631+
let checkboxInnerContainerWithoutMarginCount = checkboxNativeElement
632+
.querySelectorAll('.md-checkbox-inner-container-no-side-margin').length;
633+
expect(checkboxInnerContainerWithoutMarginCount).toBe(1);
634+
});
635+
});
620636
});
621637

622638
/** Simple component for testing a single checkbox. */
@@ -724,3 +740,9 @@ class CheckboxWithChangeEvent {
724740
class CheckboxWithFormControl {
725741
formControl = new FormControl();
726742
}
743+
744+
/** Test component without label */
745+
@Component({
746+
template: `<md-checkbox></md-checkbox>`
747+
})
748+
class CheckboxWithoutLabel {}

src/lib/checkbox/checkbox.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ export class MdCheckbox implements ControlValueAccessor {
141141
/** The native `<input type=checkbox> element */
142142
@ViewChild('input') _inputElement: ElementRef;
143143

144+
@ViewChild('labelWrapper') _labelWrapper: ElementRef;
145+
146+
get hasLabel(): boolean {
147+
const labelWrapperTextContent = this._labelWrapper.nativeElement.textContent;
148+
return labelWrapperTextContent && labelWrapperTextContent.trim().length > 0;
149+
}
150+
144151
/** Called when the checkbox is blurred. Needed to properly implement ControlValueAccessor. */
145152
onTouched: () => any = () => {};
146153

0 commit comments

Comments
 (0)