Skip to content

Commit

Permalink
Add option to configure the style of the choices list and the default…
Browse files Browse the repository at this point in the history
… value in TextPrompt (#681)

* Allow setting the style of the default value in TextPrompt

Add property "DefaultValueStyle" to TextPrompt which allows setting the style in which the default value is rendered.
When no style is set, the value is displayed as green text, keeping the existing behavior.

* Allow setting the style in which a TextPrompt's choices are displayed

Add property "ChoicesStyle" to TextPrompt which allows setting the style in the prompt's choices are rendered.
When no style is set, choices are displayed as blue text, keeping the existing behavior.
  • Loading branch information
ap0llo committed Mar 27, 2022
1 parent 7998ece commit 38d9386
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 2 deletions.
18 changes: 16 additions & 2 deletions src/Spectre.Console/Prompts/TextPrompt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,16 @@ public sealed class TextPrompt<T> : IPrompt<T>
/// </summary>
public Func<T, ValidationResult>? Validator { get; set; }

/// <summary>
/// Gets or sets the style in which the default value is displayed.
/// </summary>
public Style? DefaultValueStyle { get; set; }

/// <summary>
/// Gets or sets the style in which the list of choices is displayed.
/// </summary>
public Style? ChoicesStyle { get; set; }

/// <summary>
/// Gets or sets the default value.
/// </summary>
Expand Down Expand Up @@ -183,16 +193,20 @@ private void WritePrompt(IAnsiConsole console)
appendSuffix = true;
var converter = Converter ?? TypeConverterHelper.ConvertToString;
var choices = string.Join("/", Choices.Select(choice => converter(choice)));
builder.AppendFormat(CultureInfo.InvariantCulture, " [blue][[{0}]][/]", choices);
var choicesStyle = ChoicesStyle?.ToMarkup() ?? "blue";
builder.AppendFormat(CultureInfo.InvariantCulture, " [{0}][[{1}]][/]", choicesStyle, choices);
}

if (ShowDefaultValue && DefaultValue != null)
{
appendSuffix = true;
var converter = Converter ?? TypeConverterHelper.ConvertToString;
var defaultValueStyle = DefaultValueStyle?.ToMarkup() ?? "green";

builder.AppendFormat(
CultureInfo.InvariantCulture,
" [green]({0})[/]",
" [{0}]({1})[/]",
defaultValueStyle,
IsSecret ? "******" : converter(DefaultValue.Value));
}

Expand Down
46 changes: 46 additions & 0 deletions src/Spectre.Console/Prompts/TextPromptExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,50 @@ public static TextPrompt<T> WithConverter<T>(this TextPrompt<T> obj, Func<T, str
obj.Converter = displaySelector;
return obj;
}

/// <summary>
/// Sets the style in which the default value is displayed.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="style">The default value style.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static TextPrompt<T> DefaultValueStyle<T>(this TextPrompt<T> obj, Style style)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

if (style is null)
{
throw new ArgumentNullException(nameof(style));
}

obj.DefaultValueStyle = style;
return obj;
}

/// <summary>
/// Sets the style in which the list of choices is displayed.
/// </summary>
/// <typeparam name="T">The prompt result type.</typeparam>
/// <param name="obj">The prompt.</param>
/// <param name="style">The style to use for displaying the choices.</param>
/// <returns>The same instance so that multiple calls can be chained.</returns>
public static TextPrompt<T> ChoicesStyle<T>(this TextPrompt<T> obj, Style style)
{
if (obj is null)
{
throw new ArgumentNullException(nameof(obj));
}

if (style is null)
{
throw new ArgumentNullException(nameof(style));
}

obj.ChoicesStyle = style;
return obj;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enter Value: [Choice 1/Choice 2]: Choice 2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enter Value: [Choice 1/Choice 2]: Choice 2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enter Value: (default): Input
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enter Value: (default): Input
92 changes: 92 additions & 0 deletions test/Spectre.Console.Tests/Unit/Prompts/TextPromptTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,96 @@ public Task Should_Not_Append_Questionmark_Or_Colon_If_No_Choices_Are_Set()
// Then
return Verifier.Verify(console.Output);
}

[Fact]
[Expectation("DefaultValueStyleNotSet")]
public Task Uses_default_style_for_default_value_if_no_style_is_set()
{
// Given
var console = new TestConsole
{
EmitAnsiSequences = true,
};
console.Input.PushTextWithEnter("Input");

var prompt = new TextPrompt<string>("Enter Value:")
.ShowDefaultValue()
.DefaultValue("default");

// When
console.Prompt(prompt);

// Then
return Verifier.Verify(console.Output);
}

[Fact]
[Expectation("DefaultValueStyleSet")]
public Task Uses_specified_default_value_style()
{
// Given
var console = new TestConsole
{
EmitAnsiSequences = true,
};
console.Input.PushTextWithEnter("Input");

var prompt = new TextPrompt<string>("Enter Value:")
.ShowDefaultValue()
.DefaultValue("default")
.DefaultValueStyle(new Style(foreground: Color.Red));

// When
console.Prompt(prompt);

// Then
return Verifier.Verify(console.Output);
}

[Fact]
[Expectation("ChoicesStyleNotSet")]
public Task Uses_default_style_for_choices_if_no_style_is_set()
{
// Given
var console = new TestConsole
{
EmitAnsiSequences = true,
};
console.Input.PushTextWithEnter("Choice 2");

var prompt = new TextPrompt<string>("Enter Value:")
.ShowChoices()
.AddChoice("Choice 1")
.AddChoice("Choice 2");

// When
console.Prompt(prompt);

// Then
return Verifier.Verify(console.Output);
}

[Fact]
[Expectation("ChoicesStyleSet")]
public Task Uses_the_specified_choices_style()
{
// Given
var console = new TestConsole
{
EmitAnsiSequences = true,
};
console.Input.PushTextWithEnter("Choice 2");

var prompt = new TextPrompt<string>("Enter Value:")
.ShowChoices()
.AddChoice("Choice 1")
.AddChoice("Choice 2")
.ChoicesStyle(new Style(foreground: Color.Red));

// When
console.Prompt(prompt);

// Then
return Verifier.Verify(console.Output);
}
}

0 comments on commit 38d9386

Please sign in to comment.