@@ -134,7 +134,7 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
134
134
event . stopPropagation ( ) ;
135
135
136
136
// 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 ) {
138
138
this . toggle ( ) ;
139
139
140
140
// Emit our custom change event if the native input emitted one.
@@ -255,22 +255,20 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
255
255
}
256
256
257
257
_onDrag ( event : HammerInput ) {
258
- if ( this . _slideRenderer . isDragging ( ) ) {
258
+ if ( this . _slideRenderer . dragging ) {
259
259
this . _slideRenderer . updateThumbPosition ( event . deltaX ) ;
260
260
}
261
261
}
262
262
263
263
_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 ;
272
266
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
+ }
274
272
}
275
273
276
274
}
@@ -280,56 +278,65 @@ export class MdSlideToggle implements AfterContentInit, ControlValueAccessor {
280
278
*/
281
279
class SlideToggleRenderer {
282
280
281
+ /** Reference to the thumb HTMLElement. */
283
282
private _thumbEl : HTMLElement ;
283
+
284
+ /** Reference to the thumb bar HTMLElement. */
284
285
private _thumbBarEl : HTMLElement ;
286
+
287
+ /** Width of the thumb bar of the slide-toggle. */
285
288
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 ;
288
298
289
299
constructor ( private _elementRef : ElementRef ) {
290
300
this . _thumbEl = _elementRef . nativeElement . querySelector ( '.mat-slide-toggle-thumb-container' ) ;
291
301
this . _thumbBarEl = _elementRef . nativeElement . querySelector ( '.mat-slide-toggle-bar' ) ;
292
302
}
293
303
294
- /** Whether the slide-toggle is currently dragging. */
295
- isDragging ( ) : boolean {
296
- return ! ! this . _thumbBarWidth ;
297
- }
298
-
299
-
300
304
/** Initializes the drag of the slide-toggle. */
301
305
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 ;
307
313
}
308
314
309
- /** Stops the current drag and returns the new checked value. */
315
+ /** Resets the current drag and returns the new checked value. */
310
316
stopThumbDrag ( ) : boolean {
311
- if ( this . isDragging ( ) ) {
312
- this . _thumbBarWidth = null ;
313
- this . _thumbEl . classList . remove ( 'mat-dragging' ) ;
317
+ if ( ! this . dragging ) { return ; }
314
318
315
- applyCssTransform ( this . _thumbEl , '' ) ;
319
+ this . dragging = false ;
320
+ this . _thumbEl . classList . remove ( 'mat-dragging' ) ;
316
321
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 ;
319
326
}
320
327
321
328
/** Updates the thumb containers position from the specified distance. */
322
329
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)` ) ;
325
332
}
326
333
327
334
/** Retrieves the percentage of thumb from the moved distance. */
328
335
private _getThumbPercentage ( distance : number ) {
329
336
let percentage = ( distance / this . _thumbBarWidth ) * 100 ;
330
337
331
338
// When the toggle was initially checked, then we have to start the drag at the end.
332
- if ( this . _checked ) {
339
+ if ( this . _previousChecked ) {
333
340
percentage += 100 ;
334
341
}
335
342
0 commit comments