From 5628a542fec65c62f180776af19cc4f5d1eaa1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Barth=C3=A9lemy=20Laurans?= Date: Sun, 6 Oct 2024 18:50:35 +0200 Subject: [PATCH] [Feature] Add sumUp method to format answers after submit --- README.md | 1 + src/index.mts | 11 +++++-- test/normal.test.mts | 68 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37e8ac7..20030a7 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ const answer = await tableMultiple({ | pageSize | `number` | no | The number of lines to display. | `7` | | required | `boolean` | no | Indicate if at least one choice is necessary. | `false` | rows | `(TableRow \| Separator)[]` | yes | The list of rows. Each row offer a choice which can be multiple (radio vs checkbox vs checkbox-multi) based on the `mode` option. | +| sumUp | `TableAnswers => string` | no | This allow to display a resume of selected answers to user after validation. | | validate | `TableAnswers => boolean \| string \| Promise` | no | On submit, validate the answered content. When returning a string, it'll be used as the error message displayed to the user. Note: returning a rejected promise, we'll assume a code error happened and crash. | ## Columns diff --git a/src/index.mts b/src/index.mts index 4200369..36269eb 100644 --- a/src/index.mts +++ b/src/index.mts @@ -45,6 +45,7 @@ type TableConfig = { loop?: boolean, allowUnset?: boolean, validate?: (answers: TableAnswers) => boolean | string | Promise, + sumUp?: (answers: TableAnswers) => string } type TableAnswer = { @@ -200,6 +201,7 @@ export default createPrompt( pageSize = 7, loop = true, validate = () => true, + sumUp = () => '', } = config const [status, setStatus] = useState('idle') @@ -385,11 +387,16 @@ export default createPrompt( config.message, helpTip, ].filter(Boolean).join(' '), - '', ] if (status !== 'done') { - printToShell.push(table.toString()) + printToShell.push('', table.toString()) + } else { + const summarized = sumUp(values) + + if (summarized) { + printToShell.push(summarized) + } } printToShell.push(`${error}${ansiEscapes.cursorHide}`) diff --git a/test/normal.test.mts b/test/normal.test.mts index 7c09dac..55259d0 100644 --- a/test/normal.test.mts +++ b/test/normal.test.mts @@ -1021,6 +1021,74 @@ describe('table-multiple prompt [normal]', () => { ].join('\n')) }) + it('format answers as requested', async () => { + const choices = [ + { + value: '1', + title: 'Test 1', + }, + { + value: '2', + title: 'Test 2', + } + ] + + const { answer, events, getScreen } = await render(tableMultiple, { + message: 'What do you want?', + columns: [ + { + title: 'A?', + value: 'A', + }, + ], + rows: choices, + sumUp: (answers: TableAnswers) => answers.map(answer => answer.answers.length ? `${answer.choice.title}: ${answer.answers.join(',')}` : '').filter(Boolean).join('; ') + }) + + expect(getScreen()).toMatchInlineSnapshot([ + `"? What do you want? (Press to select, to move rows, to move columns)', + '', + '┌──────────┬───────┐', + '│ 1-2 of 2 │ A? │', + '├──────────┼───────┤', + '│ Test 1 │ [ ◯ ] │', + '├──────────┼───────┤', + '│ Test 2 │ ◯ │', + '└──────────┴───────┘"' + ].join('\n')) + + events.keypress('space') + + expect(getScreen()).toMatchInlineSnapshot([ + '"? What do you want?', + '', + '┌──────────┬───────┐', + '│ 1-2 of 2 │ A? │', + '├──────────┼───────┤', + '│ Test 1 │ [ ◉ ] │', + '├──────────┼───────┤', + '│ Test 2 │ ◯ │', + '└──────────┴───────┘"' + ].join('\n')) + + events.keypress('enter') + + await Promise.resolve() + + expect(getScreen()).toMatchInlineSnapshot([ + '"✔ What do you want?', + 'Test 1: A"', + ].join('\n')) + + await expect(answer).resolves.toEqual([ + { + choice: choices[0], + answers: ['A'], + } + ]) + }) + it('throws error if missing columns', async () => { const choices = [ {