Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Programatically change switch #4

Merged
merged 2 commits into from
Aug 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
);
}
}

}