بلاک‌ها · موبایل

کشوی منو از لبهٔ شروع با پروفایل، موجودی کیف پول، پیوندها با شمارنده، حالت شب و خروج.

۱. نصب کامپوننت‌ها

این بلاک از ۱۰ آیتم دیگ استفاده می‌کند: app-baravatarbadgebuttoncontrol-sizeiconspersianseparatorsheetswitch

پکیج‌منیجر پیش‌فرض Node.jsنصب سریع با لینک سخت و دیسک مشترکYarn نسخهٔ ۲ به بالا (Berry)رانتایم و پکیج‌منیجر Bun
npx digdesign@latest add https://docs.digdesign.ir/r/app-bar.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/separator.json https://docs.digdesign.ir/r/sheet.json https://docs.digdesign.ir/r/switch.json
pnpm dlx digdesign@latest add https://docs.digdesign.ir/r/app-bar.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/separator.json https://docs.digdesign.ir/r/sheet.json https://docs.digdesign.ir/r/switch.json
yarn dlx digdesign@latest add https://docs.digdesign.ir/r/app-bar.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/separator.json https://docs.digdesign.ir/r/sheet.json https://docs.digdesign.ir/r/switch.json
bunx --bun digdesign@latest add https://docs.digdesign.ir/r/app-bar.json https://docs.digdesign.ir/r/avatar.json https://docs.digdesign.ir/r/badge.json https://docs.digdesign.ir/r/button.json https://docs.digdesign.ir/r/control-size.json https://docs.digdesign.ir/r/icons.json https://docs.digdesign.ir/r/persian.json https://docs.digdesign.ir/r/separator.json https://docs.digdesign.ir/r/sheet.json https://docs.digdesign.ir/r/switch.json

۲. کد صفحه

کد را در app/<route>/page.tsx بگذارید و متن‌ها، داده و هندلرها را با محصول خودتان عوض کنید.

mobile-menu.tsx
"use client"

import * as React from "react"

import {
  BellIcon,
  CreditCardIcon,
  GuideIcon,
  HeartIcon,
  LogoutIcon,
  MenuIcon,
  MoonIcon,
  ReceiptIcon,
  SettingsIcon,
  ShopIcon,
  TicketIcon,
  WalletIcon,
} from "@/components/icons"
import { AppBar, AppBarActions, AppBarLeading, AppBarTitle } from "@/components/ui/app-bar"
import { ControlSizeProvider } from "@/components/ui/control-size"
import { Avatar } from "@/components/ui/avatar"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Separator } from "@/components/ui/separator"
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@/components/ui/sheet"
import { Switch } from "@/components/ui/switch"
import { formatCurrency, toFaDigits } from "@/lib/persian"
import { stockImages } from "@/lib/stock-images"

const MAIN = [
  { title: "خانه", icon: <ShopIcon />, active: true },
  { title: "سفارش‌های من", icon: <ReceiptIcon />, badge: toFaDigits(2) },
  { title: "علاقه‌مندی‌ها", icon: <HeartIcon /> },
  { title: "کیف پول", icon: <WalletIcon /> },
  { title: "کارت‌های بانکی", icon: <CreditCardIcon /> },
]
const SUPPORT = [
  { title: "اعلان‌ها", icon: <BellIcon />, badge: toFaDigits(5) },
  { title: "پشتیبانی", icon: <TicketIcon /> },
  { title: "راهنما", icon: <GuideIcon /> },
  { title: "تنظیمات", icon: <SettingsIcon /> },
]

function MenuLink({ item }: { item: { title: string; icon: React.ReactNode; active?: boolean; badge?: string } }) {
  return (
    <a
      href="#"
      aria-current={item.active ? "page" : undefined}
      className={
        item.active
          ? "flex h-12 items-center gap-3 rounded-lg bg-primary-subtle px-3 font-semibold text-foreground [&_svg]:size-5 [&_svg]:text-brand-secondary"
          : "flex h-12 items-center gap-3 rounded-lg px-3 text-foreground transition-colors hover:bg-subtle [&_svg]:size-5 [&_svg]:text-muted-foreground"
      }
    >
      {item.icon}
      <span className="flex-1">{item.title}</span>
      {item.badge && (
        <Badge color="destructive">
          {item.badge}
        </Badge>
      )}
    </a>
  )
}

