toggle-react-native
Version:
Toggle Switch component for react native, it works on iOS and Android. this is forked from https://github.com/aminebenkeroum/toggle-switch-react-native
168 lines (153 loc) • 4.35 kB
JavaScript
/**
* 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,
Platform
} from "react-native";
import PropTypes from "prop-types";
export default class ToggleSwitch extends React.Component {
static calculateDimensions(size) {
switch (size) {
case "small":
return {
width: 40,
padding: 10,
circleWidth: 15,
circleHeight: 15,
translateX: 22
};
case "large":
return {
width: 70,
padding: 20,
circleWidth: 30,
circleHeight: 30,
translateX: 38
};
default:
return {
width: 50,
padding: 15,
circleWidth: 25,
circleHeight: 25,
translateX: 30
};
}
}
static propTypes = {
isOn: PropTypes.bool.isRequired,
label: PropTypes.string,
onColor: PropTypes.string,
offColor: PropTypes.string,
size: PropTypes.string,
labelStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
thumbOnStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
thumbOffStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
trackOnStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
trackOffStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
onToggle: PropTypes.func,
icon: PropTypes.object,
disabled: PropTypes.bool,
animationSpeed: PropTypes.number,
useNativeDriver: PropTypes.bool,
circleColor: PropTypes.string,
};
static defaultProps = {
isOn: false,
onColor: "#4cd137",
offColor: "#ecf0f1",
size: "medium",
labelStyle: {},
thumbOnStyle: {},
thumbOffStyle: {},
trackOnStyle: {},
trackOffStyle: {},
icon: null,
disabled: false,
animationSpeed: 300,
useNativeDriver: true,
circleColor: 'white'
};
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
},
this.props.isOn ? this.props.trackOnStyle : this.props.trackOffStyle
];
createInsideCircleStyle = () => [
{
alignItems: "center",
justifyContent: "center",
margin: Platform.OS === "web" ? 0 : 4,
left: Platform.OS === "web" ? 4 : 0,
position: "absolute",
backgroundColor: this.props.circleColor,
transform: [{ translateX: this.offsetX }],
width: this.dimensions.circleWidth,
height: this.dimensions.circleHeight,
borderRadius: this.dimensions.circleWidth / 2,
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5
},
this.props.isOn ? this.props.thumbOnStyle : this.props.thumbOffStyle
];
render() {
const { isOn, onToggle, disabled, labelStyle, label, icon } = this.props;
const toValue = isOn
? this.dimensions.width - this.dimensions.translateX
: 0;
Animated.timing(this.offsetX, {
toValue,
duration: this.props.animationSpeed,
useNativeDriver: this.props.useNativeDriver,
}).start();
return (
<View style={styles.container}>
{label ? (
<Text style={[styles.labelStyle, labelStyle]}>{label}</Text>
) : null}
<TouchableOpacity
style={this.createToggleSwitchStyle()}
activeOpacity={0.8}
onPress={() => (disabled ? null : onToggle(!isOn))}
>
<Animated.View style={this.createInsideCircleStyle()}>
{icon}
</Animated.View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: "row",
alignItems: "center"
},
labelStyle: {
marginHorizontal: 10
}
});