The BDropdownAvatar component is a molecule that provides a dropdown menu with user information and action items. It’s designed to work with an avatar button trigger and displays the user’s name and email.
items
DropdownMenuItem[][]
default:"[]"
required
Array of dropdown menu items grouped in nested arrays. Each group is separated by a divider.
Display name of the user shown at the top of the dropdown
Email address of the user displayed below the name
Navigation path for the user profile. If provided, clicking the user info navigates to this path.
Trigger element for the dropdown (typically an AButtonAvatarDropdown component)
Custom template for rendering user information. Receives item as slot prop.
Additional dynamic slots passed through to UDropdownMenu
Basic Usage
<template>
<BDropdownAvatar
:items="menuItems"
user-name="John Doe"
user-email="[email protected]"
>
<AButtonAvatarDropdown src="/images/avatar.jpg" />
</BDropdownAvatar>
</template>
<script setup>
const menuItems = [
[
{ label: 'Profile', icon: 'i-lucide-user', click: () => navigateTo('/profile') },
{ label: 'Settings', icon: 'i-lucide-settings', click: () => navigateTo('/settings') }
],
[
{ label: 'Logout', icon: 'i-lucide-log-out', click: handleLogout }
]
]
function handleLogout() {
console.log('Logging out...')
}
</script>
With User Profile Navigation
<template>
<BDropdownAvatar
:items="menuItems"
user-name="Jane Smith"
user-email="[email protected]"
user-to="/my-profile"
>
<AButtonAvatarDropdown src="/images/jane.jpg" />
</BDropdownAvatar>
</template>
Without Email
<template>
<BDropdownAvatar
:items="menuItems"
user-name="Admin User"
>
<AButtonAvatarDropdown />
</BDropdownAvatar>
</template>
Custom User Info Slot
<template>
<BDropdownAvatar
:items="menuItems"
user-name="John Doe"
user-email="[email protected]"
>
<AButtonAvatarDropdown src="/images/avatar.jpg" />
<template #user="{ item }">
<div class="flex items-center gap-3">
<img :src="item.avatar" class="w-10 h-10 rounded-full" />
<div>
<strong>{{ item.userName }}</strong>
<p class="text-xs">{{ item.userEmail }}</p>
</div>
</div>
</template>
</BDropdownAvatar>
</template>
Complete Example with All Features
<template>
<BDropdownAvatar
:items="menuItems"
user-name="John Doe"
user-email="[email protected]"
user-to="/profile"
>
<AButtonAvatarDropdown src="/images/john-avatar.jpg">
John D.
</AButtonAvatarDropdown>
</BDropdownAvatar>
</template>
<script setup>
const menuItems = [
[
{
label: 'My Profile',
icon: 'i-lucide-user',
onSelect: () => navigateTo('/profile')
},
{
label: 'Account Settings',
icon: 'i-lucide-settings',
onSelect: () => navigateTo('/settings')
},
{
label: 'Billing',
icon: 'i-lucide-credit-card',
onSelect: () => navigateTo('/billing')
}
],
[
{
label: 'Documentation',
icon: 'i-lucide-book-open',
onSelect: () => window.open('/docs', '_blank')
},
{
label: 'Support',
icon: 'i-lucide-life-buoy',
onSelect: () => navigateTo('/support')
}
],
[
{
label: 'Sign Out',
icon: 'i-lucide-log-out',
onSelect: handleLogout
}
]
]
function handleLogout() {
// Logout logic
}
</script>
Implementation Details
The component automatically prepends a user info item to the menu:
const itemsComputed = computed((): DropdownMenuItem[][] => [
[
{
userName: props.userName,
userEmail: props.userEmail,
slot: 'user',
onSelect: () => {
const path = props.userTo
if (path) navigateTo(path)
},
},
],
...props.items,
])
Styling
The dropdown has a minimum width of 10rem (40 in Tailwind). If userTo is not provided, the first item’s hover state is disabled to prevent it from looking clickable.
Source: /home/daytona/workspace/source/app/components/b/dropdown/b-dropdown-avatar.vue:79