-
Notifications
You must be signed in to change notification settings - Fork 70
/
Copy pathToggleSwitch.js
123 lines (111 loc) · 3.01 KB
/
ToggleSwitch.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/**
* toggle-switch-react-native
* Toggle Switch component for react native, it works on iOS and Android
* https://github.com/aminebenkeroum/toggle-switch-react-native
* Email:amine.benkeroum@gmail.com
* Blog: https://medium.com/@aminebenkeroum/
* @benkeroumamine
*/
import React from 'react';
import {
StyleSheet,
Text,
View,
TouchableOpacity,
Animated,
} from 'react-native';
import PropTypes from 'prop-types'
export default class ToggleSwitch extends React.Component {
static calculateDimensions(size) {
switch (size) {
case 'small':
return ({
width: 50, padding: 10, circleWidth: 15, circleHeight: 15, translateX: 22,
});
case 'large':
return ({
width: 100, padding: 20, circleWidth: 30, circleHeight: 30, translateX: 38,
});
default:
return ({
width: 60, padding: 12, circleWidth: 18, circleHeight: 18, translateX: 26,
});
}
}
static propTypes = {
isOn: PropTypes.bool.isRequired,
label: PropTypes.string,
onColor: PropTypes.string.isRequired,
offColor: PropTypes.string.isRequired,
size: PropTypes.string,
labelStyle: PropTypes.object,
onToggle: PropTypes.func.isRequired,
icon: PropTypes.object,
}
static defaultProps = {
isOn : false,
onColor: '#634fc9',
offColor: '#ecf0f1',
size: 'medium',
labelStyle: {},
icon: null,
}
offsetX = new Animated.Value(0);
dimensions = ToggleSwitch.calculateDimensions(this.props.size);
createToggleSwitchStyle = () => ({
justifyContent: 'center',
width: this.dimensions.width,
borderRadius: 20,
padding: this.dimensions.padding,
backgroundColor: (this.props.isOn) ? this.props.onColor : this.props.offColor,
})
createInsideCircleStyle = () => ({
alignItems: 'center',
justifyContent: 'center',
margin: 4,
position: 'absolute',
backgroundColor: 'white',
transform: [{ translateX: this.offsetX }],
width: this.dimensions.circleWidth,
height: this.dimensions.circleHeight,
borderRadius: (this.dimensions.circleWidth / 2),
});
render() {
const toValue = this.props.isOn
? this.dimensions.width - this.dimensions.translateX
: 0;
Animated.timing(
this.offsetX,
{
toValue,
duration: 300,
},
).start();
return (
<View style={styles.container}>
{(this.props.label)
? <Text style={[styles.labelStyle, this.props.labelStyle]}>{this.props.label}</Text>
: null
}
<TouchableOpacity
style={this.createToggleSwitchStyle()}
activeOpacity={0.8}
onPress={() => {
this.props.onToggle(!this.props.isOn);
}}
>
<Animated.View style={this.createInsideCircleStyle()} >{this.props.icon}</Animated.View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
},
labelStyle: {
marginHorizontal: 10,
},
});