react-native-panda-ui
Version:
A set of easily styled components to get you started fast
195 lines (176 loc) • 4.86 kB
JavaScript
import React, { useEffect, useState, useRef } from 'react';
import PropTypes from 'prop-types';
import { View, ScrollView } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome5';
import Button from './Button';
const TabGroup = (props) => {
const {
options,
width,
selectedValue,
onValueChange,
style,
// props passed through to <Button>
buttonStyle,
disabled,
disabledColor='lightgrey',
size,
height,
color,
chevronColor='#000',
activeTextColor,
inactiveTextColor=activeTextColor,
scrollButtons=false,
backgroundColor
} = props;
const displayColor = disabled ? disabledColor : color;
const [showLeftChevron, setShowLeftChevron] = useState(false);
const [showRightChevron, setShowRightChevron] = useState(false);
const scrollElRef = useRef();
const componentStyle = {
paddingHorizontal: 2.5,
backgroundColor,
...style,
// flexGrow: 1,
flexDirection: 'row',
width: width || '100%',
height: height || '100%'
};
const selectedStyle = {
...componentStyle,
marginBottom: 0,
borderBottomWidth: 1,
borderBottomColor: displayColor
};
const buttonLeftStyle = {
paddingHorizontal: 2.5,
...buttonStyle,
flexGrow: 1
};
const buttonNotLeftStyle = {
...buttonLeftStyle,
borderLeftWidth: 0
};
const buttonSelectedLeftStyle = {
...buttonLeftStyle,
...selectedStyle,
flexGrow: 1
};
const buttonSelectedNotLeftStyle = {
...buttonNotLeftStyle,
...selectedStyle,
flexGrow: 1
};
const handleScroll = (event) => {
const positionX = event.nativeEvent.contentOffset.x;
const outerWidth = event.nativeEvent.layoutMeasurement.width;
const innerWidth = event.nativeEvent.contentSize.width;
const positionXRemaining = innerWidth - outerWidth - positionX;
setShowLeftChevron(positionX > 20);
setShowRightChevron(positionXRemaining > 20);
};
// On mount trigger a small scroll so that the left and right chevrons display correctly.
// This is a hacky way to do this, but we're not sure how to read the correct dimensions
// outside of a scroll event.
useEffect(() => {
scrollElRef.current.scrollTo({ x: 1 });
}, []);
return (
<View
style={componentStyle}
>
{scrollButtons && showLeftChevron &&
<Button
iconElement={<Icon name="chevron-left" size={14} color={chevronColor} />}
size="small"
height={height}
width={10}
solid={false}
style={{ marginLeft: 2, justifyContent: 'center' }}
disabled
border={false}
transparent
onPress={() => ({}) }
key="left-arrow"
/>
}
<ScrollView
ref={scrollElRef}
onScroll={handleScroll}
horizontal={true}
fadingEdgeLength={scrollButtons ? 150 : 0}
indicatorStyle="black"
contentContainerStyle={{ flexGrow: 1, height: height || '100%', padding: 0, alignItems: 'space-between' }}
>
{options.map((option, i) => {
const selected = option.value === selectedValue;
return (
<Button
icon={option.icon}
label={option.label}
transparent={true}
solid={false}
allowInteraction={!selected}
size={size}
height={height}
disabled={disabled}
border={false}
color={selected ? color : inactiveTextColor}
textColor={selected ? activeTextColor : inactiveTextColor}
style={i === 0
? selected ? buttonSelectedLeftStyle : buttonLeftStyle
: selected ? buttonSelectedNotLeftStyle : buttonNotLeftStyle}
onPress={() => onValueChange(option.value)}
key={option.value}
gradient={[]}
/>
);
})}
</ScrollView>
{scrollButtons && showRightChevron &&
<Button
iconElement={<Icon name="chevron-right" size={14} color={chevronColor} />}
size="small"
height={height}
width={10}
solid={false}
style={{ marginRight: 2, justifyContent: 'center' }}
transparent
disabled
border={false}
onPress={() => ({}) }
key="right-arrow"
/>
}
</View>
);
};
export default TabGroup;
TabGroup.propTypes = {
options: PropTypes.arrayOf(PropTypes.shape({
value: PropTypes.any.isRequired,
label: PropTypes.string,
icon: PropTypes.string
})).isRequired,
width: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]),
height: PropTypes.number,
selectedColor: PropTypes.string,
selectedValue: PropTypes.string,
disabledColor: PropTypes.string,
// selectedValue: PropTypes.any.isRequired,
onValueChange: PropTypes.func.isRequired,
disabled: PropTypes.bool,
scrollButtons: PropTypes.bool,
size: PropTypes.oneOf(['small', 'standard', 'large']),
color: PropTypes.string,
activeTextColor: PropTypes.string,
inactiveTextColor: PropTypes.string,
backgroundColor: PropTypes.string,
chevronColor: PropTypes.string,
style: PropTypes.object,
buttonStyle: PropTypes.object,
theme: PropTypes.string
};