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

قطعه‌های نوار ناوبری (نوار آیکونی که با اشاره‌گر باز می‌شود) که ProductFrame روی آن ساخته شده است — برای قاب برنامه خودِ ProductFrame را به کار ببرید

برای قاب برنامه منسوخ از 4.0

قاب برنامهٔ همهٔ محصولات ProductFrame است، یک بار در layout ریشه. قاب دست‌ساز از NavRailProvider/NavRail/AppLayout را برای ساختن قاب برنامه به کار نبرید؛ ProductFrame روی همین اجزا ساخته شده است؛ خانوادهٔ NavRail برای ساختن اجزای دیگر سیستم طراحی باقی می‌ماند.

معرفی

NavRail خانوادهٔ قطعه‌های نوار ناوبری است که ProductFrame روی آن ساخته شده: در حالت جمع فقط آیکون‌ها را در عرض 48 پیکسل نشان می‌دهد و با اشاره‌گر (hover) به 208 پیکسل باز می‌شود و برچسب‌ها را آشکار می‌کند — به‌صورت یک لایهٔ روی محتوا، بنابراین چیدمان صفحه هرگز جابه‌جا نمی‌شود. سه حالت رفتاری دارد که در localStorage ذخیره می‌شود.

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

  • هنگام ساختن جزء تازه‌ای در خود سیستم طراحی که نوار ناوبری لازم دارد، یا نگه‌داری قابی که هنوز به ProductFrame مهاجرت نکرده است.

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

  • ناوبری اصلی یک برنامهٔ چندصفحه‌ای، چه منوی برچسب‌دار چه نوار آیکونی → ProductFrame، یک بار در layout ریشه (navMode="rail" همین نوار آیکونی است).
  • ناوبری ساده و تک‌سطحی درون یک صفحه → NavTree.
  • ساب‌ناوبری هر بخش → سطح زیرمجموعهٔ منوی ProductFrame (children مقصد در nav)؛ جست‌وجو و فیلترهای یک صفحهٔ فهرست → search و filters قالب ListPage (PageToolbar فقط درون یک CustomPage). AppSecondary + SecondaryNav کنار نوار فقط برای قاب‌های پیش از 4.0 است.

محتوای صفحه

نوار در حالت پیش‌فرض جمع (48px) است و با اشاره‌گر باز می‌شود؛ از کنترل پایین می‌توانید حالت را به «همیشه باز» یا «همیشه جمع» تغییر دهید.

زمین بازی

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

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

استفاده

ترکیب قطعه‌ها، برای نگه‌داری قاب‌های پیش از 4.0 و ساختن اجزای سیستم طراحی؛ قاب برنامهٔ تازه را این‌طور نسازید، ProductFrame همین ترکیب را با منوی داده‌محور می‌دهد.

import {
  NavRailProvider,
  NavRail,
  NavRailHeader,
  NavRailContent,
  NavRailItem,
  NavRailFooter,
  NavRailBehaviorToggle,
  AppLayout,
  AppLayoutContent,
} from '@partodata/ui'
import { LayoutDashboard, Search, Settings } from 'lucide-react'

