diff --git a/.changeset/sweet-garlics-win.md b/.changeset/sweet-garlics-win.md new file mode 100644 index 00000000..d83fbf4c --- /dev/null +++ b/.changeset/sweet-garlics-win.md @@ -0,0 +1,5 @@ +--- +"@clack/prompts": patch +--- + +fix: fix autocomplete bar color when validate diff --git a/packages/prompts/src/autocomplete.ts b/packages/prompts/src/autocomplete.ts index 6472a435..ae293139 100644 --- a/packages/prompts/src/autocomplete.ts +++ b/packages/prompts/src/autocomplete.ts @@ -112,6 +112,8 @@ export const autocomplete = (opts: AutocompleteOptions) => { } default: { + const guidePrefix = `${(this.state === 'error' ? color.yellow : color.cyan)(S_BAR)} `; + const guidePrefixEnd = (this.state === 'error' ? color.yellow : color.cyan)(S_BAR_END); // Display cursor position - show plain text in navigation mode let searchText = ''; if (this.isNavigating || showPlaceholder) { @@ -132,15 +134,15 @@ export const autocomplete = (opts: AutocompleteOptions) => { // No matches message const noResults = this.filteredOptions.length === 0 && userInput - ? [`${color.cyan(S_BAR)} ${color.yellow('No matches found')}`] + ? [`${guidePrefix}${color.yellow('No matches found')}`] : []; const validationError = - this.state === 'error' ? [`${color.yellow(S_BAR)} ${color.yellow(this.error)}`] : []; + this.state === 'error' ? [`${guidePrefix}${color.yellow(this.error)}`] : []; headings.push( - `${color.cyan(S_BAR)}`, - `${color.cyan(S_BAR)} ${color.dim('Search:')}${searchText}${matches}`, + `${guidePrefix.trimEnd()}`, + `${guidePrefix}${color.dim('Search:')}${searchText}${matches}`, ...noResults, ...validationError ); @@ -153,8 +155,8 @@ export const autocomplete = (opts: AutocompleteOptions) => { ]; const footers = [ - `${color.cyan(S_BAR)} ${color.dim(instructions.join(' • '))}`, - `${color.cyan(S_BAR_END)}`, + `${guidePrefix}${color.dim(instructions.join(' • '))}`, + `${guidePrefixEnd}`, ]; // Render options with selection @@ -184,7 +186,7 @@ export const autocomplete = (opts: AutocompleteOptions) => { // Return the formatted prompt return [ ...headings, - ...displayOptions.map((option) => `${color.cyan(S_BAR)} ${option}`), + ...displayOptions.map((option) => `${guidePrefix}${option}`), ...footers, ].join('\n'); } @@ -282,6 +284,7 @@ export const autocompleteMultiselect = (opts: AutocompleteMultiSelectOpti return `${title}${color.gray(S_BAR)} ${color.strikethrough(color.dim(userInput))}`; } default: { + const barColor = this.state === 'error' ? color.yellow : color.cyan; // Instructions const instructions = [ `${color.dim('↑/↓')} to navigate`, @@ -293,22 +296,22 @@ export const autocompleteMultiselect = (opts: AutocompleteMultiSelectOpti // No results message const noResults = this.filteredOptions.length === 0 && userInput - ? [`${color.cyan(S_BAR)} ${color.yellow('No matches found')}`] + ? [`${barColor(S_BAR)} ${color.yellow('No matches found')}`] : []; const errorMessage = - this.state === 'error' ? [`${color.cyan(S_BAR)} ${color.yellow(this.error)}`] : []; + this.state === 'error' ? [`${barColor(S_BAR)} ${color.yellow(this.error)}`] : []; // Calculate header and footer line counts for rowPadding const headerLines = [ ...title.split('\n'), - `${color.cyan(S_BAR)} ${color.dim('Search:')} ${searchText}${matches}`, + `${barColor(S_BAR)} ${color.dim('Search:')} ${searchText}${matches}`, ...noResults, ...errorMessage, ]; const footerLines = [ - `${color.cyan(S_BAR)} ${color.dim(instructions.join(' • '))}`, - `${color.cyan(S_BAR_END)}`, + `${barColor(S_BAR)} ${color.dim(instructions.join(' • '))}`, + `${barColor(S_BAR_END)}`, ]; // Get limited options for display @@ -325,7 +328,7 @@ export const autocompleteMultiselect = (opts: AutocompleteMultiSelectOpti // Build the prompt display return [ ...headerLines, - ...displayOptions.map((option) => `${color.cyan(S_BAR)} ${option}`), + ...displayOptions.map((option) => `${barColor(S_BAR)} ${option}`), ...footerLines, ].join('\n'); } diff --git a/packages/prompts/test/__snapshots__/autocomplete.test.ts.snap b/packages/prompts/test/__snapshots__/autocomplete.test.ts.snap index e7c7fa35..b36a7677 100644 --- a/packages/prompts/test/__snapshots__/autocomplete.test.ts.snap +++ b/packages/prompts/test/__snapshots__/autocomplete.test.ts.snap @@ -429,15 +429,15 @@ exports[`autocompleteMultiselect > renders error when empty selection & required "", "▲ Select a fruit -│ Search: _ -│ Please select at least one item -│ ◻ Apple -│ ◻ Banana -│ ◻ Cherry -│ ◻ Grape -│ ◻ Orange -│ ↑/↓ to navigate • Tab: select • Enter: confirm • Type: to search -└", +│ Search: _ +│ Please select at least one item +│ ◻ Apple +│ ◻ Banana +│ ◻ Cherry +│ ◻ Grape +│ ◻ Orange +│ ↑/↓ to navigate • Tab: select • Enter: confirm • Type: to search +└", "", "", "", diff --git a/packages/prompts/test/__snapshots__/path.test.ts.snap b/packages/prompts/test/__snapshots__/path.test.ts.snap index f96e4641..ff0ceef8 100644 --- a/packages/prompts/test/__snapshots__/path.test.ts.snap +++ b/packages/prompts/test/__snapshots__/path.test.ts.snap @@ -44,12 +44,12 @@ exports[`text (isCI = false) > cannot submit unknown value 1`] = ` "", "", "▲ foo -│ -│ Search: /tmp/_█ -│ No matches found +│ +│ Search: /tmp/_█ +│ No matches found │ Please select a path -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "", @@ -211,12 +211,12 @@ exports[`text (isCI = false) > validation errors render and clear (using Error) "", "", "▲ foo -│ -│ Search: /tmp/r█ +│ +│ Search: /tmp/r█ │ should be /tmp/bar -│ ● /tmp/root.zip -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ● /tmp/root.zip +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "", @@ -267,12 +267,12 @@ exports[`text (isCI = false) > validation errors render and clear 1`] = ` "", "", "▲ foo -│ -│ Search: /tmp/r█ +│ +│ Search: /tmp/r█ │ should be /tmp/bar -│ ● /tmp/root.zip -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ● /tmp/root.zip +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "", @@ -345,12 +345,12 @@ exports[`text (isCI = true) > cannot submit unknown value 1`] = ` "", "", "▲ foo -│ -│ Search: /tmp/_█ -│ No matches found +│ +│ Search: /tmp/_█ +│ No matches found │ Please select a path -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "", @@ -512,12 +512,12 @@ exports[`text (isCI = true) > validation errors render and clear (using Error) 1 "", "", "▲ foo -│ -│ Search: /tmp/r█ +│ +│ Search: /tmp/r█ │ should be /tmp/bar -│ ● /tmp/root.zip -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ● /tmp/root.zip +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "", @@ -568,12 +568,12 @@ exports[`text (isCI = true) > validation errors render and clear 1`] = ` "", "", "▲ foo -│ -│ Search: /tmp/r█ +│ +│ Search: /tmp/r█ │ should be /tmp/bar -│ ● /tmp/root.zip -│ ↑/↓ to select • Enter: confirm • Type: to search -└", +│ ● /tmp/root.zip +│ ↑/↓ to select • Enter: confirm • Type: to search +└", "", "", "",