From 38d9386e0089ff8d8d1a8b6c7795d4deccf61cbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20Gr=C3=BCnwald?= Date: Sun, 27 Mar 2022 19:38:01 +0200 Subject: [PATCH] Add option to configure the style of the choices list and the default 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. --- src/Spectre.Console/Prompts/TextPrompt.cs | 18 +++- .../Prompts/TextPromptExtensions.cs | 46 ++++++++++ .../ChoicesStyleNotSet.Output.verified.txt | 1 + .../Text/ChoicesStyleSet.Output.verified.txt | 1 + ...efaultValueStyleNotSet.Output.verified.txt | 1 + .../DefaultValueStyleSet.Output.verified.txt | 1 + .../Unit/Prompts/TextPromptTests.cs | 92 +++++++++++++++++++ 7 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleNotSet.Output.verified.txt create mode 100644 test/Spectre.Console.Tests/Expectations/Prompts/Text/ChoicesStyleSet.Output.verified.txt create mode 100644 test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleNotSet.Output.verified.txt create mode 100644 test/Spectre.Console.Tests/Expectations/Prompts/Text/DefaultValueStyleSet.Output.verified.txt 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); + } }