پرتوپرتو

نوار ناوبری (NavRail)

سایدبار دوگانه حرفه‌ای با نوار آیکون و پنل ثانویه — الهام‌گرفته از Supabase

معرفی

کامپوننت NavRail یک سیستم ناوبری دوگانه است که شامل یک نوار آیکون باریک (Rail) و یک پنل ثانویه (Panel) می‌باشد. این الگو برای محصولات SaaS با صفحات و زیرمجموعه‌های متعدد طراحی شده است.

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

  • محصولات با بخش‌های متعدد و ساب‌ناوبری در هر بخش
  • داشبوردهای تحلیلی با فیلترها و تنظیمات هر صفحه
  • اپلیکیشن‌هایی که نیاز به دسته‌بندی سطح بالا و زیرمنوی متغیر دارند

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

  • اپلیکیشن‌های ساده با کمتر از ۵ صفحه — از Sidebar استفاده کنید
  • صفحات بدون ساختار سلسله‌مراتبی — از NavigationMenu یا Tabs استفاده کنید
  • فقط موبایل — از bottom navigation استفاده کنید

محتوای صفحه

روی آیکون‌های نوار کناری کلیک کنید تا پنل‌های مختلف باز شوند.

استفاده

import {
  NavRailProvider,
  NavRail,
  NavRailHeader,
  NavRailFooter,
  NavRailItem,
  NavRailContent,
  NavPanel,
  NavPanelHeader,
  NavPanelContent,
  AppLayout,
  AppLayoutContent,
  NavRailTrigger,
} from '@parto-system-design/ui'
import { LayoutDashboard, Search, Settings } from 'lucide-react'

export default function MyApp() {
  return (
    <NavRailProvider defaultActiveItem="dashboard" defaultPanelOpen>
      <AppLayout>
        <NavRail>
          <NavRailHeader>
            <Logo />
          </NavRailHeader>
          <NavRailContent>
            <NavRailItem itemId="dashboard" icon={<LayoutDashboard />} label="داشبورد" />
            <NavRailItem itemId="search" icon={<Search />} label="جستجو" />
          </NavRailContent>
          <NavRailFooter>
            <NavRailItem itemId="settings" icon={<Settings />} label="تنظیمات" />
          </NavRailFooter>
        </NavRail>

        <NavPanel forItem="dashboard">
          <NavPanelHeader title="داشبورد" />
          <NavPanelContent>{/* ساب‌ناوبری داشبورد */}</NavPanelContent>
        </NavPanel>

        <NavPanel forItem="search">
          <NavPanelHeader title="جستجو" />
          <NavPanelContent>{/* فیلترهای جستجو */}</NavPanelContent>
        </NavPanel>

        <AppLayoutContent>{/* محتوای صفحه */}</AppLayoutContent>
      </AppLayout>
    </NavRailProvider>
  )
}

حالت‌ها و انواع

حالت کنترل‌شده

برای کنترل state از بیرون (مثلاً وقتی routing مدیریت می‌شود):

const [activeItem, setActiveItem] = React.useState('dashboard')
const [panelOpen, setPanelOpen] = React.useState(true)

<NavRailProvider
  activeItem={activeItem}
  onActiveItemChange={setActiveItem}
  panelOpen={panelOpen}
  onPanelOpenChange={setPanelOpen}
>
  {/* ... */}
</NavRailProvider>

استفاده با Sidebar Primitives

داخل NavPanelContent می‌توانید از کامپوننت‌های Sidebar موجود استفاده کنید:

<NavPanel forItem="dashboard">
  <NavPanelHeader title="داشبورد" />
  <NavPanelContent>
    <SidebarProvider defaultOpen>
      <SidebarMenu>
        <SidebarMenuItem>
          <SidebarMenuButton isActive>نمای کلی</SidebarMenuButton>
        </SidebarMenuItem>
        <SidebarMenuItem>
          <SidebarMenuButton>شاخص‌ها</SidebarMenuButton>
        </SidebarMenuItem>
      </SidebarMenu>
    </SidebarProvider>
  </NavPanelContent>
</NavPanel>

رفتار موبایل

در موبایل، Rail و Panel مخفی می‌شوند و با NavRailTrigger به صورت drawer باز می‌شوند:

<AppBar
  logo={
    <>
      <NavRailTrigger />
      <span>برنامه من</span>
    </>
  }
/>

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

بکنید

  • برای هر بخش اصلی یک NavRailItem با آیکون مشخص قرار دهید - محتوای Panel را متناسب با هر بخش تنظیم کنید (ساب‌ناوبری، فیلترها، جستجو) - از NavRailSeparator برای گروه‌بندی بصری آیکون‌ها استفاده کنید

نکنید

  • بیش از ۸ آیکون در Rail قرار ندهید — اولویت‌بندی کنید - Panel را برای محتوای اصلی استفاده نکنید — فقط ناوبری و فیلترها - آیکون‌های بدون tooltip نگذارید — label برای همه آیتم‌ها الزامی است

جدول ویژگی‌ها

ویژگینوعپیش‌فرضتوضیحات
defaultActiveItemstring | nullnullآیتم فعال اولیه (uncontrolled)
activeItemstring | nullآیتم فعال (controlled)
onActiveItemChange(id: string | null) => voidcallback تغییر آیتم فعال
defaultPanelOpenbooleanfalseوضعیت اولیه پنل (uncontrolled)
panelOpenbooleanوضعیت پنل (controlled)
onPanelOpenChange(open: boolean) => voidcallback تغییر وضعیت پنل
ویژگینوعپیش‌فرضتوضیحات
side'start' | 'end''start'موقعیت نوار (در RTL، start = سمت راست)
ویژگینوعپیش‌فرضتوضیحات
itemIdstringشناسه یکتا (باید با forItem پنل مطابقت داشته باشد)
iconReactNodeآیکون نمایشی
labelstringمتن tooltip و aria-label
isActivebooleanوضعیت فعال (خودکار از context، قابل override)
asChildbooleanfalseاستفاده از Slot برای عناصر سفارشی مثل Link
ویژگینوعپیش‌فرضتوضیحات
forItemstringشناسه آیتم Rail مربوطه
ویژگینوعپیش‌فرضتوضیحات
titlestringعنوان پنل
showClosebooleantrueنمایش دکمه بستن

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

تعاملات کیبورد

کلیدعملکرد
Ctrl/Cmd + \باز/بسته کردن پنل
Escapeبستن پنل
Enter / Spaceفعال کردن آیتم Rail

ویژگی‌های ARIA

  • Rail: role="navigation" با aria-label="ناوبری اصلی"
  • Panel: role="complementary" با aria-hidden در حالت بسته
  • آیتم فعال: aria-current="page"
  • هر آیتم: aria-label از prop label

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

  • اگر فقط یک سایدبار ساده بدون Rail نیاز دارید ← Sidebar
  • برای ناوبری افقی بالای صفحه ← AppBar
  • برای ترکیب کامل AppShell با NavRail ← الگوی AppShell