Skip to content

UIAvatar

UIAvatar

A versatile avatar component that displays user profile pictures, initials, or icons with support for various sizes, shapes, and fallback options.

<template>
<UIAvatar
:src="avatarUrl"
:size="'md'"
:round="true"
:fallbackSrc="defaultAvatar"
:indicator="onlineStatus"
:indicatorSize="8"
class="border-2 border-white"
>
<template #overlay>
<div class="absolute inset-0 bg-black/40 flex items-center justify-center">
<EditIcon class="w-4 h-4 text-white" />
</div>
</template>
</UIAvatar>
</template>
<script setup lang="ts">
const avatarUrl = ref('https://example.com/avatar.jpg')
const defaultAvatar = 'https://example.com/default.jpg'
const onlineStatus = ref('https://example.com/online-indicator.svg')
</script>

Props

  • size (‘xs’ | ‘sm’ | ‘md’ | ‘lg’ | ‘xl’ | number): Avatar size
  • src (string): Image source URL
  • fallbackSrc (string): Fallback image URL
  • round (boolean): Use round shape
  • square (boolean): Use square shape
  • objectFit (‘fill’ | ‘contain’ | ‘cover’ | ‘none’ | ‘scale-down’): Image fit
  • alt (string): Image alt text
  • indicator (string): Indicator image URL
  • indicatorSize (number): Indicator size in pixels
  • indicatorPosition (‘top-right’ | ‘top-left’ | ‘bottom-right’ | ‘bottom-left’): Indicator position
  • disabled (boolean): Disable avatar interactions
  • loading (boolean): Show loading state
  • bordered (boolean): Show border
  • borderColor (string): Border color

Events

  • error: Image load error
  • load: Image loaded
  • click: Avatar clicked

Slots

  • default: Content when no image (initials/icon)
  • overlay: Overlay content
  • indicator: Custom indicator content
  • fallback: Custom fallback content

Usage Examples

  1. Basic Avatar:
<template>
<UIAvatar
src="user-avatar.jpg"
alt="User Avatar"
size="md"
/>
</template>
  1. Avatar with Initials Fallback:
<template>
<UIAvatar
:src="user.avatarUrl"
:size="40"
:round="true"
>
<template #default>
<span class="text-sm font-medium">
{{ getInitials(user.name) }}
</span>
</template>
</UIAvatar>
</template>
<script setup>
const getInitials = (name: string) => {
return name
.split(' ')
.map(part => part[0])
.join('')
.toUpperCase()
.slice(0, 2)
}
</script>
  1. Interactive Avatar with Status:
<template>
<UIAvatar
:src="profile.avatar"
:size="'lg'"
:round="true"
class="relative cursor-pointer hover:opacity-90"
@click="openProfileMenu"
>
<template #indicator>
<div
class="absolute bottom-0 right-0 w-3 h-3 rounded-full border-2 border-white"
:class="{
'bg-success-500': isOnline,
'bg-gray-300': !isOnline
}"
/>
</template>
<template #overlay>
<div
v-show="showOverlay"
class="absolute inset-0 bg-black/50 flex items-center justify-center rounded-full"
>
<CameraIcon class="w-6 h-6 text-white" />
</div>
</template>
</UIAvatar>
</template>
  1. Avatar with Loading State:
<template>
<div class="relative">
<UIAvatar
:src="imageUrl"
:size="'xl'"
:loading="isLoading"
>
<template #default>
<UISpinner
size="sm"
class="text-gray-400"
/>
</template>
</UIAvatar>
<UIButton
v-if="!isLoading"
size="sm"
class="absolute bottom-0 right-0"
@click="uploadNewImage"
>
<PencilIcon class="w-4 h-4" />
</UIButton>
</div>
</template>

Best Practices

  1. Image Handling:

    • Use appropriate image sizes
    • Implement lazy loading
    • Handle load errors
    • Optimize image assets
  2. User Experience:

    • Clear loading states
    • Smooth transitions
    • Responsive sizing
    • Interactive feedback
  3. Accessibility:

    • Descriptive alt text
    • ARIA labels
    • Keyboard navigation
    • Focus indicators
  4. Performance:

    • Cache images
    • Optimize network requests
    • Minimize reflows
    • Handle memory efficiently

Common Use Cases

  1. User Profile:
<template>
<div class="flex items-center space-x-3">
<UIAvatar
:src="user.avatar"
:size="'md'"
:round="true"
>
<template #indicator>
<UIBadge
:variant="user.status === 'online' ? 'success' : 'gray'"
size="sm"
class="absolute -bottom-1 -right-1"
/>
</template>
</UIAvatar>
<div>
<div class="font-medium">
{{ user.name }}
</div>
<div class="text-sm text-gray-500">
{{ user.role }}
</div>
</div>
</div>
</template>
  1. Avatar Upload:
<template>
<div class="space-y-4">
<UIAvatar
:src="previewUrl"
:size="'xl'"
:round="true"
class="mx-auto"
>
<template #overlay>
<label
class="absolute inset-0 cursor-pointer"
:class="[
previewUrl ? 'hover:bg-black/40' : 'bg-gray-100'
]"
>
<input
type="file"
class="hidden"
accept="image/*"
@change="handleFileChange"
/>
<div class="h-full flex items-center justify-center">
<UploadIcon
class="w-6 h-6"
:class="[
previewUrl ? 'text-white' : 'text-gray-400'
]"
/>
</div>
</label>
</template>
</UIAvatar>
<div class="text-sm text-center text-gray-500">
Click to upload profile picture
</div>
</div>
</template>
  1. Comment Avatar:
<template>
<div class="flex space-x-3">
<UIAvatar
:src="comment.author.avatar"
:size="'sm'"
:round="true"
/>
<div class="flex-1">
<div class="bg-gray-50 rounded-lg p-3">
<div class="font-medium">
{{ comment.author.name }}
</div>
<div class="text-gray-600">
{{ comment.content }}
</div>
</div>
<div class="mt-1 text-sm text-gray-500">
{{ formatDate(comment.createdAt) }}
</div>
</div>
</div>
</template>

Component Composition

The UIAvatar component works well with:

  • UIBadge for status indicators
  • UIButton for actions
  • UISpinner for loading states
  • UITooltip for additional information
  • UIPopover for menus/actions