Skip to content

Commit 7517076

Browse files
committed
refactor: add custom themed CLI example, remove unnecessary tests & update snapshots
1 parent a43ce24 commit 7517076

File tree

4 files changed

+88
-312
lines changed

4 files changed

+88
-312
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import * as p from '@clack/prompts';
2+
import color from 'picocolors';
3+
4+
async function main() {
5+
console.clear();
6+
7+
p.intro(`${color.bgMagenta(color.black(' Custom Themed CLI '))}`);
8+
9+
// Custom theme with a purple/violet color scheme
10+
// Defaults: active=cyan, submit=green, cancel=red, error=yellow
11+
// Guide defaults: guide=cyan, submit=gray, cancel=gray, error=yellow
12+
const purpleTheme = {
13+
formatSymbolActive: (str: string) => color.magenta(str), // default: cyan
14+
formatSymbolSubmit: (str: string) => color.green(str), // default: green (matching guide)
15+
formatSymbolCancel: (str: string) => color.red(str), // default: red
16+
formatSymbolError: (str: string) => color.yellow(str), // default: yellow
17+
formatGuide: (str: string) => color.magenta(str), // default: cyan
18+
formatGuideSubmit: (str: string) => color.green(str), // default: gray
19+
formatGuideCancel: (str: string) => color.red(str), // default: gray - red for cancel
20+
formatGuideError: (str: string) => color.yellow(str), // default: yellow
21+
formatErrorMessage: (str: string) => color.red(str), // default: yellow
22+
};
23+
24+
const name = await p.text({
25+
message: 'What is your project name?',
26+
placeholder: 'my-awesome-project',
27+
theme: purpleTheme,
28+
validate: (value) => {
29+
if (!value) return 'Project name is required';
30+
if (value.includes(' ')) return 'Project name cannot contain spaces';
31+
},
32+
});
33+
34+
if (p.isCancel(name)) {
35+
p.cancel('Setup cancelled.');
36+
process.exit(0);
37+
}
38+
39+
const description = await p.text({
40+
message: 'Describe your project in a few words:',
41+
placeholder: 'A blazing fast CLI tool',
42+
theme: purpleTheme,
43+
});
44+
45+
if (p.isCancel(description)) {
46+
p.cancel('Setup cancelled.');
47+
process.exit(0);
48+
}
49+
50+
const author = await p.text({
51+
message: 'Who is the author?',
52+
placeholder: 'Your Name <[email protected]>',
53+
theme: purpleTheme,
54+
validate: (value) => {
55+
if (!value) return 'Author is required';
56+
},
57+
});
58+
59+
if (p.isCancel(author)) {
60+
p.cancel('Setup cancelled.');
61+
process.exit(0);
62+
}
63+
64+
p.note(
65+
`Name: ${color.cyan(name as string)}\nDescription: ${color.cyan((description as string) || 'N/A')}\nAuthor: ${color.cyan(author as string)}`,
66+
'Project Summary'
67+
);
68+
69+
p.outro(`${color.green('✓')} Project ${color.magenta(name as string)} configured!`);
70+
}
71+
72+
main().catch(console.error);

packages/prompts/src/text.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,22 @@ export const text = (opts: TextOptions) => {
7979
}
8080
})();
8181

82-
const titlePrefix = `${hasGuide ? `${color.gray(S_BAR)}\n` : ''}${symbolText} `;
82+
// Resolve connector bar color based on state
83+
const connectorBar = (() => {
84+
switch (this.state) {
85+
case 'initial':
86+
case 'active':
87+
return theme.formatGuide(S_BAR);
88+
case 'cancel':
89+
return theme.formatGuideCancel(S_BAR);
90+
case 'error':
91+
return theme.formatGuideError(S_BAR);
92+
case 'submit':
93+
return theme.formatGuideSubmit(S_BAR);
94+
}
95+
})();
96+
97+
const titlePrefix = `${hasGuide ? `${connectorBar}\n` : ''}${symbolText} `;
8398
const title = `${titlePrefix}${opts.message}\n`;
8499
const placeholder = opts.placeholder
85100
? color.inverse(opts.placeholder[0]) + color.dim(opts.placeholder.slice(1))

