Skip to content
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

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

Merged
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
3 changes: 2 additions & 1 deletion src/lib/slide-toggle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -19,7 +20,7 @@ import {


@NgModule({
imports: [MdRippleModule, MdCommonModule, PlatformModule],
imports: [MdRippleModule, MdCommonModule, PlatformModule, ObserversModule],
exports: [MdSlideToggle, MdCommonModule],
declarations: [MdSlideToggle],
providers: [
Expand Down
5 changes: 3 additions & 2 deletions src/lib/slide-toggle/slide-toggle.html
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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 changes: 5 additions & 0 deletions src/lib/slide-toggle/slide-toggle.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
69 changes: 68 additions & 1 deletion src/lib/slide-toggle/slide-toggle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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()}
]
Expand Down Expand Up @@ -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', () => {
Expand Down Expand Up @@ -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 changes: 7 additions & 0 deletions src/lib/slide-toggle/slide-toggle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}

/**
Expand Down