@@ -134,7 +134,7 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
134134 event . stopPropagation ( ) ;
135135
136136 // Once a drag is currently in progress, we do not want to toggle the slide-toggle on a click.
137- if ( ! this . disabled && ! this . _slideRenderer . isDragging ( ) ) {
137+ if ( ! this . disabled && ! this . _slideRenderer . dragging ) {
138138 this . toggle ( ) ;
139139
140140 // Emit our custom change event if the native input emitted one.
@@ -255,22 +255,20 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
255255 }
256256
257257 _onDrag ( event : HammerInput ) {
258- if ( this . _slideRenderer . isDragging ( ) ) {
258+ if ( this . _slideRenderer . dragging ) {
259259 this . _slideRenderer . updateThumbPosition ( event . deltaX ) ;
260260 }
261261 }
262262
263263 _onDragEnd ( ) {
264- if ( ! this . _slideRenderer . isDragging ( ) ) {
265- return ;
266- }
267-
268- // Notice that we have to stop outside of the current event handler,
269- // because otherwise the click event will be fired and will reset the new checked variable.
270- setTimeout ( ( ) => {
271- this . checked = this . _slideRenderer . stopThumbDrag ( ) ;
264+ if ( this . _slideRenderer . dragging ) {
265+ this . checked = this . _slideRenderer . dragPercentage > 50 ;
272266 this . _emitChangeEvent ( ) ;
273- } , 0 ) ;
267+
268+ // The drag should be stopped outside of the current event handler, because otherwise the
269+ // click event will be fired before and will revert the drag change.
270+ setTimeout ( ( ) => this . _slideRenderer . stopThumbDrag ( ) ) ;
271+ }
274272 }
275273
276274}
@@ -280,56 +278,65 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
280278 */
281279class SlideToggleRenderer {
282280
281+ /** Reference to the thumb HTMLElement. */
283282 private _thumbEl : HTMLElement ;
283+
284+ /** Reference to the thumb bar HTMLElement. */
284285 private _thumbBarEl : HTMLElement ;
286+
287+ /** Width of the thumb bar of the slide-toggle. */
285288 private _thumbBarWidth : number ;
286- private _checked : boolean ;
287- private _percentage : number ;
289+
290+ /** Previous checked state before drag started. */
291+ private _previousChecked : boolean ;
292+
293+ /** Percentage of the thumb while dragging. */
294+ dragPercentage : number ;
295+
296+ /** Whether the thumb is currently being dragged. */
297+ dragging : boolean = false ;
288298
289299 constructor ( private _elementRef : ElementRef ) {
290300 this . _thumbEl = _elementRef . nativeElement . querySelector ( '.mat-slide-toggle-thumb-container' ) ;
291301 this . _thumbBarEl = _elementRef . nativeElement . querySelector ( '.mat-slide-toggle-bar' ) ;
292302 }
293303
294- /** Whether the slide-toggle is currently dragging. */
295- isDragging ( ) : boolean {
296- return ! ! this . _thumbBarWidth ;
297- }
298-
299-
300304 /** Initializes the drag of the slide-toggle. */
301305 startThumbDrag ( checked : boolean ) {
302- if ( ! this . isDragging ( ) ) {
303- this . _thumbBarWidth = this . _thumbBarEl . clientWidth - this . _thumbEl . clientWidth ;
304- this . _checked = checked ;
305- this . _thumbEl . classList . add ( 'mat-dragging' ) ;
306- }
306+ if ( this . dragging ) { return ; }
307+
308+ this . _thumbBarWidth = this . _thumbBarEl . clientWidth - this . _thumbEl . clientWidth ;
309+ this . _thumbEl . classList . add ( 'mat-dragging' ) ;
310+
311+ this . _previousChecked = checked ;
312+ this . dragging = true ;
307313 }
308314
309- /** Stops the current drag and returns the new checked value. */
315+ /** Resets the current drag and returns the new checked value. */
310316 stopThumbDrag ( ) : boolean {
311- if ( this . isDragging ( ) ) {
312- this . _thumbBarWidth = null ;
313- this . _thumbEl . classList . remove ( 'mat-dragging' ) ;
317+ if ( ! this . dragging ) { return ; }
314318
315- applyCssTransform ( this . _thumbEl , '' ) ;
319+ this . dragging = false ;
320+ this . _thumbEl . classList . remove ( 'mat-dragging' ) ;
316321
317- return this . _percentage > 50 ;
318- }
322+ // Reset the transform because the component will take care of the thumb position after drag.
323+ applyCssTransform ( this . _thumbEl , '' ) ;
324+
325+ return this . dragPercentage > 50 ;
319326 }
320327
321328 /** Updates the thumb containers position from the specified distance. */
322329 updateThumbPosition ( distance : number ) {
323- this . _percentage = this . _getThumbPercentage ( distance ) ;
324- applyCssTransform ( this . _thumbEl , `translate3d(${ this . _percentage } %, 0, 0)` ) ;
330+ this . dragPercentage = this . _getThumbPercentage ( distance ) ;
331+ applyCssTransform ( this . _thumbEl , `translate3d(${ this . dragPercentage } %, 0, 0)` ) ;
325332 }
326333
327334 /** Retrieves the percentage of thumb from the moved distance. */
328335 private _getThumbPercentage ( distance : number ) {
329336 let percentage = ( distance / this . _thumbBarWidth ) * 100 ;
330337
331338 // When the toggle was initially checked, then we have to start the drag at the end.
332- if ( this . _checked ) {
339+ if ( this . _previousChecked ) {
333340 percentage += 100 ;
334341 }
335342
0 commit comments