Skip to content

Commit d14cd28

Browse files
feat(question): add hint option (#181)
1 parent 865b8d0 commit d14cd28

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ Simple prompt, similar to `rl.question()` with an improved UI.
5555
5656
Use `options.defaultValue` to set a default value.
5757
58+
Use `options.hint` to display a hint alongside the question.
59+
5860
Use `options.secure` if you need to hide both input and answer. You can provide either a **boolean** or an **object** which allows to configure a `placeholder` such as `*`.
5961
6062
Use `options.signal` to set an `AbortSignal` (throws a [AbortError](#aborterror)).
@@ -311,6 +313,7 @@ export type TransformationResponse<T> = InvalidResponse | ValidTransformationRes
311313

312314
export interface QuestionOptions<T = string> extends AbstractPromptOptions {
313315
defaultValue?: string;
316+
hint?: string;
314317
validators?: PromptValidator<string>[];
315318
transformer?: PromptTransformer<T>;
316319
secure?: boolean | { placeholder: string };

src/prompts/question.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818

1919
export interface QuestionOptions<T = string> extends AbstractPromptOptions {
2020
defaultValue?: string;
21+
hint?: string;
2122
validators?: PromptValidator<string>[];
2223
transformer?: PromptTransformer<T>;
2324
secure?: boolean | {
@@ -27,6 +28,7 @@ export interface QuestionOptions<T = string> extends AbstractPromptOptions {
2728

2829
export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
2930
defaultValue?: string;
31+
hint?: string;
3032
tip: string;
3133
questionSuffixError: string;
3234
answer?: string;
@@ -40,6 +42,7 @@ export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
4042
constructor(options: QuestionOptions<T>) {
4143
const {
4244
defaultValue,
45+
hint,
4346
validators = [],
4447
transformer,
4548
secure = false,
@@ -57,6 +60,7 @@ export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
5760
}
5861

5962
this.defaultValue = defaultValue;
63+
this.hint = hint;
6064
this.tip = this.defaultValue ? ` (${this.defaultValue})` : "";
6165
this.#validators = validators;
6266
this.#transformer = transformer;
@@ -71,6 +75,10 @@ export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
7175
this.questionSuffixError = "";
7276
}
7377

78+
get formattedHint(): string {
79+
return this.hint ? styleText("gray", this.hint) : "";
80+
}
81+
7482
#question(): Promise<string> {
7583
const { resolve, promise } = Promise.withResolvers<string>();
7684

@@ -92,7 +100,9 @@ export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
92100
}
93101

94102
#getQuestionQuery() {
95-
return `${styleText("bold", `${SYMBOLS.QuestionMark} ${this.message}${this.tip}`)} ${this.questionSuffixError}`;
103+
const hintPart = this.formattedHint ? ` ${this.formattedHint}` : "";
104+
105+
return `${styleText("bold", `${SYMBOLS.QuestionMark} ${this.message}${this.tip}`)}${hintPart} ${this.questionSuffixError}`;
96106
}
97107

98108
#setQuestionSuffixError(error: string) {
@@ -117,9 +127,10 @@ export class QuestionPrompt<T = string> extends AbstractPrompt<string> {
117127

118128
#getValidatingQuery(dotCount: number) {
119129
const question = styleText("bold", `${SYMBOLS.QuestionMark} ${this.message}${this.tip}`);
120-
const hint = styleText("yellow", `[validating${".".repeat(dotCount)}]`);
130+
const hintPart = this.formattedHint ? ` ${this.formattedHint}` : "";
131+
const validating = styleText("yellow", `[validating${".".repeat(dotCount)}]`);
121132

122-
return `${question} ${hint}${EOL}`;
133+
return `${question}${hintPart} ${validating}${EOL}`;
123134
}
124135

125136
async #runTransformer(): Promise<TransformationResponse<T>> {

test/question-prompt.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,21 @@ describe("QuestionPrompt", () => {
299299
"✔ Enter a number › 123"
300300
]);
301301
});
302+
303+
it("should display hint in the question query", async() => {
304+
const logs: string[] = [];
305+
const questionPrompt = await TestingPrompt.QuestionPrompt({
306+
message: "What port?",
307+
hint: "between 8000 and 8099",
308+
inputs: ["8080"],
309+
onStdoutWrite: (log) => logs.push(log)
310+
});
311+
const input = await questionPrompt.listen();
312+
313+
assert.equal(input, "8080");
314+
assert.deepStrictEqual(logs, [
315+
"? What port? between 8000 and 8099",
316+
"✔ What port? › 8080"
317+
]);
318+
});
302319
});

0 commit comments

Comments
 (0)