Skip to main content
ProfileAvatar displays user avatars with multiple fallback options and size variants.

Import

import { ProfileAvatar } from 'popui'

Basic Usage

<script lang="ts">
  import { ProfileAvatar } from 'popui'
</script>

<ProfileAvatar name="John Doe" />

Sizes

ProfileAvatar supports five size variants:
<script lang="ts">
  import { ProfileAvatar } from 'popui'
</script>

<div class="flex items-center gap-4">
  <ProfileAvatar name="John Doe" variant="xs" />
  <ProfileAvatar name="John Doe" variant="sm" />
  <ProfileAvatar name="John Doe" variant="md" />
  <ProfileAvatar name="John Doe" variant="lg" />
  <ProfileAvatar name="John Doe" variant="xl" />
</div>

With Picture

<ProfileAvatar 
  name="John Doe" 
  picture="https://example.com/avatar.jpg"
/>
If the image fails to load, it falls back to showing the user’s initial.

With Icon

<script lang="ts">
  import { ProfileAvatar } from 'popui'
  import { User } from '@invopop/ui-icons'
</script>

<ProfileAvatar name="John Doe" icon={User} />

With Country Flag

<ProfileAvatar 
  name="John Doe" 
  picture="https://example.com/avatar.jpg"
  country="US"
/>
The country flag appears as a badge in the bottom-right corner.

Dark Theme

<ProfileAvatar name="John Doe" dark={true} />

Display Priority

ProfileAvatar displays content in the following priority order:
  1. Picture - If provided and loads successfully
  2. Icon - If provided
  3. Initial - First character of the name (uppercase)
<script lang="ts">
  import { ProfileAvatar } from 'popui'
  import { User } from '@invopop/ui-icons'
</script>

<div class="flex gap-4">
  <!-- Shows picture -->
  <ProfileAvatar 
    name="John Doe" 
    picture="https://example.com/avatar.jpg"
  />
  
  <!-- Shows icon (no picture) -->
  <ProfileAvatar 
    name="John Doe" 
    icon={User}
  />
  
  <!-- Shows initial "J" (no picture or icon) -->
  <ProfileAvatar name="John Doe" />
</div>

User List Example

<script lang="ts">
  import { ProfileAvatar } from 'popui'
  
  const users = [
    { 
      name: 'John Doe', 
      picture: 'https://example.com/john.jpg',
      country: 'US'
    },
    { 
      name: 'Jane Smith', 
      picture: 'https://example.com/jane.jpg',
      country: 'GB'
    },
    { 
      name: 'Bob Wilson',
      country: 'CA'
    }
  ]
</script>

<div class="space-y-3">
  {#each users as user}
    <div class="flex items-center gap-3">
      <ProfileAvatar 
        name={user.name} 
        picture={user.picture}
        country={user.country}
        variant="md"
      />
      <div>
        <div class="font-medium">{user.name}</div>
        <div class="text-sm text-gray-500">{user.country}</div>
      </div>
    </div>
  {/each}
</div>

Avatar Grid

<script lang="ts">
  import { ProfileAvatar } from 'popui'
  
  const team = [
    { name: 'John Doe', picture: 'https://example.com/john.jpg' },
    { name: 'Jane Smith', picture: 'https://example.com/jane.jpg' },
    { name: 'Bob Wilson' },
    { name: 'Alice Johnson' },
    { name: 'Charlie Brown' }
  ]
</script>

<div class="flex -space-x-2">
  {#each team.slice(0, 4) as member}
    <ProfileAvatar 
      name={member.name} 
      picture={member.picture}
      variant="sm"
    />
  {/each}
  {#if team.length > 4}
    <div class="size-5 rounded-md bg-gray-200 flex items-center justify-center text-xs">
      +{team.length - 4}
    </div>
  {/if}
</div>

With Tooltip

<script lang="ts">
  import { ProfileAvatar } from 'popui'
  import { TooltipAutoHide, TooltipTrigger, TooltipContent } from 'popui'
</script>

<TooltipAutoHide>
  <TooltipTrigger>
    <ProfileAvatar name="John Doe" picture="https://example.com/avatar.jpg" />
  </TooltipTrigger>
  <TooltipContent>
    John Doe ([email protected])
  </TooltipContent>
</TooltipAutoHide>

Status Indicator

<script lang="ts">
  import { ProfileAvatar } from 'popui'
</script>

<div class="relative inline-block">
  <ProfileAvatar name="John Doe" variant="md" />
  <span class="absolute bottom-0 right-0 block h-2.5 w-2.5 rounded-full bg-green-500 ring-2 ring-white"></span>
</div>

All Variants Comparison

<script lang="ts">
  import { ProfileAvatar } from 'popui'
</script>

<div class="space-y-4">
  <div class="flex items-center gap-4">
    <ProfileAvatar name="John Doe" variant="xs" />
    <span>Extra Small (xs) - 16px</span>
  </div>
  
  <div class="flex items-center gap-4">
    <ProfileAvatar name="John Doe" variant="sm" />
    <span>Small (sm) - 20px</span>
  </div>
  
  <div class="flex items-center gap-4">
    <ProfileAvatar name="John Doe" variant="md" />
    <span>Medium (md) - 28px</span>
  </div>
  
  <div class="flex items-center gap-4">
    <ProfileAvatar name="John Doe" variant="lg" />
    <span>Large (lg) - 32px</span>
  </div>
  
  <div class="flex items-center gap-4">
    <ProfileAvatar name="John Doe" variant="xl" />
    <span>Extra Large (xl) - 40px</span>
  </div>
</div>

Props

name
string
default:"''"
User’s name. Used to display the initial when no picture or icon is provided.
variant
'xs' | 'sm' | 'md' | 'lg' | 'xl'
default:"'sm'"
Size variant of the avatar.
  • xs: 16px (size-4)
  • sm: 20px (size-5)
  • md: 28px (size-7)
  • lg: 32px (size-8)
  • xl: 40px (size-10)
dark
boolean
default:"false"
Use dark theme styling.
picture
string
default:"''"
URL of the user’s profile picture. Falls back to initial if image fails to load.
country
string
default:"''"
Two-letter country code (e.g., “US”, “GB”). Displays a country flag badge in the bottom-right corner.
icon
IconSource
Icon to display instead of initial (from @steeze-ui/svelte-icon).

Size Reference

VariantPixelsTailwind ClassIcon SizeText Size
xs16pxsize-412pxtext-sm
sm20pxsize-512pxtext-sm
md28pxsize-716pxtext-base
lg32pxsize-825pxtext-lg
xl40pxsize-1025pxtext-xl

Styling

The avatar includes:
  • Rounded corners (varies by size)
  • Shadow overlay for depth
  • Automatic image error handling
  • Responsive text sizing
  • Proper alignment and centering

Default Theme

  • Background: bg-background
  • Text: text-foreground-default-secondary
  • Shadow: shadow-avatar

Dark Theme

  • Background: bg-background-inverse
  • Text: text-foreground-inverse-secondary
  • Shadow: shadow-avatar-inverse

Build docs developers (and LLMs) love