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

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

معرفی

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

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

  • منوی حساب هر محصول: آن را به user در ProductFrame بدهید (بدون size)؛ قاب آن را آخرین کنترل نوار بالا می‌گذارد، روی موبایل هم (آن‌جا فقط منوی ناوبری به پنل کشویی می‌رود)
  • هر جای دیگری که نیاز به یک dropdown هویتی دارید

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

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

زمین بازی

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

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

استفاده

import { UserMenu, type UserMenuItem } from '@partodata/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
  | { 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 فشرده یا بزرگ

بدون size، trigger روی نردبان کنترل‌هاست: دایره‌ای 30 پیکسلی (sm؛ تا 3٫x دایرهٔ 32 پیکسلی md)، هم‌قد دکمه‌های آیکونی کنارش. size="sm" و size="md" هندسهٔ ثابت قدیمی را نگه می‌دارند (دایرهٔ 28 و 32 پیکسلی). در هدر دسکتاپ، showNameInTrigger اسم کاربر را کنار آواتار می‌آورد (روی mobile هنوز پنهان می‌شود).

در قاب محصول، UserMenu را بدون size در جای user در ProductFrame بگذارید: همیشه آخرین کنترل نوار بالاست و trigger آن دایره‌ای هم‌قد دکمه‌های آیکونی همان ردیف (30 پیکسل) می‌شود. هر ردیف دیگری که ControlSizeProvider دارد هم همین کار را می‌کند؛ size صریح همیشه برنده است.

<ProductFrame product={product} nav={nav} themeToggle="user-menu" user={<UserMenu user={user} items={items} />}>
  {children}
</ProductFrame>

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 قرمز از سایر آیتم‌ها بصری متمایز است

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