UNPKG

react-native-komect-uikit

Version:
408 lines (400 loc) 11.4 kB
import PropTypes from 'prop-types'; import React from 'react'; import { View, StyleSheet, TouchableHighlight, TouchableOpacity, Platform, Switch, TextInput, } from 'react-native'; import Avatar from '../avatar/Avatar'; import Badge from '../badge/badge'; import Icon from '../icons/Icon'; import Text from '../text/Text'; import colors from '../config/colors'; import fonts from '../config/fonts'; import normalize from '../helpers/normalizeText'; const ListItem = props => { const { onPress, title, leftIcon, rightIcon, leftIconOnPress, leftIconOnLongPress, leftIconUnderlayColor, leftIconContainerStyle, avatarStyle, underlayColor, subtitle, subtitleStyle, containerStyle, wrapperStyle, titleNumberOfLines, titleStyle, titleContainerStyle, hideChevron, chevronColor, roundAvatar, component, fontFamily, rightTitle, rightTitleContainerStyle, rightTitleStyle, rightTitleNumberOfLines, subtitleContainerStyle, subtitleNumberOfLines, badge, label, onLongPress, switchButton, onSwitch, switchDisabled, switchOnTintColor, switchThumbTintColor, switchTintColor, switched, textInput, textInputAutoCapitalize, textInputAutoCorrect, textInputAutoFocus, textInputEditable, textInputKeyboardType, textInputMaxLength, textInputMultiline, textInputOnChangeText, textInputOnFocus, textInputOnBlur, textInputSelectTextOnFocus, textInputReturnKeyType, textInputValue, textInputSecure, textInputStyle, textInputContainerStyle, onPressRightIcon, ...attributes } = props; let { avatar } = props; let Component = onPress || onLongPress ? TouchableHighlight : View; let LeftIconWrapper = leftIconOnPress || leftIconOnLongPress ? TouchableHighlight : View; if (component) { Component = component; } if (typeof avatar === 'string') { avatar = { uri: avatar }; } return ( <Component onLongPress={onLongPress} onPress={onPress} underlayColor={underlayColor} style={[styles.container, containerStyle && containerStyle]} {...attributes} > <View style={[styles.wrapper, wrapperStyle && wrapperStyle]}> {React.isValidElement(leftIcon) ? leftIcon : leftIcon && leftIcon.name && <LeftIconWrapper onLongPress={leftIconOnLongPress} onPress={leftIconOnPress} underlayColor={leftIconUnderlayColor} style={[ styles.iconStyle, { flex: rightTitle && rightTitle !== '' ? 0.3 : 0.15 }, leftIconContainerStyle && leftIconContainerStyle, ]} > <View> <Icon type={leftIcon.type} iconStyle={[styles.icon, leftIcon.style && leftIcon.style]} name={leftIcon.name} color={leftIcon.color || colors.grey4} size={leftIcon.size || 24} /> </View> </LeftIconWrapper>} {avatar && <View style={styles.avatar}> {React.isValidElement(avatar) ? avatar : <Avatar containerStyle={avatarStyle && avatarStyle} rounded={roundAvatar} source={avatar} />} </View>} <View style={styles.titleSubtitleContainer}> <View style={titleContainerStyle}> {title && (typeof title === 'string' || typeof title === 'number') ? <Text numberOfLines={titleNumberOfLines} style={[ styles.title, !leftIcon && { marginLeft: 10 }, titleStyle && titleStyle, fontFamily && { fontFamily }, ]} > {title} </Text> : <View> {title} </View>} </View> <View style={subtitleContainerStyle}> {subtitle && (typeof subtitle === 'string' || typeof subtitle === 'number') ? <Text numberOfLines={subtitleNumberOfLines} style={[ styles.subtitle, !leftIcon && { marginLeft: 10 }, subtitleStyle && subtitleStyle, fontFamily && { fontFamily }, ]} > {subtitle} </Text> : <View> {subtitle} </View>} </View> </View> {rightTitle && rightTitle !== '' && !textInput && <View style={[styles.rightTitleContainer, rightTitleContainerStyle]}> <Text numberOfLines={rightTitleNumberOfLines} style={[styles.rightTitleStyle, rightTitleStyle]} > {rightTitle} </Text> </View>} {textInput && <View style={[styles.rightTitleContainer, textInputContainerStyle]}> <TextInput style={[styles.textInputStyle, textInputStyle]} defaultValue={rightTitle} value={textInputValue} autoCapitalize={textInputAutoCapitalize} autoCorrect={textInputAutoCorrect} autoFocus={textInputAutoFocus} editable={textInputEditable} keyboardType={textInputKeyboardType} maxLength={textInputMaxLength} multiline={textInputMultiline} onChangeText={textInputOnChangeText} onFocus={textInputOnFocus} onBlur={textInputOnBlur} secureTextEntry={textInputSecure} selectTextOnFocus={textInputSelectTextOnFocus} returnKeyType={textInputReturnKeyType} /> </View>} {badge && !rightTitle && <Badge {...badge} />} {!hideChevron && (React.isValidElement(rightIcon) ? rightIcon : <TouchableOpacity onPress={onPressRightIcon} disabled={!onPressRightIcon} style={styles.chevronContainer} > <Icon type={rightIcon.type} iconStyle={rightIcon.style} size={28} name={rightIcon.name || 'chevron-right'} color={rightIcon.color || chevronColor} /> </TouchableOpacity>)} {switchButton && hideChevron && <View style={styles.switchContainer}> <Switch onValueChange={onSwitch} disabled={switchDisabled} onTintColor={switchOnTintColor} thumbTintColor={switchThumbTintColor} tintColor={switchTintColor} value={switched} /> </View>} {label && label} </View> </Component> ); }; ListItem.defaultProps = { underlayColor: 'white', leftIconUnderlayColor: 'white', chevronColor: colors.grey4, rightIcon: { name: 'chevron-right' }, hideChevron: false, roundAvatar: false, switchButton: false, textInputEditable: true, titleNumberOfLines: 1, subtitleNumberOfLines: 1, rightTitleNumberOfLines: 1, }; ListItem.propTypes = { title: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.object, ]), avatar: PropTypes.any, icon: PropTypes.any, onPress: PropTypes.func, rightIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.object]), underlayColor: PropTypes.string, subtitle: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.object, ]), subtitleStyle: PropTypes.any, subtitleNumberOfLines: PropTypes.number, containerStyle: PropTypes.any, wrapperStyle: PropTypes.any, titleStyle: PropTypes.any, titleContainerStyle: PropTypes.any, titleNumberOfLines: PropTypes.number, hideChevron: PropTypes.bool, chevronColor: PropTypes.string, roundAvatar: PropTypes.bool, badge: PropTypes.any, switchButton: PropTypes.bool, onSwitch: PropTypes.func, switchDisabled: PropTypes.bool, switchOnTintColor: PropTypes.string, switchThumbTintColor: PropTypes.string, switchTintColor: PropTypes.string, switched: PropTypes.bool, textInput: PropTypes.bool, textInputAutoCapitalize: PropTypes.bool, textInputAutoCorrect: PropTypes.bool, textInputAutoFocus: PropTypes.bool, textInputEditable: PropTypes.bool, textInputKeyboardType: PropTypes.oneOf([ 'default', 'email-address', 'numeric', 'phone-pad', 'ascii-capable', 'numbers-and-punctuation', 'url', 'number-pad', 'name-phone-pad', 'decimal-pad', 'twitter', 'web-search', ]), textInputMaxLength: PropTypes.number, textInputMultiline: PropTypes.bool, textInputOnChangeText: PropTypes.func, textInputOnFocus: PropTypes.func, textInputOnBlur: PropTypes.func, textInputSelectTextOnFocus: PropTypes.bool, textInputReturnKeyType: PropTypes.string, textInputValue: PropTypes.string, textInputSecure: PropTypes.bool, textInputStyle: PropTypes.any, textInputContainerStyle: PropTypes.any, component: PropTypes.any, fontFamily: PropTypes.string, rightTitle: PropTypes.string, rightTitleContainerStyle: View.propTypes.style, rightTitleStyle: Text.propTypes.style, rightTitleNumberOfLines: PropTypes.number, subtitleContainerStyle: View.propTypes.style, label: PropTypes.any, onLongPress: PropTypes.func, leftIcon: PropTypes.oneOfType([PropTypes.element, PropTypes.object]), leftIconOnPress: PropTypes.func, leftIconOnLongPress: PropTypes.func, leftIconUnderlayColor: PropTypes.string, leftIconContainerStyle: View.propTypes.style, avatarStyle: View.propTypes.style, onPressRightIcon: PropTypes.func, }; const styles = StyleSheet.create({ avatar: { width: 34, height: 34, }, container: { paddingTop: 10, paddingRight: 10, paddingBottom: 10, borderBottomColor: colors.greyOutline, borderBottomWidth: 0.5, backgroundColor: 'transparent', }, wrapper: { flexDirection: 'row', marginLeft: 10, }, iconStyle: { justifyContent: 'center', alignItems: 'center', }, icon: { marginRight: 8, }, title: { fontSize: normalize(14), color: colors.grey1, }, subtitle: { color: colors.grey3, fontSize: normalize(12), marginTop: 1, ...Platform.select({ ios: { fontWeight: '600', }, android: { ...fonts.android.bold, }, }), }, titleSubtitleContainer: { justifyContent: 'center', flex: 1, }, chevronContainer: { flex: 0.15, alignItems: 'flex-end', justifyContent: 'center', }, switchContainer: { flex: 0.15, alignItems: 'flex-end', justifyContent: 'center', marginRight: 5, }, rightTitleContainer: { flex: 1, alignItems: 'flex-end', justifyContent: 'center', }, rightTitleStyle: { marginRight: 5, color: colors.grey4, }, textInputStyle: { height: 20, textAlign: 'right', }, }); export default ListItem;