From 06842723ea281b97dc8a21c713d687566c972b38 Mon Sep 17 00:00:00 2001 From: James Long Date: Fri, 17 Jul 2026 15:28:23 +0000 Subject: [PATCH] refactor(tui): migrate dialog views to V2 themes --- packages/tui/src/component/dialog-pair.tsx | 30 ++++++++-------- .../component/dialog-project-copy-name.tsx | 23 ++++++------ packages/tui/src/component/dialog-status.tsx | 36 ++++++++----------- .../src/component/plugin-route-missing.tsx | 13 ++++--- packages/tui/src/component/reconnecting.tsx | 6 ++-- .../tui/src/component/startup-loading.tsx | 6 ++-- packages/tui/src/ui/dialog-alert.tsx | 12 +++---- packages/tui/src/ui/dialog-confirm.tsx | 12 +++---- packages/tui/src/ui/dialog-export-result.tsx | 12 +++---- packages/tui/src/ui/dialog-help.tsx | 17 +++++---- 10 files changed, 86 insertions(+), 81 deletions(-) diff --git a/packages/tui/src/component/dialog-pair.tsx b/packages/tui/src/component/dialog-pair.tsx index 8f77bff7a13f..d26c248a6db8 100644 --- a/packages/tui/src/component/dialog-pair.tsx +++ b/packages/tui/src/component/dialog-pair.tsx @@ -16,7 +16,7 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { const client = useClient() const dialog = useDialog() const dimensions = useTerminalDimensions() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const [loadError, setLoadError] = createSignal() const [showPassword, setShowPassword] = createSignal(false) const [passwordHover, setPasswordHover] = createSignal(false) @@ -47,17 +47,17 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { - URLs - {(url) => {url}} + URLs + {(url) => {url}} - Username - {value.username} + Username + {value.username} - Password + Password setPasswordHover(true)} onMouseOut={() => setPasswordHover(false)} @@ -67,7 +67,7 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { ["localhost", "127.0.0.1", "[::1]"].includes(new URL(url).hostname))}> - + Run `opencode service set hostname 0.0.0.0` to access the service remotely. @@ -78,7 +78,7 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { flexShrink={0} alignItems={horizontal() ? "flex-end" : "center"} > - {renderUnicodeCompact(JSON.stringify(value), { border: 1 })} + {renderUnicodeCompact(JSON.stringify(value), { border: 1 })} ) @@ -87,17 +87,17 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { return ( - + Pair - dialog.clear()}> + dialog.clear()}> esc Loading server information…}> + Loading server information…}> = 36} fallback={ @@ -116,11 +116,11 @@ export function DialogPair(props: { credentials?: DialogPairCredentials }) { > {(error) => ( - + Could not load server information - {errorMessage(error())} - Close and reopen Pair to try again. + {errorMessage(error())} + Close and reopen Pair to try again. )} diff --git a/packages/tui/src/component/dialog-project-copy-name.tsx b/packages/tui/src/component/dialog-project-copy-name.tsx index 98bb711f7b91..ef51e5a37a1d 100644 --- a/packages/tui/src/component/dialog-project-copy-name.tsx +++ b/packages/tui/src/component/dialog-project-copy-name.tsx @@ -7,7 +7,7 @@ import { useDialog, type DialogContext } from "../ui/dialog" export function DialogProjectCopyName(props: { onConfirm: (name: string) => void }) { const dialog = useDialog() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const shortcuts = Keymap.useShortcuts() const [inputTarget, setInputTarget] = createSignal() let input: InputRenderable @@ -47,10 +47,10 @@ export function DialogProjectCopyName(props: { onConfirm: (name: string) => void return ( - + Name project copy - dialog.clear()}> + dialog.clear()}> esc @@ -61,17 +61,18 @@ export function DialogProjectCopyName(props: { onConfirm: (name: string) => void }} onSubmit={confirm} placeholder="Project copy name" - placeholderColor={theme.textMuted} - textColor={theme.text} - focusedTextColor={theme.text} - cursorColor={theme.text} + placeholderColor={themeV2.text.subdued()} + textColor={themeV2.text.formfield()} + focusedTextColor={themeV2.text.formfield()} + cursorColor={themeV2.text.formfield()} /> - - enter submit + + enter submit - - {shortcuts.get("dialog.project_copy.generate")} generate one + + {shortcuts.get("dialog.project_copy.generate")}{" "} + generate one diff --git a/packages/tui/src/component/dialog-status.tsx b/packages/tui/src/component/dialog-status.tsx index 32038036cf8c..7a0d71897daa 100644 --- a/packages/tui/src/component/dialog-status.tsx +++ b/packages/tui/src/component/dialog-status.tsx @@ -8,47 +8,41 @@ export type DialogStatusProps = {} export function DialogStatus() { const data = useData() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const dialog = useDialog() const mcp = createMemo(() => data.location.mcp.server.list() ?? []) + const color = (status: string) => { + if (status === "connected") return themeV2.text.feedback.success() + if (status === "failed") return themeV2.text.feedback.error() + if (status === "needs_auth") return themeV2.text.feedback.warning() + if (status === "needs_client_registration") return themeV2.text.feedback.error() + return themeV2.text.subdued() + } return ( - + Status - dialog.clear()}> + dialog.clear()}> esc - 0} fallback={No MCP servers}> + 0} fallback={No MCP servers}> - + {mcp().length} MCP server{mcp().length === 1 ? "" : "s"} {(item) => ( - - )[item.status.status], - }} - > + • - + {item.name}{" "} - + Connected {(val) => val().error} diff --git a/packages/tui/src/component/plugin-route-missing.tsx b/packages/tui/src/component/plugin-route-missing.tsx index 98fb3efb3bf8..2cbe40446b0f 100644 --- a/packages/tui/src/component/plugin-route-missing.tsx +++ b/packages/tui/src/component/plugin-route-missing.tsx @@ -1,15 +1,20 @@ import { useTheme } from "../context/theme" export function PluginRouteMissing(props: { id: string; name: string; onHome: () => void }) { - const { theme } = useTheme() + const { themeV2 } = useTheme() return ( - + Unknown plugin route: {props.id}/{props.name} - - go home + + go home ) diff --git a/packages/tui/src/component/reconnecting.tsx b/packages/tui/src/component/reconnecting.tsx index 99fb3ecb795c..538daafdd7c4 100644 --- a/packages/tui/src/component/reconnecting.tsx +++ b/packages/tui/src/component/reconnecting.tsx @@ -2,7 +2,7 @@ import { useTheme } from "../context/theme" import { Spinner } from "./spinner" export function Reconnecting() { - const theme = useTheme().theme + const { themeV2 } = useTheme() return ( - Waiting for background service... + Waiting for background service... ) diff --git a/packages/tui/src/component/startup-loading.tsx b/packages/tui/src/component/startup-loading.tsx index 6665c0c2e8c4..9e539ca2f5d0 100644 --- a/packages/tui/src/component/startup-loading.tsx +++ b/packages/tui/src/component/startup-loading.tsx @@ -3,7 +3,7 @@ import { useTheme } from "../context/theme" import { Spinner } from "./spinner" export function StartupLoading(props: { ready: () => boolean }) { - const theme = useTheme().theme + const { themeV2 } = useTheme().contextual("elevated") const [show, setShow] = createSignal(false) const text = createMemo(() => (props.ready() ? "Finishing startup..." : "Loading plugins...")) let wait: NodeJS.Timeout | undefined @@ -54,8 +54,8 @@ export function StartupLoading(props: { ready: () => boolean }) { return ( - - {text()} + + {text()} diff --git a/packages/tui/src/ui/dialog-alert.tsx b/packages/tui/src/ui/dialog-alert.tsx index 998398272380..6f796095647b 100644 --- a/packages/tui/src/ui/dialog-alert.tsx +++ b/packages/tui/src/ui/dialog-alert.tsx @@ -11,7 +11,7 @@ export type DialogAlertProps = { export function DialogAlert(props: DialogAlertProps) { const dialog = useDialog() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") Keymap.createLayer(() => ({ mode: "modal", @@ -30,27 +30,27 @@ export function DialogAlert(props: DialogAlertProps) { return ( - + {props.title} - dialog.clear()}> + dialog.clear()}> esc - {props.message} + {props.message} { props.onConfirm?.() dialog.clear() }} > - ok + ok diff --git a/packages/tui/src/ui/dialog-confirm.tsx b/packages/tui/src/ui/dialog-confirm.tsx index c9bb952fd54f..43778d22d81d 100644 --- a/packages/tui/src/ui/dialog-confirm.tsx +++ b/packages/tui/src/ui/dialog-confirm.tsx @@ -18,7 +18,7 @@ export type DialogConfirmResult = boolean | undefined export function DialogConfirm(props: DialogConfirmProps) { const dialog = useDialog() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const [store, setStore] = createStore({ active: "confirm" as "confirm" | "cancel", }) @@ -57,15 +57,15 @@ export function DialogConfirm(props: DialogConfirmProps) { return ( - + {props.title} - dialog.clear()}> + dialog.clear()}> esc - {props.message} + {props.message} @@ -73,14 +73,14 @@ export function DialogConfirm(props: DialogConfirmProps) { { if (key === "confirm") props.onConfirm?.() if (key === "cancel") props.onCancel?.() dialog.clear() }} > - + {Locale.titlecase(key === "cancel" ? (props.label ?? key) : key)} diff --git a/packages/tui/src/ui/dialog-export-result.tsx b/packages/tui/src/ui/dialog-export-result.tsx index f7d7cb199e87..d6e8eae4347f 100644 --- a/packages/tui/src/ui/dialog-export-result.tsx +++ b/packages/tui/src/ui/dialog-export-result.tsx @@ -5,7 +5,7 @@ import { useDialog, type DialogContext } from "./dialog" export function DialogExportResult(props: { path: string; onClose?: () => void }) { const dialog = useDialog() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const close = () => { props.onClose?.() @@ -27,19 +27,19 @@ export function DialogExportResult(props: { path: string; onClose?: () => void } return ( - + Session exported - + esc - {props.path} + {props.path} - - Close + + Close diff --git a/packages/tui/src/ui/dialog-help.tsx b/packages/tui/src/ui/dialog-help.tsx index a78b1f7d9632..6ab1f9cad9f5 100644 --- a/packages/tui/src/ui/dialog-help.tsx +++ b/packages/tui/src/ui/dialog-help.tsx @@ -5,7 +5,7 @@ import { useDialog } from "./dialog" export function DialogHelp() { const dialog = useDialog() - const { theme } = useTheme() + const { themeV2 } = useTheme().contextual("elevated") const shortcuts = Keymap.useShortcuts() Keymap.createLayer(() => ({ @@ -19,21 +19,26 @@ export function DialogHelp() { return ( - + Help - dialog.clear()}> + dialog.clear()}> esc/enter - + Press {shortcuts.get("command.palette.show")} to see all available actions and commands in any context. - dialog.clear()}> - ok + dialog.clear()} + > + ok