fix: prevent Shift+Enter from triggering chat in new tab search input#628
fix: prevent Shift+Enter from triggering chat in new tab search input#628shadowfax92 wants to merge 3 commits intomainfrom
Conversation
Shift+Enter in the new tab combobox was being processed by downshift as a regular Enter key, causing it to start a chat session. Guard the onKeyDown handler to call preventDefault() when Shift is held, so downshift skips the event entirely. Closes #560
Greptile SummaryThis PR fixes a bug where pressing Shift+Enter in the new tab search input would incorrectly trigger a chat session. The fix introduces downshift's Key changes:
Correctness analysis: Confidence Score: 5/5Safe to merge — the fix is correct, uses downshift's official API, and has no impact on existing behavior. No P0 or P1 issues found. The prior concern about preventDownshiftDefault reliability has been fully addressed by switching to stateReducer. The ref-based timing is sound (onKeyDown fires before the internal dispatch), and returning the current state from the reducer correctly suppresses both onStateChange and onSelectedItemChange. All remaining observations are P2 or lower. No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant onKeyDown as onKeyDown handler
participant shiftRef as shiftHeldRef
participant Downshift as Downshift internals
participant stateReducer as stateReducer
participant Callbacks as onStateChange/onSelectedItemChange
User->>onKeyDown: Shift+Enter keydown
onKeyDown->>shiftRef: set current to true
onKeyDown->>Downshift: callAllEventHandlers continues
Downshift->>stateReducer: InputKeyDownEnter action
stateReducer->>shiftRef: read current (true)
stateReducer-->>Downshift: return state (no-op)
Note over Downshift,Callbacks: No state change, callbacks skipped
Note over Callbacks: executeDefaultAction blocked
User->>onKeyDown: Enter keydown (no Shift)
onKeyDown->>shiftRef: set current to false
onKeyDown->>Downshift: callAllEventHandlers continues
Downshift->>stateReducer: InputKeyDownEnter action
stateReducer->>shiftRef: read current (false)
stateReducer-->>Downshift: return changes (normal flow)
Downshift->>Callbacks: state change applied
Note over Callbacks: executeDefaultAction fires
Reviews (2): Last reviewed commit: "fix: use stateReducer to block Shift+Ent..." | Re-trigger Greptile |
| if (e.key === 'Enter' && e.shiftKey) { | ||
| e.preventDefault() | ||
| return | ||
| } |
There was a problem hiding this comment.
e.preventDefault() does not stop downshift's internal handler
e.preventDefault() prevents browser-native defaults (e.g. form submission) but does not prevent downshift from processing the key event. Downshift's getInputProps uses a callAllEventHandlers utility that calls both the user-supplied handler and its own internal handler sequentially. It stops only when event.nativeEvent.preventDownshiftDefault is true — it does not check event.defaultPrevented.
Because of this, even after your guard returns, downshift's internal handler still fires, sees Enter, and can:
- Select the currently highlighted suggestion →
onSelectedItemChange→runSelectedAction→ starts a chat - Dispatch
InputKeyDownEntertoonStateChangeunder certain conditions
The fix needs to additionally set the downshift-specific flag:
| if (e.key === 'Enter' && e.shiftKey) { | |
| e.preventDefault() | |
| return | |
| } | |
| if (e.key === 'Enter' && e.shiftKey) { | |
| e.preventDefault() | |
| ;(e.nativeEvent as any).preventDownshiftDefault = true | |
| return | |
| } |
Without preventDownshiftDefault = true, Shift+Enter will still be processed by downshift whenever a suggestion is highlighted, and the original bug is likely to persist.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/browseros-agent/apps/agent/entrypoints/newtab/index/NewTab.tsx
Line: 495-498
Comment:
**`e.preventDefault()` does not stop downshift's internal handler**
`e.preventDefault()` prevents browser-native defaults (e.g. form submission) but does **not** prevent downshift from processing the key event. Downshift's `getInputProps` uses a `callAllEventHandlers` utility that calls both the user-supplied handler and its own internal handler sequentially. It stops only when `event.nativeEvent.preventDownshiftDefault` is `true` — it does **not** check `event.defaultPrevented`.
Because of this, even after your guard returns, downshift's internal handler still fires, sees `Enter`, and can:
1. Select the currently highlighted suggestion → `onSelectedItemChange` → `runSelectedAction` → starts a chat
2. Dispatch `InputKeyDownEnter` to `onStateChange` under certain conditions
The fix needs to additionally set the downshift-specific flag:
```suggestion
if (e.key === 'Enter' && e.shiftKey) {
e.preventDefault()
;(e.nativeEvent as any).preventDownshiftDefault = true
return
}
```
Without `preventDownshiftDefault = true`, Shift+Enter will still be processed by downshift whenever a suggestion is highlighted, and the original bug is likely to persist.
How can I resolve this? If you propose a fix, please make it concise.preventDefault() doesn't stop downshift's internal Enter key handling. Downshift checks event.nativeEvent.preventDownshiftDefault to decide whether to skip its built-in behavior.
preventDownshiftDefault on the SyntheticEvent doesn't reliably prevent downshift from processing Enter. Switch to stateReducer, which is downshift's official customization mechanism: track shiftKey in a ref via onKeyDown, then return current state from the reducer when InputKeyDownEnter fires with Shift held.
|
@greptileai review |
|
@claude review |
|
Claude finished @shadowfax92's task in 1m 44s —— View job Code Review
SummaryThe Greptile review is outdated — it analyzed commit Analysis of Current Implementation (
|
Summary
stateReducerto interceptInputKeyDownEnterwhen Shift is held, returning the current state (no-op)shiftKeyin a ref via the input'sonKeyDownhandlerCloses #560
Rework
Initial approach using
preventDownshiftDefaulton the SyntheticEvent didn't reliably prevent downshift from processing Enter. Switched tostateReducer, which is downshift's official customization mechanism and works at the state management level rather than the event level.Test plan
@to trigger mention picker, press Tab — should still close mention picker🤖 Generated with Claude Code