UNPKG

react-native-ui-lib

Version:

UI Components Library for React Native ###### Lateset version support RN44

174 lines (164 loc) 4.29 kB
import React, {PropTypes} from 'react'; import {StyleSheet, ViewPropTypes} from 'react-native'; import {BaseComponent} from '../../commons'; import {Constants} from '../../helpers'; import {Colors, BorderRadiuses} from '../../style'; import View from '../view'; import Text from '../text'; import Image from '../image'; /** * Avatar component */ export default class Avatar extends BaseComponent { static displayName = 'Avatar'; static propTypes = { /** * Background color for Avatar */ backgroundColor: PropTypes.string, /** * Additional spacing styles for the container */ containerStyle: ViewPropTypes.style, /** * The image source (external or assets) */ imageSource: PropTypes.oneOfType([PropTypes.object, PropTypes.number]), /** * Label that can represent initials */ label: PropTypes.string, /** * The label color */ labelColor: PropTypes.string, /** * ribbon label to display on the avatar */ ribbonLabel: PropTypes.string, /** * ribbon custom style */ ribbonStyle: ViewPropTypes.style, /** * ribbon label custom style */ ribbonLabelStyle: Text.propTypes.style, /** * Determine if to show online badge */ isOnline: PropTypes.bool, /** * Custom size for the Avatar */ size: PropTypes.number, /** * Use to identify the avatar in tests */ testID: PropTypes.string, }; static defaultProps = { backgroundColor: Colors.dark80, size: 50, labelColor: Colors.dark10, } generateStyles() { this.styles = createStyles(this.props); } renderRibbon() { const {ribbonLabel, ribbonStyle, ribbonLabelStyle} = this.props; if (ribbonLabel) { return ( <View style={[this.styles.ribbon, ribbonStyle]}> <Text numberOfLines={1} text100 white style={[ribbonLabelStyle]}> {ribbonLabel} </Text> </View> ); } } render() { const {label, imageSource, isOnline, testID} = this.props; const containerStyle = this.extractContainerStyle(this.props); return ( <View style={[this.styles.container, containerStyle]} testID={testID}> <View style={this.styles.initialsContainer}> <Text numberOfLines={1} style={this.styles.initials}> {label} </Text> </View> <Image style={this.styles.image} source={imageSource} /> {isOnline && <View style={this.styles.onlineBadge} testID={`${testID}.onlineBadge`}> <View style={this.styles.onlineBadgeInner}/> </View>} {this.renderRibbon()} </View> ); } } function createStyles({size, backgroundColor, labelColor, imageSource}) { const borderRadius = size / 2; const fontSizeToImageSizeRatio = 0.32; const styles = StyleSheet.create({ container: { alignItems: 'center', justifyContent: 'center', width: size, height: size, backgroundColor, borderRadius, }, initialsContainer: { alignItems: 'center', justifyContent: 'center', }, initials: { fontSize: size * fontSizeToImageSizeRatio, color: labelColor, backgroundColor: 'rgba(0,0,0,0)', }, defaultImage: { width: size, height: size, borderRadius, }, image: { ...StyleSheet.absoluteFillObject, position: 'absolute', width: size, height: size, borderRadius, }, onlineBadge: { height: 13.5, width: 13.5, padding: 1.5, borderRadius: 999, backgroundColor: imageSource ? Colors.white : 'transparent', position: 'absolute', right: imageSource ? -1.5 : 0, top: 4.5, }, onlineBadgeInner: { flex: 1, borderRadius: 999, backgroundColor: Colors.green30, }, fixAbsolutePosition: { position: undefined, left: undefined, bottom: undefined, }, ribbon: { position: 'absolute', right: Constants.isIOS ? '-15%' : 0, top: Constants.isIOS ? '-10%' : 0, backgroundColor: Colors.blue30, borderRadius: BorderRadiuses.br100, paddingHorizontal: 6, paddingVertical: 3, }, }); return styles; }