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 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 9aee83f5..7e940625 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'; @@ -26,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; @@ -48,7 +49,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 ? (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)}` diff --git a/packages/prompts/test/__snapshots__/confirm.test.ts.snap b/packages/prompts/test/__snapshots__/confirm.test.ts.snap index 6f7f7bf8..8b880f9d 100644 --- a/packages/prompts/test/__snapshots__/confirm.test.ts.snap +++ b/packages/prompts/test/__snapshots__/confirm.test.ts.snap @@ -156,6 +156,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`] = ` [ "", @@ -353,6 +373,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 6f7e311b..3483e25c 100644 --- a/packages/prompts/test/confirm.test.ts +++ b/packages/prompts/test/confirm.test.ts @@ -74,6 +74,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',