useHotkeys
ثبت میانبرهای صفحهکلید با پشتیبانی cross-platform از کلید mod (Cmd/Ctrl) و مدیریت scope
معرفی
هوک useHotkeys یک میانبر صفحهکلید را ثبت میکند و هنگام unmount بهصورت خودکار حذفش میکند. گرامر combo از mod پشتیبانی میکند (روی macOS تبدیل به ⌘ و در سایر سیستمها Ctrl میشود)، و بهصورت هوشمند وقتی کاربر در حال تایپ در input است، میانبرهای بدون modifier را نادیده میگیرد.
چه زمانی استفاده کنیم
- ثبت میانبرهای سراسری در کامپوننت قاب برنامه، همانجا که
ProductFrameرندر میشود (مثلاًCtrl+Kبرای CommandPalette) - میانبرهای محلی برای عملیات صفحه (مثل
Escapeبرای بستن پنل،/برای focus در جستجو) - میانبر وظایف مشخص:
Mod+Sبرای ذخیره،Mod+Shift+Pبرای پالت فرمانها
چه زمانی استفاده نکنیم
- برای event های فرم یا primitive های Radix که خودشان keyboard handling دارند
- برای استفادهی همزمان با
Inputها بدون modifier — بهصورت پیشفرض رد میشود (برای تجربهی تایپ)
استفاده
پایه
import { useHotkeys } from '@partodata/ui'
// app/frame.tsx — کنار ProductFrame، یک بار برای کل برنامه
function GlobalShortcuts() {
const [paletteOpen, setPaletteOpen] = React.useState(false)
useHotkeys('mod+k', () => setPaletteOpen((v) => !v))
return <CommandPalette open={paletteOpen} onOpenChange={setPaletteOpen} items={items} />
}چند combo همزمان
// Escape یا Mod+W هر دو پنل را میبندند
useHotkeys(['escape', 'mod+w'], close, { enabled: open })محدود به شرط
با enabled میتوانید میانبر را فقط در برخی شرایط زنده نگه دارید:
useHotkeys('enter', submitForm, { enabled: isFormValid })هدف اختصاصی (ref)
const panelRef = React.useRef<HTMLDivElement>(null)
useHotkeys('escape', closePanel, { target: panelRef })
// فقط وقتی focus داخل panelRef باشد فعال است (چون keydown bubble میشود)گرامر combo
<part>[+<part>]*| بخش | توضیح |
|---|---|
mod | ⌘ روی macOS، Ctrl در بقیه — پیشنهاد رسمی |
ctrl | Ctrl صریح (بدون fallback روی Mac) |
cmd | ⌘ (روی Mac) / Win (در بقیه) |
shift | Shift |
alt | Alt / Option |
meta | Meta (تقریباً معادل cmd) |
| کلید | k، enter، escape، space، فلشها، ... |
| علامت | / یا slash، . یا period، , یا comma، ;، '، [، ]، \، -، =، ` |
| علامت با Shift | ? (همان shift+slash)، <، >، :، "، {، }، |، _، ~ |
مثالها:
'mod+k'— ⌘K روی macOS، Ctrl+K در بقیه'mod+shift+p'— میانبر سهکلیده'escape'— فقط Escape'ctrl+k'— Ctrl صریح (روی Mac ⌘ کار نمیکند)
پارامترها
combo: HotkeyCombo
یک رشته یا آرایهای از رشتهها. آرایه بهصورت OR تفسیر میشود.
handler: (event: KeyboardEvent) => void
callback که با تطابق فراخوانی میشود. event.preventDefault() پیشفرض اعمال میشود.
options?: UseHotkeysOptions
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
preventDefault | boolean | true | فراخوانی event.preventDefault() هنگام تطابق |
ignoreWhenTyping | boolean | true | نادیده گرفتن combo هنگام focus در input/textarea بدون modifier |
enabled | boolean | true | فعال/غیرفعال کردن listener |
target | RefObject<HTMLElement> | HTMLElement | Document | document | هدف listener. ref برای scope کردن میانبر به یک ناحیهی خاص |
صفحهکلید فارسی و چیدمانهای غیرلاتین
میانبر حرفی، رقمی یا علامتی روی هر چیدمان کار میکند: useHotkeys('k', …)، useHotkeys('/', …) و useHotkeys('?', …) را همانطور که مینویسید بگذارید.
روی چیدمان فارسی (ISIRI 9147) کلید K حرف «ن»، کلید J حرف «ت» و کلید X حرف «ط» میدهد و Shift و / علامت «؟» را. مقایسهٔ event.key === 'k' هرگز برای کاربر فارسی اجرا نمیشود. useHotkeys دو کار میکند:
- اول کلیدی را که چیدمان چاپ کرده با ترکیب مقایسه میکند (
event.key)؛ پس خوانندهای که چیدمان لاتین دیگری دارد (Dvorak، AZERTY، آلمانی) همان حرفی را میگیرد که روی کلید نوشته است. - اگر چیدمان برای یک حرف یا رقم، حرف و رقم لاتین چاپ نکرده باشد (مثلاً «ن» بهجای K، یا رقم فارسی بهجای رقم لاتین)، کلید فیزیکی (
event.code:KeyK،Digit1) تصمیم میگیرد. علامت (Slash،Comma، …) فقط وقتی با کلید فیزیکی تطبیق میخورد که چیدمان نویسهٔ غیر ASCII چاپ کرده باشد؛ چیدمان آلمانی که روی کلید/فیزیکی علامت-میدهد،/را اجرا نمیکند.
یکی از میانبرها را روی صفحهکلید بزنید، یا یکی از نمونههای چیدمان فارسی را بفرستید. چیدمان فارسی روی کلید K حرف «ن» میدهد؛ میانبر باز هم کار میکند.
- event.key
- —
- event.code
- —
- Kهنوز اجرا نشده
- /هنوز اجرا نشده
- ?هنوز اجرا نشده
- Ctrl+Bهنوز اجرا نشده
قاعده: میانبر حرفی با useHotkeys نوشته میشود، نه e.key === 'k' در keydown دستی (قاعدهٔ lint parto/no-handmade-key-shortcut). اگر رویداد خام لازم است، event.code را مقایسه کنید ('KeyJ'، 'Slash')، مثل EntityDrawer برای J و K. کلیدهای نامدار (Enter، Escape، فلشها و فاصله) روی همهٔ چیدمانها یکیاند و با event.key درستاند.
میانبر تازه را قبل از «تمام» روی چیدمان فارسی امتحان کنید (Alt+Shift چیدمان را عوض میکند).
ابزار کمکی: formatHotkey
برای نمایش combo در UI، از formatHotkey استفاده کنید — روی macOS سمبلهای ⌘⇧⌥ تولید میکند، در ویندوز/لینوکس متن Ctrl+Shift+Alt.
import { formatHotkey } from '@partodata/ui'
formatHotkey('mod+shift+p') // '⌘⇧P' (Mac) یا 'Ctrl+Shift+P' (بقیه)راهنمای استفاده
- میانبر سراسری را در یک نقطه متمرکز (کامپوننت قاب برنامه، کنار
ProductFrame) ثبت کنید — نه درون کامپوننتهای صفحه که ممکن است چند بار mount/unmount شوند - وقتی
Inputدارید و میخواهیدEnterرا کنترل کنید، ازonKeyDownخود input استفاده کنید، نهuseHotkeys— چونignoreWhenTypingفعال است - برای نمایش میانبر در UI از
formatHotkeyاستفاده کنید، نه حرف تایپشده؛formatHotkey('slash')همان/را میدهد - برای میانبرهای متضاد بین صفحات (مثلاً
/در یک صفحه focus میکند و در صفحهی دیگر کنشی دیگر انجام میدهد)، ازenabledبرای context-scoping استفاده کنید
هوکها و کامپوننتهای مرتبط
- CommandPalette — کامپوننت پالت که داخلاً از
useHotkeys('mod+k')استفاده میکند