کاستومایز
منوی خطچینHook Sidebar
یه ستونِ ناوبری که یه خطِ خطچین از بالاش میآد پایین و با یه قلابِ گوشهدار به ردیفِ فعال قالب میشه؛ ردیفِ زیرِ نشانگر هم قلابِ کمرنگِ خودش رو میگیره.
وابستگیها
نوع تعامل
روی هر ردیف بزن تا انتخاب شه؛ خطِ رنگی از بالای فهرست تا مرکزِ همون ردیف میآد و با یه گوشهی ۶پیکسلی بهش وصل میشه. با عبورِ نشانگر (یا فوکوس با Tab) یه خطِ خطچینِ کمرنگ از ردیفِ فعال تا ردیفِ زیرِ نشانگر کشیده میشه تا معلوم باشه با زدن کجا میری. خط با فنر جابهجا میشه، نه با پرش. اگه `href` بدی ردیف پیوند میشه، وگرنه دکمه؛ در هر دو حالت `onChange` صدا زده میشه.
پراپها
گزینههایی که میتونی به کامپوننت بدی؛ ستارهدارها اجباریاند.
items*HookSidebarItem[]پیشفرض: ["حساب کاربری", "اعلانها", "امنیت"]ردیفها. هر آیتم یا رشته است یا `{ label, href }`؛ هر آیتم `href` دار بهصورت پیوند رندر میشه، بقیه دکمه.
labelstringعنوانِ بالای ستون. همونجا `aria-label`ِ ناوبری هم میشه، مگر خودت `aria-label` بدهی.
valuenumberایندکسِ انتخابشده در حالتِ کنترلشده. برای همگامکردن با مسیر (مثلاً با `usePathname`) همینه.
defaultValuenumberپیشفرض: 0ایندکسِ اولیه در حالتِ نامکنترلشده.
onChange(index: number) => voidبا هر انتخاب، ایندکسِ تازه رو برمیگردونه.
colorstringپیشفرض: var(--brand, currentColor)رنگِ خطِ فعال. هر مقدارِ CSS قبوله؛ اگه پروژهات `--brand` نداره، رنگِ متن میشه.
نصب
۱. این آدرس رو یکبار توی components.json بذار تا shadcn مخزن فارسیفای رو بشناسه.
{
"registries": {
"@farsify": "https://farsify.ir/r/{name}.json"
}
}۲. بعد با دستورِ زیر کامپوننت رو نصب کن.
npx shadcn@latest add @farsify/hook-sidebarپیشنیاز: Tailwind CSS v4 و صفحهٔ راستبهچپ dir="rtl".
نمونه
"use client";
import { useState } from "react";
import { HookSidebar } from "@/components/farsify/hook-sidebar";
const items = [
{ label: "حساب کاربری", href: "/settings/account" },
{ label: "اعلانها", href: "/settings/notifications" },
{ label: "امنیت", href: "/settings/security" },
{ label: "صورتحساب", href: "/settings/billing" },
];
export function SettingsMenu() {
const [active, setActive] = useState(0);
return (
<HookSidebar
label="تنظیمات"
className="w-52"
items={items}
value={active}
onChange={setActive}
/>
);
}
// خطِ یکدست با رنگِ دلخواه، بدونِ عنوان
<HookSidebar
className="w-44"
items={["خانه", "محصولات", "درباره"]}
dashed={false}
color="#007bff"
/>
// همگام با مسیر — خودِ کامپوننت به Next وابسته نیست، پس مسیر را شما میدهید
const pathname = usePathname();
const index = items.findIndex((item) => item.href === pathname);
<HookSidebar items={items} value={index} />نکتهها
- عرضِ ستون رو خودِ کامپوننت نمیسازه؛ `className="w-52"` یا هر عرضِ دیگهای بده تا ردیفها همعرضِ هم بشن.
- `next/link` عمداً import نشده — نسخهی تحویلی باید در پروژهی بدونِ Next هم کامپایل شه. اگه ناوبریِ نرم میخوای، `value` رو از مسیر بده.
- موقعیتِ خط با اندازهگیریِ DOM حساب میشه، پس متنِ بلند یا اندازهی فونتِ متفاوت چیز رو نمیشکنه؛ `ResizeObserver` همزمانِ ردیفها و کلِ فهرست رو نگاه میکنه.
- ستون در راستبهچپ از سمتِ راست میآد و قلاب به چپ برمیگرده؛ چیزی رو دستی آینه نکن.
- برای فهرستهای بلند ارتفاعِ ثابت با `overflow-y-auto` بهتره تا ستونِ بیپایان؛ خط داخلِ همون قاب اندازهگیری میشه.
مجوز
کد بعد از نصب مالِ خودته؛ هر تغییری خواستی بده و توی پروژهی خودت نگهش دار. برای پروژههای شخصی و تجاری آزاده، حتی اگه کدت بسته باشه. فقط اسم و لینک فارسیفای رو یه جا توی پروژه نگه دار.