diff --git a/README.md b/README.md index 9136b65..b62d463 100644 --- a/README.md +++ b/README.md @@ -33,18 +33,18 @@ render() { ## Properties -| Prop | Type | Description | -|---|---|---| -|**`disable`**|`Boolean`|Enable / Disable the entire component. Default is false.| -|**`values`**|`Array(String)`|The labels for the control's segment buttons, in order.| -|**`onChange`**|`function`|Callback that is called when the user taps a segment.| -|**`selectedIndex`**|`Number`|Index of the selected segment.| -|**`offsetHeight`**|`Number`|Active Segment's offset height.| -|**`style`**|`Styles`|Styles props of segment control.| -|**`segmentControlStyle`**|`Styles`|Styles props of segment control.| -|**`activeSegmentStyle`**|`Styles`|Styles props of active segment view.| -|**`selectedTextStyle`**|`Styles`|Selected Segment's text style.| -|**`unSelectedTextStyle`**|`Styles`|Unselected Segment's text style.| +| Prop | Type | Default | Description | +|---|---|---|---| +|**`disable`**|`Boolean`|`false`|Enable / Disable the entire component. Default is false.| +|**`values`**|`Array(String)`|`-`|The labels for the control's segment buttons, in order.| +|**`onChange`**|`function`|`-`|Callback that is called when the user taps a segment.| +|**`selectedIndex`**|`Number`|`0`|Index of the selected segment.| +|**`offsetHeight`**|`Number`|`3`|Active Segment's offset height.| +|**`style`**|`Styles`|`{ }`|Styles props of segment control.| +|**`segmentControlStyle`**|`Styles`|`{ }`|Styles props of segment control.| +|**`activeSegmentStyle`**|`Styles`|`{ }`|Styles props of active segment view.| +|**`selectedTextStyle`**|`Styles`|`{ }`|Selected Segment's text style.| +|**`unSelectedTextStyle`**|`Styles`|`{ }`|Unselected Segment's text style.| ## License diff --git a/src/SegmentControl/Segment.js b/src/SegmentControl/Segment.js index b43c91e..7f310b9 100644 --- a/src/SegmentControl/Segment.js +++ b/src/SegmentControl/Segment.js @@ -14,12 +14,13 @@ const Segment = ({ title, style, textStyle, onPress }) => ( ) Segment.defaultProps = { - style: {} + style: {}, + textStyle: {} } Segment.propTypes = { title: PropTypes.string.isRequired, - textStyle: ViewPropTypes.style.isRequired, + textStyle: Text.propTypes.style, onPress: PropTypes.func.isRequired, style: ViewPropTypes.style } diff --git a/src/SegmentControl/index.js b/src/SegmentControl/index.js index 9a604ac..10661e4 100644 --- a/src/SegmentControl/index.js +++ b/src/SegmentControl/index.js @@ -1,6 +1,6 @@ import React from 'react' import PropTypes from 'prop-types' -import { View, Animated, ViewPropTypes, Easing } from 'react-native' +import { View, Animated, ViewPropTypes, Easing, Text} from 'react-native' import styles from './styles' import Segment from './Segment' @@ -19,6 +19,47 @@ class SegmentControl extends React.Component { activeSegmentPosition: { x: props.offsetHeight, y: props.offsetHeight }, positionAnimationValue: new Animated.Value(0) } + + this.componentShouldReRender = false + } + + UNSAFE_componentWillUpdate(nextProps, nextState) { + if(this.componentShouldReRender) { + return; + } + + if (!this.componentShouldReRender && nextProps.selectedIndex != this.state.selectedIndex) { + this.onParentStateChange(nextProps.selectedIndex) + } + } + + /** + * Trigger change when state is changed from parent component + * + * @param {Number} index + */ + onParentStateChange = index => { + + this.componentShouldReRender = true + + setTimeout(() => this.componentShouldReRender = false, 1000) + + const animate = () => { + Animated.timing(this.state.positionAnimationValue, { + toValue: this.state.activeSegmentPosition.x, + duration: 150, + useNativeDriver: this.props.useNativeDriver, + easing: Easing.ease + }).start() + } + + this.setState( + prevState => ({ + selectedIndex: index, + activeSegmentPosition: { x: prevState.segmentDimension.width * index + this.props.offsetHeight, y: prevState.activeSegmentPosition.y } + }), + animate + ) } /** @@ -31,6 +72,7 @@ class SegmentControl extends React.Component { Animated.timing(this.state.positionAnimationValue, { toValue: this.state.activeSegmentPosition.x, duration: 150, + useNativeDriver: this.props.useNativeDriver, easing: Easing.ease }).start(() => this.props.onChange(index)) } @@ -56,7 +98,8 @@ class SegmentControl extends React.Component { const animate = () => { Animated.timing(this.state.positionAnimationValue, { toValue: segmentWidth * this.state.selectedIndex + this.props.offsetHeight, - duration: 100 + duration: 100, + useNativeDriver: this.props.useNativeDriver, }).start() } @@ -81,6 +124,7 @@ class SegmentControl extends React.Component { > {this.props.values.map((segment, index) => (