-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
index.ts
86 lines (72 loc) · 2.45 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import {
createPrompt,
useState,
useKeypress,
useRef,
usePrefix,
isEnterKey,
isUpKey,
isDownKey,
isNumberKey,
Paginator,
AsyncPromptConfig,
} from '@inquirer/core';
import chalk from 'chalk';
import figures from 'figures';
import ansiEscapes from 'ansi-escapes';
type SelectConfig = AsyncPromptConfig & {
choices: { value: string; name?: string; description?: string; disabled?: boolean }[];
pageSize?: number;
};
export default createPrompt<string, SelectConfig>((config, done) => {
const [status, setStatus] = useState('pending');
const [cursorPosition, setCursorPos] = useState(0);
const { choices, pageSize = 7 } = config;
const paginator = useRef(new Paginator()).current;
const prefix = usePrefix();
useKeypress((key) => {
if (isEnterKey(key)) {
setStatus('done');
done(choices[cursorPosition]!.value);
} else if (isUpKey(key) || isDownKey(key)) {
let newCursorPosition = cursorPosition;
const offset = isUpKey(key) ? -1 : 1;
let selectedOption;
while (!selectedOption || selectedOption.disabled) {
newCursorPosition =
(newCursorPosition + offset + choices.length) % choices.length;
selectedOption = choices[newCursorPosition];
}
setCursorPos(newCursorPosition);
} else if (isNumberKey(key)) {
// Adjust index to start at 1
const newCursorPosition = Number(key.name) - 1;
// Abort if the choice doesn't exists or if disabled
if (!choices[newCursorPosition] || choices[newCursorPosition]!.disabled) {
return;
}
setCursorPos(newCursorPosition);
}
});
const message = chalk.bold(config.message);
if (status === 'done') {
const choice = choices[cursorPosition]!;
return `${prefix} ${message} ${chalk.cyan(choice.name || choice.value)}`;
}
const allChoices = choices
.map(({ name, value, disabled }, index) => {
const line = name || value;
if (disabled) {
return chalk.dim(`- ${line} (disabled)`);
}
if (index === cursorPosition) {
return chalk.cyan(`${figures.pointer} ${line}`);
}
return ` ${line}`;
})
.join('\n');
const windowedChoices = paginator.paginate(allChoices, cursorPosition, pageSize);
const choice = choices[cursorPosition];
const choiceDescription = choice && choice.description ? `\n${choice.description}` : ``;
return `${prefix} ${message}\n${windowedChoices}${choiceDescription}${ansiEscapes.cursorHide}`;
});