From 4a2a150487f5aa88d4182bd3bdbb04aa37727006 Mon Sep 17 00:00:00 2001 From: Matthias Keckl <53833818+matthyk@users.noreply.github.com> Date: Mon, 19 Feb 2024 17:20:02 +0100 Subject: [PATCH] add `renderSelectedChoices` style option (#1360) * add renderSelectedChoices style option * Update packages/checkbox/src/index.mts Co-authored-by: Simon Boudrias * fix formatting --------- Co-authored-by: Simon Boudrias --- packages/checkbox/README.md | 4 ++ packages/checkbox/checkbox.test.mts | 60 +++++++++++++++++++++++++++++ packages/checkbox/src/index.mts | 16 ++++++-- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/packages/checkbox/README.md b/packages/checkbox/README.md index f336a21ac..b188c4942 100644 --- a/packages/checkbox/README.md +++ b/packages/checkbox/README.md @@ -67,6 +67,10 @@ type Theme = { highlight: (text: string) => string; key: (text: string) => string; disabledChoice: (text: string) => string; + renderSelectedChoices: ( + selectedChoices: ReadonlyArray>, + allChoices: ReadonlyArray | Separator>, + ) => string; }; icon: { checked: string; diff --git a/packages/checkbox/checkbox.test.mts b/packages/checkbox/checkbox.test.mts index aaf087e79..1cc60cdd5 100644 --- a/packages/checkbox/checkbox.test.mts +++ b/packages/checkbox/checkbox.test.mts @@ -685,4 +685,64 @@ describe('checkbox prompt', () => { events.keypress('enter'); await expect(answer).resolves.toEqual([1]); }); + + it('renderSelectedChoices', async () => { + const { answer, events, getScreen } = await render(checkbox, { + message: 'Select your favourite number.', + choices: numberedChoices, + theme: { + style: { + renderSelectedChoices(selected: { value: number }[]) { + if (selected.length > 1) { + return `You have selected ${selected[0].value} and ${selected.length - 1} more.`; + } + return `You have selected ${selected + .slice(0, 1) + .map((c) => c.value) + .join(', ')}.`; + }, + }, + }, + }); + + events.keypress('space'); + events.keypress('down'); + events.keypress('space'); + events.keypress('down'); + events.keypress('space'); + events.keypress('enter'); + + await answer; + expect(getScreen()).toMatchInlineSnapshot( + '"? Select your favourite number. You have selected 1 and 2 more."', + ); + }); + + it('renderSelectedChoices - using allChoices parameter', async () => { + const { answer, events, getScreen } = await render(checkbox, { + message: 'Select your favourite number.', + choices: numberedChoices, + theme: { + style: { + renderSelectedChoices( + selected: { value: number }[], + all: ({ value: number } | Separator)[], + ) { + return `You have selected ${selected.length} out of ${all.length} options.`; + }, + }, + }, + }); + + events.keypress('space'); + events.keypress('down'); + events.keypress('down'); + events.keypress('space'); + events.keypress('enter'); + + await answer; + expect(getScreen()).toMatchInlineSnapshot( + '"? Select your favourite number. You have selected 2 out of 12 options."', + ); + }); }); diff --git a/packages/checkbox/src/index.mts b/packages/checkbox/src/index.mts index 4ed8e0648..b322dbcb2 100644 --- a/packages/checkbox/src/index.mts +++ b/packages/checkbox/src/index.mts @@ -27,6 +27,10 @@ type CheckboxTheme = { }; style: { disabledChoice: (text: string) => string; + renderSelectedChoices: ( + selectedChoices: ReadonlyArray>, + allChoices: ReadonlyArray | Separator>, + ) => string; }; }; @@ -38,6 +42,8 @@ const checkboxTheme: CheckboxTheme = { }, style: { disabledChoice: (text: string) => chalk.dim(`- ${text}`), + renderSelectedChoices: (selectedChoices) => + selectedChoices.map((choice) => choice.name || choice.value).join(', '), }, }; @@ -193,10 +199,12 @@ export default createPrompt( }); if (status === 'done') { - const selection = items - .filter(isChecked) - .map((choice) => choice.name || choice.value); - return `${prefix} ${message} ${theme.style.answer(selection.join(', '))}`; + const selection = items.filter(isChecked); + const answer = theme.style.answer( + theme.style.renderSelectedChoices(selection, items), + ); + + return `${prefix} ${message} ${answer}`; } let helpTip = '';