Skip to main content

Avatar

Avatars represent a user or entity with an image, icon, or text initials.

Usage​

import { Avatar } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
<Avatar imageUri="https://i.pravatar.cc/80" />
<Avatar icon="account" />
<Avatar label="JD" />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Content priority​

The avatar renders the first available content in this order:

  1. imageUri — displays the image
  2. icon — displays an icon by name through the theme's iconResolver (defaults to account)
  3. label — displays up to 2 uppercase initials

Sizes​

SizeUse case
extraSmallInline mentions, dense lists
smallList items, compact layouts
mediumDefault — profile cards, headers
largeProfile screens, detail views
extraLargeHero sections, onboarding
import { Avatar } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', gap: 16 }}>
<Avatar label="AB" size="extraSmall" />
<Avatar label="AB" size="small" />
<Avatar label="AB" size="medium" />
<Avatar label="AB" size="large" />
<Avatar label="AB" size="extraLarge" />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Interactive Avatar​

When onPress is provided, the avatar renders as a Pressable with automatic state-layer feedback (hover and press):

import { Avatar } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { Alert, View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Avatar
imageUri="https://i.pravatar.cc/80"
onPress={() => Alert.alert('Tapped')}
accessibilityLabel="Open profile"
/>
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Custom colors​

Override the container and content colors:

import { Avatar } from '@rootnative/components'
import { mdiResolver } from '@rootnative/components/mdi'
import { ThemeProvider } from '@rootnative/core'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { View } from 'react-native'

export default function App() {
return (
<SafeAreaProvider>
<ThemeProvider iconResolver={mdiResolver}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Avatar label="AB" containerColor="#E8DEF8" contentColor="#1D1B20" />
</View>
</ThemeProvider>
</SafeAreaProvider>
)
}

Props​

PropTypeDefaultRequiredDescription
imageUristring-NoURI of the image to display. Takes priority over `icon` and `label`.
iconIconSource-NoIcon to display. Accepts a string name (resolved via the theme's `iconResolver`, for example `mdiResolver`), a pre-rendered element, or a render function that receives `{ size, color }`. Takes priority over `label` when `imageUri` is not set.
labelstring-NoText initials to display (1–2 characters recommended). Shown when `imageUri` and `icon` are not set.
sizeenummediumNoSize of the avatar.
containerColorstring-NoOverride the container (background) color. State-layer colors (hover, press) are derived automatically when `onPress` is set.
contentColorstring-NoOverride the content (icon / initials) color.
styleStyleProp<ViewStyle>-NoCustom style applied to the root container. Static form only — the function form `(state) => style` is not supported because the component drives its container background through Reanimated. Use `containerColor` / `contentColor` for state-aware styling.
onPress() => void-NoWhen provided, the avatar becomes interactive (Pressable).
disabledbooleanNoWhether the avatar is disabled. Blocks interaction, renders the content at 38% opacity, and reports `accessibilityState: { disabled: true }`. Only applies when `onPress` is set.
accessibilityLabelstring-NoRequired when `onPress` is provided — labels the button for screen readers.
hrefAttrs{ target?: string; rel?: string; download?: string | boolean; }-NoWeb only. The `target`, `rel` and `download` of the `<a>` that a view with an `href` renders, for example under Expo Router's `<Link asChild>`. `target: '_blank'` opens the link in a new tab. Native ignores it.
onKeyDown(event: { nativeEvent: { key?: string; }; }) => void-No-