GROWI currently uses react-hotkeys (v2.0.0, 91 modules in async chunk) to manage keyboard shortcuts via a custom subscriber pattern. The library is identified as an optimization target due to its module footprint. This specification covers the migration from react-hotkeys to tinykeys, a lightweight (~400B) keyboard shortcut library, while preserving all existing hotkey functionality and the subscriber-based architecture.
react-hotkeys's GlobalHotKeys to capture key events and convert them to custom key expressionsgetHotkeyStrokes()| Shortcut | Action |
|---|---|
c |
Open page creation modal |
e |
Start page editing |
/ |
Focus global search |
Ctrl+/ or Meta+/ |
Open shortcuts help modal |
↑↑↓↓←→←→BA |
Show staff credits (Konami code) |
XXBBAAYYA↓← |
Switch to mirror mode (Konami code) |
Objective: As a developer, I want to replace react-hotkeys with tinykeys, so that the application's async chunk module count is reduced and the hotkey system uses a modern, lightweight library.
tinykeys as the keyboard shortcut library instead of react-hotkeys.react-hotkeys package shall be removed from package.json dependencies.react-hotkeys implementation.Objective: As a user, I want single-key shortcuts to continue working after the migration, so that my workflow is not disrupted.
c key (outside an input/textarea/editable element), the Hotkeys system shall open the page creation modal.e key (outside an input/textarea/editable element), the Hotkeys system shall start page editing if the page is editable and no modal is open./ key (outside an input/textarea/editable element), the Hotkeys system shall open the global search modal.Objective: As a user, I want modifier-key shortcuts to continue working after the migration, so that keyboard shortcut help remains accessible.
Ctrl+/ (or Meta+/ on macOS), the Hotkeys system shall open the shortcuts help modal.Objective: As a user, I want multi-key sequences (Konami codes) to continue working after the migration, so that easter egg features remain accessible.
↑↑↓↓←→←→BA, the Hotkeys system shall show the staff credits modal.XXBBAAYYA↓←, the Hotkeys system shall apply the mirror mode CSS class to the document body.Objective: As a user, I want single-key shortcuts to not fire when I am typing in an input field, so that keyboard shortcuts do not interfere with text entry.
<input>, <textarea>, or contenteditable element is focused, the Hotkeys system shall suppress single-key shortcuts (e.g., c, e, /).<input>, <textarea>, or contenteditable element is focused, the Hotkeys system shall still allow modifier-key shortcuts (e.g., Ctrl+/).Objective: As a developer, I want hotkey bindings to be properly registered and cleaned up on component mount/unmount, so that there are no memory leaks or stale handlers.
useEffect return pattern.Objective: As a developer, I want the subscriber-based architecture to be preserved or appropriately modernized, so that adding or modifying hotkeys remains straightforward.
Objective: As a developer, I want the migrated hotkey system to use TypeScript, so that the code benefits from type safety and better IDE support.
.ts/.tsx files) rather than JavaScript (.js/.jsx).