packages/prompts/test/__snapshots__/text.test.ts.snap

Lines changed: 0 additions & 216 deletions
Original file line numberDiff line numberDiff line change
@@ -33,95 +33,6 @@ exports[`text (isCI = false) > can cancel 1`] = `
3333
]
3434
`;
3535
36-
exports[`text (isCI = false) > custom theme changes active symbol color 1`] = `
37-
[
38-
"<cursor.hide>",
39-
"│
40-
[MAGENTA]◆[/MAGENTA] foo
41-
[BLUE]│[/BLUE] _
42-
[BLUE]└[/BLUE]
43-
",
44-
"<cursor.backward count=999><cursor.up count=4>",
45-
"<cursor.down count=1>",
46-
"<erase.down>",
47-
"◇ foo
48-
│",
49-
"
50-
",
51-
"<cursor.show>",
52-
]
53-
`;
54-
55-
exports[`text (isCI = false) > custom theme changes cancel symbol color 1`] = `
56-
[
57-
"<cursor.hide>",
58-
"│
59-
◆ foo
60-
│ _
61-
└
62-
",
63-
"<cursor.backward count=999><cursor.up count=4>",
64-
"<cursor.down count=1>",
65-
"<erase.down>",
66-
"[ORANGE]■[/ORANGE] foo
67-
[BROWN]│[/BROWN]",
68-
"
69-
",
70-
"<cursor.show>",
71-
]
72-
`;
73-
74-
exports[`text (isCI = false) > custom theme changes error colors 1`] = `
75-
[
76-
"<cursor.hide>",
77-
"│
78-
◆ foo
79-
│ _
80-
└
81-
",
82-
"<cursor.backward count=999><cursor.up count=4>",
83-
"<cursor.down count=2>",
84-
"<erase.line><cursor.left count=1>",
85-
"│ x█",
86-
"<cursor.down count=2>",
87-
"<cursor.backward count=999><cursor.up count=4>",
88-
"<cursor.down count=1>",
89-
"<erase.down>",
90-
"[RED_BG]▲[/RED_BG] foo
91-
[RED]│[/RED] x█
92-
[RED]└[/RED] [BOLD_RED]custom error[/BOLD_RED]
93-
",
94-
"<cursor.backward count=999><cursor.up count=4>",
95-
"<cursor.down count=1>",
96-
"<erase.down>",
97-
"■ foo
98-
│ x
99-
│",
100-
"
101-
",
102-
"<cursor.show>",
103-
]
104-
`;
105-
106-
exports[`text (isCI = false) > custom theme changes submit symbol color 1`] = `
107-
[
108-
"<cursor.hide>",
109-
"│
110-
◆ foo
111-
│ _
112-
└
113-
",
114-
"<cursor.backward count=999><cursor.up count=4>",
115-
"<cursor.down count=1>",
116-
"<erase.down>",
117-
"[PURPLE]◇[/PURPLE] foo
118-
[PINK]│[/PINK]",
119-
"
120-
",
121-
"<cursor.show>",
122-
]
123-
`;
124-
12536
exports[`text (isCI = false) > defaultValue sets the value but does not render 1`] = `
12637
[
12738
"<cursor.hide>",
@@ -177,25 +88,6 @@ exports[`text (isCI = false) > global withGuide: false removes guide 1`] = `
17788
]
17889
`;
17990
180-
exports[`text (isCI = false) > partial theme only overrides specified options 1`] = `
181-
[
182-
"<cursor.hide>",
183-
"│
184-
[CUSTOM]◆[/CUSTOM] foo
185-
│ _
186-
└
187-
",
188-
"<cursor.backward count=999><cursor.up count=4>",
189-
"<cursor.down count=1>",
190-
"<erase.down>",
191-
"◇ foo
192-
│",
193-
"
194-
",
195-
"<cursor.show>",
196-
]
197-
`;
198-
19991
exports[`text (isCI = false) > placeholder is not used as value when pressing enter 1`] = `
20092
[
20193
"<cursor.hide>",
@@ -438,95 +330,6 @@ exports[`text (isCI = true) > can cancel 1`] = `
438330
]
439331
`;
440332
441-
exports[`text (isCI = true) > custom theme changes active symbol color 1`] = `
442-
[
443-
"<cursor.hide>",
444-
"│
445-
[MAGENTA]◆[/MAGENTA] foo
446-
[BLUE]│[/BLUE] _
447-
[BLUE]└[/BLUE]
448-
",
449-
"<cursor.backward count=999><cursor.up count=4>",
450-
"<cursor.down count=1>",
451-
"<erase.down>",
452-
"◇ foo
453-
│",
454-
"
455-
",
456-
"<cursor.show>",
457-
]
458-
`;
459-
460-
exports[`text (isCI = true) > custom theme changes cancel symbol color 1`] = `
461-
[
462-
"<cursor.hide>",
463-
"│
464-
◆ foo
465-
│ _
466-
└
467-
",
468-
"<cursor.backward count=999><cursor.up count=4>",
469-
"<cursor.down count=1>",
470-
"<erase.down>",
471-
"[ORANGE]■[/ORANGE] foo
472-
[BROWN]│[/BROWN]",
473-
"
474-
",
475-
"<cursor.show>",
476-
]
477-
`;
478-
479-
exports[`text (isCI = true) > custom theme changes error colors 1`] = `
480-
[
481-
"<cursor.hide>",
482-
"│
483-
◆ foo
484-
│ _
485-
└
486-
",
487-
"<cursor.backward count=999><cursor.up count=4>",
488-
"<cursor.down count=2>",
489-
"<erase.line><cursor.left count=1>",
490-
"│ x█",
491-
"<cursor.down count=2>",
492-
"<cursor.backward count=999><cursor.up count=4>",
493-
"<cursor.down count=1>",
494-
"<erase.down>",
495-
"[RED_BG]▲[/RED_BG] foo
496-
[RED]│[/RED] x█
497-
[RED]└[/RED] [BOLD_RED]custom error[/BOLD_RED]
498-
",
499-
"<cursor.backward count=999><cursor.up count=4>",
500-
"<cursor.down count=1>",
501-
"<erase.down>",
502-
"■ foo
503-
│ x
504-
│",
505-
"
506-
",
507-
"<cursor.show>",
508-
]
509-
`;
510-
511-
exports[`text (isCI = true) > custom theme changes submit symbol color 1`] = `
512-
[
513-
"<cursor.hide>",
514-
"│
515-
◆ foo
516-
│ _
517-
└
518-
",
519-
"<cursor.backward count=999><cursor.up count=4>",
520-
"<cursor.down count=1>",
521-
"<erase.down>",
522-
"[PURPLE]◇[/PURPLE] foo
523-
[PINK]│[/PINK]",
524-
"
525-
",
526-
"<cursor.show>",
527-
]
528-
`;
529-
530333
exports[`text (isCI = true) > defaultValue sets the value but does not render 1`] = `
531334
[
532335
"<cursor.hide>",
@@ -582,25 +385,6 @@ exports[`text (isCI = true) > global withGuide: false removes guide 1`] = `
582385
]
583386
`;
584387
585-
exports[`text (isCI = true) > partial theme only overrides specified options 1`] = `
586-
[
587-
"<cursor.hide>",
588-
"│
589-
[CUSTOM]◆[/CUSTOM] foo
590-
│ _
591-
└
592-
",
593-
"<cursor.backward count=999><cursor.up count=4>",
594-
"<cursor.down count=1>",
595-
"<erase.down>",
596-
"◇ foo
597-
│",
598-
"
599-
",
600-
"<cursor.show>",
601-
]
602-
`;
603-
604388
exports[`text (isCI = true) > placeholder is not used as value when pressing enter 1`] = `
605389
[
606390
"<cursor.hide>",

0 commit comments

Comments
 (0)