import styled from '@emotion/native'; import { GestureResponderEvent, ImageSourcePropType, ViewProps as ViewPropsBase, } from 'react-native'; import { variant } from 'styled-system'; import { ColorName, ViewStyle } from '@emotion/react'; import { Text } from 'components/text'; import { Center, Container, Image, StyleSystemThemedProps, TouchableHighlight, } from 'components/layout'; import React from 'react'; import { Pencil, EllipseBordered } from 'icons'; import { Visible } from 'components/visible'; import { TextVariant } from 'components/text/Text'; import { Fab } from 'components/fab'; import { sliceFirstAndCapitalize } from 'utils/text'; const colorVariants: Record = { base: { backgroundColor: 'base', }, 'base-01': { backgroundColor: 'base-01', }, 'base-02': { backgroundColor: 'base-02', }, primary: { backgroundColor: 'primary', }, 'primary-01': { backgroundColor: 'primary-01', }, secondary: { backgroundColor: 'secondary', }, 'secondary-01': { backgroundColor: 'secondary-01', }, success: { backgroundColor: 'success', }, 'success-01': { backgroundColor: 'success-01', }, transparent: { backgroundColor: 'transparent', }, }; const sizeVariants: Record = { 'extra-small': { width: 25, height: 25, }, small: { width: 30, height: 30, }, medium: { width: 40, height: 40, }, large: { width: 50, height: 50, }, 'extra-large': { width: 55, height: 55, }, }; const imageSizeVariants: Record = { 'extra-small': 25, small: 30, medium: 40, large: 50, 'extra-large': 55, }; const ellipseColorVariants: Record = { online: 'success', offline: 'body', 'out-of-office': 'secondary', }; const avatarBorderRadius: Record = { 'extra-small': 5, small: 6, medium: 8, large: 10, 'extra-large': 11, }; const AvatarLocal = styled(Center)( variant({ prop: 'colorVariant', variants: colorVariants, }), variant({ prop: 'sizeVariant', variants: sizeVariants, }) ); export const Avatar: React.FC = ({ title, size = 25, bordered, borderedWidth = 1, shapeVariant = 'circle', titleVariant, statusBorderVariant = 'base', asset, sizeVariant, colorVariant, titleColor, status, editable, borderedColor, uri, icon, onPress, ...props }) => { const localSize = sizeVariant ? imageSizeVariants[sizeVariant] : size || imageSizeVariants.medium; const ellipseColor = status && ellipseColorVariants[status]; const source = asset ? asset : { uri }; const isSource = asset || uri; const isTitle = !isSource && title; const isIcon = !isTitle && icon; const isSizeVariant = sizeVariant ? avatarBorderRadius[sizeVariant] : size * 0.2; const borderRadius = shapeVariant === 'circle' ? localSize / 2 : isSizeVariant; const borderRadiusColor = borderedColor ? borderedColor : 'transparent'; const isLess70 = size < 80 ? -2 : -1; const topRight = size < 51 ? -3 : isLess70; return ( <> {}} underlayColor="transparent" backgroundColor="transparent" position="absolute" zIndex={2} bottom={0} left={0} right={0} borderRadius={localSize} top={0} alignItems="flex-start" justifyContent="flex-end" > } /> {sliceFirstAndCapitalize(title)} {icon} ); }; export type AvatarColorVariant = | 'base' | 'base-01' | 'base-02' | 'secondary' | 'secondary-01' | 'primary' | 'primary-01' | 'success' | 'success-01' | 'transparent'; export type AvatarSizeVariant = 'extra-small' | 'small' | 'medium' | 'large' | 'extra-large'; export type AvatarShapeVariant = 'square' | 'circle'; type AvatarType = StyleSystemThemedProps & ViewProps & AvatarProps; export type AvatarStatusVariants = 'online' | 'offline' | 'out-of-office'; export interface ViewProps extends ViewPropsBase { colorVariant?: AvatarColorVariant; sizeVariant?: AvatarSizeVariant; } export interface AvatarProps { onPress?: ((event: GestureResponderEvent) => void) | undefined; editable?: boolean; icon?: JSX.Element; uri?: string | null; shapeVariant?: AvatarShapeVariant; size?: number; // you have to pass size or sizeVariant title?: string; statusBorderVariant?: ColorName; status?: AvatarStatusVariants; titleColor?: ColorName; borderedColor?: ColorName; titleVariant?: TextVariant; bordered?: boolean; borderedWidth?: number; asset?: ImageSourcePropType; }