feat(chat): allow Tab to confirm slash commands#54
Conversation
Mingholy
left a comment
There was a problem hiding this comment.
Code Review: PR #54
Summary
This is a one-line change that adds e.key === "Tab" as an alternative to e.key === "Enter" for confirming the currently highlighted slash command in the autocomplete dropdown. This is a well-known UX pattern (VS Code, browser address bars, and shell tab-completion all work this way).
Implementation Quality
The change is correct and well-scoped:
-
Capture-phase interception works correctly. The
keydownlistener onwindowuses{ capture: true }and calls bothe.preventDefault()ande.stopImmediatePropagation(), which will prevent the Tab key from shifting focus away from the composer textarea when the dropdown is open. When the dropdown is not open (theif (!open) returnguard at the top of the effect), Tab retains its normal browser behavior (focus navigation). This is exactly the right thing. -
No conflict with Composer's
handleKeyDown. I verified that the Composer's ownonKeyDownhandler does not handle Tab at all, so there is no double-handling risk. -
flatOrdered.length > 0guard is preserved. Tab on an empty result set is a no-op, same as Enter. Good. -
No edge case with modifier keys. One minor consideration:
e.key === "Tab"fires for both bare Tab and Shift+Tab. In practice this is harmless -- Shift+Tab would also confirm the selected command, which is fine since the dropdown is about to close anyway. But if you ever want Shift+Tab to navigate upward (like some autocomplete widgets), you'd add&& !e.shiftKeyto the condition. Not required for this PR, just a note.
Code Quality
Clean, minimal diff. The || grouping with "Enter" is the right approach -- no new branches, no new abstractions. Nothing to complain about.
Security
No security implications. This is a purely client-side UI interaction change with no data flow or state changes beyond what Enter already does.
Verdict
LGTM. This is a small, correct, well-motivated quality-of-life improvement. Ship it.
Summary
Before / After
Starting state (both): type
/compin the loop composer — the slash menu opens with/compacthighlighted./comp)./compact) and closes the menu; focus stays in the composer.Test plan
cd web && bunx tsc -bbun run buildgit diff --checkweb, andserverpackage manifests do not define alintscript.