Skip to content

Avatar

DisplayWeb + NativeNativeMIT
View in Mobile Storybook

User portrait — sizes, initials fallback, image source.

bun add @otfdashkit/ui-native

Code

import { Avatar, XStack, YStack, SizableText, Circle } from '@otfdashkit/ui-native'
import { ShowcaseFrame, Section } from '../../components/ShowcaseFrame'
import { PEOPLE as ROSTER, avatar } from '../../lib/fixtures'

// Real, self-hosted persona portraits (R2).
const PEOPLE = ROSTER.slice(0, 4).map((p) => ({ name: p.name, src: p.avatar }))
const SARAH_SRC = avatar('sarah')

export default function AvatarShowcase() {
  return (
    <ShowcaseFrame
      title="Avatar"
      description="User portrait — image source with sized circular fallback."
      docPath="packages/ui-native/src/primitives/Avatar.tsx"
    >
      <Section title="Sizes">
        <XStack gap="$3" alignItems="center" flexWrap="wrap">
          {[24, 32, 40, 56, 80].map((size) => (
            <Avatar key={size} circular size={size}>
              <Avatar.Image source={{ uri: SARAH_SRC }} />
              <Avatar.Fallback backgroundColor="$color5">
                <SizableText size="$2" fontWeight="600">SC</SizableText>
              </Avatar.Fallback>
            </Avatar>
          ))}
        </XStack>
      </Section>

      <Section title="Initials fallback">
        <XStack gap="$3" alignItems="center" flexWrap="wrap">
          {PEOPLE.map((person) => {
            const initials = person.name
              .split(' ')
              .map((n) => n[0])
              .join('')
            return (
              <YStack key={person.name} alignItems="center" gap="$1">
                <Avatar circular size={56}>
                  <Avatar.Fallback backgroundColor="$color6" alignItems="center" justifyContent="center">
                    <SizableText size="$5" fontWeight="700" color="$color12">
                      {initials}
                    </SizableText>
                  </Avatar.Fallback>
                </Avatar>
                <SizableText size="$1" color="$color11">{person.name}</SizableText>
              </YStack>
            )
          })}
        </XStack>
      </Section>

      <Section title="Stacked">
        <XStack alignItems="center">
          {PEOPLE.map((person, i) => (
            <Avatar
              key={person.name}
              circular
              size={40}
              marginLeft={i === 0 ? 0 : -12}
              borderWidth={2}
              borderColor="$background"
            >
              <Avatar.Image source={{ uri: person.src }} />
              <Avatar.Fallback backgroundColor="$color5" />
            </Avatar>
          ))}
          <Circle
            size={40}
            marginLeft={-12}
            backgroundColor="$color4"
            borderWidth={2}
            borderColor="$background"
            alignItems="center"
            justifyContent="center"
          >
            <SizableText size="$2" fontWeight="600" color="$color12">+8</SizableText>
          </Circle>
        </XStack>
      </Section>
    </ShowcaseFrame>
  )
}

Free with the SDK. This component ships in @otfdashkit/ui-native under the MIT license.