Skip to content

Commit 00e7472

Browse files
authored
feat(tui): new dialog designs behind new designs experiment (#55810)
Lands the rest of the dialog redesign stack, all behind the new-designs experiment: - put dialog search in the title row (#55800) - hide dialog search on short lists (#55801) - read the experiment through useNewDesigns (#55802) - raise dialog footers (#55805) - standardize dialog footer actions (#55806) - style selected dialog list rows (#55807) - show list overflow indicator (#55808) - restyle dialog headers (#55809) - use vivid agent colors (#55810)
1 parent 50d4280 commit 00e7472

37 files changed

Lines changed: 734 additions & 304 deletions

‎packages/tui/src/component/command-palette.tsx‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ export function CommandPaletteDialog() {
6161
}
6262

6363
return (
64-
<DialogSelect ref={(value) => (ref = value)} title="Commands" options={list()} flat={true} filterThreshold={0.7} />
64+
<DialogSelect
65+
ref={(value) => (ref = value)}
66+
title="Commands"
67+
searchInTitle
68+
titlePlaceholder="Search commands"
69+
options={list()}
70+
flat={true}
71+
filterThreshold={0.7}
72+
/>
6573
)
6674
}

‎packages/tui/src/component/dialog-agent.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export function DialogAgent() {
2020
return (
2121
<DialogSelect
2222
title="Select agent"
23+
searchInTitle
24+
titlePlaceholder="Search agents"
2325
current={local.agent.current()?.id}
2426
options={options()}
2527
onSelect={(option) => {

‎packages/tui/src/component/dialog-config.tsx‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createMemo, createSignal } from "solid-js"
2-
import { useConfig } from "../config"
2+
import { useConfig, useNewDesigns } from "../config"
33
import { useThemes } from "../context/theme"
44
import { DialogSelect } from "../ui/dialog-select"
55
import { useToast } from "../ui/toast"
@@ -332,6 +332,7 @@ export function settingID(setting: Setting) {
332332

333333
export function DialogConfig(props: { current?: string }) {
334334
const config = useConfig()
335+
const newDesigns = useNewDesigns()
335336
const toast = useToast()
336337
const themes = useThemes()
337338
const current = Math.max(
@@ -394,12 +395,14 @@ export function DialogConfig(props: { current?: string }) {
394395
return (
395396
<DialogSelect
396397
title="Settings"
398+
searchInTitle
399+
titlePlaceholder="Search settings"
397400
options={options()}
398401
current={current}
399402
filterThreshold={0.7}
400403
onMove={(option) => setSelected(option.value)}
401404
onSelect={(option) => void change(1, option.value)}
402-
footerHints={[{ title: "change", label: "←/→" }]}
405+
footerHints={newDesigns() ? [] : [{ title: "change", label: "←/→" }]}
403406
bindings={[
404407
{
405408
bind: "left",

‎packages/tui/src/component/dialog-debug.tsx‎

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { createMemo, createSignal, For } from "solid-js"
22
import { Keymap } from "../context/keymap"
33
import { useTheme } from "../context/theme"
4-
import { DialogFooter, DialogHeader, DialogLayout, useDialog } from "../ui/dialog"
4+
import { DialogHeader, DialogLayout, useDialog } from "../ui/dialog"
55
import { useRoute } from "../context/route"
66
import { useLocal } from "../context/local"
77
import { useClipboard } from "../context/clipboard"
88
import { useToast } from "../ui/toast"
99
import { describeOS, describeTerminal } from "../util/system"
1010
import { useTuiApp } from "../context/runtime"
11+
import { useNewDesigns } from "../config"
1112

1213
export function DialogDebug() {
1314
const theme = useTheme()
@@ -17,6 +18,7 @@ export function DialogDebug() {
1718
const clipboard = useClipboard()
1819
const toast = useToast()
1920
const app = useTuiApp()
21+
const newDesigns = useNewDesigns()
2022
const [copied, setCopied] = createSignal(false)
2123

2224
dialog.setSize("large")
@@ -48,27 +50,26 @@ export function DialogDebug() {
4850

4951
Keymap.createLayer(() => ({
5052
mode: "modal",
51-
commands: [{ bind: "return", title: "Copy debug info", group: "Dialog", run: copy }],
53+
commands: [{ bind: newDesigns() ? "c" : "return", title: "Copy debug info", group: "Dialog", run: copy }],
5254
}))
5355

56+
const copyAction = () => ({
57+
title: copied() ? "✓ copied" : "copy",
58+
key: newDesigns() ? "c" : "enter",
59+
color: copied() ? theme.text.feedback.success.base : undefined,
60+
onTrigger: copy,
61+
})
62+
5463
return (
5564
<DialogLayout
56-
header={<DialogHeader title="Debug" />}
57-
footer={
58-
<DialogFooter
59-
actions={[
60-
{
61-
title: copied() ? "✓ copied" : "copy",
62-
key: "enter",
63-
side: "right",
64-
color: copied() ? theme.text.feedback.success.base : undefined,
65-
onTrigger: copy,
66-
},
67-
]}
68-
>
69-
<text fg={theme.text.muted}>Share this when reporting an issue.</text>
70-
</DialogFooter>
71-
}
65+
header={<DialogHeader title="Debug" description="Share this when reporting an issue" />}
66+
footer={{
67+
actions: { primary: [copyAction()] },
68+
get children() {
69+
if (newDesigns()) return undefined
70+
return <text fg={theme.text.muted}>Share this when reporting an issue.</text>
71+
},
72+
}}
7273
>
7374
{/* No click-to-copy here: releasing a mouse selection must trigger the
7475
global copy-on-select so users can copy a single value, e.g. the session id. */}

‎packages/tui/src/component/dialog-error-details.tsx‎

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ export function DialogErrorDetails(props: {
6161
],
6262
}))
6363

64+
const actions = () => [
65+
{ title: "investigate", key: "i", onTrigger: investigate },
66+
copied()
67+
? { title: "✓ copied", color: theme.text.feedback.success.base, onTrigger: copy }
68+
: { title: "copy details", key: "c", onTrigger: copy },
69+
]
70+
6471
useKeyboard((event) => {
6572
if (event.name === "up") return scroll?.scrollBy(-1)
6673
if (event.name === "down") return scroll?.scrollBy(1)
@@ -101,17 +108,8 @@ export function DialogErrorDetails(props: {
101108
</Show>
102109
</box>
103110
}
104-
footer={
105-
<DialogFooter
106-
actions={[
107-
{ title: "investigate", key: "i", onTrigger: investigate },
108-
copied()
109-
? { title: "✓ copied", color: theme.text.feedback.success.base, onTrigger: copy }
110-
: { title: "copy details", key: "c", onTrigger: copy },
111-
{ title: "scroll", key: "↑/↓", side: "right" },
112-
]}
113-
/>
114-
}
111+
footer={{ actions: { primary: actions() } }}
112+
legacyFooter={<DialogFooter actions={{ secondary: actions(), primary: [{ title: "scroll", key: "↑/↓" }] }} />}
115113
>
116114
<scrollbox
117115
ref={(element: ScrollBoxRenderable) => (scroll = element)}

‎packages/tui/src/component/dialog-experiments.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createMemo, createSignal } from "solid-js"
2-
import { useConfig } from "../config"
2+
import { useConfig, useNewDesigns } from "../config"
33
import { DIALOG_LIST_INSET } from "../ui/dialog"
44
import { DialogSelect } from "../ui/dialog-select"
55
import { useTheme } from "../context/theme"
@@ -24,6 +24,7 @@ export const experiments: Experiment[] = [
2424

2525
export function DialogExperiments() {
2626
const config = useConfig()
27+
const newDesigns = useNewDesigns()
2728
const theme = useTheme()
2829
const toast = useToast()
2930
const [selected, setSelected] = createSignal<Experiment>()
@@ -67,7 +68,7 @@ export function DialogExperiments() {
6768
<text fg={theme.text.muted}>No experiments available</text>
6869
</box>
6970
}
70-
footerHints={experiments.length > 0 ? [{ title: "change", label: "←/→" }] : []}
71+
footerHints={experiments.length > 0 && !newDesigns() ? [{ title: "change", label: "←/→" }] : []}
7172
bindings={
7273
experiments.length > 0
7374
? [

‎packages/tui/src/component/dialog-highlights.tsx‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ export function DialogHighlights(props: { version: string; items: ReadonlyArray<
3535
return (
3636
<DialogLayout
3737
header={<DialogHeader title={`What's new in ${props.version}`} />}
38-
footer={
38+
footer={{ actions: { primary: [{ title: "ok", key: "enter", onTrigger: () => dialog.clear() }] } }}
39+
legacyFooter={
3940
<box flexDirection="row" justifyContent="space-between" alignItems="center">
40-
<DialogFooter actions={[{ title: "scroll", key: "↑/↓" }]} />
41+
<DialogFooter actions={{ secondary: [{ title: "scroll", key: "↑/↓" }] }} />
4142
<box
4243
paddingLeft={3}
4344
paddingRight={3}

‎packages/tui/src/component/dialog-image-preview.tsx‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,25 @@ export function DialogImagePreview(props: { images: readonly ImagePreviewItem[];
3939
<DialogLayout
4040
id="prompt-image-viewer"
4141
header={<DialogHeader title={`Image ${index() + 1} of ${props.images.length}`} />}
42-
footer={
42+
footer={{
43+
actions: {
44+
primary:
45+
props.images.length > 1
46+
? [
47+
{ title: "previous", key: "←", onTrigger: () => move(-1) },
48+
{ title: "next", key: "→", onTrigger: () => move(1) },
49+
]
50+
: [],
51+
},
52+
get children() {
53+
return (
54+
<text fg={failed() ? theme.text.feedback.error.base : theme.text.muted} wrapMode="none" truncate>
55+
{failed() ? "No preview" : (current().mention?.text ?? `Image ${index() + 1}`)}
56+
</text>
57+
)
58+
},
59+
}}
60+
legacyFooter={
4361
<box flexDirection="row" justifyContent="space-between">
4462
<text fg={theme.text.muted} onMouseUp={() => move(-1)}>
4563
{props.images.length > 1 ? "← previous" : ""}

0 commit comments

Comments
 (0)