diff options
| author | Adam <[email protected]> | 2026-02-17 15:53:38 -0600 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-02-17 15:53:38 -0600 |
| commit | d327a2b1cf750a7552d149078658fdc8ad037171 (patch) | |
| tree | 7711236d05cd7377af0d1118c85fe1300f6b18dd /packages/app/src/components | |
| parent | c1b03b728af259a1556dc39db58e162b382527b3 (diff) | |
| download | opencode-d327a2b1cf750a7552d149078658fdc8ad037171.tar.gz opencode-d327a2b1cf750a7552d149078658fdc8ad037171.zip | |
chore(app): use radio group in prompt input (#14025)
Diffstat (limited to 'packages/app/src/components')
| -rw-r--r-- | packages/app/src/components/prompt-input.tsx | 89 |
1 files changed, 49 insertions, 40 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index ca7cc0325..dcd5bd2f1 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -1,5 +1,5 @@ import { useFilteredList } from "@opencode-ai/ui/hooks" -import { createEffect, on, Component, Show, For, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js" +import { createEffect, on, Component, Show, onCleanup, Switch, Match, createMemo, createSignal } from "solid-js" import { createStore } from "solid-js/store" import { createFocusSignal } from "@solid-primitives/active-element" import { useLocal } from "@/context/local" @@ -26,6 +26,7 @@ import type { IconName } from "@opencode-ai/ui/icons/provider" import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip" import { IconButton } from "@opencode-ai/ui/icon-button" import { Select } from "@opencode-ai/ui/select" +import { RadioGroup } from "@opencode-ai/ui/radio-group" import { useDialog } from "@opencode-ai/ui/context/dialog" import { ModelSelectorPopover } from "@/components/dialog-select-model" import { DialogSelectModelUnpaid } from "@/components/dialog-select-model-unpaid" @@ -249,7 +250,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => { return messages.some((m) => m.role === "user") }) - const MAX_HISTORY = 100 const [history, setHistory] = persisted( Persist.global("prompt-history", ["prompt-history.v1"]), createStore<{ @@ -319,6 +319,9 @@ export const PromptInput: Component<PromptInputProps> = (props) => { requestAnimationFrame(() => editorRef?.focus()) } + const shellModeKey = "mod+shift+x" + const normalModeKey = "mod+shift+e" + command.register("prompt-input", () => [ { id: "file.attach", @@ -328,6 +331,22 @@ export const PromptInput: Component<PromptInputProps> = (props) => { disabled: store.mode !== "normal", onSelect: pick, }, + { + id: "prompt.mode.shell", + title: language.t("command.prompt.mode.shell"), + category: language.t("command.category.session"), + keybind: shellModeKey, + disabled: store.mode === "shell", + onSelect: () => setMode("shell"), + }, + { + id: "prompt.mode.normal", + title: language.t("command.prompt.mode.normal"), + category: language.t("command.category.session"), + keybind: normalModeKey, + disabled: store.mode === "normal", + onSelect: () => setMode("normal"), + }, ]) const closePopover = () => setStore("popover", null) @@ -1339,45 +1358,35 @@ export const PromptInput: Component<PromptInputProps> = (props) => { </TooltipKeybind> </Show> </div> - - <div class="shrink-0"> - <div - data-component="prompt-mode-toggle" - 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" - > - <div - 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" - style={{ - transform: store.mode === "shell" ? "translateX(0px)" : "translateX(calc(100% + 4px))", - }} - /> - <button - type="button" - class="relative z-10 flex-1 h-full p-0.5 flex items-center justify-center" - aria-pressed={store.mode === "shell"} - onClick={() => setMode("shell")} - > - <div - class="w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base" - classList={{ "hover:bg-transparent": store.mode === "shell" }} - > - <Icon name="console" class="size-[18px]" /> - </div> - </button> - <button - type="button" - class="relative z-10 flex-1 h-full p-0.5 flex items-center justify-center" - aria-pressed={store.mode === "normal"} - onClick={() => setMode("normal")} - > - <div - class="w-full h-full flex items-center justify-center rounded-[2px] transition-colors hover:bg-surface-inset-base" - classList={{ "hover:bg-transparent": store.mode === "normal" }} + <div class="shrink-0" data-component="prompt-mode-toggle"> + <RadioGroup + options={["shell", "normal"] as const} + current={store.mode} + value={(mode) => mode} + label={(mode) => ( + <TooltipKeybind + placement="top" + gutter={4} + title={language.t(mode === "shell" ? "command.prompt.mode.shell" : "command.prompt.mode.normal")} + keybind={command.keybind(mode === "shell" ? "prompt.mode.shell" : "prompt.mode.normal")} + class="size-full flex items-center justify-center" > - <Icon name="prompt" class="size-[18px]" /> - </div> - </button> - </div> + <Icon + name={mode === "shell" ? "console" : "prompt"} + class="size-[18px]" + classList={{ + "text-icon-strong-base": mode === "shell" && store.mode === "shell", + "text-icon-interactive-base": mode === "normal" && store.mode === "normal", + "text-icon-weak": store.mode !== mode, + }} + /> + </TooltipKeybind> + )} + onSelect={(mode) => mode && setMode(mode)} + fill + pad="none" + class="w-[68px]" + /> </div> </div> </div> |
