Skip to content

Commit

Permalink
Merge pull request #4 from ShaunLloyd/programatically-change-switch
Browse files Browse the repository at this point in the history
Programatically change switch
  • Loading branch information
baderahmed authored Aug 16, 2017
2 parents 9663048 + 13529f0 commit 5f06710
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 137 deletions.
92 changes: 51 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# react-native-customisable-switch
A React Native module that allows you to customize switch (style, form and animation), availble for android and IOS.
A React Native module that allows you to customize switch (style, form and animation), available for android and IOS.

### Content
- [Installation](#installation)
- [Examples](#usage-example)
- [Properties](#properties)
- [Properties](#component-properties)
- [Questions](#questions)

### Installation
Expand All @@ -19,26 +19,38 @@ npm install --save react-native-customisable-switch

```javascript
import React, { Component } from 'react';
import {
Text,
View,
} from 'react-native';
import { Text, View } from 'react-native';
import Switch from 'react-native-customisable-switch';

export default class Test extends Component {
constructor(props) {
super(props);
this.state = {
switchOneValue: false,
switchTwoValue: false,
switchThreeValue: true,
};
}

render() {
const {
switchOneValue,
switchTwoValue,
switchOneValue,
} = this.state;

return(
<View style={styles.container}>
<View style={styles.container}>
<Switch />
<Switch
value={switchOneValue}
onChangeValue={() => this.setState({ switchOneValue: !switchOneValue })}
/>
</View>
<View style={styles.container}>
<Switch
defaultValue={true}
value={switchTwoValue}
onChangeValue={() => this.setState({ switchTwoValue: !switchTwoValue })}
activeText={''}
inactiveText={''}
fontSize={16}
Expand All @@ -60,14 +72,12 @@ export default class Test extends Component {
buttonBorderWidth={0}
animationTime={150}
padding={true}
onChangeValue={(value) => {
console.log(value);
}}
/>
</View>
<View style={styles.container}>
<Switch
defaultValue={false}
<Switch
value={switchThreeValue}
onChangeValue={() => this.setState({ switchThreeValue: !switchThreeValue })}
activeText={'On'}
inactiveText={'Off'}
fontSize={16}
Expand All @@ -82,9 +92,6 @@ export default class Test extends Component {
buttonBorderWidth={0}
animationTime={150}
padding={true}
onChangeValue={(value) => {
console.log(value);
}}
/>
</View>
</View>
Expand All @@ -101,30 +108,33 @@ const styles = StyleSheet.create({
},
)};
```
### Properties
* **defaultValue** (Boolean): false //Default switch value<br />
* **onChangeValue** (Function): () => null //Sends the current value of switch
* **activeText** (String): "On" //Text when switch is activated<br />
* **inactiveText** (String): "Off" //Text when switch is inactivated<br />
* **fontSize** (Number): 16 //Size of text<br />
* **activeTextColor** (String): "rgba(255, 255, 255, 1)" //Color of activated switch text<br />
* **inactiveTextColor** (String): "rgba(255, 255, 255, 1)" //Color of inactivated switch text<br />
* **activeBackgroundColor** (String): "rgba(50, 163, 50, 1)" //Background color of activated switch<br />
* **inactiveBackgroundColor** (String): "rgba(137, 137, 137, 1)" //Background color of inactivated switch<br />
* **activeButtonBackgroundColor** (String): "rgba(255, 255, 255, 1)" //Color of activated switch button<br />
* **inactiveButtonBackgroundColor** (String): "rgba(255, 255, 255, 1)" //Color of inactivated switch button<br />
* **switchWidth** (Number): 70 // Switch width<br />
* **switchHeight** (Number): 30 // Switch height<br />
* **switchBorderRadius** (Number): 15 // Switch border radius<br />
* **switchBorderColor** (String): 'rgba(0, 0, 0, 1)' // Switch border color<br />
* **switchBorderWidth** (Number): 0 //Switch border width<br />
* **buttonWidth** (Number): 25 //Switch button width<br />
* **buttonHeight** (Number): 25 //Switch button height<br />
* **buttonBorderRadius** (Number): 15 // Switch button border radius<br />
* **buttonBorderColor** (String): "rgba(0, 0, 0, 1)" // Switch button border color<br />
* **buttonBorderWidth** (Number): 0 //Switch button border width<br />
* **animationTime** (Number): 150 // Animation duration<br />
* **padding** (Boolean): true // Switch horizontal padding<br />
### Component Properties
| Property | Type | Default Value | Description |
|-------------------------|----------|--------------------------|---------------------------------------------------------------------------|
| value | boolean | false | Switch value to determine whether or not the switch is active or inactive |
| onChangeValue | function | () => null | Function to handle the change of the value property |
| activeText | string | "On" | Text when the switch is activate |
| inactiveText | string | "Off" | Text when the switch is inactive |
| fontSize | number | 16 | Text Size for `activeText` and `inactiveText` |
| activeTextColor | string | "rgba(255, 255, 255, 1)" | Text color of `activeText` |
| inactiveTextColor | string | "rgba(255, 255, 255, 1)" | Text color of `inactiveText` |
| activeBackgroundColor | string | "rgba(50, 163, 50, 1)" | Background color of the switch while active |
| inactiveBackgroundColor | string | "rgba(137, 137, 137, 1)" | Background color of the switch while inactive |
| switchWidth | number | 70 | Width of the switch |
| switchHeight | number | 30 | Height of the switch |
| switchBorderRadius | number | 15 | Border radius of the switch |
| switchBorderColor | string | "rgba(0, 0, 0, 1)" | Border color of the switch |
| switchBorderWidth | number | 0 | Border width of the switch |
| buttonWidth | number | 25 | Width of the button in the switch |
| buttonHeight | number | 25 | Height of the button in the switch |
| buttonBorderRadius | number | 15 | Border radius of the button in the switch |
| buttonBorderColor | string | "rgba(0, 0, 0, 1)" | Border color of the button in the switch |
| buttonBorderWidth | number | 0 | Border width of the button in the switch |
| animationTime | number | 150 | Time of toggle animation in milliseconds |
| padding | boolean | true | Whether the switch has a horizontal padding of 5 or not |
### Questions
Create an issue (https://github.com/baderahmed/react-native-customisable-switch/issues)
Create an issue (https://github.com/baderahmed/react-native-customisable-switch/issues)
177 changes: 81 additions & 96 deletions src/switch.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { Component, PropTypes } from 'react';
import {
Text,
TouchableWithoutFeedback,
Expand All @@ -9,35 +9,34 @@ import {
import styles from './styles.js';

export default class Switch extends Component {

static propTypes = {
defaultValue: React.PropTypes.bool,
onChangeValue: React.PropTypes.func,
activeText: React.PropTypes.string,
inactiveText: React.PropTypes.string,
fontSize: React.PropTypes.number,
activeTextColor: React.PropTypes.string,
inactiveTextColor: React.PropTypes.string,
activeBackgroundColor: React.PropTypes.string,
inactiveBackgroundColor: React.PropTypes.string,
activeButtonBackgroundColor: React.PropTypes.string,
inactiveButtonBackgroundColor: React.PropTypes.string,
switchWidth: React.PropTypes.number,
switchHeight: React.PropTypes.number,
switchBorderRadius: React.PropTypes.number,
switchBorderColor: React.PropTypes.string,
switchBorderWidth: React.PropTypes.number,
buttonWidth: React.PropTypes.number,
buttonHeight: React.PropTypes.number,
buttonBorderRadius: React.PropTypes.number,
buttonBorderColor: React.PropTypes.string,
buttonBorderWidth: React.PropTypes.number,
animationTime: React.PropTypes.number,
padding: React.PropTypes.bool,
value: PropTypes.bool,
onChangeValue: PropTypes.func,
activeText: PropTypes.string,
inactiveText: PropTypes.string,
fontSize: PropTypes.number,
activeTextColor: PropTypes.string,
inactiveTextColor: PropTypes.string,
activeBackgroundColor: PropTypes.string,
inactiveBackgroundColor: PropTypes.string,
activeButtonBackgroundColor: PropTypes.string,
inactiveButtonBackgroundColor: PropTypes.string,
switchWidth: PropTypes.number,
switchHeight: PropTypes.number,
switchBorderRadius: PropTypes.number,
switchBorderColor: PropTypes.string,
switchBorderWidth: PropTypes.number,
buttonWidth: PropTypes.number,
buttonHeight: PropTypes.number,
buttonBorderRadius: PropTypes.number,
buttonBorderColor: PropTypes.string,
buttonBorderWidth: PropTypes.number,
animationTime: PropTypes.number,
padding: PropTypes.bool,
};

static defaultProps = {
defaultValue: false,
value: false,
onChangeValue: () => null,
activeText: '',
inactiveText: '',
Expand Down Expand Up @@ -67,44 +66,45 @@ export default class Switch extends Component {
this.padding = props.padding ? 5 : 0;
this.transformValue = (props.switchWidth - props.buttonWidth - this.padding);
this.state = {
value: props.defaultValue,
transformValue: new Animated.Value(props.value ? this.transformValue : this.padding),
backgroundColor: new Animated.Value(props.value ? 90 : -90),
buttonBackgroundColor: new Animated.Value(props.value ? 90 : -90),
};
}

startGroupAnimations = () => {
const { animationTime, onChangeValue } = this.props;
this.setState({ value: !this.state.value }, () => {
const { value } = this.state;
Animated.parallel([
Animated.spring(this.state.transformValue, {
toValue: value ? this.transformValue : this.padding,
duration: animationTime,
}),
Animated.timing(this.state.backgroundColor, {
toValue: value ? 75 : -75,
duration: animationTime,
}),
Animated.timing(this.state.buttonBackgroundColor, {
toValue: value ? 75 : -75,
duration: animationTime,
})
]).start(onChangeValue(value));
});
componentDidUpdate(prevProps) {
const { value } = this.props;
if (value !== prevProps) this.startGroupAnimations();
}

startGroupAnimations = () => {
const { animationTime, onChangeValue, value } = this.props;
Animated.parallel([
Animated.spring(this.state.transformValue, {
toValue: value ? this.transformValue : this.padding,
duration: animationTime,
}),
Animated.timing(this.state.backgroundColor, {
toValue: value ? 75 : -75,
duration: animationTime,
}),
Animated.timing(this.state.buttonBackgroundColor, {
toValue: value ? 75 : -75,
duration: animationTime,
})
]).start();
}

render() {
const {
transformValue,
backgroundColor,
buttonBackgroundColor,
value,
} = this.state;

const {
value,
onChangeValue,
activeText,
inactiveText,
fontSize,
Expand Down Expand Up @@ -137,7 +137,7 @@ render() {
const buttonBackgroundColorValue = buttonBackgroundColor.interpolate({
inputRange: [-90, 90],
outputRange: [
inactiveButtonBackgroundColor,
inactiveButtonBackgroundColor,
activeButtonBackgroundColor,
],
});
Expand All @@ -147,7 +147,7 @@ render() {

return (
<TouchableWithoutFeedback
onPress={this.startGroupAnimations}
onPress={onChangeValue}
>
<View
style={[
Expand All @@ -159,63 +159,48 @@ render() {
]}
>
<Animated.View
style={[
{
backgroundColor: backgroundColorValue,
height: switchHeight,
width: switchWidth,
borderRadius: switchBorderRadius,
borderWidth: switchBorderWidth,
borderColor: switchBorderColor,
zIndex: 1,
position: 'absolute',
top: (containerHeight - switchHeight)/2,
left: (containerWidth - switchWidth)/2,
}
]}
style={{
backgroundColor: backgroundColorValue,
height: switchHeight,
width: switchWidth,
borderRadius: switchBorderRadius,
borderWidth: switchBorderWidth,
borderColor: switchBorderColor,
zIndex: 1,
position: 'absolute',
top: (containerHeight - switchHeight) / 2,
left: (containerWidth - switchWidth) / 2,
}}
>
<View
style={[
styles.animatedContainer,
]}
>
<View style={styles.animatedContainer}>
<View style={styles.textContainer}>
<Text style={{
color: activeTextColor,
fontSize,
}}>
<Text style={{ color: activeTextColor, fontSize }}>
{value ? activeText : ''}
</Text>
</View>
</View>
<View style={styles.textContainer}>
<Text style={{
color: inactiveTextColor,
fontSize,
}}>
<Text style={{ color: inactiveTextColor, fontSize }}>
{value ? '' : inactiveText}
</Text>
</View>
</View>
</View>
</Animated.View>
<Animated.View style={[
{
backgroundColor: buttonBackgroundColorValue,
borderRadius: buttonBorderRadius,
borderWidth: buttonBorderWidth,
borderColor: buttonBorderColor,
width: buttonWidth,
height: buttonHeight,
zIndex: 3,
position: 'absolute',
top: (containerHeight - buttonHeight)/2,
left: transformValue,
}
]}
>
</Animated.View>
<Animated.View
style={{
backgroundColor: buttonBackgroundColorValue,
borderRadius: buttonBorderRadius,
borderWidth: buttonBorderWidth,
borderColor: buttonBorderColor,
width: buttonWidth,
height: buttonHeight,
zIndex: 3,
position: 'absolute',
top: (containerHeight - buttonHeight)/2,
left: transformValue,
}}
/>
</View>
</TouchableWithoutFeedback>
);
}
}

}

0 comments on commit 5f06710

Please sign in to comment.