diff --git a/src/lib/slide-toggle/slide-toggle.scss b/src/lib/slide-toggle/slide-toggle.scss index 28e6ca24a191..6859b01bc02e 100644 --- a/src/lib/slide-toggle/slide-toggle.scss +++ b/src/lib/slide-toggle/slide-toggle.scss @@ -66,6 +66,12 @@ md-slide-toggle { cursor: pointer; } +/* If the label should be placed before the thumb then we just change the orders. */ +.md-slide-toggle-label-before { + .md-slide-toggle-label { order: 1; } + .md-slide-toggle-container { order: 2; } +} + // Container for the composition of the slide-toggle / switch indicator. .md-slide-toggle-container { cursor: grab; @@ -73,10 +79,17 @@ md-slide-toggle { height: $md-slide-toggle-height; position: relative; +} +/* Apply the margin for slide-toggles and revert it for RTL toggles with labelPosition before. */ +[dir="rtl"] .md-slide-toggle-label-before .md-slide-toggle-container, .md-slide-toggle-container { margin-right: $md-slide-toggle-spacing; + margin-left: 0; +} - [dir='rtl'] & { +/* Switch the margins in RTL mode and also switch it if the labelPosition is set to before. */ +[dir='rtl'], .md-slide-toggle-label-before { + .md-slide-toggle-container { margin-left: $md-slide-toggle-spacing; margin-right: 0; } diff --git a/src/lib/slide-toggle/slide-toggle.spec.ts b/src/lib/slide-toggle/slide-toggle.spec.ts index c554806b1878..d956cfda2cbb 100644 --- a/src/lib/slide-toggle/slide-toggle.spec.ts +++ b/src/lib/slide-toggle/slide-toggle.spec.ts @@ -357,6 +357,16 @@ describe('MdSlideToggle', () => { expect(document.activeElement).toBe(inputElement); expect(slideToggleElement.classList).toContain('md-slide-toggle-focused'); }); + + it('should set a element class if labelPosition is set to before', () => { + expect(slideToggleElement.classList).not.toContain('md-slide-toggle-label-before'); + + testComponent.labelPosition = 'before'; + fixture.detectChanges(); + + expect(slideToggleElement.classList).toContain('md-slide-toggle-label-before'); + }); + }); describe('custom template', () => { @@ -584,6 +594,7 @@ function dispatchFocusChangeEvent(eventName: string, element: HTMLElement): void [aria-label]="slideLabel" [aria-labelledby]="slideLabelledBy" [tabIndex]="slideTabindex" + [labelPosition]="labelPosition" (change)="onSlideChange($event)" (click)="onSlideClick($event)"> @@ -603,6 +614,7 @@ class SlideToggleTestApp { slideLabelledBy: string; slideTabindex: number; lastEvent: MdSlideToggleChange; + labelPosition: string; onSlideClick(event: Event) {} onSlideChange(event: MdSlideToggleChange) { diff --git a/src/lib/slide-toggle/slide-toggle.ts b/src/lib/slide-toggle/slide-toggle.ts index 331ef3378895..5030bc51d4c3 100644 --- a/src/lib/slide-toggle/slide-toggle.ts +++ b/src/lib/slide-toggle/slide-toggle.ts @@ -51,6 +51,7 @@ let nextId = 0; '[class.md-disabled]': 'disabled', // This md-slide-toggle prefix will change, once the temporary ripple is removed. '[class.md-slide-toggle-focused]': '_hasFocus', + '[class.md-slide-toggle-label-before]': 'labelPosition == "before"', '(mousedown)': '_setMousedown()' }, templateUrl: 'slide-toggle.html', @@ -85,6 +86,9 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor { /** Used to specify the tabIndex value for the underlying input element. */ @Input() tabIndex: number = 0; + /** Whether the label should appear after or before the checkbox. Defaults to 'after' */ + @Input() labelPosition: 'before' | 'after' = 'after'; + /** Used to set the aria-label attribute on the underlying input element. */ @Input('aria-label') ariaLabel: string = null;