Skip to content

UIAvatarGroup

UIAvatarGroup

A component that displays multiple avatars in a grouped layout with support for overflow handling, tooltips, and custom styling.

<template>
<UIAvatarGroup
:options="users"
:max="5"
:size="'md'"
:randomizeColor="true"
@click="handleAvatarClick"
>
<template #more="{ count }">
<div class="text-sm font-medium">
+{{ count }}
</div>
</template>
</UIAvatarGroup>
</template>
<script setup lang="ts">
interface User {
id: string
name: string
avatar?: string
color?: string
}
const users = ref<User[]>([
{
id: '1',
name: 'John Doe',
avatar: 'john.jpg'
},
{
id: '2',
name: 'Jane Smith',
avatar: 'jane.jpg'
},
{
id: '3',
name: 'Mike Johnson',
color: '#4F46E5'
}
])
</script>

Props

  • options (array): Array of avatar options
  • max (number): Maximum visible avatars
  • size (‘xs’ | ‘sm’ | ‘md’ | ‘lg’ | ‘xl’ | number): Avatar size
  • randomizeColor (boolean): Randomize background colors
  • maxRestCount (number): Maximum items in overflow
  • maxRestHeight (number): Maximum height of overflow dropdown
  • disableDropdown (boolean): Disable overflow dropdown
  • vertical (boolean): Stack avatars vertically
  • spacing (number): Space between avatars
  • reverse (boolean): Reverse avatar order
  • tooltipPlacement (string): Tooltip placement
  • tooltipOffset (number): Tooltip offset

Events

  • click: Avatar clicked
  • more-click: More button clicked
  • hover: Avatar hovered

Slots

  • more: Custom more indicator content
  • avatar: Custom avatar template
  • tooltip: Custom tooltip content

Usage Examples

  1. Basic Avatar Group:
<template>
<UIAvatarGroup
:options="members"
:max="3"
size="md"
/>
</template>
<script setup>
const members = [
{ name: 'John Doe', avatar: 'john.jpg' },
{ name: 'Jane Smith', avatar: 'jane.jpg' },
{ name: 'Mike Johnson', avatar: 'mike.jpg' },
{ name: 'Sarah Wilson', avatar: 'sarah.jpg' }
]
</script>
  1. Interactive Group with Tooltips:
<template>
<UIAvatarGroup
:options="teamMembers"
:max="5"
:randomizeColor="true"
tooltipPlacement="top"
>
<template #avatar="{ item }">
<UIAvatar
:src="item.avatar"
:size="'md'"
:round="true"
>
<template #indicator>
<div
class="absolute -bottom-0.5 -right-0.5 w-2.5 h-2.5 rounded-full border-2 border-white"
:class="{
'bg-success-500': item.online,
'bg-gray-300': !item.online
}"
/>
</template>
</UIAvatar>
</template>
<template #tooltip="{ item }">
<div class="p-2">
<div class="font-medium">
{{ item.name }}
</div>
<div class="text-sm text-gray-500">
{{ item.role }}
</div>
</div>
</template>
</UIAvatarGroup>
</template>
  1. Customized Overflow:
<template>
<UIAvatarGroup
:options="participants"
:max="4"
:maxRestCount="20"
>
<template #more="{ count, items }">
<UIPopover
trigger="click"
placement="bottom-start"
>
<template #trigger>
<div
class="w-10 h-10 rounded-full bg-gray-100 flex items-center justify-center cursor-pointer hover:bg-gray-200"
>
<span class="text-sm font-medium text-gray-600">
+{{ count }}
</span>
</div>
</template>
<div class="p-2 w-64">
<div class="font-medium mb-2">
Other Participants
</div>
<div class="space-y-2 max-h-60 overflow-auto">
<div
v-for="item in items"
:key="item.id"
class="flex items-center space-x-2 p-2 hover:bg-gray-50 rounded"
>
<UIAvatar
:src="item.avatar"
size="sm"
:round="true"
/>
<div class="flex-1">
<div class="text-sm font-medium">
{{ item.name }}
</div>
<div class="text-xs text-gray-500">
{{ item.email }}
</div>
</div>
</div>
</div>
</div>
</UIPopover>
</template>
</UIAvatarGroup>
</template>

Best Practices

  1. Visual Design:

    • Consistent sizing
    • Clear overflow indication
    • Proper spacing
    • Responsive layout
  2. User Experience:

    • Interactive feedback
    • Tooltip information
    • Smooth transitions
    • Clear navigation
  3. Accessibility:

    • ARIA labels
    • Keyboard navigation
    • Screen reader support
    • Focus management
  4. Performance:

    • Optimize image loading
    • Efficient rendering
    • Memory management
    • Event delegation

Common Use Cases

  1. Team Display:
<template>
<div class="space-y-2">
<div class="text-sm font-medium text-gray-500">
Team Members ({{ team.members.length }})
</div>
<UIAvatarGroup
:options="team.members"
:max="5"
:size="'md'"
class="mb-4"
/>
<UIButton
size="sm"
variant="outline"
@click="inviteMembers"
>
Add Members
</UIButton>
</div>
</template>
  1. Meeting Participants:
<template>
<div class="flex items-center justify-between p-4 border-b">
<div class="flex items-center space-x-4">
<h2 class="font-medium">
Meeting Participants
</h2>
<UIAvatarGroup
:options="participants"
:max="3"
:size="'sm'"
>
<template #more="{ count }">
<UIBadge variant="gray">
+{{ count }} others
</UIBadge>
</template>
</UIAvatarGroup>
</div>
<UIButton
size="sm"
@click="inviteParticipants"
>
Invite
</UIButton>
</div>
</template>
  1. Project Collaborators:
<template>
<div class="flex items-center space-x-2">
<UIAvatarGroup
:options="collaborators"
:max="4"
:size="'sm'"
:randomizeColor="true"
/>
<UIPopover
trigger="click"
placement="bottom-start"
>
<template #trigger>
<UIButton
size="sm"
variant="ghost"
class="!p-1"
>
<PlusIcon class="w-4 h-4" />
</UIButton>
</template>
<div class="p-4 w-80">
<UISearch
v-model="search"
placeholder="Search users..."
class="mb-4"
/>
<div class="space-y-2 max-h-60 overflow-auto">
<div
v-for="user in filteredUsers"
:key="user.id"
class="flex items-center justify-between p-2 hover:bg-gray-50 rounded"
>
<div class="flex items-center space-x-3">
<UIAvatar
:src="user.avatar"
size="sm"
:round="true"
/>
<div>
<div class="text-sm font-medium">
{{ user.name }}
</div>
<div class="text-xs text-gray-500">
{{ user.email }}
</div>
</div>
</div>
<UIButton
size="sm"
variant="ghost"
@click="addCollaborator(user)"
>
Add
</UIButton>
</div>
</div>
</div>
</UIPopover>
</div>
</template>

Component Composition

The UIAvatarGroup component works well with:

  • UIAvatar for individual avatars
  • UIPopover for overflow menus
  • UITooltip for information
  • UIBadge for counts
  • UIButton for actions
  • UISearch for filtering