diff --git a/packages/opencode/src/cli/cmd/tui/component/hoverable-label.tsx b/packages/opencode/src/cli/cmd/tui/component/hoverable-label.tsx new file mode 100644 index 00000000000..73944c3adcf --- /dev/null +++ b/packages/opencode/src/cli/cmd/tui/component/hoverable-label.tsx @@ -0,0 +1,51 @@ +import { RGBA } from "@opentui/core" +import { createSignal, createUniqueId, onCleanup, type JSX } from "solid-js" +import { useTheme, selectedForeground } from "@tui/context/theme" + +const [activeId, setActiveId] = createSignal(null) + +type HoverableLabelProps = { + children: (hover: boolean, hoverFg: () => RGBA) => JSX.Element + onClick?: () => void + disabled?: boolean +} + +export function HoverableLabel(props: HoverableLabelProps) { + const id = createUniqueId() + const { theme } = useTheme() + const hoverFg = () => selectedForeground(theme) + + const isHovered = () => activeId() === id && !props.disabled + + onCleanup(() => { + if (activeId() !== id) return + setActiveId(null) + }) + + const handleMouseOver = () => { + if (props.disabled) return + setActiveId(id) + } + + const handleMouseOut = () => { + if (activeId() !== id) return + setActiveId(null) + } + + const handleClick = () => { + if (props.disabled) return + setActiveId(null) + props.onClick?.() + } + + return ( + + {props.children(isHovered(), hoverFg)} + + ) +} diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 4558914cb7e..39fc3e80144 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -30,6 +30,9 @@ import { DialogAlert } from "../../ui/dialog-alert" import { useToast } from "../../ui/toast" import { useKV } from "../../context/kv" import { useTextareaKeybindings } from "../textarea-keybindings" +import { DialogAgent } from "../dialog-agent" +import { DialogModel } from "../dialog-model" +import { HoverableLabel } from "../hoverable-label" export type PromptProps = { sessionID?: string @@ -932,22 +935,30 @@ export function Prompt(props: PromptProps) { syntaxStyle={syntax()} /> - - {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} - - - - - {local.model.parsed().model} + dialog.replace(() => )}> + {(hover, hoverFg) => ( + + {store.mode === "shell" ? "Shell" : Locale.titlecase(local.agent.current().name)}{" "} - {local.model.parsed().provider} - - · - - {local.model.variant.current()} - - - + )} + + + dialog.replace(() => )}> + {(hover, hoverFg) => ( + + + {local.model.parsed().model} + + {local.model.parsed().provider} + + · + + {local.model.variant.current()} + + + + )} + @@ -1062,12 +1073,22 @@ export function Prompt(props: PromptProps) { - - {keybind.print("agent_cycle")} switch agent - - - {keybind.print("command_list")} commands - + dialog.replace(() => )}> + {(hover, hoverFg) => ( + + {keybind.print("agent_cycle")} {" "} + switch agent + + )} + + command.show()}> + {(hover, hoverFg) => ( + + {keybind.print("command_list")} {" "} + commands + + )} +