Last active
January 30, 2018 00:46
-
-
Save MovingGifts/c32a900d7da08495e7983608d549541b to your computer and use it in GitHub Desktop.
ToggleSwitch vs ProgressIndicator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This file demonstrates a basic ReactXP app. | |
*/ | |
import React from 'react'; | |
import RX from 'reactxp'; | |
import ToggleSwitch from './ToggleSwitch'; | |
const styles = { | |
container: RX.Styles.createViewStyle({ | |
padding: 16, | |
justifyContent: 'center', | |
alignItems: 'center' | |
}) | |
}; | |
export default class SecondPanel extends RX.Component { | |
constructor(props) { | |
super(props); | |
this._onChangeToggle = this._onChangeToggle.bind(this); | |
this.state = { | |
toggleValue: true | |
}; | |
} | |
render() { | |
return ( | |
<RX.View style={ styles.container }> | |
<ToggleSwitch | |
value={ this.state.toggleValue } | |
onChange={ this._onChangeToggle } | |
/> | |
</RX.View> | |
); | |
} | |
// Note that we define this as a variable rather than a normal method. Using this | |
// method, we prebind the method to this component instance. This prebinding ensures | |
// that each time we pass the variable as a prop in the render function, it will | |
// not change. We want to avoid unnecessary prop changes because this will trigger | |
// extra work within React's virtual DOM diffing mechanism. | |
_onChangeToggle(newValue) { | |
this.setState({toggleValue: newValue}); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ToggleSwitch.js | |
* Copyright: Microsoft 2017 | |
* | |
* A simple toggle control built in ReactXP that allows users to | |
* pick between two values. | |
*/ | |
import React from 'react'; | |
import RX from 'reactxp'; | |
const _knobLeftOff = 2; // In pixels | |
const _knobLeftOn = 22; // In pixels | |
const _animationDuration = 250; // In milliseconds | |
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 default class ToggleSwitch extends RX.Component { | |
_knobLeftAnimationValue; | |
_knobLeftAnimationStyle; | |
_toggleColorAnimationValue; | |
_toggleColorAnimationStyle; | |
constructor(props){ | |
super(props); | |
// This value controls the left offset of the knob, which we will | |
// animate when the user toggles the control. | |
this._knobLeftAnimationValue = RX.Animated.createValue(this.props.value ? _knobLeftOn : _knobLeftOff); | |
this._knobLeftAnimationStyle = RX.Styles.createAnimatedViewStyle({ | |
left: this._knobLeftAnimationValue | |
}); | |
// This value controls the background color of the control. Here we make | |
// use of the interpolate method to smoothly transition between two colors. | |
this._toggleColorAnimationValue = RX.Animated.createValue(this.props.value ? 1 : 0); | |
this._toggleColorAnimationStyle = RX.Styles.createAnimatedTextInputStyle({ | |
backgroundColor: RX.Animated.interpolate(this._toggleColorAnimationValue, | |
[0, 1], ['#66f', '#ddd']) | |
}); | |
this._handleClick = this._handleClick.bind(this); | |
} | |
// componentWillUpdate(newProps) { | |
componentDidUpdate(newProps) { | |
// If the value of the toggle changes, animate the toggle sliding | |
// from one side to the other. In parallel, animate the opacity change. | |
if (this.props.value !== newProps.value) { | |
RX.Animated.parallel([ | |
RX.Animated.timing(this._knobLeftAnimationValue, { | |
toValue: newProps.value ? _knobLeftOn : _knobLeftOff, | |
duration: _animationDuration, | |
easing: RX.Animated.Easing.InOut() | |
}), | |
RX.Animated.timing(this._toggleColorAnimationValue, { | |
toValue: newProps.value ? 1 : 0, | |
duration: _animationDuration, | |
easing: RX.Animated.Easing.InOut() | |
}) | |
]) | |
.start(); | |
} | |
} | |
render() { | |
const knobStyles = [_styles.toggleKnob, this._knobLeftAnimationStyle]; | |
const backgroundStyle = [_styles.toggleSwitchBackground, this._toggleColorAnimationStyle]; | |
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> | |
); | |
} | |
_handleClick(e) { | |
e.stopPropagation(); | |
alert('hit'); // added for testing first click | |
if (this.props.onChange) { | |
this.props.onChange(!this.props.value); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment