fix(ui): preserve prompt text when dismissing mention picker (#285)

## Summary
- preserve the current prompt text when dismissing the `@` mention/file
picker with `Esc`
- let `Enter` fall back to normal prompt submission when the mention
picker is open but there is no selectable result

## Verification
- source inspection of the prompt input and picker flow
- local `npm run typecheck --workspace @codenomad/ui` is blocked in this
environment because workspace dependencies are not installed

--
Yours,
[CodeNomadBot](https://github.com/NeuralNomadsAI/CodeNomad)

Co-authored-by: Shantur Rathore <i@shantur.com>
This commit is contained in:
codenomadbot[bot]
2026-04-04 00:48:37 +01:00
committed by GitHub
parent 141be2cde0
commit 7996e514c4
3 changed files with 7 additions and 22 deletions

View File

@@ -540,6 +540,10 @@ export default function PromptInput(props: PromptInputProps) {
mode={pickerMode()}
onClose={handlePickerClose}
onSelect={handlePickerSelect}
onSubmitWithoutSelection={() => {
handlePickerClose()
void handleSend()
}}
agents={instanceAgents()}
commands={getCommands(props.instanceId)}
instanceClient={instance()!.client}

View File

@@ -324,28 +324,6 @@ export function usePromptPicker(options: PromptPickerOptions): PromptPickerContr
const pos = atPosition()
if (pickerMode() === "mention" && pos !== null) {
setIgnoredAtPositions((prev) => new Set(prev).add(pos))
// Remove the partial @mention text from the textarea when ESC is pressed
const textarea = options.getTextarea()
if (textarea) {
const currentPrompt = options.prompt()
const cursorPos = textarea.selectionStart
// Remove text from @ position to cursor position
const before = currentPrompt.substring(0, pos)
const after = currentPrompt.substring(cursorPos)
options.setPrompt(before + after)
// Restore cursor position to where @ was
setTimeout(() => {
const nextTextarea = options.getTextarea()
if (nextTextarea) {
nextTextarea.setSelectionRange(pos, pos)
}
}, 0)
// Clear ignoredAtPositions so typing @ again will work
setIgnoredAtPositions(new Set<number>())
}
}
setShowPicker(false)
setAtPosition(null)

View File

@@ -79,6 +79,7 @@ interface UnifiedPickerProps {
mode?: "mention" | "command"
onSelect: (item: PickerItem, action: PickerSelectAction) => void
onClose: () => void
onSubmitWithoutSelection?: () => void
agents: Agent[]
commands?: SDKCommand[]
instanceClient: OpencodeClient | null
@@ -404,6 +405,8 @@ const UnifiedPicker: Component<UnifiedPickerProps> = (props) => {
if (selected) {
const action: PickerSelectAction = e.key === "Tab" ? "tab" : e.shiftKey ? "shiftEnter" : "enter"
props.onSelect(selected, action)
} else if (e.key === "Enter" && mode() === "mention") {
props.onSubmitWithoutSelection?.()
}
} else if (e.key === "Escape") {
e.preventDefault()