From 3c07dffc46b09794ecf518cd660edb9e19261f8c Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sun, 2 Feb 2025 11:02:07 +0800 Subject: [PATCH] feat(CssBuilder): add AddStyle method (#5272) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 增加 AddStyle 方法 * test: 增加单元测试 * refactor: use AddStyle method * doc: 重构代码 * refactor: 重构代码 --- .../Components/Affix/Affix.razor.cs | 4 +- .../Components/Captcha/Captcha.razor.cs | 6 +- .../Components/Drawer/Drawer.razor.cs | 6 +- .../Components/EditorForm/EditorForm.razor.cs | 2 +- .../Components/Label/BootstrapLabel.razor.cs | 2 +- .../ValidateForm/ValidateForm.razor.cs | 2 +- src/BootstrapBlazor/Utils/CssBuilder.cs | 66 ++++++++++++++++++- test/UnitTest/Utils/CssBuilderTest.cs | 66 +++++++++++++++++++ 8 files changed, 142 insertions(+), 12 deletions(-) diff --git a/src/BootstrapBlazor/Components/Affix/Affix.razor.cs b/src/BootstrapBlazor/Components/Affix/Affix.razor.cs index d4905fa9460..bd5e4606755 100644 --- a/src/BootstrapBlazor/Components/Affix/Affix.razor.cs +++ b/src/BootstrapBlazor/Components/Affix/Affix.razor.cs @@ -40,8 +40,8 @@ public partial class Affix .Build(); private string? StyleString => CssBuilder.Default("position: sticky;") - .AddClass($"z-index: {ZIndex};", ZIndex.HasValue) - .AddClass($"{Position.ToDescriptionString()}: {Offset}px;") + .AddStyle("z-index", $"{ZIndex}", ZIndex.HasValue) + .AddStyle($"{Position.ToDescriptionString()}", $"{Offset}px") .AddStyleFromAttributes(AdditionalAttributes) .Build(); } diff --git a/src/BootstrapBlazor/Components/Captcha/Captcha.razor.cs b/src/BootstrapBlazor/Components/Captcha/Captcha.razor.cs index d426c02d434..13ff538f54a 100644 --- a/src/BootstrapBlazor/Components/Captcha/Captcha.razor.cs +++ b/src/BootstrapBlazor/Components/Captcha/Captcha.razor.cs @@ -20,15 +20,15 @@ public partial class Captcha /// 获得 组件宽度 /// private string? StyleString => CssBuilder.Default() - .AddClass($"width: {Width + 42}px;", Width > 0) + .AddStyle("width", $"{Width + 42}px", Width > 0) .Build(); /// /// 获得 加载图片失败样式 /// private string? FailedStyle => CssBuilder.Default() - .AddClass($"width: {Width}px;", Width > 0) - .AddClass($"height: {Height}px;", Height > 0) + .AddStyle("width", $"{Width}px", Width > 0) + .AddStyle("height", $"{Height}px", Height > 0) .Build(); /// diff --git a/src/BootstrapBlazor/Components/Drawer/Drawer.razor.cs b/src/BootstrapBlazor/Components/Drawer/Drawer.razor.cs index dceccd69e83..cf3e86aba3a 100644 --- a/src/BootstrapBlazor/Components/Drawer/Drawer.razor.cs +++ b/src/BootstrapBlazor/Components/Drawer/Drawer.razor.cs @@ -19,7 +19,7 @@ public partial class Drawer .Build(); private string? StyleString => CssBuilder.Default() - .AddClass($"--bb-drawer-position: {Position};", !string.IsNullOrEmpty(Position)) + .AddStyle("--bb-drawer-position", $"{Position}", !string.IsNullOrEmpty(Position)) .AddStyleFromAttributes(AdditionalAttributes) .Build(); @@ -27,8 +27,8 @@ public partial class Drawer /// 获得 抽屉 Style 字符串 /// private string? DrawerStyleString => CssBuilder.Default() - .AddClass($"--bb-drawer-width: {Width};", !string.IsNullOrEmpty(Width) && Placement != Placement.Top && Placement != Placement.Bottom) - .AddClass($"--bb-drawer-height: {Height};", !string.IsNullOrEmpty(Height) && (Placement == Placement.Top || Placement == Placement.Bottom)) + .AddStyle("--bb-drawer-width", $"{Width}", !string.IsNullOrEmpty(Width) && Placement != Placement.Top && Placement != Placement.Bottom) + .AddStyle("--bb-drawer-height", $"{Height}", !string.IsNullOrEmpty(Height) && (Placement == Placement.Top || Placement == Placement.Bottom)) .Build(); /// diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs index 356c7668eec..74d67201214 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs @@ -50,7 +50,7 @@ public partial class EditorForm : IShowLabel .Build(); private string? FormStyleString => CssBuilder.Default() - .AddClass($"--bb-row-label-width: {LabelWidth}px;", LabelWidth.HasValue) + .AddStyle("--bb-row-label-width", $"{LabelWidth}px", LabelWidth.HasValue) .Build(); /// diff --git a/src/BootstrapBlazor/Components/Label/BootstrapLabel.razor.cs b/src/BootstrapBlazor/Components/Label/BootstrapLabel.razor.cs index 9de80e6afd4..d5d7608f38d 100644 --- a/src/BootstrapBlazor/Components/Label/BootstrapLabel.razor.cs +++ b/src/BootstrapBlazor/Components/Label/BootstrapLabel.razor.cs @@ -36,7 +36,7 @@ public partial class BootstrapLabel .Build(); private string? StyleString => CssBuilder.Default() - .AddClass($"--bb-row-label-width: {LabelWidth}px;", LabelWidth.HasValue) + .AddStyle($"--bb-row-label-width", $"{LabelWidth}px", LabelWidth.HasValue) .Build(); /// diff --git a/src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs b/src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs index 8d5fd93bb19..5333e8be2b4 100644 --- a/src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs +++ b/src/BootstrapBlazor/Components/ValidateForm/ValidateForm.razor.cs @@ -131,7 +131,7 @@ public partial class ValidateForm private string? ShowAllInvalidResultString => ShowAllInvalidResult ? "true" : null; private string? StyleString => CssBuilder.Default() - .AddClass($"--bb-row-label-width: {LabelWidth}px;", LabelWidth.HasValue) + .AddStyle("--bb-row-label-width", $"{LabelWidth}px", LabelWidth.HasValue) .Build(); /// diff --git a/src/BootstrapBlazor/Utils/CssBuilder.cs b/src/BootstrapBlazor/Utils/CssBuilder.cs index d0b744099bb..a67669c64d9 100644 --- a/src/BootstrapBlazor/Utils/CssBuilder.cs +++ b/src/BootstrapBlazor/Utils/CssBuilder.cs @@ -106,7 +106,71 @@ public CssBuilder AddClassFromAttributes(IDictionary? additional } /// - /// Adds a conditional Style when it exists in a dictionary to the builder with space separator. + /// Adds a raw string to the builder that will be concatenated with the next style or value added to the builder. + /// + /// style property name + /// CSS style to conditionally add. + /// CssBuilder + public CssBuilder AddStyle(string key, string? value) + { + if (!string.IsNullOrEmpty(value)) stringBuffer.Add($"{key}: {value};"); + return this; + } + + /// + /// Adds a conditional css Style to the builder with space separator. + /// + /// style property name + /// CSS style to conditionally add. + /// Condition in which the CSS style is added. + /// CssBuilder + public CssBuilder AddStyle(string key, string? value, bool when = true) => when ? AddStyle(key, value) : this; + + /// + /// Adds a conditional css Style to the builder with space separator. + /// + /// style property name + /// CSS style to conditionally add. + /// Condition in which the CSS Style is added. + /// CssBuilder + public CssBuilder AddStyle(string key, string? value, Func when) => AddStyle(key, value, when()); + + /// + /// Adds a conditional css Style to the builder with space separator. + /// + /// style property name + /// Function that returns a css Style to conditionally add. + /// Condition in which the CSS Style is added. + /// CssBuilder + public CssBuilder AddStyle(string key, Func value, bool when = true) => when ? AddStyle(key, value()) : this; + + /// + /// Adds a conditional css Style to the builder with space separator. + /// + /// style property name + /// Function that returns a css Style to conditionally add. + /// Condition in which the CSS Style is added. + /// CssBuilder + public CssBuilder AddStyle(string key, Func value, Func when) => AddStyle(key, value, when()); + + /// + /// Adds a conditional nested CssBuilder to the builder with space separator. + /// + /// CSS Style to conditionally add. + /// Condition in which the CSS Style is added. + /// CssBuilder + public CssBuilder AddStyle(CssBuilder builder, bool when = true) => when ? AddClass(builder.Build()) : this; + + /// + /// Adds a conditional CSS Class to the builder with space separator. + /// + /// CSS Class to conditionally add. + /// Condition in which the CSS Class is added. + /// CssBuilder + public CssBuilder AddStyle(CssBuilder builder, Func when) => AddClass(builder, when()); + + /// + /// Adds a conditional css Style when it exists in a dictionary to the builder with space separator. /// Null safe operation. /// /// Additional Attribute splat parameters diff --git a/test/UnitTest/Utils/CssBuilderTest.cs b/test/UnitTest/Utils/CssBuilderTest.cs index ebaf19063f9..27c02e19955 100644 --- a/test/UnitTest/Utils/CssBuilderTest.cs +++ b/test/UnitTest/Utils/CssBuilderTest.cs @@ -21,6 +21,51 @@ public void AddClass_When() Assert.Contains("cls_test", classString); } + [Fact] + public void AddStyle_When() + { + var classString = CssBuilder.Default() + .AddStyle("width", () => "cls_test", () => false) + .Build(); + Assert.DoesNotContain("widht: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", () => "cls_test", false) + .Build(); + Assert.DoesNotContain("widht: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", "cls_test", false) + .Build(); + Assert.DoesNotContain("widht: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", () => "cls_test", () => true) + .Build(); + Assert.Contains("width: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", () => "cls_test", true) + .Build(); + Assert.Contains("width: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", "cls_test", true) + .Build(); + Assert.Contains("width: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", "cls_test", () => true) + .Build(); + Assert.Contains("width: cls_test;", classString); + + classString = CssBuilder.Default() + .AddStyle("width", "cls_test_width") + .AddStyle("height", "cls_test_height") + .Build(); + Assert.Equal("width: cls_test_width; height: cls_test_height;", classString); + } + [Fact] public void AddClass_Builder() { @@ -37,6 +82,27 @@ public void AddClass_Builder() Assert.Contains("cls_test", classString); } + [Fact] + public void AddStyle_Builder() + { + var builder = CssBuilder.Default("width: cls_test_width;"); + + var classString = CssBuilder.Default() + .AddStyle(builder, false) + .Build(); + Assert.DoesNotContain("width: cls_test_width;", classString); + + classString = CssBuilder.Default() + .AddStyle(builder, () => true) + .Build(); + Assert.Contains("width: cls_test_width;", classString); + + classString = CssBuilder.Default() + .AddStyle(builder, true) + .Build(); + Assert.Contains("width: cls_test_width;", classString); + } + [Fact] public void AddStyleFromAttributes_Ok() {