fix(slide-toggle): remove side-margin if slide-toggle label is empty (#6881)

* Removes the side-margin of the actual indicator of the slide-toggle if the user label is empty (similar as in #4730)

Fixes #6868
This commit is contained in:
Paul Gschwendtner
2017-09-12 02:30:07 +02:00
committed by mmalerba
parent 2239e7daf0
commit a1ec81ab69
5 changed files with 85 additions and 4 deletions
+2 -1
View File
@@ -9,6 +9,7 @@
import {NgModule} from '@angular/core';
import {HAMMER_GESTURE_CONFIG} from '@angular/platform-browser';
import {PlatformModule} from '@angular/cdk/platform';
import {ObserversModule} from '@angular/cdk/observers';
import {MdSlideToggle} from './slide-toggle';
import {
FOCUS_ORIGIN_MONITOR_PROVIDER,
@@ -19,7 +20,7 @@ import {
@NgModule({
imports: [MdRippleModule, MdCommonModule, PlatformModule],
imports: [MdRippleModule, MdCommonModule, PlatformModule, ObserversModule],
exports: [MdSlideToggle, MdCommonModule],
declarations: [MdSlideToggle],
providers: [
+3 -2
View File
@@ -1,6 +1,7 @@
<label class="mat-slide-toggle-label" #label>
<div class="mat-slide-toggle-bar">
<div class="mat-slide-toggle-bar"
[class.mat-slide-toggle-bar-no-side-margin]="!labelContent.textContent || !labelContent.textContent.trim()">
<input #input class="mat-slide-toggle-input cdk-visually-hidden" type="checkbox"
[id]="inputId"
@@ -32,7 +33,7 @@
</div>
<span class="mat-slide-toggle-content">
<span class="mat-slide-toggle-content" #labelContent (cdkObserveContent)="_onLabelTextChange()">
<ng-content></ng-content>
</span>
</label>
+5
View File
@@ -74,6 +74,11 @@ $mat-slide-toggle-bar-track-width: $mat-slide-toggle-bar-width - $mat-slide-togg
}
}
.mat-slide-toggle-bar-no-side-margin {
margin-left: 0;
margin-right: 0;
}
// The thumb container is responsible for the dragging functionality.
// The container includes the visual thumb and the ripple container element.
.mat-slide-toggle-thumb-container {
+68 -1
View File
@@ -16,7 +16,11 @@ describe('MdSlideToggle without forms', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [MdSlideToggleModule],
declarations: [SlideToggleBasic, SlideToggleWithTabindexAttr],
declarations: [
SlideToggleBasic,
SlideToggleWithTabindexAttr,
SlideToggleWithoutLabel
],
providers: [
{provide: HAMMER_GESTURE_CONFIG, useFactory: () => gestureConfig = new TestGestureConfig()}
]
@@ -493,6 +497,62 @@ describe('MdSlideToggle without forms', () => {
expect(slideThumbContainer.classList).not.toContain('mat-dragging');
}));
});
describe('without label', () => {
let fixture: ComponentFixture<SlideToggleWithoutLabel>;
let testComponent: SlideToggleWithoutLabel;
let slideToggleElement: HTMLElement;
let slideToggleBarElement: HTMLElement;
beforeEach(() => {
fixture = TestBed.createComponent(SlideToggleWithoutLabel);
const slideToggleDebugEl = fixture.debugElement.query(By.directive(MdSlideToggle));
testComponent = fixture.componentInstance;
slideToggleElement = slideToggleDebugEl.nativeElement;
slideToggleBarElement = slideToggleDebugEl
.query(By.css('.mat-slide-toggle-bar')).nativeElement;
});
it('should remove margin for slide-toggle without a label', () => {
fixture.detectChanges();
expect(slideToggleBarElement.classList)
.toContain('mat-slide-toggle-bar-no-side-margin');
});
it('should not remove margin if initial label is set through binding', async(() => {
testComponent.label = 'Some content';
fixture.detectChanges();
expect(slideToggleBarElement.classList)
.not.toContain('mat-slide-toggle-bar-no-side-margin');
}));
it('should re-add margin if label is added asynchronously', async(() => {
fixture.detectChanges();
expect(slideToggleBarElement.classList)
.toContain('mat-slide-toggle-bar-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 slide-toggle.
setTimeout(() => {
// The MutationObserver from the cdkObserveContent directive detected the content change
// and notified the slide-toggle component. The slide-toggle then marks the component as
// dirty by calling `markForCheck()`. This needs to be reflected by the component template
// then.
fixture.detectChanges();
expect(slideToggleElement.classList)
.not.toContain('mat-slide-toggle-bar-no-side-margin');
}, 1);
}));
});
});
describe('MdSlideToggle with forms', () => {
@@ -806,3 +866,10 @@ class SlideToggleWithFormControl {
template: `<md-slide-toggle tabindex="5"></md-slide-toggle>`
})
class SlideToggleWithTabindexAttr {}
@Component({
template: `<md-slide-toggle>{{label}}</md-slide-toggle>`
})
class SlideToggleWithoutLabel {
label: string;
}
+7
View File
@@ -278,6 +278,13 @@ export class MdSlideToggle extends _MdSlideToggleMixinBase implements OnDestroy,
}
}
/** Method being called whenever the label text changes. */
_onLabelTextChange() {
// This method is getting called whenever the label of the slide-toggle changes.
// Since the slide-toggle uses the OnPush strategy we need to notify it about the change
// that has been recognized by the cdkObserveContent directive.
this._changeDetectorRef.markForCheck();
}
}
/**