Skip to content

[feature] Add keybinding conflict detection/warning for useKeymap #3752

Description

@pixeltannu

What problem does this solve?

As TermUI apps grow, multiple components (e.g. a Modal on top of a main
Dashboard) can each register their own useKeymap bindings. If two
active components both bind the same key (e.g. ctrl+c for "cancel" in a
modal vs. "quit" in the parent), the behavior is currently silent —
whichever handler wins isn't obvious, and there's no dev-time feedback.
This makes debugging keyboard-interaction bugs harder as apps scale,
especially for contributors new to the codebase.

Proposed solution

Add development-mode conflict detection to the keymap system that warns
when two simultaneously active components register overlapping key
bindings, without changing runtime behavior in production.

import { useKeymap } from '@termuijs/jsx'

function Modal() {
  useKeymap([
    { key: 'c', ctrl: true, action: () => closeModal() },
  ])
  // ...
}

// If a parent component also has ctrl+c bound while Modal is mounted:
// [TermUI] Keymap conflict: "ctrl+c" is bound in both <Modal> and 
// <Dashboard>. The most recently mounted binding takes priority.
  • Only active in a NODE_ENV=development-style mode, zero overhead in
    production builds
  • Clearly states which components conflict and which binding currently
    "wins", so contributors can quickly trace focus/priority issues
  • Could optionally expose a useKeymap(bindings, { priority: number })
    option for explicit conflict resolution instead of implicit mount-order

Alternatives considered

  • Leaving conflicts silent (current state) — simplest, but leads to
    confusing bugs that are hard to trace, especially in larger apps with
    many nested focusable components
  • Throwing a hard error on conflict — too strict; some conflicts are
    intentional (e.g. a modal deliberately overriding a parent's key while open)

Metadata

Metadata

Assignees

Labels

assignedIssue claimed by a contributor.type:feature+10 pts. New feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions