Xzero UI
Pro library

User menu

Your account, settings, theme, and sign out behind the avatar. Opens as a bottom sheet on phones.

$ pnpm dlx shadcn@4.23.0 add @xzero-ui/user-menu
Live · keyboard ready

When to use

When not to use

Installation

Register both Xzero UI namespaces in your project's components.json:

{
  "registries": {
    "@xzero-ui": "https://mcp.xzero.co.uk/r/{name}.json",
    "@xzero-ui-pro": "https://mcp.xzero.co.uk/r/pro/{name}.json"
  }
}
npx shadcn@4.23.0 add @xzero-ui/user-menu

Install xzero-foundation once, and import @/components/xzero/foundation.css in your app root. No Xzero token is used by this snapshot. For sample portraits, photos, fonts, or logos, download https://mcp.xzero.co.uk/install-assets.mjs and run node xzero-install-assets.mjs <receiving-project>.

Usage

import { UserMenu } from "@/components/xzero/user-menu/user-menu";
import { CreditCard, Settings, UserRound } from "lucide-react";

export function TopBarAccount({ user }: { user: { name: string; email: string } }) {
  return (
    <UserMenu
      user={{ ...user, plan: "Pro" }}
      showName
      onThemeChange={setThemePreference}
      items={[
        { label: "Profile", icon: <UserRound size={16} />, onSelect: openProfile },
        { label: "Settings", icon: <Settings size={16} />, keys: ["⌘", ","], onSelect: openSettings },
        { label: "Billing", icon: <CreditCard size={16} />, onSelect: openBilling },
      ]}
      onSignOut={() => signOut()}
    />
  );
}

API reference

UserMenu

Account menu behind an avatar trigger: a compact identity header, a short group of account links, an inline theme switch, and sign out. Below 640px it opens as a bottom sheet.

PropTypeDefaultDescription
user (required)UserMenuUser–{ name, email, plan?, avatarSrc?, avatarSrcSet? }. Falls back to initials without a photo. plan shows as a small accent badge.
itemsUserMenuItem[][]Account destinations: { label, icon?, keys?, onSelect? }. Keep it to three or four. keys show quiet shortcut hints such as ["⌘", ","].
showNamebooleanfalseShows the name and a chevron beside the avatar from 640px up. Phones always show the avatar alone.
theme"light" | "dark" | "system"–Controlled theme preference.
defaultTheme"light" | "dark" | "system""system"Initial theme when uncontrolled.
onThemeChange(theme: ThemePreference) => void–Reports the choice. Applying it to the page is up to the app. The menu stays open.
showThemebooleantrueShows the inline light, dark, and system switch.
status"available" | "busy" | "away"–Controlled presence status. Passing status or onStatusChange adds the presence dot and an inline status switch.
defaultStatus"available" | "busy" | "away""available"Initial status when uncontrolled.
onStatusChange(status: UserStatus) => void–Called when a status is chosen. The menu stays open.
onSignOut() => void | Promise<unknown>–Sign out handler. A returned promise keeps the menu open with a spinner until it settles.
signOutKeysstring[]–Shortcut hint for the sign out item.
openboolean–Controlled open state.
defaultOpenbooleanfalseInitial open state when uncontrolled. A menu that starts open does not take focus.
onOpenChange(open: boolean) => void–Called when the menu opens or closes.
align"start" | "center" | "end""end"Panel alignment against the trigger.
portalbooleantrueRenders the desktop panel on the body. Pass false to keep it inside the trigger wrapper, for example in a contained preview. The mobile sheet always uses the body.
refRef<HTMLButtonElement>–The trigger button, for returning focus.
classNamestring–Extra class on the trigger.

PresenceDot

The status mark on its own, for avatars elsewhere in the app. Each status has its own shape as well as color.

PropTypeDefaultDescription
status (required)"available" | "busy" | "away" | "offline"–Status to show.
classNamestring–Extra class for positioning.

Keyboard interactions

KeysAction
Enter / Space / ArrowDownOpens the menu from the avatar and moves to the first row.
ArrowUpOpens the menu from the avatar and moves to the last row.
ArrowDown / ArrowUpMoves between rows, looping at the ends. The highlight follows.
Home / EndMoves to the first or last row.
A to ZTypeahead jumps to the next row starting with the typed letters.
ArrowLeft / ArrowRightChooses the previous or next option in the theme or status switch.
Enter / SpaceActivates the row, or chooses a theme or status without closing.
Escape / TabCloses the menu and returns focus to the avatar.

Accessibility

Motion

Responsive behavior

Performance

Notes for AI

Also in menus

Guidance for AI tools

User menu: Your account, settings, theme, and sign out behind the avatar. Opens as a bottom sheet on phones. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it.

Full library index: https://ui.xzero.co.uk/llms.txt

Browse all components