Skip to content

Commit d327a2b

Browse files
authored
chore(app): use radio group in prompt input (anomalyco#14025)
1 parent c1b03b7 commit d327a2b

19 files changed

Lines changed: 207 additions & 111 deletions

File tree

packages/app/src/components/prompt-input.tsx

Lines changed: 49 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useFilteredList } from "@opencode-ai/ui/hooks"
2-
import { createEffect, on, Component, Show, For, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js"
2+
import { createEffect, on, Component, Show, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js"
33
import { createStore } from "solid-js/store"
44
import { createFocusSignal } from "@solid-primitives/active-element"
55
import { useLocal } from "@/context/local"
@@ -26,6 +26,7 @@ import type { IconName } from "@opencode-ai/ui/icons/provider"
2626
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
2727
import { IconButton } from "@opencode-ai/ui/icon-button"
2828
import { Select } from "@opencode-ai/ui/select"
29+
import { RadioGroup } from "@opencode-ai/ui/radio-group"
2930
import { useDialog } from "@opencode-ai/ui/context/dialog"
3031
import { ModelSelectorPopover } from "@/components/dialog-select-model"
3132
import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid"
@@ -249,7 +250,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
249250
return messages.some((m) => m.role === "user")
250251
})
251252

252-
const MAX_HISTORY = 100
253253
const [history, setHistory] = persisted(
254254
Persist.global("prompt-history", ["prompt-history.v1"]),
255255
createStore<{
@@ -319,6 +319,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
319319
requestAnimationFrame(() => editorRef?.focus())
320320
}
321321

322+
const shellModeKey = "mod+shift+x"
323+
const normalModeKey = "mod+shift+e"
324+
322325
command.register("prompt-input", () => [
323326
{
324327
id: "file.attach",
@@ -328,6 +331,22 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
328331
disabled: store.mode !== "normal",
329332
onSelect: pick,
330333
},
334+
{
335+
id: "prompt.mode.shell",
336+
title: language.t("command.prompt.mode.shell"),
337+
category: language.t("command.category.session"),
338+
keybind: shellModeKey,
339+
disabled: store.mode === "shell",
340+
onSelect: () => setMode("shell"),
341+
},
342+
{
343+
id: "prompt.mode.normal",
344+
title: language.t("command.prompt.mode.normal"),
345+
category: language.t("command.category.session"),
346+
keybind: normalModeKey,
347+
disabled: store.mode === "normal",
348+
onSelect: () => setMode("normal"),
349+
},
331350
])
332351

333352
const closePopover = () => setStore("popover", null)
@@ -1339,45 +1358,35 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
13391358
</TooltipKeybind>
13401359
</Show>
13411360
</div>
1342-
1343-
<div class="shrink-0">
1344-
<div
1345-
data-component="prompt-mode-toggle"
1346-
class="relative h-7 w-[68px] rounded-[4px] bg-surface-inset-base border border-[0.5px] border-border-weak-base p-0 flex items-center gap-1 overflow-visible"
1347-
>
1348-
<div
1349-
class="absolute inset-y-0 left-0 w-[calc((100%-4px)/2)] rounded-[4px] bg-surface-raised-stronger-non-alpha shadow-[var(--shadow-xs-border)] transition-transform duration-200 ease-out will-change-transform"
1350-
style={{
1351-
transform: store.mode === "shell" ? "translateX(0px)" : "translateX(calc(100% + 4px))",
1352-
}}
1353-
/>
1354-
<button
1355-
type="button"
1356-
class="relative z-10 flex-1 h-full p-0.5 flex items-center justify-center"
1357-
aria-pressed={store.mode === "shell"}
1358-
onClick={() => setMode("shell")}
1359-
>
1360-
<div
1361-
class="w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base"
1362-
classList={{ "hover:bg-transparent": store.mode === "shell" }}
1363-
>
1364-
<Icon name="console" class="size-[18px]" />
1365-
</div>
1366-
</button>
1367-
<button
1368-
type="button"
1369-
class="relative z-10 flex-1 h-full p-0.5 flex items-center justify-center"
1370-
aria-pressed={store.mode === "normal"}
1371-
onClick={() => setMode("normal")}
1372-
>
1373-
<div
1374-
class="w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base"
1375-
classList={{ "hover:bg-transparent": store.mode === "normal" }}
1361+
<div class="shrink-0" data-component="prompt-mode-toggle">
1362+
<RadioGroup
1363+
options={["shell", "normal"] as const}
1364+
current={store.mode}
1365+
value={(mode) => mode}
1366+
label={(mode) => (
1367+
<TooltipKeybind
1368+
placement="top"
1369+
gutter={4}
1370+
title={language.t(mode === "shell" ? "command.prompt.mode.shell" : "command.prompt.mode.normal")}
1371+
keybind={command.keybind(mode === "shell" ? "prompt.mode.shell" : "prompt.mode.normal")}
1372+
class="size-full flex items-center justify-center"
13761373
>
1377-
<Icon name="prompt" class="size-[18px]" />
1378-
</div>
1379-
</button>
1380-
</div>
1374+
<Icon
1375+
name={mode === "shell" ? "console" : "prompt"}
1376+
class="size-[18px]"
1377+
classList={{
1378+
"text-icon-strong-base": mode === "shell" && store.mode === "shell",
1379+
"text-icon-interactive-base": mode === "normal" && store.mode === "normal",
1380+
"text-icon-weak": store.mode !== mode,
1381+
}}
1382+
/>
1383+
</TooltipKeybind>
1384+
)}
1385+
onSelect={(mode) => mode && setMode(mode)}
1386+
fill
1387+
pad="none"
1388+
class="w-[68px]"
1389+
/>
13811390
</div>
13821391
</div>
13831392
</div>

packages/app/src/i18n/ar.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export const dict = {
6363
"command.agent.cycle.reverse.description": "التبديل إلى الوكيل السابق",
6464
"command.model.variant.cycle": "تغيير جهد التفكير",
6565
"command.model.variant.cycle.description": "التبديل إلى مستوى الجهد التالي",
66+
"command.prompt.mode.shell": "التبديل إلى وضع Shell",
67+
"command.prompt.mode.normal": "التبديل إلى وضع Prompt",
6668
"command.permissions.autoaccept.enable": "قبول التعديلات تلقائيًا",
6769
"command.permissions.autoaccept.disable": "إيقاف قبول التعديلات تلقائيًا",
6870
"command.workspace.toggle": "تبديل مساحات العمل",
@@ -210,6 +212,7 @@ export const dict = {
210212
"prompt.placeholder.summarizeComments": "لخّص التعليقات…",
211213
"prompt.placeholder.summarizeComment": "لخّص التعليق…",
212214
"prompt.mode.shell": "Shell",
215+
"prompt.mode.normal": "Prompt",
213216
"prompt.mode.shell.exit": "esc للخروج",
214217
"prompt.example.1": "إصلاح TODO في قاعدة التعليمات البرمجية",
215218
"prompt.example.2": "ما هو المكدس التقني لهذا المشروع؟",

packages/app/src/i18n/br.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export const dict = {
6363
"command.agent.cycle.reverse.description": "Mudar para o agente anterior",
6464
"command.model.variant.cycle": "Alternar nível de raciocínio",
6565
"command.model.variant.cycle.description": "Mudar para o próximo nível de esforço",
66+
"command.prompt.mode.shell": "Alternar para o modo Shell",
67+
"command.prompt.mode.normal": "Alternar para o modo Prompt",
6668
"command.permissions.autoaccept.enable": "Aceitar edições automaticamente",
6769
"command.permissions.autoaccept.disable": "Parar de aceitar edições automaticamente",
6870
"command.workspace.toggle": "Alternar espaços de trabalho",
@@ -210,6 +212,7 @@ export const dict = {
210212
"prompt.placeholder.summarizeComments": "Resumir comentários…",
211213
"prompt.placeholder.summarizeComment": "Resumir comentário…",
212214
"prompt.mode.shell": "Shell",
215+
"prompt.mode.normal": "Prompt",
213216
"prompt.mode.shell.exit": "esc para sair",
214217
"prompt.example.1": "Corrigir um TODO no código",
215218
"prompt.example.2": "Qual é a stack tecnológica deste projeto?",

packages/app/src/i18n/bs.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const dict = {
6969
"command.agent.cycle.reverse.description": "Prebaci na prethodnog agenta",
7070
"command.model.variant.cycle": "Promijeni nivo razmišljanja",
7171
"command.model.variant.cycle.description": "Prebaci na sljedeći nivo",
72+
"command.prompt.mode.shell": "Prebaci na Shell način",
73+
"command.prompt.mode.normal": "Prebaci na Prompt način",
7274
"command.permissions.autoaccept.enable": "Automatski prihvataj izmjene",
7375
"command.permissions.autoaccept.disable": "Zaustavi automatsko prihvatanje izmjena",
7476
"command.workspace.toggle": "Prikaži/sakrij radne prostore",
@@ -228,6 +230,7 @@ export const dict = {
228230
"prompt.placeholder.summarizeComments": "Sažmi komentare…",
229231
"prompt.placeholder.summarizeComment": "Sažmi komentar…",
230232
"prompt.mode.shell": "Shell",
233+
"prompt.mode.normal": "Prompt",
231234
"prompt.mode.shell.exit": "esc za izlaz",
232235

233236
"prompt.example.1": "Popravi TODO u bazi koda",

packages/app/src/i18n/da.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const dict = {
6969
"command.agent.cycle.reverse.description": "Skift til forrige agent",
7070
"command.model.variant.cycle": "Skift tænkeindsats",
7171
"command.model.variant.cycle.description": "Skift til næste indsatsniveau",
72+
"command.prompt.mode.shell": "Skift til shell-tilstand",
73+
"command.prompt.mode.normal": "Skift til prompt-tilstand",
7274
"command.permissions.autoaccept.enable": "Accepter ændringer automatisk",
7375
"command.permissions.autoaccept.disable": "Stop automatisk accept af ændringer",
7476
"command.workspace.toggle": "Skift arbejdsområder",
@@ -226,6 +228,7 @@ export const dict = {
226228
"prompt.placeholder.summarizeComments": "Opsummér kommentarer…",
227229
"prompt.placeholder.summarizeComment": "Opsummér kommentar…",
228230
"prompt.mode.shell": "Shell",
231+
"prompt.mode.normal": "Prompt",
229232
"prompt.mode.shell.exit": "esc for at afslutte",
230233

231234
"prompt.example.1": "Ret en TODO i koden",

packages/app/src/i18n/de.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export const dict = {
6767
"command.agent.cycle.reverse.description": "Zum vorherigen Agenten wechseln",
6868
"command.model.variant.cycle": "Denkaufwand wechseln",
6969
"command.model.variant.cycle.description": "Zum nächsten Aufwandslevel wechseln",
70+
"command.prompt.mode.shell": "In den Shell-Modus wechseln",
71+
"command.prompt.mode.normal": "In den Prompt-Modus wechseln",
7072
"command.permissions.autoaccept.enable": "Änderungen automatisch akzeptieren",
7173
"command.permissions.autoaccept.disable": "Automatische Annahme von Änderungen stoppen",
7274
"command.workspace.toggle": "Arbeitsbereiche umschalten",
@@ -215,6 +217,7 @@ export const dict = {
215217
"prompt.placeholder.summarizeComments": "Kommentare zusammenfassen…",
216218
"prompt.placeholder.summarizeComment": "Kommentar zusammenfassen…",
217219
"prompt.mode.shell": "Shell",
220+
"prompt.mode.normal": "Prompt",
218221
"prompt.mode.shell.exit": "esc zum Verlassen",
219222
"prompt.example.1": "Ein TODO in der Codebasis beheben",
220223
"prompt.example.2": "Was ist der Tech-Stack dieses Projekts?",

packages/app/src/i18n/en.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const dict = {
6969
"command.agent.cycle.reverse.description": "Switch to the previous agent",
7070
"command.model.variant.cycle": "Cycle thinking effort",
7171
"command.model.variant.cycle.description": "Switch to the next effort level",
72+
"command.prompt.mode.shell": "Switch to shell mode",
73+
"command.prompt.mode.normal": "Switch to prompt mode",
7274
"command.permissions.autoaccept.enable": "Auto-accept edits",
7375
"command.permissions.autoaccept.disable": "Stop auto-accepting edits",
7476
"command.workspace.toggle": "Toggle workspaces",
@@ -228,6 +230,7 @@ export const dict = {
228230
"prompt.placeholder.summarizeComments": "Summarize comments…",
229231
"prompt.placeholder.summarizeComment": "Summarize comment…",
230232
"prompt.mode.shell": "Shell",
233+
"prompt.mode.normal": "Prompt",
231234
"prompt.mode.shell.exit": "esc to exit",
232235

233236
"prompt.example.1": "Fix a TODO in the codebase",

packages/app/src/i18n/es.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export const dict = {
6969
"command.agent.cycle.reverse.description": "Cambiar al agente anterior",
7070
"command.model.variant.cycle": "Alternar esfuerzo de pensamiento",
7171
"command.model.variant.cycle.description": "Cambiar al siguiente nivel de esfuerzo",
72+
"command.prompt.mode.shell": "Cambiar al modo Shell",
73+
"command.prompt.mode.normal": "Cambiar al modo Prompt",
7274
"command.permissions.autoaccept.enable": "Aceptar ediciones automáticamente",
7375
"command.permissions.autoaccept.disable": "Dejar de aceptar ediciones automáticamente",
7476
"command.workspace.toggle": "Alternar espacios de trabajo",
@@ -227,6 +229,7 @@ export const dict = {
227229
"prompt.placeholder.summarizeComments": "Resumir comentarios…",
228230
"prompt.placeholder.summarizeComment": "Resumir comentario…",
229231
"prompt.mode.shell": "Shell",
232+
"prompt.mode.normal": "Prompt",
230233
"prompt.mode.shell.exit": "esc para salir",
231234

232235
"prompt.example.1": "Arreglar un TODO en el código",

packages/app/src/i18n/fr.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export const dict = {
6363
"command.agent.cycle.reverse.description": "Passer à l'agent précédent",
6464
"command.model.variant.cycle": "Changer l'effort de réflexion",
6565
"command.model.variant.cycle.description": "Passer au niveau d'effort suivant",
66+
"command.prompt.mode.shell": "Passer en mode Shell",
67+
"command.prompt.mode.normal": "Passer en mode Prompt",
6668
"command.permissions.autoaccept.enable": "Accepter automatiquement les modifications",
6769
"command.permissions.autoaccept.disable": "Arrêter l'acceptation automatique des modifications",
6870
"command.workspace.toggle": "Basculer les espaces de travail",
@@ -210,6 +212,7 @@ export const dict = {
210212
"prompt.placeholder.summarizeComments": "Résumer les commentaires…",
211213
"prompt.placeholder.summarizeComment": "Résumer le commentaire…",
212214
"prompt.mode.shell": "Shell",
215+
"prompt.mode.normal": "Prompt",
213216
"prompt.mode.shell.exit": "esc pour quitter",
214217
"prompt.example.1": "Corriger un TODO dans la base de code",
215218
"prompt.example.2": "Quelle est la pile technique de ce projet ?",

packages/app/src/i18n/ja.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export const dict = {
6363
"command.agent.cycle.reverse.description": "前のエージェントに切り替え",
6464
"command.model.variant.cycle": "思考レベルの切り替え",
6565
"command.model.variant.cycle.description": "次の思考レベルに切り替え",
66+
"command.prompt.mode.shell": "シェルモードに切り替える",
67+
"command.prompt.mode.normal": "プロンプトモードに切り替える",
6668
"command.permissions.autoaccept.enable": "編集を自動承認",
6769
"command.permissions.autoaccept.disable": "編集の自動承認を停止",
6870
"command.workspace.toggle": "ワークスペースを切り替え",
@@ -209,6 +211,7 @@ export const dict = {
209211
"prompt.placeholder.summarizeComments": "コメントを要約…",
210212
"prompt.placeholder.summarizeComment": "コメントを要約…",
211213
"prompt.mode.shell": "シェル",
214+
"prompt.mode.normal": "プロンプト",
212215
"prompt.mode.shell.exit": "escで終了",
213216
"prompt.example.1": "コードベースのTODOを修正",
214217
"prompt.example.2": "このプロジェクトの技術スタックは何ですか?",

0 commit comments

Comments
 (0)