Skip to content

Commit

Permalink
Merge branch 'main' into test
Browse files Browse the repository at this point in the history
  • Loading branch information
SBoudrias committed Sep 7, 2024
2 parents c1a4186 + 4937ea3 commit da3285a
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 21 deletions.
4 changes: 2 additions & 2 deletions packages/demo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@inquirer/demo",
"version": "0.9.0",
"version": "0.9.1",
"engines": {
"node": ">=18"
},
Expand Down Expand Up @@ -62,7 +62,7 @@
"homepage": "https://github.com/SBoudrias/Inquirer.js",
"dependencies": {
"@inquirer/core": "^9.1.0",
"@inquirer/prompts": "^5.4.0",
"@inquirer/prompts": "^5.5.0",
"yoctocolors-cjs": "^2.1.2"
},
"publishConfig": {
Expand Down
2 changes: 2 additions & 0 deletions packages/expand/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ const answer = await expand({
| expanded | `boolean` | no | Expand the choices by default |
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |

`Separator` objects can be used in the `choices` array 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.

### `Choice` object

The `Choice` object is typed as
Expand Down
54 changes: 53 additions & 1 deletion packages/expand/expand.test.mts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, expect } from 'vitest';
import { render } from '@inquirer/testing';
import expand from './src/index.mjs';
import expand, { Separator } from './src/index.mjs';

const overwriteChoices = [
{
Expand Down Expand Up @@ -144,6 +144,58 @@ describe('expand prompt', () => {
await expect(answer).resolves.toEqual('abort');
});

it('supports separators', async () => {
const { answer, events, getScreen } = await render(expand, {
message: 'Overwrite this file?',
choices: [
{
value: 'Yarn',
key: 'y',
},
new Separator(),
{
value: 'npm',
key: 'n',
},
],
});

expect(getScreen()).toMatchInlineSnapshot(`"? Overwrite this file? (ynH)"`);

events.type('h');
events.keypress('enter');
expect(getScreen()).toMatchInlineSnapshot(`
"? Overwrite this file? h
y) Yarn
──────────────
n) npm"
`);

events.type('y');
expect(getScreen()).toMatchInlineSnapshot(`
"? Overwrite this file? y
y) Yarn
──────────────
n) npm
>> Yarn"
`);

events.keypress('backspace');
events.type('n');
expect(getScreen()).toMatchInlineSnapshot(`
"? Overwrite this file? n
y) Yarn
──────────────
n) npm
>> npm"
`);

events.keypress('enter');
expect(getScreen()).toMatchInlineSnapshot(`"? Overwrite this file? npm"`);

await expect(answer).resolves.toEqual('npm');
});

it('selects without value', async () => {
const { answer, events, getScreen } = await render(expand, {
message: 'Overwrite this file?',
Expand Down
2 changes: 1 addition & 1 deletion packages/expand/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@inquirer/expand",
"version": "2.2.0",
"version": "2.3.0",
"description": "Inquirer checkbox prompt",
"main": "./dist/cjs/index.js",
"typings": "./dist/cjs/types/index.d.ts",
Expand Down
38 changes: 30 additions & 8 deletions packages/expand/src/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
usePrefix,
isEnterKey,
makeTheme,
Separator,
type Theme,
} from '@inquirer/core';
import type { PartialDeep } from '@inquirer/type';
Expand Down Expand Up @@ -64,18 +65,24 @@ type ExpandConfig<
ChoicesObject = readonly { key: Key; name: string }[] | readonly Choice<Value>[],
> = {
message: string;
choices: ChoicesObject extends readonly { key: Key; name: string }[]
choices: ChoicesObject extends readonly (Separator | { key: Key; name: string })[]
? ChoicesObject
: readonly Choice<Value>[];
: readonly (Separator | Choice<Value>)[];
default?: Key | 'h';
expanded?: boolean;
theme?: PartialDeep<Theme>;
};

function normalizeChoices<Value>(
choices: readonly { key: Key; name: string }[] | readonly Choice<Value>[],
): NormalizedChoice<Value>[] {
choices:
| readonly (Separator | { key: Key; name: string })[]
| readonly (Separator | Choice<Value>)[],
): (Separator | NormalizedChoice<Value>)[] {
return choices.map((choice) => {
if (Separator.isSeparator(choice)) {
return choice;
}

const name: string = 'name' in choice ? choice.name : String(choice.value);
const value = 'value' in choice ? choice.value : name;
return {
Expand Down Expand Up @@ -109,7 +116,10 @@ export default createPrompt(
if (answer === 'h' && !expanded) {
setExpanded(true);
} else {
const selectedChoice = choices.find(({ key }) => key === answer);
const selectedChoice = choices.find(
(choice): choice is NormalizedChoice<Value> =>
!Separator.isSeparator(choice) && choice.key === answer,
);
if (selectedChoice) {
setStatus('done');
// Set the value as we might've selected the default one.
Expand All @@ -132,8 +142,9 @@ export default createPrompt(
if (status === 'done') {
// If the prompt is done, it's safe to assume there is a selected value.
const selectedChoice = choices.find(
({ key }) => key === value,
) as NormalizedChoice<Value>;
(choice): choice is NormalizedChoice<Value> =>
!Separator.isSeparator(choice) && choice.key === value.toLowerCase(),
)!;
return `${prefix} ${message} ${theme.style.answer(selectedChoice.name)}`;
}

Expand All @@ -143,6 +154,8 @@ export default createPrompt(
let longChoices = '';
let shortChoices = allChoices
.map((choice) => {
if (Separator.isSeparator(choice)) return '';

if (choice.key === defaultKey) {
return choice.key.toUpperCase();
}
Expand All @@ -157,6 +170,10 @@ export default createPrompt(
shortChoices = '';
longChoices = allChoices
.map((choice) => {
if (Separator.isSeparator(choice)) {
return ` ${choice.separator}`;
}

const line = ` ${choice.key}) ${choice.name}`;
if (choice.key === value.toLowerCase()) {
return theme.style.highlight(line);
Expand All @@ -168,7 +185,10 @@ export default createPrompt(
}

let helpTip = '';
const currentOption = allChoices.find(({ key }) => key === value.toLowerCase());
const currentOption = choices.find(
(choice): choice is NormalizedChoice<Value> =>
!Separator.isSeparator(choice) && choice.key === value.toLowerCase(),
);
if (currentOption) {
helpTip = `${colors.cyan('>>')} ${currentOption.name}`;
}
Expand All @@ -184,3 +204,5 @@ export default createPrompt(
];
},
);

export { Separator } from '@inquirer/core';
4 changes: 2 additions & 2 deletions packages/inquirer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "inquirer",
"version": "10.2.0",
"version": "10.2.1",
"description": "A collection of common interactive command line user interfaces.",
"author": "Simon Boudrias <admin@simonboudrias.com>",
"main": "./dist/cjs/index.js",
Expand Down Expand Up @@ -56,7 +56,7 @@
"license": "MIT",
"dependencies": {
"@inquirer/core": "^9.1.0",
"@inquirer/prompts": "^5.4.0",
"@inquirer/prompts": "^5.5.0",
"@inquirer/type": "^1.5.3",
"@types/mute-stream": "^0.0.4",
"ansi-escapes": "^4.3.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/prompts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@inquirer/prompts",
"version": "5.4.0",
"version": "5.5.0",
"description": "Inquirer prompts, combined in a single package",
"main": "./dist/cjs/index.js",
"typings": "./dist/cjs/types/index.d.ts",
Expand Down Expand Up @@ -79,7 +79,7 @@
"@inquirer/checkbox": "^2.5.0",
"@inquirer/confirm": "^3.2.0",
"@inquirer/editor": "^2.2.0",
"@inquirer/expand": "^2.2.0",
"@inquirer/expand": "^2.3.0",
"@inquirer/input": "^2.3.0",
"@inquirer/number": "^1.1.0",
"@inquirer/password": "^2.2.0",
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ __metadata:
resolution: "@inquirer/demo@workspace:packages/demo"
dependencies:
"@inquirer/core": "npm:^9.1.0"
"@inquirer/prompts": "npm:^5.4.0"
"@inquirer/prompts": "npm:^5.5.0"
yoctocolors-cjs: "npm:^2.1.2"
bin:
inquirer-demo: index.mjs
Expand Down Expand Up @@ -500,7 +500,7 @@ __metadata:
languageName: unknown
linkType: soft

"@inquirer/expand@npm:^2.2.0, @inquirer/expand@workspace:packages/expand":
"@inquirer/expand@npm:^2.3.0, @inquirer/expand@workspace:packages/expand":
version: 0.0.0-use.local
resolution: "@inquirer/expand@workspace:packages/expand"
dependencies:
Expand Down Expand Up @@ -548,14 +548,14 @@ __metadata:
languageName: unknown
linkType: soft

"@inquirer/prompts@npm:^5.4.0, @inquirer/prompts@workspace:*, @inquirer/prompts@workspace:packages/prompts":
"@inquirer/prompts@npm:^5.5.0, @inquirer/prompts@workspace:*, @inquirer/prompts@workspace:packages/prompts":
version: 0.0.0-use.local
resolution: "@inquirer/prompts@workspace:packages/prompts"
dependencies:
"@inquirer/checkbox": "npm:^2.5.0"
"@inquirer/confirm": "npm:^3.2.0"
"@inquirer/editor": "npm:^2.2.0"
"@inquirer/expand": "npm:^2.2.0"
"@inquirer/expand": "npm:^2.3.0"
"@inquirer/input": "npm:^2.3.0"
"@inquirer/number": "npm:^1.1.0"
"@inquirer/password": "npm:^2.2.0"
Expand Down Expand Up @@ -4550,7 +4550,7 @@ __metadata:
resolution: "inquirer@workspace:packages/inquirer"
dependencies:
"@inquirer/core": "npm:^9.1.0"
"@inquirer/prompts": "npm:^5.4.0"
"@inquirer/prompts": "npm:^5.5.0"
"@inquirer/type": "npm:^1.5.3"
"@types/mute-stream": "npm:^0.0.4"
ansi-escapes: "npm:^4.3.2"
Expand Down

0 comments on commit da3285a

Please sign in to comment.