export default function LegacyRailFrame() {
  const [active, setActive] = React.useState('dashboard')

  return (
    <NavRailProvider side="start" defaultBehavior="expandable">
      <AppLayout>
        <NavRail>
          <NavRailHeader>
            <Logo />
          </NavRailHeader>
          <NavRailContent>
            <NavRailItem
              itemId="dashboard"
              icon={<LayoutDashboard />}
              label="داشبورد"
              isActive={active === 'dashboard'}
              onClick={() => setActive('dashboard')}
            />
            <NavRailItem
              itemId="search"
              icon={<Search />}
              label="جستجو"
              isActive={active === 'search'}
              onClick={() => setActive('search')}
            />
          </NavRailContent>
          <NavRailFooter>
            <NavRailItem itemId="settings" icon={<Settings />} label="تنظیمات" />
            <NavRailBehaviorToggle />
          </NavRailFooter>
        </NavRail>

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

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

حالت‌های رفتاری

نوار سه حالت دارد که کاربر از طریق کنترل پایین (NavRailBehaviorToggle، آیکون PanelLeftDashed) عوض می‌کند و انتخابش در localStorage با کلید parto-sidebar-behavior ذخیره می‌شود:

حالترفتار
expandableپیش‌فرض — جمع (48px)، با اشاره‌گر به 208px باز می‌شود (لایهٔ روی محتوا، بدون جابه‌جایی)
openهمیشه باز — چیدمان کل 208px را رزرو می‌کند (بدون overlay)
closedهمیشه جمع — اشاره‌گر کاری نمی‌کند
<NavRailProvider defaultBehavior="open">{/* ... */}</NavRailProvider>

برای کنترل کامل از بیرون، behavior و onBehaviorChange را بدهید:

const [behavior, setBehavior] = React.useState<NavRailBehavior>('expandable')

<NavRailProvider behavior={behavior} onBehaviorChange={setBehavior}>
  {/* ... */}
</NavRailProvider>

پنل جانبی (Part 2)

برای محتوای فرعیِ ماندگار (فیلترها، ساب‌ناوبری، فهرست گزارش‌ها) از AppSecondary در کنار نوار استفاده کنید و داخلش از خانوادهٔ SecondaryNav بهره بگیرید:

<NavRailProvider>
  <AppLayout>
    <NavRail>{/* ... */}</NavRail>
    <AppSecondary resizable>
      <AppSecondaryHeader>
        <AppSecondaryTitle>گزارش‌ها</AppSecondaryTitle>
      </AppSecondaryHeader>
      <AppSecondaryContent className="p-2">
        <SecondaryNavSearchInput placeholder="جستجو…" aria-label="جستجو" />
        <SecondaryNavTitle>پیشنهادی</SecondaryNavTitle>
        <SecondaryNavItem isActive>نمای کلی هفتگی</SecondaryNavItem>
        <SecondaryNavItem>روند تعامل</SecondaryNavItem>
      </AppSecondaryContent>
    </AppSecondary>
    <AppLayoutContent>{/* محتوا */}</AppLayoutContent>
  </AppLayout>
</NavRailProvider>

رفتار موبایل

در موبایل، نوار به یک Sheet تبدیل می‌شود که با NavRailTrigger باز می‌شود و آیتم‌ها را با برچسب کامل نشان می‌دهد. اگر AppSecondary هم داشته باشید، محتوای آن به‌صورت خودکار داخل همان Sheet، زیر آیتم‌های ناوبری قرار می‌گیرد تا محتوای بخش فعال در موبایل هم در دسترس بماند:

<SiteHeaderStart>
  <NavRailTrigger />
  {/* عنوان */}
</SiteHeaderStart>

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

بکنید

  • برای هر مقصد اصلی یک NavRailItem با آیکون و label مشخص بگذارید — برچسب هم tooltip حالت جمع است و هم متن حالت باز. - کنترل حالت (NavRailBehaviorToggle) را در پاورقی نوار قرار دهید تا کاربر بتواند نوار را «همیشه باز» یا «همیشه جمع» کند. - از NavRailSeparator برای گروه‌بندی بصری آیکون‌ها استفاده کنید.

نکنید

  • بیش از 8 آیکون در نوار نگذارید — اولویت‌بندی کنید. - label را برای هیچ آیتمی خالی نگذارید؛ هم برای tooltip و هم برای دسترس‌پذیری الزامی است. - محتوای فرعی هر بخش را داخل خود نوار نگذارید؛ برای آن AppSecondary هست.

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

Prop

Type

Prop

Type

Prop

Type

کنترل پاورقی برای تغییر حالت رفتاری نوار. بدون prop؛ حالت را از NavRailProvider می‌خواند.

AppSecondary

Prop

Type

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

ویژگی‌های ARIA

  • نوار: role="navigation" با aria-label="ناوبری اصلی".
  • آیتم فعال: aria-current="page".
  • هر آیتم: aria-label از prop label (چه جمع، چه باز).
  • دستهٔ تغییر عرض پنل جانبی: role="separator" با aria-label.

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

کلیدعملکرد
Tabحرکت بین آیتم‌ها (و دستهٔ تغییر عرض پنل جانبی)
Enter / Spaceفعال‌کردن آیتم
← / →روی دستهٔ تغییر عرض: تغییر عرض پنل جانبی (گام 16px، بین 256 تا 512)

نوار عمداً میان‌بر کیبوردیِ باز/بسته ندارد (مطابق استودیوی Supabase)؛ حالت از طریق کنترل پاورقی تغییر می‌کند.

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

  • برای قاب برنامه ← ProductFrame — روی همین نوار ساخته شده است.
  • برای محتوای پنل جانبی (Part 2) ← SecondaryNav.
  • برای ناوبری درختی ساده درون یک صفحه ← NavTree.
  • برای هدر بالای صفحه ← SiteHeader.