پرتوپرتو

منوی کاربر (UserMenu)

dropdown حساب کاربری با آواتار trigger + هدر مشخصات + آیتم‌های مقطع‌بندی‌شده (پروفایل، تنظیمات، تم، خروج)

معرفی

UserMenu یک dropdown استاندارد برای منوی حساب کاربری است که روی یک trigger آواتاری نشسته. درون‌ش: هدر مشخصات کاربر (نام، ایمیل، نقش) + لیست آیتم‌های قابل‌تنظیم با پشتیبانی از separator، label، و submenu یک‌سطح.

چه زمانی استفاده کنیم:

  • در SiteHeaderEnd نزدیک NotificationCenter برای دسترسی به پروفایل، تنظیمات، تم، و خروج
  • در App Shell mobile (drawer) به جای نوار هدر افقی
  • هر جای دیگری که نیاز به یک dropdown هویتی دارید

چه زمانی استفاده نکنیم:

  • برای action menu یک ردیف جدول — از DropdownMenu مستقیم استفاده کنید
  • برای انتخاب یکی از چند گزینه — از Select یا RadioGroup استفاده کنید
  • وقتی هدر هویتی نیاز نیست و صرفاً چند menu-item دارید — DropdownMenu ساده کافی است
آیکون روی آواتار کلیک کنید

زمین بازی

با تغییر تنظیمات زیر، پیش‌نمایش زنده را مشاهده کنید.

زمین بازی
تنظیمات
ظاهر
محتوا
داده
3
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

import { UserMenu, type UserMenuItem } from '@parto-system-design/ui'
import { User, Settings, Moon, LogOut } from 'lucide-react'

const items: UserMenuItem[] = [
  { label: 'پروفایل', icon: User, onSelect: () => router.push('/profile') },
  { label: 'تنظیمات', icon: Settings, shortcut: 'mod+,', onSelect: openSettings },
  { type: 'separator' },
  { label: 'حالت تاریک', icon: Moon, onSelect: toggleTheme },
  { type: 'separator' },
  { label: 'خروج', icon: LogOut, destructive: true, onSelect: logout },
]

<UserMenu
  user={{
    name: 'علی رضایی',
    email: 'ali@parto.ir',
    role: 'تحلیل‌گر ارشد',
  }}
  items={items}
/>

Discriminated Union برای آیتم‌ها

UserMenuItem چهار نوع دارد:

type UserMenuItem =
  | { type?: 'item'; label: string; icon?; shortcut?; onSelect; destructive?; disabled? }
  | { type: 'separator' }
  | { type: 'label'; label: string } // section heading (uppercase tracked)
  | { type: 'submenu'; label: string; icon?; items: UserMenuItem[] }
  • آیتم پیش‌فرض (type حذف شود یا 'item' باشد): یک ردیف قابل‌کلیک. destructive آن را قرمز می‌کند.
  • 'separator': خط افقی
  • 'label': سرگروه بصری (مثل "سازمان")
  • 'submenu': submenu تودرتو — یک سطح

تم (theme toggle)

برای حفظ استقلال DS از هر theme library (next-themes، خودش)، UserMenu توکن theme-toggle ندارد. یک آیتم معمولی با onSelect بنویسید که تم را در سطح اپ بدل کند:

import { useTheme } from 'next-themes'

function useThemeToggleItem(): UserMenuItem {
  const { theme, setTheme } = useTheme()
  return {
    label: theme === 'dark' ? 'حالت روشن' : 'حالت تاریک',
    icon: theme === 'dark' ? Sun : Moon,
    onSelect: () => setTheme(theme === 'dark' ? 'light' : 'dark'),
  }
}

trigger فشرده یا بزرگ

اگر در موبایل یا sidebar سپری استفاده می‌کنید، از size="sm" بدون showNameInTrigger استفاده کنید. در هدر دسکتاپ، showNameInTrigger اسم کاربر را کنار آواتار می‌آورد (روی mobile هنوز پنهان می‌شود).

Props

Prop

Type

UserMenuUser

Prop

Type

راهنمای استفاده

بکنید

  • role را برای تمایز کاربرانی که در چند سازمان عضوند نمایش دهید - destructive: true را فقط برای خروج استفاده کنید — نه برای هر عمل «خطرناک» - برای منوی شاخص تم، از submenu با سه حالت (روشن / تاریک / سیستمی) استفاده کنید، نه toggle دوحالته

نکنید

  • بیش از یک submenu تودرتو نکنید — depth بیشتر قابل کشف نیست - چیزی غیر از action یا navigation درون این منو نگذارید — این hub شخصی کاربر است، نه منوی اپ - theme toggle را به صورت checkbox یا switch درون dropdown نگذارید — از item با state-based label استفاده کنید

دسترسی‌پذیری

  • trigger aria-label متناسب با locale دارد («منوی حساب»)
  • dropdown از DropdownMenu Radix استفاده می‌کند — کیبوردی کامل (Tab، Arrow Up/Down، Enter، Escape)
  • آیتم destructive با رنگ قرمز + focus highlight قرمز از سایر آیتم‌ها بصری متمایز است

کامپوننت‌های مرتبط

  • DropdownMenu — primitive که UserMenu روی آن است
  • Avatar — درون trigger و هدر dropdown استفاده می‌شود
  • SiteHeader — مصرف‌کننده‌ی اصلی UserMenu