Context
ONECMS required keyboard shortcuts (theme toggle, help dialog) and context-aware interaction support.
Existing behavior relied on module-level window.addEventListener usage, which introduced:
- Scattered key handling
- No scope control (modal vs page conflicts)
- No permission or feature-flag filtering
- No lifecycle safety guarantees
- No unified action registry
Additionally, future requirements include:
- Context-specific guided walkthroughs
- Discoverability surfaces
- Potential command palette expansion
A decision was required on whether to:
- Use an existing shortcut/command library, or
- Build a minimal internal interaction runtime.
Decision
We implemented a custom, dependency-free Scoped Shortcut Engine under src/lib/internal/ShortcutManager.
The engine provides:
- Stack-based scoped resolution
- Declarative registration via
useShortcut - Policy injection (feature flags, permissions, editable guard)
- Single global keyboard listener
- Centralized action registry
No third-party shortcut or command palette packages were used.
The engine is intentionally UI-agnostic and serves as an interaction runtime, not merely a key detector.
Consequences
Enables
- Deterministic scope priority (modal overrides page)
- Context-aware guided walkthroughs
- Future command palette without architectural changes
- Permission- and feature-aware action filtering
- Centralized discoverability surface
- Strict testable infra (≥90% branch coverage)
Restricts
- Internal ownership of keyboard edge-case handling
- Responsibility for long-term maintenance
- No out-of-the-box fuzzy search or UI primitives
Trade-offs Accepted
- Slight initial implementation overhead
- Custom combo matcher instead of library abstraction
- Additional test surface
These trade-offs were accepted to maintain architectural control, extensibility, and consistency with existing runtime patterns (AI runtime, upload engine, reminder engine).
Notes
The global dialog acts as a shell and may evolve to render:
- Context-specific walkthrough content
- Shortcut list
- Future command palette surface
No architectural changes are required to support these expansions.