11import React , { forwardRef , useState } from "react" ;
2+ import { ImageProps , ImageSourcePropType } from "react-native" ;
23
34import { DefaultUser } from "../../icons" ;
4- import { Box , Text } from "../../primitives" ;
5+ import { Box , BoxProps , Text } from "../../primitives" ;
56import { useTheme } from "../../theme" ;
6- import { createComponent , cx , styleAdapter } from "../../utils" ;
7+ import { createComponent , cx , isUndefined , styleAdapter } from "../../utils" ;
8+ import { useAvatarGroup } from "../avatar-group" ;
79import { Icon } from "../icon" ;
810
911import { AvatarImage } from "./AvatarImage" ;
10- import { useAvatarProps } from "./AvatarProps" ;
11- import type { AvatarProps , AvatarSizes } from "./avatarPropTypes" ;
1212import { AvatarStatus } from "./AvatarStatus" ;
1313
1414function getInitials ( name : string , size : AvatarSizes ) {
@@ -28,63 +28,126 @@ function getInitials(name: string, size: AvatarSizes) {
2828 : initials . toUpperCase ( ) ;
2929}
3030
31+ export type AvatarSizes = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" ;
32+ export type AvatarStatusType = "active" | "away" | "sleep" | "typing" | null ;
33+
34+ export interface AvatarProps extends BoxProps {
35+ /**
36+ * React Native Image component Props, except for source
37+ */
38+ imageProps : Omit < ImageProps , "source" > ;
39+ /**
40+ * The image source (either a remote URL or a local file resource).
41+ * Check https://reactnative.dev/docs/image#imagesource
42+ */
43+ src : ImageSourcePropType ;
44+ /**
45+ * How large should avatar be?
46+ *
47+ * @default xl
48+ */
49+ size : AvatarSizes ;
50+ /**
51+ * If `true`, Avatar looks like a squared.
52+ *
53+ * @default false
54+ */
55+ squared : boolean ;
56+ /**
57+ * Name prop used for `alt` & calculate placeholder initials.
58+ */
59+ name : string ;
60+ /**
61+ * Shows AvatarBadge with the given type
62+ *
63+ * @default none
64+ */
65+ status : AvatarStatusType ;
66+ /**
67+ * StatusIndicator's Background Color & StatusIndicator Ring Color.
68+ *
69+ * @default ["bg-white-900", "ring-white-900"]"
70+ */
71+ parentsBackground : string ;
72+ }
73+
3174const RNAvatar : React . FC < Partial < AvatarProps > > = forwardRef <
3275 typeof Box ,
3376 Partial < AvatarProps >
3477> ( ( props , ref ) => {
3578 const tailwind = useTheme ( ) ;
3679 const avatarTheme = useTheme ( "avatar" ) ;
37- const { _imageProps, _basicProps, _otherProps, _statusProps } =
38- useAvatarProps ( props ) ;
39- const { name, style, ...boxProps } = _otherProps ;
40- const isSourceAvailable = React . useMemo (
41- ( ) => ( _imageProps ?. src ? true : false ) ,
42- [ _imageProps ?. src ] ,
43- ) ;
80+
81+ const avatarGroupProps = useAvatarGroup ( ) ;
82+
83+ const {
84+ size = avatarGroupProps ?. size || "xl" ,
85+ squared = false ,
86+ name,
87+ style,
88+ src,
89+ status,
90+ parentsBackground = "text-white-900" ,
91+ imageProps = { } ,
92+ ...boxProps
93+ } = props ;
94+
95+ const isSquared = isUndefined ( avatarGroupProps )
96+ ? squared
97+ : avatarGroupProps . squared ;
98+
99+ const isSourceAvailable = React . useMemo ( ( ) => ( src ? true : false ) , [ src ] ) ;
44100 const [ imageAvailable , setImageAvailable ] = useState ( isSourceAvailable ) ;
45101 const loadFallback = ( ) => setImageAvailable ( false ) ;
46102
47103 return (
48104 < Box
49105 style = { [
50- avatarTheme . borderRadius . size [ _basicProps . size ] ,
106+ avatarTheme . borderRadius . size [ size ] ,
51107 tailwind . style (
52108 cx (
53109 avatarTheme . base ,
54- avatarTheme . size [ _basicProps . size ] ,
55- ! _basicProps . squared ? avatarTheme . circular : "" ,
110+ avatarTheme . size [ size ] ,
111+ ! isSquared ? avatarTheme . circular : "" ,
56112 ) ,
57113 ) ,
58114 styleAdapter ( style ) ,
59115 ] }
60116 ref = { ref }
61117 { ...boxProps }
62118 >
63- { imageAvailable && _imageProps . src ? (
64- < AvatarImage { ..._imageProps } handleFallback = { loadFallback } />
119+ { imageAvailable && src ? (
120+ < AvatarImage
121+ size = { size }
122+ imageProps = { imageProps }
123+ src = { src }
124+ squared = { isSquared }
125+ handleFallback = { loadFallback }
126+ />
65127 ) : name ? (
66128 < Text
67129 style = { tailwind . style (
68- cx (
69- avatarTheme . initials . base ,
70- avatarTheme . initials . size [ _basicProps . size ] ,
71- ) ,
130+ cx ( avatarTheme . initials . base , avatarTheme . initials . size [ size ] ) ,
72131 ) }
73132 adjustsFontSizeToFit
74133 allowFontScaling = { false }
75134 >
76- { getInitials ( name , _basicProps . size ) }
135+ { getInitials ( name , size ) }
77136 </ Text >
78137 ) : (
79138 < Icon
80139 icon = { < DefaultUser /> }
81- style = { tailwind . style (
82- cx ( avatarTheme . defaultUserIcon [ _basicProps . size ] ) ,
83- ) }
140+ style = { tailwind . style ( cx ( avatarTheme . defaultUserIcon [ size ] ) ) }
84141 color = { tailwind . getColor ( "text-gray-800" ) }
85142 />
86143 ) }
87- { _statusProps . status && < AvatarStatus { ..._statusProps } /> }
144+ { status && (
145+ < AvatarStatus
146+ parentsBackground = { parentsBackground }
147+ size = { size }
148+ status = { status }
149+ />
150+ ) }
88151 </ Box >
89152 ) ;
90153} ) ;
0 commit comments