diff --git a/src/Spectre.Console/Prompts/TextPrompt.cs b/src/Spectre.Console/Prompts/TextPrompt.cs index ebe3fbb..0d9b501 100644 --- a/src/Spectre.Console/Prompts/TextPrompt.cs +++ b/src/Spectre.Console/Prompts/TextPrompt.cs @@ -63,6 +63,16 @@ public sealed class TextPrompt : IPrompt /// public Func? Validator { get; set; } + /// + /// Gets or sets the style in which the default value is displayed. + /// + public Style? DefaultValueStyle { get; set; } + + /// + /// Gets or sets the style in which the list of choices is displayed. + /// + public Style? ChoicesStyle { get; set; } + /// /// Gets or sets the default value. /// @@ -183,16 +193,20 @@ public sealed class TextPrompt : IPrompt 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)); } diff --git a/src/Spectre.Console/Prompts/TextPromptExtensions.cs b/src/Spectre.Console/Prompts/TextPromptExtensions.cs index 318639f..c44f427 100644 --- a/src/Spectre.Console/Prompts/TextPromptExtensions.cs +++ b/src/Spectre.Console/Prompts/TextPromptExtensions.cs @@ -305,4 +305,50 @@ public static class TextPromptExtensions obj.Converter = displaySelector; return obj; } + + /// + /// Sets the style in which the default value is displayed. + /// + /// The prompt result type. + /// The prompt. + /// The default value style. + /// The same instance so that multiple calls can be chained. + public static TextPrompt DefaultValueStyle(this TextPrompt 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; + } + + /// + /// Sets the style in which the list of choices is displayed. + /// + /// The prompt result type. + /// The prompt. + /// The style to use for displaying the choices. + /// The same instance so that multiple calls can be chained. + public static TextPrompt ChoicesStyle(this TextPrompt 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; + } } \ No newline at end of file diff --git a/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleNotSet.Output.verified.txt b/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleNotSet.Output.verified.txt new file mode 100644 index 0000000..aa019d5 --- /dev/null +++ b/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleNotSet.Output.verified.txt @@ -0,0 +1 @@ +Enter Value: [Choice 1/Choice 2]: Choice 2 diff --git a/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleSet.Output.verified.txt b/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleSet.Output.verified.txt new file mode 100644 index 0000000..f9e65f2 --- /dev/null +++ b/test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleSet.Output.verified.txt @@ -0,0 +1 @@ +Enter Value: [Choice 1/Choice 2]: Choice 2 diff --git a/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleNotSet.Output.verified.txt b/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleNotSet.Output.verified.txt new file mode 100644 index 0000000..d6c517c --- /dev/null +++ b/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleNotSet.Output.verified.txt @@ -0,0 +1 @@ +Enter Value: (default): Input diff --git a/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleSet.Output.verified.txt b/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleSet.Output.verified.txt new file mode 100644 index 0000000..e520e91 --- /dev/null +++ b/test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleSet.Output.verified.txt @@ -0,0 +1 @@ +Enter Value: (default): Input diff --git a/test/Spectre.Console.Tests/Unit/Prompts/TextPromptTests.cs b/test/Spectre.Console.Tests/Unit/Prompts/TextPromptTests.cs index a3a8ee3..aceb2a1 100644 --- a/test/Spectre.Console.Tests/Unit/Prompts/TextPromptTests.cs +++ b/test/Spectre.Console.Tests/Unit/Prompts/TextPromptTests.cs @@ -241,4 +241,96 @@ public sealed class TextPromptTests // 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("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("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("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("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); + } }