/**
 * ToggleSwitch.tsx
 * Copyright: Microsoft 2017
 *
 * A simple toggle control built in ReactXP that allows users to
 * pick between two values.
 */ import * as React from 'react' ; import * as RX from 'reactxp' ; export interface ToggleSwitchProps extends RX . CommonProps { value ? : boolean ; onChange ? : ( newValue : boolean ) => void ; } const ANIMATION_DURATION = 250 ; const KNOB_LEFT_OFF = 2 ; const KNOB_LEFT_ON = 22 ; const _styles = { container : RX . Styles . createButtonStyle ( { flexDirection : 'row' , alignItems : 'center' } ) , toggleSwitch : RX . Styles . createViewStyle ( { flexDirection : 'row' , borderRadius : 15 , marginVertical : 8 , height : 30 , width : 50 , backgroundColor : '#ddd' } ) , toggleSwitchBackground : RX . Styles . createViewStyle ( { position : 'absolute' , top : 0 , bottom : 0 , left : 0 , right : 0 , borderRadius : 15 } ) , toggleKnob : RX . Styles . createViewStyle ( { top : 2 , height : 26 , width : 26 , borderRadius : 13 , backgroundColor : 'white' } ) } ; export class ToggleSwitch extends RX . Component < ToggleSwitchProps , RX . Stateless > { private _knobLeftAnimationValue : RX . Animated . Value ; private _knobLeftAnimationStyle : RX . Types . AnimatedViewStyleRuleSet ; private _toggleColorAnimationValue : RX . Animated . Value ; private _toggleColorAnimationStyle : RX . Types . AnimatedViewStyleRuleSet ; constructor ( props ) { super ( props ) ; this . _knobLeftAnimationValue = RX . Animated . createValue ( props . value ? KNOB_LEFT_ON : KNOB_LEFT_OFF ) ; this . _knobLeftAnimationStyle = RX . Styles . createAnimatedViewStyle ( { left : this . _knobLeftAnimationValue } ) ; this . _toggleColorAnimationValue = RX . Animated . createValue ( props . value ? 1 : 0 ) ; this . _toggleColorAnimationStyle = RX . Styles . createAnimatedTextInputStyle ( { backgroundColor : RX . Animated . interpolate ( this . _toggleColorAnimationValue , [ 0 , 1 ] , [ '#66f' , '#ddd' ] ) } ) ; } componentDidUpdate ( prevProps ) { if ( prevProps . value !== this . props . value ) { RX . Animated . parallel ( [ RX . Animated . timing ( this . _knobLeftAnimationValue , { duration : ANIMATION_DURATION , toValue : this . props . value ? KNOB_LEFT_ON : KNOB_LEFT_OFF , easing : RX . Animated . Easing . InOut ( ) } ) , RX . Animated . timing ( this . _toggleColorAnimationValue , { duration : ANIMATION_DURATION , toValue : this . props . value ? 1 : 0 , easing : RX . Animated . Easing . InOut ( ) } ) ] ) . start ( ) ; } } render ( ) { const backgroundStyle = [ _styles . toggleSwitchBackground , this . _toggleColorAnimationStyle ] ; const knobStyles = [ _styles . toggleKnob , this . _knobLeftAnimationStyle ] ; return ( < RX . Button style = { _styles . container } onPress = { this . _handleClick } > < RX . View style = { _styles . toggleSwitch } > < RX . Animated . View style = { backgroundStyle } /> < RX . Animated . View style = { knobStyles } / > < /RX.View> < /RX.Button>); } private _handleClick = ( e ) => { e . stopPropagation ( ) ; if ( this . props . onChange ) { this . props . onChange ( ! this . props . value ) ; } } ; }