Skip to content

Commit

Permalink
Feat(@inquirer/checkbox) Add property to choices (matching inquirer API)
Browse files Browse the repository at this point in the history
  • Loading branch information
SBoudrias committed Jul 17, 2024
1 parent 2cc9e31 commit d274d15
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 10 deletions.
18 changes: 9 additions & 9 deletions packages/checkbox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ const answer = await checkbox({

## Options

| Property | Type | Required | Description |
| -------- | ------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| message | `string` | yes | The question to ask |
| choices | `Array<{ value: string, name?: string, disabled?: boolean \| string, checked?: boolean } \| Separator>` | yes | List of the available choices. The `value` will be returned as the answer, and used as display if no `name` is defined. Choices who're `disabled` will be displayed, but not selectable. |
| pageSize | `number` | no | By default, lists of choice longer than 7 will be paginated. Use this option to control how many choices will appear on the screen at once. |
| loop | `boolean` | no | Defaults to `true`. When set to `false`, the cursor will be constrained to the top and bottom of the choice list without looping. |
| required | `boolean` | no | When set to `true`, ensures at least one choice must be selected. |
| validate | `string\[\] => boolean \| string \| Promise<boolean \| string>` | no | On submit, validate the choices. 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. |
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |
| Property | Type | Required | Description |
| -------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| message | `string` | yes | The question to ask |
| choices | `Array<{ value: string, name?: string, short?: string, disabled?: boolean \| string, checked?: boolean } \| Separator>` | yes | List of the available choices. The `value` will be returned as the answer, and used as display if no `name` is defined. Choices who're `disabled` will be displayed, but not selectable. `short` if defined will be used instead of `name` once submitted. |
| pageSize | `number` | no | By default, lists of choice longer than 7 will be paginated. Use this option to control how many choices will appear on the screen at once. |
| loop | `boolean` | no | Defaults to `true`. When set to `false`, the cursor will be constrained to the top and bottom of the choice list without looping. |
| required | `boolean` | no | When set to `true`, ensures at least one choice must be selected. |
| validate | `string\[\] => boolean \| string \| Promise<boolean \| string>` | no | On submit, validate the choices. 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. |
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |

The `Separator` object can be used to render non-selectable lines in the choice list. By default it'll render a line, but you can provide the text as argument (`new Separator('-- Dependencies --')`). This option is often used to add labels to groups within long list of options.

Expand Down
45 changes: 45 additions & 0 deletions packages/checkbox/checkbox.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,51 @@ describe('checkbox prompt', () => {
);
});

it('allow customizing short names after selection', async () => {
const { answer, events, getScreen } = await render(checkbox, {
message: 'Select a commit',
choices: [
{
name: '2cc9e311 (HEAD -> main) Fix(inquirer): Ensure no mutation of the question',
value: '2cc9e311',
short: '2cc9e311',
},
{
name: '3272b94a (origin/main) Fix(inquirer): Fix close method not required',
value: '3272b94a',
short: '3272b94a',
},
{
name: 'e4e10545 Chore(dev-deps): Bump dev-deps',
value: 'e4e10545',
short: 'e4e10545',
},
],
});

expect(getScreen()).toMatchInlineSnapshot(`
"? Select a commit (Press <space> to select, <a> to toggle all, <i> to invert
selection, and <enter> to proceed)
❯◯ 2cc9e311 (HEAD -> main) Fix(inquirer): Ensure no mutation of the question
◯ 3272b94a (origin/main) Fix(inquirer): Fix close method not required
◯ e4e10545 Chore(dev-deps): Bump dev-deps"
`);

events.keypress('space');
events.keypress('down');
events.keypress('space');
expect(getScreen()).toMatchInlineSnapshot(`
"? Select a commit
◉ 2cc9e311 (HEAD -> main) Fix(inquirer): Ensure no mutation of the question
❯◉ 3272b94a (origin/main) Fix(inquirer): Fix close method not required
◯ e4e10545 Chore(dev-deps): Bump dev-deps"
`);

events.keypress('enter');
await expect(answer).resolves.toEqual(['2cc9e311', '3272b94a']);
expect(getScreen()).toMatchInlineSnapshot(`"? Select a commit 2cc9e311, 3272b94a"`);
});

it('using allChoices parameter', async () => {
const { answer, events, getScreen } = await render(checkbox, {
message: 'Select your favourite number.',
Expand Down
5 changes: 4 additions & 1 deletion packages/checkbox/src/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,17 @@ const checkboxTheme: CheckboxTheme = {
style: {
disabledChoice: (text: string) => colors.dim(`- ${text}`),
renderSelectedChoices: (selectedChoices) =>
selectedChoices.map((choice) => choice.name || choice.value).join(', '),
selectedChoices
.map((choice) => choice.short ?? choice.name ?? choice.value)
.join(', '),
},
helpMode: 'auto',
};

type Choice<Value> = {
name?: string;
value: Value;
short?: string;
disabled?: boolean | string;
checked?: boolean;
type?: never;
Expand Down

0 comments on commit d274d15

Please sign in to comment.