منوی زمینه — ContextMenu
ContextMenu فهرست کنشهای ثانویهٔ یک ناحیه را در مختصات اشارهگر نشان میدهد؛ مثلاً کارت یک ایده یا ردیف یک جدول. با کلیک راست، کلید منو یا Shift+F10 و لمس طولانی باز میشود. منو فقط یک میانبر است: هر کنش باید از مسیر دیگری هم در دسترس باشد. ساختار منو، رفتار کیبورد (از React Aria) و برچسب «(مخرب)» برای کنشهای خطرناک ثابت است.
وضعیت: beta · لایه: ۳ (کپی کد) · کد: کپی کد
import { ContextMenu } from '@tokapps/tuk';نمونهٔ زنده
روی این ناحیه کلیک راست کنید یا Shift+F10 بزنید.
کارت کمپین
کد قابل کپی
پایه: فهرست تخت با میانبر
import { ContextMenu } from '@tokapps/tuk';import { Icon } from '@tokapps/icons';const items = [ { id: 'copy', label: 'کپی متن', icon: <Icon name="copy" size="sm" />, shortcut: '⌘C' }, { id: 'link', label: 'کپی پیوند', icon: <Icon name="link.copy" size="sm" /> }, { id: 'delete', label: 'حذف ایده', icon: <Icon name="delete" size="sm" />, danger: true },];export function IdeaContextArea() { return ( <ContextMenu items={items} aria-label="کنشهای ایده" onAction={(id) => console.log(id)}> <div tabIndex={0}>متن ایده را اینجا بنویسید</div> </ContextMenu> );}حالت پیشرفته: بخشبندی با عنوان و کنش مخرب
import { ContextMenu } from '@tokapps/tuk';import { Icon } from '@tokapps/icons';const copy = { id: 'copy', label: 'کپی متن', icon: <Icon name="copy" size="sm" />, shortcut: '⌘C' };const link = { id: 'link', label: 'کپی پیوند', icon: <Icon name="link.copy" size="sm" /> };const remove = { id: 'delete', label: 'حذف ایده', icon: <Icon name="delete" size="sm" />, danger: true };export function CampaignCardMenu({ onAction }: { onAction: (id: string) => void }) { return ( <ContextMenu aria-label="کنشهای کارت" longPressMs={500} onAction={onAction} sections={[ { id: 'share', items: [copy, link] }, { id: 'danger', heading: 'خطرناک', items: [remove] }, ]} > <div tabIndex={0}>کارت کمپین</div> </ContextMenu> );}حالت غیرفعال: منوی بسته و کنشهای آیتم
import { ContextMenu } from '@tokapps/tuk';const items = [ { id: 'copy', label: 'کپی متن' }, { id: 'publish', label: 'انتشار', disabled: true },];export function ReadOnlyRow({ locked }: { locked: boolean }) { return ( <ContextMenu items={items} aria-label="کنشهای ردیف" disabled={locked}> <div tabIndex={0}>ردیف جدول</div> </ContextMenu> );}همهٔ پیکربندیها
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| کپی کد | کپی کد | — | فهرست تخت. یکی از کپی کد یا کپی کد لازم است. |
| کپی کد | کپی کد | — | فهرست بخشبندیشده؛ اگر داده شود، کپی کد نادیده گرفته میشود. |
| کپی کد | کپی کد | — | اجرای کنش با شناسهٔ آیتم. |
| کپی کد | کپی کد | — (الزامی) | ناحیهٔ فعال. برای کیبورد، فرزند باید فوکوسپذیر باشد. |
| کپی کد | کپی کد | کپی کد | نام منو برای صفحهخوان. |
| کپی کد | کپی کد | کپی کد | اگر کپی کد باشد منوی ContextMenu باز نمیشود و منوی مرورگر به حال خود میماند. |
| کپی کد | کپی کد (ms) | کپی کد | مدت لمس طولانی برای باز شدن. |
| کپی کد | کپی کد | — | مقصد صدای این نمونه؛ بدون آن، مقصد سراسری صدا (در صورت ثبت) استفاده میشود. |
| کپی کد | کپی کد (کپی کد یا کپی کد) | کپی کد | رفتار چاپ. |
| کپی کد | کپی کد | — | جهت صریح؛ بدون مقدار، جهت از ساختار صفحه میآید. |
| کپی کد | کپی کد | — | کلاس روی منو. |
فیلدهای کپی کد
| فیلد | نوع | پیشفرض | توضیح |
|---|---|---|---|
| کپی کد | کپی کد | — (الزامی) | شناسهٔ یکتا؛ در کپی کد برگردانده میشود. |
| کپی کد | کپی کد | — (الزامی) | برچسب آیتم؛ نام دسترسی آیتم از آن گرفته میشود. |
| کپی کد | کپی کد | — | آیکون، معمولاً کپی کد با نام معنایی. |
| کپی کد | کپی کد | — | میانبر نمایشی (مثلاً کپی کد) که همیشه LTR نمایش داده میشود. |
| کپی کد | کپی کد | کپی کد | رنگ خطر و برچسب متنی «(مخرب)» برای صفحهخوان. |
| کپی کد | کپی کد | کپی کد | آیتم غیرفعال. |
| کپی کد | کپی کد | — | هنگام اجرای همین آیتم صدا زده میشود. همزمان کپی کد سطح منو با شناسهٔ آیتم هم صدا زده میشود. |
فیلدهای کپی کد
| فیلد | نوع | پیشفرض | توضیح |
|---|---|---|---|
| کپی کد | کپی کد | — (الزامی) | شناسهٔ بخش. |
| کپی کد | کپی کد | — | عنوان بخش؛ گروه نامدار برای صفحهخوان. |
| کپی کد | کپی کد | — (الزامی) | آیتمهای بخش. |
ساختار و اسلاتها
ترتیب اجزا: کپی کد و پس از آن لنگر مجازی کپی کد و منوی شناور کپی کد.
- بنیان ثابت: ناحیه کپی کد · لنگر مجازی (کپی کد، ثابتشده در مختصات اشارهگر) · منوی کپی کد با نقش کپی کد · آیتمهای کپی کد با نقش کپی کد · کپی کد · کپی کد (کلید کپی کد) · کپی کد · کپی کد.
- قابلتغییر: کپی کد روی منو، آیکون و میانبر آیتم، و توکنهای کپی کد و کپی کد.
همهٔ حالتها
| حالت | نشانه (data-attribute یا prop) | نمایش |
|---|---|---|
| بسته (پیشفرض) | منو در DOM دیده نمیشود | فقط ناحیه نمایش داده میشود. |
| باز | کپی کد · کپی کد | منو با محو و بزرگشدن کوچک در مختصات اشارهگر ظاهر میشود. |
| بستهشدن | کپی کد | منو محو میشود. |
| آیتم focused | کپی کد | پسزمینهٔ کپی کد. |
| آیتم hover | کپی کد | پسزمینهٔ کپی کد. |
| آیتم pressed | کپی کد | پسزمینهٔ کپی کد. |
| آیتم focus-visible | کپی کد | حلقهٔ کپی کد داخل آیتم. |
| آیتم disabled | کپی کد (prop کپی کد) | رنگ کمرنگ و بدون پاسخ به کلیک. |
| آیتم danger | کپی کد (prop کپی کد) | رنگ کپی کد و برچسب «(مخرب)» برای صفحهخوان. |
| منو غیرفعال | prop کپی کد روی ContextMenu | منوی زمینه باز نمیشود؛ منوی مرورگر دیده میشود. |
| لمس طولانی | کپی کد | پس از مدت تعیینشده باز میشود؛ اگر انگشت بیش از ۱۰px جابهجا شود، لغو میشود. |
قرارداد پوشش (Overlay Contract)
- دام فوکوس: منو غیرمودال است؛ فوکوس را مدیریت میکند و با بستهشدن به عنصر قبلی برمیگردد. آیتم فوکوسدار حلقهٔ مرئی دارد.
- Escape: منو را میبندد و طبق قرارداد a11y فوکوس به ناحیه برمیگردد. در کد صراحتاً بازگشت فوکوس به ناحیه تعریف نشده است؛ محرک Popover یک لنگر مخفی و غیرفوکوسپذیر است، پس این رفتار باید در تست بررسی شود.
- پسزمینه (backdrop): پرده رسم نمیشود؛ کلیک بیرون از منو آن را میبندد. انتخاب آیتم هم منو را میبندد.
- قفل اسکرول: قفل اسکرول ندارد؛ موقعیت با اسکرول بهروز میشود یا منو بسته میشود.
- کشیدن برای بستن: ندارد.
- تودرتو: زیرمنو و شناور درون مودال پشتیبانی میشود (z-index شناور بالاتر از مودال است).
تغییرات مجاز برای توسعهدهنده
- variant: کپی کد (فهرست تخت با کپی کد) یا کپی کد (بخشبندی با کپی کد).
- size: فقط کپی کد.
- آیتم: کپی کد، کپی کد، کپی کد، کپی کد، کپی کد.
- بخش: کپی کد برای عنوان و جداکننده خودکار بین بخشها.
- نقاط توسعه: کپی کد؛ کپی کد؛ کپی کد؛ کپی کد؛ کپی کد (رویداد کپی کد و کپی کد)؛ کپی کد؛ توکنهای سطح کامپوننت کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد؛ و پیامهای متنی کپی کد.
تغییرات ممنوع (بنیان ثابت)
- ساختار DOM ناحیه، لنگر مجازی و منو.
- نقش کپی کد و کپی کد و کپی کد الزامی منو.
- رفتار کیبورد: کپی کد، کپی کد، کپی کد، کپی کد، کپی کد و کپی کد از React Aria میآیند.
- برچسب «(مخرب)» برای آیتمهای کپی کد.
- هدف لمسی ۴۴px روی اشارهگر درشت (کپی کد).
- کاهش حرکت: حذف انیمیشن ورود و خروج.
- منو فقط میانبر است؛ نباید تنها راه رسیدن به یک کنش شود.
RTL، کیبورد و صفحهخوان
- RTL: جایگذاری کپی کد منطقی است. میانبر (کپی کد) LTR و ایزوله (کپی کد) نمایش داده میشود.
- کیبورد: کپی کد یا کلید منو باز میکند (رویداد کپی کد مرورگر). کپی کد و کپی کد بین آیتمها حرکت میکنند، کپی کد و کپی کد به ابتدا و انتها میروند، کپی کد کنش را اجرا و کپی کد منو را میبندد.
- صفحهخوان: منو کپی کد با کپی کد است؛ آیتمها کپی کد هستند؛ بخشها گروه نامدار هستند؛ آیتم مخرب با «(مخرب)» اعلام میشود.
صدا، حرکت، چاپ و کاهش حرکت
- صدا: opt-in است. رویداد کپی کد (کپی کد) هنگام باز شدن و کپی کد (کپی کد) هنگام انتخاب. مقصد: کپی کد روی همین نمونه، یا مقصد سراسری که با کپی کد ثبت شده است؛ بدون هیچکدام بیصداست. هیچوقت برای hover صدا پخش نمیشود. معادل بصری: برجسته شدن آیتم و بسته شدن منو.
- حرکت: نام معنایی کپی کد با خواص کپی کد و کپی کد. با کپی کد یا کپی کد بدون انیمیشن است.
- چاپ: پیشفرض کپی کد و در چاپ پنهان است. در کد کپی کد قاعدهٔ کپی کد بدون شرط کپی کد منو را پنهان میکند؛ یعنی کپی کد عملاً اثری ندارد.
توکنها
- فایل توکنهای کامپوننتی: کپی کد (گروه overlays؛ این کامپوننت توکن کپی کد اختصاصی ندارد).
- توکنهای سطح کامپوننت مصرفی: کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد و سایر موارد در کپی کد.
- توکنهای معنایی مصرفی: کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد، کپی کد.
- فهرست کامل: کپی کد.
قرارداد ARCH
- آیکون آیتمها فقط با کپی کد و نام معنایی (مثلاً کپی کد) تعیین میشود؛ مسیر asset در کد مصرفکننده نمیآید.
- تم فقط حرکت و توکنهای مجاز را تغییر میدهد؛ DOM، ARIA و کیبورد ثابتاند.
- gesture این کامپوننت لمس طولانی است؛ معادل کیبوردی آن Shift+F10 یا کلید منو، و معادل اشارهگر کلیک راست است.
نکات
- برای جستجوی سراسری کنشها از CommandMenu استفاده کنید.
- برای محتوای غیرمنو (فرم یا انتخاب بلند) از Popover استفاده کنید.
- برای ناوبری اصلی از Navigation استفاده کنید، نه منوی زمینه.
- در موبایل، کنشهای مهم را در برگهٔ زندهٔ داک هم در دسترس بگذارید تا فقط به لمس طولانی وابسته نباشند.