/**
 * منوی کناری اپ: در موبایل از لبهٔ شروع (راست در RTL) باز می‌شود. برای
 * پنلِ وب از Sidebar استفاده کنید که در موبایل خودش به همین کشو تبدیل می‌شود.
 */
export default function MobileMenuBlock() {
  const [open, setOpen] = React.useState(true)
  const [dark, setDark] = React.useState(false)

  return (
    <ControlSizeProvider size="xl" asChild>
    <div className="mx-auto flex min-h-svh w-full max-w-md flex-col bg-background">
      <AppBar sticky>
        <AppBarLeading>
          <Button variant="ghost" size="icon" aria-label="باز کردن منو" onClick={() => setOpen(true)}>
            <MenuIcon />
          </Button>
        </AppBarLeading>
        <AppBarTitle>فروشگاه دیگ</AppBarTitle>
        <AppBarActions>
          <Avatar alt="آرمیتا رستگار" size="sm" src={stockImages.personWoman1.src} />
        </AppBarActions>
      </AppBar>
      <main className="flex flex-1 items-center justify-center p-6 text-center text-sm text-muted-foreground">
        منو را با دکمهٔ بالا باز کنید.
      </main>

      <Sheet open={open} onOpenChange={setOpen}>
        <ControlSizeProvider size="xl" asChild>
          <SheetContent side="start" className="flex w-[85%] max-w-xs flex-col gap-0 p-0">
            <SheetHeader className="gap-5 border-b border-border p-4 pt-6">
              <SheetTitle className="sr-only">منوی اصلی</SheetTitle>
              <div className="flex items-center gap-3">
                <Avatar alt="آرمیتا رستگار" size="lg" src={stockImages.personWoman1.src} />
                <div className="flex min-w-0 flex-col">
                  <span className="truncate font-semibold">آرمیتا رستگار</span>
                  <bdi dir="ltr" className="text-sm text-muted-foreground">
                    {toFaDigits("0912 123 4567")}
                  </bdi>
                </div>
              </div>
              <div className="flex items-center justify-between gap-3 rounded-xl bg-inverse p-4 text-[var(--dig-white)] [--muted-foreground:var(--dig-neutral-400)]">
                <span className="flex flex-col gap-0.5">
                  <span className="text-xs text-muted-foreground">موجودی کیف پول</span>
                  <span className="text-lg font-black tabular-nums">{formatCurrency(1_345_000)}</span>
                </span>
                <Button variant="ghost" className="text-[var(--dig-white)] hover:bg-inverse-raised">
                  افزایش
                </Button>
              </div>
            </SheetHeader>

            <nav aria-label="منوی اصلی" className="flex flex-1 flex-col gap-1 overflow-y-auto p-4">
              {MAIN.map((item) => (
                <MenuLink key={item.title} item={item} />
              ))}
              <Separator className="my-2" />
              {SUPPORT.map((item) => (
                <MenuLink key={item.title} item={item} />
              ))}
              <div className="flex h-12 items-center gap-3 px-3 [&_svg]:size-5 [&_svg]:text-muted-foreground">
                <MoonIcon />
                <label htmlFor="dark-mode" className="flex-1">
                  حالت شب
                </label>
                <Switch id="dark-mode" checked={dark} onCheckedChange={setDark} />
              </div>
            </nav>

            <div className="border-t border-border p-4">
              <Button variant="ghost" color="destructive" fullWidth className="justify-start">
                <LogoutIcon />
                خروج از حساب
              </Button>
            </div>
          </SheetContent>
        </ControlSizeProvider>
      </Sheet>
    </div>
    </ControlSizeProvider>
  )
}