From b7d4f8f86912aaec3302bdccbca863dc53c5baea Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Thu, 26 Mar 2026 23:10:02 +0000 Subject: [PATCH] feat(ui): add clear action to prompt input --- packages/ui/src/components/prompt-input.tsx | 95 ++++++++++++------- .../ui/src/lib/i18n/messages/en/messaging.ts | 2 + .../ui/src/lib/i18n/messages/es/messaging.ts | 2 + .../ui/src/lib/i18n/messages/fr/messaging.ts | 2 + .../ui/src/lib/i18n/messages/he/messaging.ts | 2 + .../ui/src/lib/i18n/messages/ja/messaging.ts | 2 + .../ui/src/lib/i18n/messages/ru/messaging.ts | 2 + .../lib/i18n/messages/zh-Hans/messaging.ts | 2 + .../ui/src/styles/messaging/prompt-input.css | 34 ++++--- 9 files changed, 98 insertions(+), 45 deletions(-) diff --git a/packages/ui/src/components/prompt-input.tsx b/packages/ui/src/components/prompt-input.tsx index c06dbb02..214ed534 100644 --- a/packages/ui/src/components/prompt-input.tsx +++ b/packages/ui/src/components/prompt-input.tsx @@ -1,5 +1,5 @@ import { Suspense, createEffect, createSignal, lazy, on, onCleanup, Show } from "solid-js" -import { ArrowBigUp, ArrowBigDown, Loader2, Mic } from "lucide-solid" +import { ArrowBigUp, ArrowBigDown, Loader2, Mic, X } from "lucide-solid" import ExpandButton from "./expand-button" import { clearAttachments, removeAttachment } from "../stores/attachments" import { resolvePastedPlaceholders } from "../lib/prompt-placeholders" @@ -351,6 +351,19 @@ export default function PromptInput(props: PromptInputProps) { textareaRef?.focus() } + function handleClearPrompt() { + clearPrompt() + clearHistoryDraft() + resetHistoryNavigation() + setShowPicker(false) + setPickerMode("mention") + setAtPosition(null) + setSearchQuery("") + setIgnoredAtPositions(new Set()) + syncAttachmentCounters("") + textareaRef?.focus() + } + function insertBlockContent(block: string) { const textarea = textareaRef const current = prompt() @@ -422,6 +435,8 @@ export default function PromptInput(props: PromptInputProps) { return hasText || attachments().length > 0 } + const canClearPrompt = () => prompt().length > 0 + const shellHint = () => mode() === "shell" ? { key: "Esc", text: t("promptInput.hints.shell.exit") } @@ -543,7 +558,7 @@ export default function PromptInput(props: PromptInputProps) { autocomplete="off" />
-
+
+ +
+
+ + + +
- - - -
diff --git a/packages/ui/src/lib/i18n/messages/en/messaging.ts b/packages/ui/src/lib/i18n/messages/en/messaging.ts index 27701293..ae32e79c 100644 --- a/packages/ui/src/lib/i18n/messages/en/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/en/messaging.ts @@ -142,6 +142,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "again to abort session", "promptInput.stopSession.ariaLabel": "Stop session", "promptInput.stopSession.title": "Stop session", + "promptInput.clear.ariaLabel": "Clear prompt text", + "promptInput.clear.title": "Clear prompt text", "promptInput.send.ariaLabel": "Send message", "promptInput.send.errorFallback": "Failed to send message", "promptInput.send.errorTitle": "Send failed", diff --git a/packages/ui/src/lib/i18n/messages/es/messaging.ts b/packages/ui/src/lib/i18n/messages/es/messaging.ts index c5411592..f363b61e 100644 --- a/packages/ui/src/lib/i18n/messages/es/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/es/messaging.ts @@ -144,6 +144,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "otra vez para abortar la sesión", "promptInput.stopSession.ariaLabel": "Detener sesión", "promptInput.stopSession.title": "Detener sesión", + "promptInput.clear.ariaLabel": "Borrar el texto del prompt", + "promptInput.clear.title": "Borrar el texto del prompt", "promptInput.send.ariaLabel": "Enviar mensaje", "promptInput.send.errorFallback": "No se pudo enviar el mensaje", "promptInput.send.errorTitle": "Error al enviar", diff --git a/packages/ui/src/lib/i18n/messages/fr/messaging.ts b/packages/ui/src/lib/i18n/messages/fr/messaging.ts index 9cebf563..b3ba59a9 100644 --- a/packages/ui/src/lib/i18n/messages/fr/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/fr/messaging.ts @@ -144,6 +144,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "à nouveau pour interrompre la session", "promptInput.stopSession.ariaLabel": "Arrêter la session", "promptInput.stopSession.title": "Arrêter la session", + "promptInput.clear.ariaLabel": "Effacer le texte du prompt", + "promptInput.clear.title": "Effacer le texte du prompt", "promptInput.send.ariaLabel": "Envoyer le message", "promptInput.send.errorFallback": "Impossible d'envoyer le message", "promptInput.send.errorTitle": "Échec de l'envoi", diff --git a/packages/ui/src/lib/i18n/messages/he/messaging.ts b/packages/ui/src/lib/i18n/messages/he/messaging.ts index 1b900be1..f45cc8e2 100644 --- a/packages/ui/src/lib/i18n/messages/he/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/he/messaging.ts @@ -142,6 +142,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "שוב כדי לבטל את הסשן", "promptInput.stopSession.ariaLabel": "עצור סשן", "promptInput.stopSession.title": "עצור סשן", + "promptInput.clear.ariaLabel": "נקה את טקסט הפרומפט", + "promptInput.clear.title": "נקה את טקסט הפרומפט", "promptInput.send.ariaLabel": "שלח הודעה", "promptInput.send.errorFallback": "שליחת ההודעה נכשלה", "promptInput.send.errorTitle": "השליחה נכשלה", diff --git a/packages/ui/src/lib/i18n/messages/ja/messaging.ts b/packages/ui/src/lib/i18n/messages/ja/messaging.ts index ef95ce22..f8e3cf46 100644 --- a/packages/ui/src/lib/i18n/messages/ja/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/ja/messaging.ts @@ -144,6 +144,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "もう一度押すとセッションを中断", "promptInput.stopSession.ariaLabel": "セッションを停止", "promptInput.stopSession.title": "セッションを停止", + "promptInput.clear.ariaLabel": "プロンプトのテキストをクリア", + "promptInput.clear.title": "プロンプトのテキストをクリア", "promptInput.send.ariaLabel": "メッセージを送信", "promptInput.send.errorFallback": "メッセージの送信に失敗しました", "promptInput.send.errorTitle": "送信に失敗", diff --git a/packages/ui/src/lib/i18n/messages/ru/messaging.ts b/packages/ui/src/lib/i18n/messages/ru/messaging.ts index 40547b3f..c696a114 100644 --- a/packages/ui/src/lib/i18n/messages/ru/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/ru/messaging.ts @@ -144,6 +144,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "еще раз, чтобы прервать сессию", "promptInput.stopSession.ariaLabel": "Остановить сессию", "promptInput.stopSession.title": "Остановить сессию", + "promptInput.clear.ariaLabel": "Очистить текст prompt", + "promptInput.clear.title": "Очистить текст prompt", "promptInput.send.ariaLabel": "Отправить сообщение", "promptInput.send.errorFallback": "Не удалось отправить сообщение", "promptInput.send.errorTitle": "Не удалось отправить", diff --git a/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts index 4aa31036..6d618bbd 100644 --- a/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts +++ b/packages/ui/src/lib/i18n/messages/zh-Hans/messaging.ts @@ -144,6 +144,8 @@ export const messagingMessages = { "promptInput.overlay.againToAbort": "再次按下以中止会话", "promptInput.stopSession.ariaLabel": "停止会话", "promptInput.stopSession.title": "停止会话", + "promptInput.clear.ariaLabel": "清除输入框文本", + "promptInput.clear.title": "清除输入框文本", "promptInput.send.ariaLabel": "发送消息", "promptInput.send.errorFallback": "发送消息失败", "promptInput.send.errorTitle": "发送失败", diff --git a/packages/ui/src/styles/messaging/prompt-input.css b/packages/ui/src/styles/messaging/prompt-input.css index 31605f10..d0a9d87e 100644 --- a/packages/ui/src/styles/messaging/prompt-input.css +++ b/packages/ui/src/styles/messaging/prompt-input.css @@ -37,7 +37,7 @@ .prompt-input { @apply w-full pt-2.5 border text-sm resize-none outline-none transition-colors; padding-inline-start: 0.75rem; - padding-inline-end: 5.5rem; + padding-inline-end: 7.5rem; font-family: inherit; background-color: var(--surface-base); color: var(--text-primary); @@ -90,22 +90,32 @@ inset-inline-end: 0.25rem; bottom: 0.25rem; display: flex; - flex-direction: column; - align-items: flex-end; - justify-content: flex-start; + flex-direction: row; + align-items: flex-start; + justify-content: flex-end; gap: 0.125rem; z-index: 2; } -.prompt-nav-top-row { +.prompt-nav-column { display: flex; - align-items: center; - justify-content: flex-end; + flex-direction: column; + align-items: flex-end; + justify-content: flex-start; gap: 0.125rem; } +.prompt-nav-column-left { + min-width: 1.75rem; +} + +.prompt-nav-column-right { + min-width: 1.75rem; +} + .prompt-expand-button, -.prompt-history-button { +.prompt-history-button, +.prompt-clear-button { @apply w-7 h-7 flex items-center justify-center rounded-md; color: var(--text-muted); background-color: var(--control-ghost-bg); @@ -115,7 +125,8 @@ } .prompt-expand-button:hover:not(:disabled), -.prompt-history-button:hover:not(:disabled) { +.prompt-history-button:hover:not(:disabled), +.prompt-clear-button:hover:not(:disabled) { background-color: var(--surface-secondary); color: var(--text-primary); } @@ -127,7 +138,8 @@ } .prompt-expand-button:disabled, -.prompt-history-button:disabled { +.prompt-history-button:disabled, +.prompt-clear-button:disabled { opacity: 0.4; cursor: not-allowed; } @@ -397,7 +409,7 @@ .prompt-input { min-height: 0; padding: 0.5rem 0.75rem; - padding-inline-end: 5.5rem; + padding-inline-end: 7.5rem; padding-bottom: 0.75rem; }