diff options
| author | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
|---|---|---|
| committer | Andrew <saintruler@gmail.com> | 2019-03-11 21:00:02 +0400 |
| commit | 7e7dd5244e8d26485ad7950a89c04c98c4fef83f (patch) | |
| tree | 810730c4650392080fb87a78d3b527201e89fe4b /frontend/app/components/switch | |
Initial commit/
Diffstat (limited to 'frontend/app/components/switch')
| -rw-r--r-- | frontend/app/components/switch/index.android.js | 171 | ||||
| -rw-r--r-- | frontend/app/components/switch/index.ios.js | 36 | ||||
| -rw-r--r-- | frontend/app/components/switch/types.js | 35 |
3 files changed, 242 insertions, 0 deletions
diff --git a/frontend/app/components/switch/index.android.js b/frontend/app/components/switch/index.android.js new file mode 100644 index 0000000..2750545 --- /dev/null +++ b/frontend/app/components/switch/index.android.js @@ -0,0 +1,171 @@ +/* + * + * This is modified version of https://github.com/poberwong/react-native-switch-pro + * Copyright (c) 2016 PoberWong + * + */ +import React from 'react'; +import { + Animated, + Easing, + PanResponder, +} from 'react-native'; +import { RkComponent } from 'react-native-ui-kitten'; + +const width = 52; +const height = 32; +const animationDuration = 200; +const offLeftValue = -2; +const onLeftValue = 20; + +export class RkSwitch extends RkComponent { + componentName = 'RkSwitch'; + typeMapping = { + container: { + onColor: 'onColor', + offColor: 'offColor', + }, + thumb: {}, + }; + selectedType = 'selected'; + + constructor(props) { + super(props); + this.offset = width - height; + this.handlerSize = height; + this.state = { + name: this.props.name, + value: this.props.value, + toggleable: true, + alignItems: this.props.value ? 'flex-end' : 'flex-start', + left: this.props.value ? onLeftValue : offLeftValue, + handlerAnimation: new Animated.Value(this.handlerSize), + switchAnimation: new Animated.Value(this.props.value ? -1 : 1), + }; + } + + componentWillReceiveProps(nextProps) { + const { value } = this.state; + if (nextProps === this.props) { + return; + } + if (typeof nextProps.value !== 'undefined' && nextProps.value !== value) { + this.toggleSwitch(true); + } + } + + componentWillMount() { + this.panResponder = PanResponder.create({ + onStartShouldSetPanResponder: () => true, + onStartShouldSetPanResponderCapture: () => true, + onMoveShouldSetPanResponder: () => true, + onMoveShouldSetPanResponderCapture: () => true, + onPanResponderTerminationRequest: () => true, + onPanResponderGrant: this.onPanResponderGrant, + onPanResponderMove: this.onPanResponderMove, + onPanResponderRelease: this.onPanResponderRelease, + }); + } + + onPanResponderGrant = () => { + this.animateHandler(height * 0.9); + }; + + onPanResponderMove = (evt, gestureState) => { + const { value } = this.state; + + this.setState({ + toggleable: value ? (gestureState.dx < 10) : (gestureState.dx > -10), + }); + }; + + onPanResponderRelease = () => { + const { toggleable } = this.state; + const { disabled, onValueChange } = this.props; + + if (toggleable && !disabled) { + if (onValueChange) { + this.toggleSwitch(onValueChange); + } + } + }; + + toggleSwitch = (result, callback = () => null) => { + const { value, switchAnimation } = this.state; + const toValue = !value; + + this.animateHandler(this.handlerSize); + + this.animateSwitch(toValue, () => { + callback(toValue); + this.setState({ + value: toValue, + left: toValue ? onLeftValue : offLeftValue, + }); + switchAnimation.setValue(toValue ? -1 : 1); + }); + }; + + animateSwitch = (value, callback = () => null) => { + const { switchAnimation } = this.state; + + Animated.timing( + switchAnimation, + { + toValue: value ? this.offset : -this.offset, + duration: animationDuration, + easing: Easing.linear, + }, + ).start(callback); + }; + + animateHandler = (value, callback = () => null) => { + const { handlerAnimation } = this.state; + + Animated.timing( + handlerAnimation, + { + toValue: value, + duration: animationDuration, + easing: Easing.linear, + }, + ).start(callback); + }; + + render() { + const { + switchAnimation, handlerAnimation, left, value, + } = this.state; + const { + style, + ...rest + } = this.props; + + const type = value ? this.selectedType : ''; + const { container, thumb } = this.defineStyles(type); + const onColor = this.extractNonStyleValue(container, 'onColor'); + const offColor = this.extractNonStyleValue(container, 'offColor'); + + const interpolatedBackgroundColor = switchAnimation.interpolate({ + inputRange: value ? [-this.offset, -1] : [1, this.offset], + outputRange: [offColor, onColor], + }); + + return ( + <Animated.View + {...rest} + {...this.panResponder.panHandlers} + style={[style, container, { + backgroundColor: interpolatedBackgroundColor, + }]}> + <Animated.View style={[thumb, { + position: 'absolute', + left, + height: handlerAnimation, + transform: [{ translateX: switchAnimation }], + }]} + /> + </Animated.View> + ); + } +} diff --git a/frontend/app/components/switch/index.ios.js b/frontend/app/components/switch/index.ios.js new file mode 100644 index 0000000..068cbfb --- /dev/null +++ b/frontend/app/components/switch/index.ios.js @@ -0,0 +1,36 @@ +import React from 'react'; +import { Switch } from 'react-native'; +import { RkComponent } from 'react-native-ui-kitten'; + + +export class RkSwitch extends RkComponent { + componentName = 'RkSwitch'; + typeMapping = { + container: { + onColor: 'onColor', + offColor: 'offColor', + }, + main: {}, + }; + selectedType = 'selected'; + + constructor(props) { + super(props); + this.onChange = this.props.onValueChange ? + this.props.onValueChange + : () => true; + } + + render() { + const { container } = this.defineStyles(); + const onColor = this.extractNonStyleValue(container, 'onColor'); + return ( + <Switch + style={this.props.style} + value={this.props.value} + onValueChange={(value) => this.onChange(value)} + onTintColor={onColor} + /> + ); + } +} diff --git a/frontend/app/components/switch/types.js b/frontend/app/components/switch/types.js new file mode 100644 index 0000000..96b116e --- /dev/null +++ b/frontend/app/components/switch/types.js @@ -0,0 +1,35 @@ +export const SwitchTypes = (theme) => ({ + _base: { + container: { + width: 52, + height: 32, + overflow: 'hidden', + justifyContent: 'center', + borderRadius: 16, + borderWidth: 1, + borderColor: theme.colors.border.secondary, + onColor: theme.colors.primary, + offColor: { + android: theme.colors.screen.base, + ios: theme.colors.border.base, + }, + }, + thumb: { + position: 'absolute', + height: 32, + width: 32, + borderWidth: 1, + borderColor: theme.colors.border.secondary, + backgroundColor: theme.colors.screen.base, + borderRadius: 16, + }, + }, + selected: { + thumb: { + borderColor: theme.colors.primary, + }, + container: { + borderColor: theme.colors.primary, + }, + }, +}); |