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 sizesrc(string): Image source URLfallbackSrc(string): Fallback image URLround(boolean): Use round shapesquare(boolean): Use square shapeobjectFit(‘fill’ | ‘contain’ | ‘cover’ | ‘none’ | ‘scale-down’): Image fitalt(string): Image alt textindicator(string): Indicator image URLindicatorSize(number): Indicator size in pixelsindicatorPosition(‘top-right’ | ‘top-left’ | ‘bottom-right’ | ‘bottom-left’): Indicator positiondisabled(boolean): Disable avatar interactionsloading(boolean): Show loading statebordered(boolean): Show borderborderColor(string): Border color
Events
error: Image load errorload: Image loadedclick: Avatar clicked
Slots
default: Content when no image (initials/icon)overlay: Overlay contentindicator: Custom indicator contentfallback: Custom fallback content
Usage Examples
- Basic Avatar:
<template> <UIAvatar src="user-avatar.jpg" alt="User Avatar" size="md" /></template>- 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>- 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>- 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
-
Image Handling:
- Use appropriate image sizes
- Implement lazy loading
- Handle load errors
- Optimize image assets
-
User Experience:
- Clear loading states
- Smooth transitions
- Responsive sizing
- Interactive feedback
-
Accessibility:
- Descriptive alt text
- ARIA labels
- Keyboard navigation
- Focus indicators
-
Performance:
- Cache images
- Optimize network requests
- Minimize reflows
- Handle memory efficiently
Common Use Cases
- 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>- 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>- 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