Skip to main content
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.

Props

items
DropdownMenuItem[][]
default:"[]"
required
Array of dropdown menu items grouped in nested arrays. Each group is separated by a divider.
userName
string
required
Display name of the user shown at the top of the dropdown
userEmail
string
default:""
Email address of the user displayed below the name
userTo
string
default:""
Navigation path for the user profile. If provided, clicking the user info navigates to this path.

Slots

default
required
Trigger element for the dropdown (typically an AButtonAvatarDropdown component)
Custom template for rendering user information. Receives item as slot prop.
[name: string]
Additional dynamic slots passed through to UDropdownMenu

Usage

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

Build docs developers (and LLMs) love