Skip to content

Feat conflict detection#4

Merged
KevinVandy merged 3 commits intoTanStack:mainfrom
solssak:feat-conflict-detection
Feb 8, 2026
Merged

Feat conflict detection#4
KevinVandy merged 3 commits intoTanStack:mainfrom
solssak:feat-conflict-detection

Conversation

@solssak
Copy link
Contributor

@solssak solssak commented Feb 6, 2026

🎯 Changes

This PR implements hotkey conflict detection with configurable behavior strategies, addressing the "Warn/error on conflicting shortcuts (TBD)" roadmap item from the README.

Motivation:
When multiple components or modules register the same hotkey, developers need control over how these conflicts are handled. Without this feature, duplicate registrations silently coexist, which can lead to unexpected behavior and difficult debugging.

Implementation:

  • Added ConflictBehavior type with 4 strategies: 'warn', 'error', 'replace', 'allow'
  • Added conflictBehavior option to HotkeyOptions (defaults to 'warn' for safety)
  • Implemented #findConflictingRegistration() and #handleConflict() private methods
  • Added 5 comprehensive test cases covering all scenarios
  • Fixed ESLint no-unnecessary-condition warning
    Usage:
// Default: warn but allow both registrations
manager.register('Mod+S', handler1)
manager.register('Mod+S', handler2) // ⚠️ console.warn
// Strict mode: prevent conflicts
manager.register('Mod+S', handler, { conflictBehavior: 'error' }) // throws
// Override mode: replace existing
manager.register('Mod+S', newHandler, { conflictBehavior: 'replace' })
// Silent mode: intentional duplicates
manager.register('Mod+S', handler, { conflictBehavior: 'allow' })
Note: Conflicts are only detected when both the hotkey AND target match. Different targets (e.g., document vs a specific element) don't conflict.

✅ Checklist

🚀 Release Impact

@KevinVandy
Copy link
Member

my refactors are too frequent resulting in merge conflicts 😭. This is a great idea though and I was thinking about it myself. If you rebase, we'll get this in

ESLint was correctly identifying that the final if statement was
unnecessary since all other cases (allow, warn, error) return early.
At this point in the code, conflictBehavior must be 'replace'.
@solssak solssak force-pushed the feat-conflict-detection branch from 541bd90 to 7febeb4 Compare February 8, 2026 01:56
@solssak
Copy link
Contributor Author

solssak commented Feb 8, 2026

Rebased onto the latest main. All 20/21 targets pass locally (test:eslint, test:lib, test:types, build, test:sherif, test:knip). The only failure is test:docs, which also fails on main — a local Node.js/TS runner issue, not related to this PR.

During the rebase, I adapted the implementation to the new file structure — ConflictBehavior type and conflictBehavior option are now in hotkey-manager.ts alongside HotkeyOptions, matching the current module organization.

Ready for review whenever you get a chance!

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 8, 2026

Open in StackBlitz

npm i https://pkg.pr.new/TanStack/keys/@tanstack/keys@4
npm i https://pkg.pr.new/TanStack/keys/@tanstack/keys-devtools@4
npm i https://pkg.pr.new/TanStack/keys/@tanstack/react-keys@4
npm i https://pkg.pr.new/TanStack/keys/@tanstack/react-keys-devtools@4

commit: 081f91f

@KevinVandy KevinVandy merged commit ce5d0f2 into TanStack:main Feb 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants