diff --git a/packages/tui/src/component/dialog-config.tsx b/packages/tui/src/component/dialog-config.tsx index 01527cba537..6c9df2b505d 100644 --- a/packages/tui/src/component/dialog-config.tsx +++ b/packages/tui/src/component/dialog-config.tsx @@ -10,6 +10,8 @@ type Setting = { title: string category: string path: string[] + /** Shown below the list while the setting is selected, under the "new-designs" experiment. */ + description: string default: unknown values?: readonly unknown[] labels?: readonly string[] @@ -27,6 +29,7 @@ export const settings: Setting[] = [ title: "Theme", category: "Appearance", path: ["theme", "name"], + description: "Color theme used across the interface", default: "opencode", keywords: ["color scheme", "colors"], open: (dialog) => @@ -38,6 +41,7 @@ export const settings: Setting[] = [ title: "Color mode", category: "Appearance", path: ["theme", "mode"], + description: "Dark or light variant, or follow the system", default: "system", values: ["system", "dark", "light"], keywords: ["dark mode", "light mode", "system theme"], @@ -46,6 +50,7 @@ export const settings: Setting[] = [ title: "Animations", category: "Appearance", path: ["animations"], + description: "Whether spinners and transitions animate", default: false, values: [false, true], labels: ["off", "on"], @@ -55,6 +60,7 @@ export const settings: Setting[] = [ title: "Sidebar", category: "Session", path: ["session", "sidebar"], + description: "Whether the sidebar shows when there is room", default: "auto", values: ["hide", "auto"], keywords: ["side panel"], @@ -63,6 +69,7 @@ export const settings: Setting[] = [ title: "Scrollbar", category: "Session", path: ["session", "scrollbar"], + description: "Whether a scrollbar is shown next to the chat", default: false, values: [false, true], labels: ["off", "on"], @@ -72,6 +79,7 @@ export const settings: Setting[] = [ title: "Thinking", category: "Session", path: ["session", "thinking"], + description: "Whether model thinking is shown in the chat", default: "hide", values: ["hide", "show"], keywords: ["reasoning", "chain of thought"], @@ -80,6 +88,7 @@ export const settings: Setting[] = [ title: "Markdown", category: "Session", path: ["session", "markdown"], + description: "Whether chat markdown is rendered or shown as source", default: "rendered", values: ["source", "rendered"], keywords: ["syntax", "concealment", "rendering"], @@ -88,6 +97,7 @@ export const settings: Setting[] = [ title: "Tool grouping", category: "Session", path: ["session", "grouping"], + description: "Whether consecutive reads and searches are grouped", default: "auto", values: ["none", "auto"], keywords: ["transcript", "messages", "reads", "searches"], @@ -96,6 +106,7 @@ export const settings: Setting[] = [ title: "Verbosity", category: "Session", path: ["session", "verbosity"], + description: "How much tool activity is shown in the chat", default: "medium", values: ["low", "medium", "high"], keywords: ["detail", "activity", "summary", "transcript"], @@ -104,6 +115,7 @@ export const settings: Setting[] = [ title: "Transcript images", category: "Session", path: ["session", "image_preview"], + description: "Whether images are shown in the chat", default: false, values: [false, true], labels: ["off", "on"], @@ -113,6 +125,7 @@ export const settings: Setting[] = [ title: "TPS", category: "Session", path: ["session", "tps"], + description: "Whether tokens per second are shown for responses", default: true, values: [false, true], labels: ["off", "on"], @@ -122,6 +135,7 @@ export const settings: Setting[] = [ title: "New session location", category: "Session", path: ["session", "new_location"], + description: "Directory new sessions start in", default: "launch", values: ["launch", "inherit"], labels: ["launch directory", "active session"], @@ -131,6 +145,7 @@ export const settings: Setting[] = [ title: "Permissions", category: "Session", path: ["session", "permissions"], + description: "Whether permission requests ask you or auto accept", default: "prompt", values: ["prompt", "autoaccept"], labels: ["prompt", "auto accept"], @@ -140,6 +155,7 @@ export const settings: Setting[] = [ title: "Mode", category: "Tabs", path: ["tabs", "mode"], + description: "Whether sessions open in tabs", default: "auto", values: ["off", "on", "auto"], }, @@ -147,6 +163,7 @@ export const settings: Setting[] = [ title: "Scope", category: "Tabs", path: ["tabs", "scope"], + description: "Whether tabs are per directory or shared everywhere", default: "cwd", values: ["cwd", "global"], labels: ["current directory", "global"], @@ -155,6 +172,7 @@ export const settings: Setting[] = [ title: "Layout", category: "Tabs", path: ["tabs", "layout"], + description: "Whether tabs run along the top or down the side", default: "horizontal", values: ["horizontal", "vertical"], keywords: ["sidebar", "orientation", "left"], @@ -163,6 +181,7 @@ export const settings: Setting[] = [ title: "Indicators", category: "Tabs", path: ["tabs", "indicators"], + description: "Whether tabs show status icons or always numbers", default: "status", values: ["status", "numbers"], labels: ["status icons", "always show numbers"], @@ -172,6 +191,7 @@ export const settings: Setting[] = [ title: "Layout", category: "Diffs", path: ["diffs", "view"], + description: "Whether diffs are side by side or in one column", default: "auto", values: ["auto", "split", "unified"], keywords: ["diff layout", "split diff", "unified diff"], @@ -180,6 +200,7 @@ export const settings: Setting[] = [ title: "Wrapping", category: "Diffs", path: ["diffs", "wrap"], + description: "Whether long lines in diffs wrap", default: "word", values: ["none", "word"], keywords: ["diff wrap", "word wrap", "line wrap"], @@ -188,6 +209,7 @@ export const settings: Setting[] = [ title: "File tree", category: "Diffs", path: ["diffs", "tree"], + description: "Whether a file tree is shown next to diffs", default: true, values: [false, true], labels: ["off", "on"], @@ -197,6 +219,7 @@ export const settings: Setting[] = [ title: "Single patch", category: "Diffs", path: ["diffs", "single"], + description: "Whether diffs show one file at a time", default: false, values: [false, true], labels: ["off", "on"], @@ -206,6 +229,7 @@ export const settings: Setting[] = [ title: "Scroll speed", category: "Input", path: ["scroll", "speed"], + description: "How far each scroll step moves", default: 3, step: 0.25, min: 0.25, @@ -217,6 +241,7 @@ export const settings: Setting[] = [ title: "Acceleration", category: "Input", path: ["scroll", "acceleration"], + description: "Whether scrolling speeds up the faster you scroll", default: false, values: [false, true], labels: ["off", "on"], @@ -226,6 +251,7 @@ export const settings: Setting[] = [ title: "Mouse", category: "Input", path: ["mouse"], + description: "Whether the interface responds to the mouse", default: true, values: [false, true], labels: ["off", "on"], @@ -235,6 +261,7 @@ export const settings: Setting[] = [ title: "Editor context", category: "Input", path: ["prompt", "editor"], + description: "Whether your editor's selection is added to prompts", default: true, values: [false, true], labels: ["off", "on"], @@ -244,6 +271,7 @@ export const settings: Setting[] = [ title: "Large pastes", category: "Input", path: ["prompt", "paste"], + description: "Whether large pastes are summarized or shown in full", default: "compact", values: ["compact", "full"], keywords: ["paste summary", "clipboard", "pasted content"], @@ -252,6 +280,7 @@ export const settings: Setting[] = [ title: "Image previews", category: "Input", path: ["prompt", "image_preview"], + description: "Whether attached images are previewed in the prompt", default: false, values: [false, true], labels: ["off", "on"], @@ -261,6 +290,7 @@ export const settings: Setting[] = [ title: "Leader timeout", category: "Input", path: ["leader", "timeout"], + description: "How long the leader key waits for the next key", default: 2000, step: 250, min: 250, @@ -272,6 +302,7 @@ export const settings: Setting[] = [ title: "Notifications", category: "Alerts", path: ["attention", "notifications"], + description: "Whether to notify when a session needs attention", default: false, values: [false, true], labels: ["off", "on"], @@ -281,6 +312,7 @@ export const settings: Setting[] = [ title: "Sounds", category: "Alerts", path: ["attention", "sound"], + description: "Whether a sound plays when a session needs attention", default: false, values: [false, true], labels: ["off", "on"], @@ -290,6 +322,7 @@ export const settings: Setting[] = [ title: "Volume", category: "Alerts", path: ["attention", "volume"], + description: "Volume of alert sounds", default: 0.4, step: 0.1, min: 0, @@ -301,6 +334,7 @@ export const settings: Setting[] = [ title: "Release highlights", category: "Alerts", path: ["highlights"], + description: "Whether release highlights are shown after an update", default: true, values: [false, true], labels: ["off", "on"], @@ -310,6 +344,7 @@ export const settings: Setting[] = [ title: "Window title", category: "Terminal", path: ["terminal", "title"], + description: "Whether the window title shows the current session", default: true, values: [false, true], labels: ["off", "on"], @@ -319,6 +354,7 @@ export const settings: Setting[] = [ title: "Copy behavior", category: "Terminal", path: ["terminal", "copy"], + description: "Whether selecting text copies it", default: process.platform === "win32" ? "manual" : "select", values: ["manual", "select"], keywords: ["selection", "clipboard"], @@ -327,6 +363,7 @@ export const settings: Setting[] = [ title: "Developer tools", category: "Debug", path: ["debug", "devtools"], + description: "Whether the developer tools bar is shown", default: false, values: [false, true], labels: ["off", "on"], @@ -380,6 +417,7 @@ export function DialogConfig(props: { current?: string }) { display(setting) ), footerOverhang: newDesigns() ? 2 : undefined, + detail: newDesigns() ? setting.description : undefined, value: index, })), ) @@ -412,7 +450,11 @@ export function DialogConfig(props: { current?: string }) { searchInTitle titlePlaceholder="Search settings" options={options()} - current={current} + // Under new designs the opening setting is focused without the current-item marker; changing a value keeps the + // selection where it is. + current={newDesigns() ? undefined : current} + focusTarget={newDesigns() ? current : undefined} + preserveSelection={newDesigns()} filterThreshold={0.7} onMove={(option) => setSelected(option.value)} onSelect={(option) => { diff --git a/packages/tui/src/ui/dialog-select.tsx b/packages/tui/src/ui/dialog-select.tsx index 996f3263257..c298c8d40ce 100644 --- a/packages/tui/src/ui/dialog-select.tsx +++ b/packages/tui/src/ui/dialog-select.tsx @@ -114,8 +114,9 @@ export interface DialogSelectOption { gutter?: (color: RGBA) => JSX.Element margin?: JSX.Element /** - * Shown below the list while this option is selected, under the "new-designs" experiment. A function is called - * each time the option becomes selected, because a rendered element cannot be shown again once it is removed. + * Shown below the list while this option is selected, under the "new-designs" experiment. A string is shown in muted + * text. A function is called each time the option becomes selected, because a rendered element cannot be shown again + * once it is removed. */ detail?: string | (() => JSX.Element) onSelect?: (ctx: DialogContext) => void @@ -838,7 +839,7 @@ export function DialogSelect(props: DialogSelectProps) { when={detailView()} keyed fallback={ - + {detailText() || " "} }