diff --git a/packages/select/README.md b/packages/select/README.md index a8a41c775..8fa2b9d7b 100644 --- a/packages/select/README.md +++ b/packages/select/README.md @@ -64,14 +64,14 @@ const answer = await select({ ## Options -| Property | Type | Required | Description | -| -------- | ---------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| message | `string` | yes | The question to ask | -| choices | `Array<{ value: string, name?: string, description?: string, disabled?: boolean \| string } \| 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. The `description` will be displayed under the prompt when the cursor land over the choice. | -| default | `string` | no | Defines in front of which item the cursor will initially appear. When omitted, the cursor will appear on the first selectable item. | -| 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. | -| 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, description?: string, disabled?: boolean \| string } \| 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. The `description` will be displayed under the prompt when the cursor land over the choice. `short` if defined will be used instead of `name` once submitted. | +| default | `string` | no | Defines in front of which item the cursor will initially appear. When omitted, the cursor will appear on the first selectable item. | +| 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. | +| 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. diff --git a/packages/select/select.test.mts b/packages/select/select.test.mts index 87da489c5..8e2db8e7f 100644 --- a/packages/select/select.test.mts +++ b/packages/select/select.test.mts @@ -366,6 +366,40 @@ describe('select prompt', () => { await expect(answer).rejects.toBeInstanceOf(Error); }); + it('allow customizing short names after selection', async () => { + const { answer, events, getScreen } = await render(select, { + 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 (Use arrow keys) + ❯ 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'); + expect(getScreen()).toMatchInlineSnapshot(`"? Select a commit 2cc9e311"`); + }); + it('throws if all choices are disabled', async () => { const { answer } = await render(select, { message: 'Select a topping', diff --git a/packages/select/src/index.mts b/packages/select/src/index.mts index 73c32bafb..eb59aa785 100644 --- a/packages/select/src/index.mts +++ b/packages/select/src/index.mts @@ -37,6 +37,7 @@ type Choice = { value: Value; name?: string; description?: string; + short?: string; disabled?: boolean | string; type?: never; }; @@ -184,7 +185,8 @@ export default createPrompt( if (status === 'done') { const answer = - selectedChoice.name || + selectedChoice.short ?? + selectedChoice.name ?? // TODO: Could we enforce that at the type level? Name should be defined for non-string values. String(selectedChoice.value); return `${prefix} ${message} ${theme.style.answer(answer)}`;