Repository: ant-design-blazor/ant-design-blazor (csharp)

Issue:
Input: Allow clear on empty string
<!--

请尽量使用英语，因为我们有来自全球的贡献者，使用英语会让您的问题和需求得到更迅速的响应和解决。
推荐使用：https://cn.bing.com/translator

Please use English as much as possible, as we have contributors from all over the world,
using English will allow your questions and needs to be responded to and resolved more quickly.
-->

### Is your feature request related to a problem? Please describe.
In my project, there is a semantic difference between a null value and an empty string. I'd like to support this during data entry by showing the clear icon even when the Input is empty (in case the `Value` is not null). As far as I could find, this is not yet possible.

### Describe the solution you'd like
An extra parameter of Input called something like `ClearEmpty` or `AllowClearEmpty`, that changes the logic of ClearIcon to check `_inputString is null` instead of `string.IsNullOrEmpty(_inputString)` for adding the _hidden_ CSS class.

Pull request description:
<!--
First of all, thank you for your contribution! 😄

New feature please send pull request to feature branch, and rest to master branch.
Pull request will be merged after one of collaborators approve.
Please makes sure that these form are filled before submitting your pull request, thank you!

[[中文版模板 / Chinese template](https://github.com/ant-design-blazor/ant-design-blazor/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)]

-->

### 🤔 This is a ...

- [x] New feature
- [ ] Bug fix
- [ ] Site / documentation update
- [ ] Demo update
- [ ] Component style update
- [ ] Bundle size optimization
- [ ] Performance optimization
- [ ] Refactoring
- [ ] Code style optimization
- [ ] Test Case
- [ ] Branch merge
- [ ] Other (about what?)

### 🔗 Related issue link

<!--
1. Describe the source of requirement, like related issue link.
-->
#4167 

### 💡 Background and solution

<!--
1. Describe the problem and the scenario.
2. GIF or snapshot should be provided if includes UI/interactive modification.
3. How to fix the problem, and list final API implementation and usage sample if that is an new feature.
-->
Allows different or more complex logic for when the clear icon should be shown, e.g. even when the input is empty (but not null).

### 📝 Changelog

<!--
Describe changes from userside, and list all potential break changes or other risks.
--->

| Language   | Changelog |
| ---------- | --------- |
| 🇺🇸 English | New `ShowClear` parameter allows overriding when the clear button is shown. |
| 🇨🇳 Chinese |           |

### ☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

- [x] Doc is updated/provided or not needed
- [x] Demo is updated/provided or not needed
- [x] Changelog is provided or not needed

Patch:
diff --git a/components/input/Input.cs b/components/input/Input.cs
index e50d537b9d..059dd6fd20 100644
--- a/components/input/Input.cs
+++ b/components/input/Input.cs
@@ -68,6 +68,15 @@ public class Input<TValue> : AntInputComponentBase<TValue>
         [Parameter]
         public bool AllowClear { get; set; }
 
+        /// <summary>
+        /// Overrides whether the clear icon is shown. When <see langword="null"/>, it is shown if and only if the input string is not empty.
+        /// </summary>
+        /// <remarks>
+        /// Requires <see cref="AllowClear"/> to be <see langword="true"/>, otherwise this has no effect.
+        /// </remarks>
+        [Parameter]
+        public bool? ShowClear { get; set; }
+
         /// <summary>
         /// Callback when the content is cleared by clicking the "ClearIcon"
         /// </summary>
@@ -517,7 +526,7 @@ internal virtual void OnCompositionEnd(JsonElement e)
             builder.OpenElement(31, "span");
             builder.AddAttribute(32, "class", $"{PrefixCls}-clear-icon " +
                 (Suffix != null ? $"{PrefixCls}-clear-icon-has-suffix " : "") +
-                (string.IsNullOrEmpty(_inputString) || Disabled ? $"{PrefixCls}-clear-icon-hidden " : ""));
+                (!ShowClear ?? string.IsNullOrEmpty(_inputString) || Disabled ? $"{PrefixCls}-clear-icon-hidden " : ""));
 
             builder.OpenComponent<Icon>(33);
 
diff --git a/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.md b/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.md
index 4e660b84a0..4957e37f28 100644
--- a/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.md
+++ b/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.md
@@ -11,4 +11,4 @@ title:
 
 
 ## en-US
-Input box with the remove icon, click the icon to delete everything.
+Input box with the remove icon, click the icon to delete everything. `ShowClear` can be used to override when the icon is shown.
diff --git a/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.razor b/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.razor
index d417607ded..9889ecaec0 100644
--- a/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.razor
+++ b/site/AntDesign.Docs/Demos/Components/Input/demo/Clear.razor
@@ -2,6 +2,9 @@
     <Input Placeholder="input with clear icon" AllowClear="true" OnChange="onChange" TValue="string"/>
     <br />
     <br />
+    <Input Placeholder="clear icon always shown" AllowClear="true" ShowClear="true" OnChange="onChange" TValue="string" />
+    <br />
+    <br />
     <TextArea Placeholder="textarea with clear icon"  AllowClear="true" OnChange="onChange" />
 </div>
 @code{
diff --git a/site/AntDesign.Docs/Demos/Components/Input/doc/index.en-US.md b/site/AntDesign.Docs/Demos/Components/Input/doc/index.en-US.md
index a1727aee7e..cf44b5f59e 100644
--- a/site/AntDesign.Docs/Demos/Components/Input/doc/index.en-US.md
+++ b/site/AntDesign.Docs/Demos/Components/Input/doc/index.en-US.md
@@ -43,6 +43,7 @@ A basic widget for getting the user input is a text field. Keyboard and mouse ca
 | Placeholder              | Provide prompt information that describes the expected value of the input field        | string        | -        |
 | Prefix | The prefix icon for the Input.                           | RenderFragment        | -        |
 | ReadOnly | When present, it specifies that an input field is read-only. | boolean | false    | 0.9
+| ShowClear | Overrides whether the clear button should be shown when `AllowClear` is true (otherwise this has no effect). If null, the default behavior is used, and the clear button is only shown if the input is not empty. | boolean?     | -      |
 | Size |The size of the input box. Note: in the context of a form, the `large` size is used. Available: `large` `default` `small`       | string        | -         |
 | StopPropagation Controls onclick & blur event propagation.    | boolean    | false      | 0.10.0
 | Style | Set CSS style. When using, be aware that some styles can be set only by `WrapperStyle` | string | - |  |


Test patch:
diff --git a/tests/AntDesign.Tests/Input/InputTests.razor b/tests/AntDesign.Tests/Input/InputTests.razor
index f5f82f8e32..fb78adab87 100644
--- a/tests/AntDesign.Tests/Input/InputTests.razor
+++ b/tests/AntDesign.Tests/Input/InputTests.razor
@@ -144,6 +144,34 @@
         cut.Find("span.ant-input-clear-icon").GetAttribute("class")!.Contains("ant-input-clear-icon-hidden").Should().BeTrue();
 	}
 
+    [Fact]
+    public void Input_show_clearButton_when_show_clear_true()
+    {
+        //Arrange
+        var cut = Render<AntDesign.Input<string>>(
+            @<AntDesign.Input TValue="string" AllowClear ShowClear="true"/>);
+        // Not hidden even when empty
+        cut.Find("span.ant-input-clear-icon").GetAttribute("class")!.Contains("ant-input-clear-icon-hidden").Should().BeFalse();
+
+        cut.Find("input").Input("test");
+        // Not hidden after adding input
+        cut.Find("span.ant-input-clear-icon").GetAttribute("class")!.Contains("ant-input-clear-icon-hidden").Should().BeFalse();
+    }
+
+    [Fact]
+    public void Input_hide_clearButton_when_show_clear_false()
+    {
+        //Arrange
+        var cut = Render<AntDesign.Input<string>>(
+            @<AntDesign.Input TValue="string" AllowClear ShowClear="false" />);
+        // Hidden when empty
+        cut.Find("span.ant-input-clear-icon").GetAttribute("class")!.Contains("ant-input-clear-icon-hidden").Should().BeTrue();
+
+        cut.Find("input").Input("test");
+        // Hidden even after adding input
+        cut.Find("span.ant-input-clear-icon").GetAttribute("class")!.Contains("ant-input-clear-icon-hidden").Should().BeTrue();
+    }
+
     [Fact]
     public void Input_default_change()
     {