From 555d6c126d19d02d35adfa2468ee074acb32fada Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Wed, 4 Feb 2026 00:02:25 +0100 Subject: [PATCH 1/3] feat: add `vertical` option to `confirm` prompt --- .gitignore | 3 ++ packages/prompts/src/confirm.ts | 3 +- .../test/__snapshots__/confirm.test.ts.snap | 40 +++++++++++++++++++ packages/prompts/test/confirm.test.ts | 16 ++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0947dace..67634e43 100644 --- a/.gitignore +++ b/.gitignore @@ -124,6 +124,9 @@ dist # Stores VSCode versions used for testing VSCode extensions .vscode-test +# JetBrains IDEA +.idea + # yarn v2 .yarn/cache .yarn/unplugged diff --git a/packages/prompts/src/confirm.ts b/packages/prompts/src/confirm.ts index 4ee30acc..81e6044f 100644 --- a/packages/prompts/src/confirm.ts +++ b/packages/prompts/src/confirm.ts @@ -14,6 +14,7 @@ export interface ConfirmOptions extends CommonOptions { active?: string; inactive?: string; initialValue?: boolean; + vertical?: boolean; } export const confirm = (opts: ConfirmOptions) => { const active = opts.active ?? 'Yes'; @@ -41,7 +42,7 @@ export const confirm = (opts: ConfirmOptions) => { this.value ? `${color.green(S_RADIO_ACTIVE)} ${active}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}` - } ${color.dim('/')} ${ + }${opts.vertical ? `\n${color.cyan(S_BAR)} ` : ` ${color.dim('/')} `}${ !this.value ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}` diff --git a/packages/prompts/test/__snapshots__/confirm.test.ts.snap b/packages/prompts/test/__snapshots__/confirm.test.ts.snap index 254e48f8..7fa57e35 100644 --- a/packages/prompts/test/__snapshots__/confirm.test.ts.snap +++ b/packages/prompts/test/__snapshots__/confirm.test.ts.snap @@ -139,6 +139,26 @@ exports[`confirm (isCI = false) > renders message with choices 1`] = ` ] `; +exports[`confirm (isCI = false) > renders options in vertical alignment 1`] = ` +[ + "", + "│ +◆ foo +│ ● Yes +│ ○ No +└ +", + "", + "", + "", + "◇ foo +│ Yes", + " +", + "", +] +`; + exports[`confirm (isCI = false) > right arrow moves to next choice 1`] = ` [ "", @@ -302,6 +322,26 @@ exports[`confirm (isCI = true) > renders message with choices 1`] = ` ] `; +exports[`confirm (isCI = true) > renders options in vertical alignment 1`] = ` +[ + "", + "│ +◆ foo +│ ● Yes +│ ○ No +└ +", + "", + "", + "", + "◇ foo +│ Yes", + " +", + "", +] +`; + exports[`confirm (isCI = true) > right arrow moves to next choice 1`] = ` [ "", diff --git a/packages/prompts/test/confirm.test.ts b/packages/prompts/test/confirm.test.ts index 0268059c..75679797 100644 --- a/packages/prompts/test/confirm.test.ts +++ b/packages/prompts/test/confirm.test.ts @@ -72,6 +72,22 @@ describe.each(['true', 'false'])('confirm (isCI = %s)', (isCI) => { expect(output.buffer).toMatchSnapshot(); }); + test('renders options in vertical alignment', async () => { + const result = prompts.confirm({ + message: 'foo', + vertical: true, + input, + output, + }); + + input.emit('keypress', '', { name: 'return' }); + + const value = await result; + + expect(value).toBe(true); + expect(output.buffer).toMatchSnapshot(); + }); + test('right arrow moves to next choice', async () => { const result = prompts.confirm({ message: 'foo', From 4efc384ef8deab9907da0d553d1e3933fb82070d Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Wed, 4 Feb 2026 00:13:08 +0100 Subject: [PATCH 2/3] add changeset --- .changeset/small-toys-move.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/small-toys-move.md diff --git a/.changeset/small-toys-move.md b/.changeset/small-toys-move.md new file mode 100644 index 00000000..0993e01c --- /dev/null +++ b/.changeset/small-toys-move.md @@ -0,0 +1,5 @@ +--- +"@clack/prompts": patch +--- + +add `vertical` arrangement option to `confirm` prompt From 827a807f574cf0c6ded2530fb8d856e8dbda8cd3 Mon Sep 17 00:00:00 2001 From: Bartosz Kaszubowski Date: Wed, 4 Feb 2026 12:07:50 +0100 Subject: [PATCH 3/3] render correctly with `withGuide` opt --- packages/prompts/src/confirm.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/prompts/src/confirm.ts b/packages/prompts/src/confirm.ts index 8e1e251c..7e940625 100644 --- a/packages/prompts/src/confirm.ts +++ b/packages/prompts/src/confirm.ts @@ -27,7 +27,7 @@ export const confirm = (opts: ConfirmOptions) => { output: opts.output, initialValue: opts.initialValue ?? true, render() { - const hasGuide = (opts.withGuide ?? settings.withGuide) !== false; + const hasGuide = opts.withGuide ?? settings.withGuide; const title = `${hasGuide ? `${color.gray(S_BAR)}\n` : ''}${symbol(this.state)} ${opts.message}\n`; const value = this.value ? active : inactive; @@ -49,7 +49,7 @@ export const confirm = (opts: ConfirmOptions) => { this.value ? `${color.green(S_RADIO_ACTIVE)} ${active}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(active)}` - }${opts.vertical ? `\n${color.cyan(S_BAR)} ` : ` ${color.dim('/')} `}${ + }${opts.vertical ? (hasGuide ? `\n${color.cyan(S_BAR)} ` : '\n') : ` ${color.dim('/')} `}${ !this.value ? `${color.green(S_RADIO_ACTIVE)} ${inactive}` : `${color.dim(S_RADIO_INACTIVE)} ${color.dim(inactive)}`