PathLogs UI
English

Hooks

useHotkeys

Горячие клавиши с последовательностями и модификаторами.

Глобальные горячие клавиши с поддержкой последовательностей: нажали «g», затем «d» — перешли на дашборд.

Пример

gdДашбордgmМои задачиdОтметить готовойmodkПоиск
  • Нажмите сочетание — сюда попадёт срабатывание

Запись клавиш

Аккорды разделяются пробелом, модификаторы внутри аккорда — плюсом:

tsx
"k"            // просто клавиша
"g d"          // последовательность: g, затем d
"mod+k"        // Ctrl на Windows/Linux, ⌘ на macOS
"mod+shift+p"  // несколько модификаторов
"?"            // shift подставляется сам
"escape"       // esc, up, down, left, right, enter, space, delete
modмодификатор

Ctrl и ⌘ одной записью. Отдельно ctrl и cmd различать не нужно — приложению почти всегда важно «системный модификатор».

shiftмодификатор

Требуется, только если написан явно. «?» набирается с shift на большинстве раскладок, и требование shift: false ломало бы такую запись.

altмодификатор

Он же option на macOS.

Параметры

keys*string

Запись клавиш.

handler*(e: KeyboardEvent) => void

Что сделать. preventDefault вызывается за вас.

labelstring

Подпись для экрана справки. Записи без неё считаются служебными и в справку не попадают.

groupstring

Раздел в справке: «Навигация», «Доска».

allowInInputboolean

по умолчанию: false

Сработает и когда фокус в поле ввода. Для mod+k и escape.

enabledboolean

по умолчанию: true

Временно выключить запись, не убирая её из списка.

Второй аргумент хука — общие настройки: enabled выключает весь набор, timeout задаёт окно ожидания второй клавиши (по умолчанию 1200 мс), target позволяет слушать не window, а конкретный элемент.

Поля ввода

Обычные клавиши в поле ввода принадлежат полю, а не приложению. Записи с allowInInput — исключение.

Справка

Тот же массив отдаётся компоненту HotkeysHelp — он показывает экран справки по «?» и сам вызывает useHotkeys:

tsx
import { HotkeysHelp } from "@toimetdev/pathlogs-core";

const hotkeys = [
  { keys: "g d", label: "Дашборд", group: "Навигация", handler: goDashboard },
];

// useHotkeys вызывать отдельно не нужно — HotkeysHelp сделает это сам
<HotkeysHelp hotkeys={hotkeys} hint="«g» — лидер: нажмите g, затем вторую клавишу." />

Один список на обработку и на справку — разъехаться им негде.

Матчер отдельно

Разбор и сопоставление не знают про DOM и покрыты тестами:

tsx
import {
  parseHotkey,        // "g d" → [{ key: "g" }, { key: "d" }]
  chordFromEvent,     // KeyboardEvent → аккорд
  chordMatches,       // совпадают ли аккорды
  createHotkeyMatcher // машина состояний для последовательностей
} from "@toimetdev/pathlogs-hooks";

Матчер хранит не буфер нажатий, а индекс внутри незавершённой последовательности: буфер пришлось бы чистить по таймеру, а индекс достаточно сравнить со временем последнего нажатия. Поэтому «g», нажатая минуту назад, не превращает случайную «d» в переход.