From 47dbef31d70fdd66c5bc7c52bc53ead9c53825d6 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 19:58:54 +0800 Subject: [PATCH 1/6] feat(EditorForm): add EditorFormGroupType parameter --- .../Components/EditorForm/EditorForm.razor.cs | 4 ++ .../EditorForm/EditorForm.razor.scss | 41 ++++++++++++++++++- .../Components/GroupBox/GroupBox.razor | 4 +- .../Enums/EditorFormGroupType.cs | 25 +++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 src/BootstrapBlazor/Enums/EditorFormGroupType.cs diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs index 5695ceb3771..7135935da33 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs @@ -16,6 +16,7 @@ namespace BootstrapBlazor.Components; public partial class EditorForm : IShowLabel, IDisposable { private string? ClassString => CssBuilder.Default("bb-editor") + .AddClass("bb-editor-group-row-header", GroupType == EditorFormGroupType.RowHeader) .AddClassFromAttributes(AdditionalAttributes) .Build(); @@ -192,6 +193,9 @@ public partial class EditorForm : IShowLabel, IDisposable [Parameter] public bool IsRenderWhenValueChanged { get; set; } + [Parameter] + public EditorFormGroupType GroupType { get; set; } + /// /// 获得/设置 级联上下文 EditContext 实例 内置于 EditForm 或者 ValidateForm 时有值 /// Gets or sets Cascading EditContext Instance. Available when inside EditForm or ValidateForm diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.scss b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.scss index e90496b074b..0e1b29d833e 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.scss +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.scss @@ -1,4 +1,4 @@ -.bb-editor { +.bb-editor { position: relative; .ef-loading { @@ -9,4 +9,43 @@ bottom: 0; background-color: var(--bs-body-bg); } + + &.bb-editor-group-row-header { + .groupbox { + --bb-groupbox-padding: 0; + --bb-groupbox-legend-top: 0; + --bb-groupbox-legend-left: 0; + --bb-groupbox-divider-color: var(--bs-border-color); + display: flex; + flex-direction: row; + flex-wrap: nowrap; + align-items: center; + border: 0; + + .legend { + writing-mode: vertical-rl; + text-orientation: mixed; + position: relative; + color: var(--bb-groupbox-divider-color); + } + + .row { + margin-inline-start: 1rem; + flex: 1; + width: 1%; + min-width: 0; + position: relative; + + &::before { + content: ""; + width: 1px; + background-color: var(--bb-groupbox-divider-color); + position: absolute; + top: 1rem; + bottom: 0; + left: -0.5rem; + } + } + } + } } diff --git a/src/BootstrapBlazor/Components/GroupBox/GroupBox.razor b/src/BootstrapBlazor/Components/GroupBox/GroupBox.razor index f69ada6fc1a..8abd0d2c7be 100644 --- a/src/BootstrapBlazor/Components/GroupBox/GroupBox.razor +++ b/src/BootstrapBlazor/Components/GroupBox/GroupBox.razor @@ -1,7 +1,7 @@ -@namespace BootstrapBlazor.Components +@namespace BootstrapBlazor.Components @inherits BootstrapComponentBase
- + @Title @ChildContent
diff --git a/src/BootstrapBlazor/Enums/EditorFormGroupType.cs b/src/BootstrapBlazor/Enums/EditorFormGroupType.cs new file mode 100644 index 00000000000..fca287b1c36 --- /dev/null +++ b/src/BootstrapBlazor/Enums/EditorFormGroupType.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the Apache 2.0 License +// See the LICENSE file in the project root for more information. +// Maintainer: Argo Zhang(argo@live.ca) Website: https://www.blazor.zone + +namespace BootstrapBlazor.Components; + +/// +/// EditorForm 分组类型 +/// EditorForm group type +/// +public enum EditorFormGroupType +{ + /// + /// 使用 GroupBox 形式 + /// Group box + /// + GroupBox, + + /// + /// 使用 RowHeader 形式 + /// Row header + /// + RowHeader, +} From 5e50cdfa0701091843adc5e7a4551a1f0f5b5663 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 19:59:02 +0800 Subject: [PATCH 2/6] =?UTF-8?q?doc:=20=E5=A2=9E=E5=8A=A0=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Components/Samples/EditorForms.razor | 24 +++++++++++++++++++ .../Components/Samples/EditorForms.razor.cs | 1 + src/BootstrapBlazor.Server/Locales/en-US.json | 5 +++- src/BootstrapBlazor.Server/Locales/zh-CN.json | 5 +++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor index b4fae6803be..2d45a430aaf 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor @@ -149,6 +149,30 @@ + +
+

@((MarkupString)Localizer["GroupDescription"].Value)

+ + + + + + + +
+ + + + + + + + + + + +
+ diff --git a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs index f451e966079..249084b481d 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/EditorForms.razor.cs @@ -26,6 +26,7 @@ public sealed partial class EditorForms private IStringLocalizer? FooLocalizer { get; set; } private List _ignoreItems = []; + private EditorFormGroupType _groupType = EditorFormGroupType.GroupBox; private Task OnSwitchIgnoreItems() { diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 533283f3425..9f3b70579a0 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -2152,7 +2152,10 @@ "ValidateFormIntro": "Data compliance checks are implemented through nested ValidateForm components", "ValidateFormTips1": "The component is built into the ValidateForm to turn on data compliance checks, and hobbyfields use the EditTemplate template to customize the component to render the data", "ValidateFormTips2": "Make the birthday field read-only by setting the Readonly property", - "ValidateFormTitle": "Turn on data validation" + "ValidateFormTitle": "Turn on data validation", + "GroupTitle": "Group", + "GroupIntro": "The grouping format can be controlled by setting the groupType value.", + "GroupDescription": "Grouping is enabled by setting the GroupName parameter of the EditorItem component, and the order is controlled by GroupOrder." }, "BootstrapBlazor.Server.Components.Samples.Editors": { "DoMethodAsyncButton1": "Insert Html", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index f5090947aac..d2a69378689 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -2152,7 +2152,10 @@ "ValidateFormIntro": "通过嵌套 ValidateForm 组件实现数据合规检查功能", "ValidateFormTips1": "组件内置到 ValidateForm 内开启数据合规检查功能,爱好 字段使用 EditTemplate 模板自定义组件呈现数据", "ValidateFormTips2": "通过设置 Readonly 属性,使 生日 字段为只读", - "ValidateFormTitle": "开启数据验证" + "ValidateFormTitle": "开启数据验证", + "GroupTitle": "分组功能", + "GroupIntro": "通过设置 GroupType 值控制分组形式", + "GroupDescription": "通过设置 EditorItem 组件参数 GroupName 开启分组功能,通过 GroupOrder 控制顺序 " }, "BootstrapBlazor.Server.Components.Samples.Editors": { "DoMethodAsyncButton1": "插入一段 Html", From 080acbb702910de1edba4b965918b4a1837a7d29 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 20:03:49 +0800 Subject: [PATCH 3/6] =?UTF-8?q?test:=20=E6=9B=B4=E6=96=B0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/UnitTest/Components/EditorFormTest.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/UnitTest/Components/EditorFormTest.cs b/test/UnitTest/Components/EditorFormTest.cs index b6b1fcbf617..736a136e38b 100644 --- a/test/UnitTest/Components/EditorFormTest.cs +++ b/test/UnitTest/Components/EditorFormTest.cs @@ -177,6 +177,25 @@ public void Buttons_Ok() }); } + [Fact] + public void GroupType_Ok() + { + var foo = new Foo(); + var cut = Context.Render>(pb => + { + pb.Add(a => a.Model, foo); + pb.Add(a => a.GroupType, EditorFormGroupType.GroupBox); + }); + + cut.DoesNotContain("bb-editor-group-row-header"); + + cut.Render(pb => + { + pb.Add(a => a.GroupType, EditorFormGroupType.RowHeader); + }); + cut.Contains("bb-editor-group-row-header"); + } + [Fact] public void Alignment_Right() { From a64ab5eafdb07709f5407b9292733166a471b44a Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 20:03:56 +0800 Subject: [PATCH 4/6] =?UTF-8?q?doc:=20=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs index 7135935da33..f54352c97bf 100644 --- a/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs +++ b/src/BootstrapBlazor/Components/EditorForm/EditorForm.razor.cs @@ -193,6 +193,10 @@ public partial class EditorForm : IShowLabel, IDisposable [Parameter] public bool IsRenderWhenValueChanged { get; set; } + /// + /// 获得/设置 分组类型 默认 + /// Gets or sets group type. Default is + /// [Parameter] public EditorFormGroupType GroupType { get; set; } From 7bcca938d767c97090f378152798f16f0b45b7c1 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 20:04:21 +0800 Subject: [PATCH 5/6] chore: bump version 10.3.1-beta03 --- src/BootstrapBlazor/BootstrapBlazor.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index 093db25ddde..c31ef07228b 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@  - 10.3.1-beta02 + 10.3.1-beta03 From 811105414641d264ce3e7b5e0fbdcedc8ff03790 Mon Sep 17 00:00:00 2001 From: Argo Zhang Date: Sat, 31 Jan 2026 20:06:16 +0800 Subject: [PATCH 6/6] =?UTF-8?q?doc:=20=E6=9B=B4=E6=96=B0=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/BootstrapBlazor.Server/Locales/en-US.json | 8 ++++---- src/BootstrapBlazor.Server/Locales/zh-CN.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 9f3b70579a0..7846f91f9b8 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -2129,6 +2129,9 @@ "EditorFormTips3": "Complex edit columns, set up EditTemplate templates, and edit custom components", "EditorFormTips4": "The buttons in the form can be set up multiplely, just set the buttons Buttons template", "GroupBoxTitle": "An example of a form", + "GroupDescription": "Grouping is enabled by setting the GroupName parameter of the EditorItem component, and the order is controlled by GroupOrder.", + "GroupIntro": "The grouping format can be controlled by setting the groupType value.", + "GroupTitle": "Group", "IgnoreItemsDescription": "This attribute has the same priority as the Ignore parameter in EditorItem. If it is set to ignore anywhere, it will not be rendered.", "IgnoreItemsIntro": "By setting the IgnoreItems value, you can notify the component not to render the specified column in the collection.", "IgnoreItemsSwitchButtonText": "Switch", @@ -2152,10 +2155,7 @@ "ValidateFormIntro": "Data compliance checks are implemented through nested ValidateForm components", "ValidateFormTips1": "The component is built into the ValidateForm to turn on data compliance checks, and hobbyfields use the EditTemplate template to customize the component to render the data", "ValidateFormTips2": "Make the birthday field read-only by setting the Readonly property", - "ValidateFormTitle": "Turn on data validation", - "GroupTitle": "Group", - "GroupIntro": "The grouping format can be controlled by setting the groupType value.", - "GroupDescription": "Grouping is enabled by setting the GroupName parameter of the EditorItem component, and the order is controlled by GroupOrder." + "ValidateFormTitle": "Turn on data validation" }, "BootstrapBlazor.Server.Components.Samples.Editors": { "DoMethodAsyncButton1": "Insert Html", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index d2a69378689..d881e55de8f 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -2129,6 +2129,9 @@ "EditorFormTips3": "复杂编辑列,设置 EditTemplate 模板,进行自定义组件进行编辑", "EditorFormTips4": "表单内按钮可以设置多个,设置 Buttons 模板即可", "GroupBoxTitle": "表单示例", + "GroupDescription": "通过设置 EditorItem 组件参数 GroupName 开启分组功能,通过 GroupOrder 控制顺序 ", + "GroupIntro": "通过设置 GroupType 值控制分组形式", + "GroupTitle": "分组功能", "IgnoreItemsDescription": "此属性的优先级与 EditorItem 参数 Ignore 相同,任何一个地方设置了忽略,最终都不会渲染", "IgnoreItemsIntro": "通过设置 IgnoreItems 值通知组件不渲染集合中的指定列", "IgnoreItemsSwitchButtonText": "切换", @@ -2152,10 +2155,7 @@ "ValidateFormIntro": "通过嵌套 ValidateForm 组件实现数据合规检查功能", "ValidateFormTips1": "组件内置到 ValidateForm 内开启数据合规检查功能,爱好 字段使用 EditTemplate 模板自定义组件呈现数据", "ValidateFormTips2": "通过设置 Readonly 属性,使 生日 字段为只读", - "ValidateFormTitle": "开启数据验证", - "GroupTitle": "分组功能", - "GroupIntro": "通过设置 GroupType 值控制分组形式", - "GroupDescription": "通过设置 EditorItem 组件参数 GroupName 开启分组功能,通过 GroupOrder 控制顺序 " + "ValidateFormTitle": "开启数据验证" }, "BootstrapBlazor.Server.Components.Samples.Editors": { "DoMethodAsyncButton1": "插入一段 Html",