Reputation: 46
I am trying to implement a Switch component in react native but the switch different in the android platform. I did explore a lot but I didn't find any references finally i found but it is in type script and a class-based component can someone help me to convert in JSX and functional-based component?
import * as React from 'react';
import {
Animated,
Easing,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
interface Props {
onColor: string;
offColor: string;
label: string;
onToggle: () => void;
style: object;
isOn: boolean;
labelStyle: object;
}
interface DefaultProps {
onColor: string;
offColor: string;
label: string;
onToggle: () => void;
style: object;
isOn: boolean;
labelStyle: object;
}
export default class Toggle extends React.PureComponent<Props> {
animatedValue = new Animated.Value(0);
static defaultProps: DefaultProps = {
onColor: '#4cd137',
offColor: '#ecf0f1',
label: '',
onToggle: () => {},
style: {},
isOn: false,
labelStyle: {},
};
render() {
const moveToggle = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 20],
});
const {
isOn,
onColor,
offColor,
style,
onToggle,
labelStyle,
label,
} = this.props;
const color = isOn ? onColor : offColor;
this.animatedValue.setValue(isOn ? 0 : 1);
Animated.timing(this.animatedValue, {
toValue: isOn ? 1 : 0,
duration: 300,
easing: Easing.linear,
}).start();
return (
<View style={styles.container}>
{!!label && <Text style={[styles.label, labelStyle]}>{label}</Text>}
<TouchableOpacity
onPress={() => {
typeof onToggle === 'function' && onToggle();
}}>
<View
style={[styles.toggleContainer, style, { backgroundColor: color }]}>
<Animated.View
style={[
styles.toggleWheelStyle,
{
marginLeft: moveToggle,
},
]}
/>
</View>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
},
toggleContainer: {
width: 50,
height: 30,
marginLeft: 3,
borderRadius: 15,
justifyContent: 'center',
},
label: {
marginRight: 2,
},
toggleWheelStyle: {
width: 25,
height: 25,
backgroundColor: 'white',
borderRadius: 12.5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5,
},
});
Upvotes: 0
Views: 2483
Reputation: 19
Switch button with typescript
import React, {useEffect, useState} from 'react';
import {Animated, Easing, StyleSheet, Text, TouchableOpacity, View} from
'react-native';
import theme from '@/constants/themeConstants';
type TProps = {
value: boolean;
onChange: () => void;
onColor?: string;
offColor?: string;
label?: string;
labelStyle?: any;
};
const Switch: React.FC<TProps> = ({
value,
onChange,
onColor = 'green',
offColor = 'grey',
label = '',
labelStyle,
}) => {
const [isEnabled, setIsEnabled] = useState(false);
useEffect(() => {
value && setIsEnabled(value);
}, [value]);
const toggleSwitch = () => {
setIsEnabled(!isEnabled);
onChange();
};
const animatedValue = new Animated.Value(0);
const moveToggle = animatedValue.interpolate({
inputRange: [-0.2, 0.9],
outputRange: [0, 20],
});
const color = value ? onColor : offColor;
animatedValue.setValue(value ? 0 : 1);
Animated.timing(animatedValue, {
toValue: value ? 1 : 0,
duration: 300,
easing: Easing.linear,
useNativeDriver: false,
}).start();
return (
<View style={styles.container}>
{!!label && <Text style={[styles.label, labelStyle]}>{label}
</Text>}
<TouchableOpacity onPress={toggleSwitch} activeOpacity={1}>
<View style={[styles.toggleContainer, {backgroundColor:
color}]}>
<Animated.View style={[styles.toggleWheelStyle,
{marginLeft: moveToggle}]} />
</View>
</TouchableOpacity>
</View>
);
};
export default Switch;
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
},
toggleContainer: {
width: 50,
height: 30,
marginLeft: 3,
borderRadius: 15,
justifyContent: 'center',
},
label: {
marginRight: 2,
},
toggleWheelStyle: {
width: 25,
height: 25,
backgroundColor: 'white',
borderRadius: 12.5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5,
},
});
Upvotes: 0
Reputation: 1250
Basically, as a functional component in jsx, the above would translate to:
import * as React from 'react';
import {
Animated,
Easing,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import PropTypes from 'prop-types';
const Toggle = props => {
const animatedValue = new Animated.Value(0);
const moveToggle = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 20],
});
const {isOn, onColor, offColor, style, onToggle, labelStyle, label} = props;
const color = isOn ? onColor : offColor;
animatedValue.setValue(isOn ? 0 : 1);
Animated.timing(animatedValue, {
toValue: isOn ? 1 : 0,
duration: 300,
easing: Easing.linear,
useNativeDriver: false,
}).start();
return (
<View style={styles.container}>
{!!label && <Text style={[styles.label, labelStyle]}>{label}</Text>}
<TouchableOpacity onPress={typeof onToggle === 'function' && onToggle}>
<View style={[styles.toggleContainer, style, {backgroundColor: color}]}>
<Animated.View
style={[
styles.toggleWheelStyle,
{
marginLeft: moveToggle,
},
]}
/>
</View>
</TouchableOpacity>
</View>
);
};
Toggle.propTypes = {
onColor: PropTypes.string,
offColor: PropTypes.string,
label: PropTypes.string,
onToggle: PropTypes.func,
style: PropTypes.object,
isOn: PropTypes.bool.isRequired,
labelStyle: PropTypes.object,
};
Toggle.defaultProps = {
onColor: '#4cd137',
offColor: '#ecf0f1',
label: '',
onToggle: () => {},
style: {},
isOn: false,
labelStyle: {},
};
export default Toggle;
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
},
toggleContainer: {
width: 50,
height: 30,
marginLeft: 3,
borderRadius: 15,
justifyContent: 'center',
},
label: {
marginRight: 2,
},
toggleWheelStyle: {
width: 25,
height: 25,
backgroundColor: 'white',
borderRadius: 12.5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2,
},
shadowOpacity: 0.2,
shadowRadius: 2.5,
elevation: 1.5,
},
});
USAGE:
import React, {useState} from 'react';
import {View} from 'react-native';
import Toggle from '..path/to/toggle';
const Screen = () => {
const [toggleIsOn, setToggle] = useState(false);
return (
<View>
<Toggle
isOn={toggleIsOn}
onToggle={() => {
setToggle(!toggleIsOn);
}}
/>
</View>
);
};
export default Screen;
You would need to install prop-types
(yarn install prop-types
) so you can specify types or use flow because js
out of the box isn't type safe.
Upvotes: 3