react-native-komect-uikit
Version:
React Native UI Toolkit
285 lines (272 loc) • 6.85 kB
JavaScript
/**
* @Author: will
* @Date: 2017-06-20T09:43:15+08:00
* @Filename: Button.js
* @Last modified by: will
* @Last modified time: 2017-06-20T11:43:06+08:00
*/
import PropTypes from 'prop-types';
import React from 'react';
import {
TouchableNativeFeedback,
TouchableHighlight,
StyleSheet,
View,
Image,
Platform,
ActivityIndicator,
Text as NativeText,
} from 'react-native';
import colors from '../config/colors';
import Text from '../text/Text';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import getIconType from '../helpers/getIconType';
import normalize from '../helpers/normalizeText';
const log = () => {
console.log('please attach method to this component'); //eslint-disable-line no-console
};
const Button = props => {
const {
disabled,
loading,
loadingRight,
activityIndicatorStyle,
buttonStyle,
borderRadius,
title,
onPress,
icon,
image,
imageStyle,
iconComponent,
secondary,
secondary2,
secondary3,
primary1,
primary2,
backgroundColor,
color,
fontSize,
underlayColor,
raised,
textStyle,
large,
iconRight,
fontWeight,
disabledStyle,
fontFamily,
containerViewStyle,
rounded,
outline,
transparent,
...attributes
} = props;
let { Component } = props;
let iconElement;
if (icon) {
let Icon;
if (iconComponent) {
Icon = iconComponent;
} else if (!icon.type) {
Icon = MaterialIcon;
} else {
Icon = getIconType(icon.type);
}
iconElement = (
<Icon
{...icon}
color={icon.color || 'white'}
size={icon.size || (large ? 26 : 18)}
style={[
iconRight ? styles.iconRight : styles.icon,
icon.style && icon.style,
]}
/>
);
}
let loadingElement;
if (loading) {
loadingElement = (
<ActivityIndicator
animating={true}
style={[styles.activityIndicatorStyle, activityIndicatorStyle]}
color={color || 'white'}
size={(large && 'large') || 'small'}
/>
);
}
if (!Component && Platform.OS === 'ios') {
Component = TouchableHighlight;
}
if (!Component && Platform.OS === 'android') {
Component = TouchableNativeFeedback;
}
if (!Component) {
Component = TouchableHighlight;
}
if (Platform.OS === 'android' && (borderRadius && !attributes.background)) {
attributes.background = TouchableNativeFeedback.Ripple(
'ThemeAttrAndroid',
true
);
}
let textElement;
if (title) {
textElement = (
<Text
style={[
styles.text,
color && { color },
!large && styles.smallFont,
fontSize && { fontSize },
textStyle && textStyle,
fontWeight && { fontWeight },
fontFamily && { fontFamily },
]}
>
{title}
</Text>
);
}
let imageElement;
if (image) {
imageElement = (
<Image style={imageStyle} source={image}/>
);
}
const baseFont = {
color: (textStyle && textStyle.color) || color || stylesObject.text.color,
size: (textStyle && textStyle.fontSize) ||
fontSize ||
(!large && stylesObject.smallFont.fontSize) ||
stylesObject.text.fontSize,
};
return (
<View
style={[styles.container, raised && styles.raised, containerViewStyle]}
>
<Component
underlayColor={underlayColor || 'transparent'}
onPress={onPress || log}
disabled={disabled || false}
{...attributes}
>
<View
style={[
styles.button,
secondary && { backgroundColor: colors.secondary },
secondary2 && { backgroundColor: colors.secondary2 },
secondary3 && { backgroundColor: colors.secondary3 },
primary1 && { backgroundColor: colors.primary1 },
primary2 && { backgroundColor: colors.primary2 },
backgroundColor && { backgroundColor: backgroundColor },
borderRadius && { borderRadius },
!large && styles.small,
rounded && {
borderRadius: baseFont.size * 3.8,
paddingHorizontal: !large ?
stylesObject.small.padding * 1.5 :
stylesObject.button.padding * 1.5,
},
outline && {
borderWidth: 1,
backgroundColor: 'transparent',
borderColor: baseFont.color,
},
transparent && {
borderWidth: 0,
backgroundColor: 'transparent',
},
buttonStyle && buttonStyle,
disabled && { backgroundColor: colors.disabled },
disabled && disabledStyle && disabledStyle,
]}
>
{image && imageElement}
{icon && !iconRight && iconElement}
{loading && !loadingRight && loadingElement}
{title && textElement}
{loading && loadingRight && loadingElement}
{icon && iconRight && iconElement}
</View>
</Component>
</View>
);
};
Button.propTypes = {
buttonStyle: View.propTypes.style,
title: PropTypes.string,
onPress: PropTypes.any,
icon: PropTypes.object,
iconComponent: PropTypes.any,
secondary: PropTypes.bool,
secondary2: PropTypes.bool,
secondary3: PropTypes.bool,
primary1: PropTypes.bool,
primary2: PropTypes.bool,
backgroundColor: PropTypes.string,
color: PropTypes.string,
fontSize: PropTypes.any,
underlayColor: PropTypes.string,
raised: PropTypes.bool,
textStyle: NativeText.propTypes.style,
disabled: PropTypes.bool,
loading: PropTypes.bool,
activityIndicatorStyle: View.propTypes.style,
loadingRight: PropTypes.bool,
Component: PropTypes.any,
borderRadius: PropTypes.number,
large: PropTypes.bool,
iconRight: PropTypes.bool,
fontWeight: PropTypes.string,
disabledStyle: View.propTypes.style,
fontFamily: PropTypes.string,
};
const stylesObject = {
container: {
marginLeft: 15,
marginRight: 15,
},
button: {
padding: 19,
backgroundColor: colors.primary,
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row',
},
text: {
color: 'white',
fontSize: normalize(16),
},
icon: {
marginRight: 10,
},
iconRight: {
marginLeft: 10,
},
small: {
padding: 12,
},
smallFont: {
fontSize: normalize(14),
},
activityIndicatorStyle: {
marginHorizontal: 10,
height: 0,
},
raised: {
...Platform.select({
ios: {
shadowColor: 'rgba(0,0,0, .4)',
shadowOffset: { height: 1, width: 1 },
shadowOpacity: 1,
shadowRadius: 1,
},
android: {
elevation: 2,
},
}),
},
};
const styles = StyleSheet.create(stylesObject);
export default Button;