Skip to content

Commit f37d81e

Browse files
authored
feat(Collapse): add HeaderTemplate parameter (#4763)
* doc: 更正资源文件键值不正确问题 * refactor: 移除宏定义 * refactor: 更正单词拼写错误 * doc: 增加注释文档 * feat: 增加 HeaderClass 参数 * feat: 增加 HeaderTemplate 支持 * doc: 文档格式化 * doc: 更新 HeaderTemplate 示例 * doc: 更新注释 * doc: 更新 CollapseItem 文档 * chore: bump version 9.0.2-beta07 * test: 更新单元测试
1 parent abfd210 commit f37d81e

File tree

12 files changed

+220
-45
lines changed

12 files changed

+220
-45
lines changed

src/BootstrapBlazor.Server/Components/App.razor

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@inject IWebHostEnvironment Env
2-
@inject IStringLocalizer<App> Localizer
2+
@inject IStringLocalizer<BaseLayout> Localizer
33

44
<!DOCTYPE html>
55
<html lang="en" data-bs-theme='light'>
@@ -12,7 +12,7 @@
1212
<meta name="keywords" content="bootstrap,blazor,wasm,webassembly,UI,netcore,web,assembly">
1313
<meta name="description" content="基于 Bootstrap 风格的 Blazor UI 组件库,用于研发企业级中后台产品。">
1414
<meta name="author" content="argo (argo@live.ca)">
15-
<title>@Localizer["Title"]</title>
15+
<title>@Localizer["SiteTitle"]</title>
1616
<base href="/" />
1717
<link rel="icon" href="favicon.ico" type="image/x-icon">
1818
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

src/BootstrapBlazor.Server/Extensions/StaticFileResponseContextExtensions.cs

-2
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,10 @@ public static RenderFragment RenderAssets(this ComponentBase component) => build
5353

5454
private static void RenderCss(this RenderTreeBuilder builder, string url)
5555
{
56-
#if NET9_0_OR_GREATER
5756
builder.OpenElement(0, "link");
5857
builder.AddAttribute(1, "rel", "stylesheet");
5958
builder.AddAttribute(2, "href", url);
6059
builder.CloseElement();
61-
#endif
6260
}
6361

6462
public static void ProcessCache(this StaticFileResponseContext context, IConfiguration configuration)

src/BootstrapBlazor.Shared/Components/Samples/Collapses.razor

+40-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
}
119119
</CollapseItems>
120120
</Collapse>
121-
<Button Text="@Localizer["ButtonText"]" OnClick="OnToggle" class="mt-3" />
121+
<Button Text="@Localizer["ButtonText"]" OnClick="OnToggle" class="mt-3"></Button>
122122
</DemoBlock>
123123

124124
<DemoBlock Title="@Localizer["IconTitle"]" Introduction="@Localizer["IconIntro"]" Name="Icon">
@@ -140,4 +140,43 @@
140140
</Collapse>
141141
</DemoBlock>
142142

143+
<DemoBlock Title="@Localizer["HeaderTemplateTitle"]" Introduction="@Localizer["HeaderTemplateIntro"]" Name="HeaderTemplate">
144+
<Collapse>
145+
<CollapseItems>
146+
<CollapseItem Text="@Localizer["Consistency"]">
147+
<HeaderTemplate>
148+
<div class="p-2">
149+
<Select Items="Items" @bind-Value="Value" IsPopover="true"></Select>
150+
</div>
151+
</HeaderTemplate>
152+
<ChildContent>
153+
<div>@Localizer["ConsistencyItem1"]</div>
154+
<div>@Localizer["ConsistencyItem2"]</div>
155+
<div>@Value</div>
156+
</ChildContent>
157+
</CollapseItem>
158+
<CollapseItem Text="@Localizer["Feedback"]">
159+
<HeaderTemplate>
160+
<div class="p-2">Header-Test</div>
161+
</HeaderTemplate>
162+
<ChildContent>
163+
<div>@Localizer["FeedbackItem1"]</div>
164+
<div>@Localizer["FeedbackItem2"]</div>
165+
</ChildContent>
166+
</CollapseItem>
167+
<CollapseItem Text="@Localizer["Controllability"]">
168+
<HeaderTemplate>
169+
<div class="p-2">Header-Test</div>
170+
</HeaderTemplate>
171+
<ChildContent>
172+
<div>@Localizer["ControllabilityItem1"]</div>
173+
<div>@Localizer["ControllabilityItem2"]</div>
174+
</ChildContent>
175+
</CollapseItem>
176+
</CollapseItems>
177+
</Collapse>
178+
</DemoBlock>
179+
143180
<AttributeTable Items="@GetAttributes()" />
181+
182+
<AttributeTable Items="@GetCollapseItemAttributes()" Title="@nameof(CollapseItem)" />

src/BootstrapBlazor.Shared/Components/Samples/Collapses.razor.cs

+68-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ private void OnToggle()
2626
State = !State;
2727
}
2828

29-
/// <summary>
30-
/// 获得属性方法
31-
/// </summary>
32-
/// <returns></returns>
29+
private string Value { get; set; }
30+
31+
private IEnumerable<SelectedItem> Items { get; set; } = new[]
32+
{
33+
new SelectedItem ("Beijing", "北京"),
34+
new SelectedItem ("Shanghai", "上海") { Active = true },
35+
};
36+
3337
private AttributeItem[] GetAttributes() =>
3438
[
3539
new()
@@ -57,4 +61,64 @@ private AttributeItem[] GetAttributes() =>
5761
DefaultValue = " — "
5862
}
5963
];
64+
65+
private AttributeItem[] GetCollapseItemAttributes() =>
66+
[
67+
new()
68+
{
69+
Name = "Text",
70+
Description = Localizer["CollapseItemAttributeText"],
71+
Type = "RenderFragment",
72+
ValueList = " — ",
73+
DefaultValue = " — "
74+
},
75+
new()
76+
{
77+
Name = "Icon",
78+
Description = Localizer["CollapseItemAttributeIcon"],
79+
Type = "Func<CollapseItem, Task>",
80+
ValueList = " — ",
81+
DefaultValue = " — "
82+
},
83+
new()
84+
{
85+
Name = "TitleColor",
86+
Description = Localizer["CollapseItemAttributeTitleColor"],
87+
Type = "Func<CollapseItem, Task>",
88+
ValueList = " — ",
89+
DefaultValue = " — "
90+
},
91+
new()
92+
{
93+
Name = "Class",
94+
Description = Localizer["CollapseItemAttributeClass"],
95+
Type = "Func<CollapseItem, Task>",
96+
ValueList = " — ",
97+
DefaultValue = " — "
98+
},
99+
new()
100+
{
101+
Name = "HeaderClass",
102+
Description = Localizer["CollapseItemAttributeHeaderClass"],
103+
Type = "Func<CollapseItem, Task>",
104+
ValueList = " — ",
105+
DefaultValue = " — "
106+
},
107+
new()
108+
{
109+
Name = "HeaderTemplate",
110+
Description = Localizer["CollapseItemAttributeHeaderTemplate"],
111+
Type = "Func<CollapseItem, Task>",
112+
ValueList = " — ",
113+
DefaultValue = " — "
114+
},
115+
new()
116+
{
117+
Name = "IsCollapsed",
118+
Description = Localizer["CollapseItemAttributeIsCollapsed"],
119+
Type = "bool",
120+
ValueList = "true|false",
121+
DefaultValue = "false"
122+
}
123+
];
60124
}

src/BootstrapBlazor.Shared/Locales/en-US.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -3859,7 +3859,16 @@
38593859
"Controllability": "Controllability",
38603860
"ControllabilityItem1": "User decision-making: according to the scene can give the user action advice or security tips, but can not replace the user to make decisions;",
38613861
"ControllabilityItem2": "Results controllable: Users are free to perform actions, including undoing, falling back, and terminating the current operation.",
3862-
"ButtonText": "Toggle"
3862+
"ButtonText": "Toggle",
3863+
"HeaderTemplateTitle": "Header Template",
3864+
"HeaderTemplateIntro": "Customize the <b>Header</b> display content by setting <code>HeaderTemplate</code>",
3865+
"CollapseItemAttributeText": "The title of header",
3866+
"CollapseItemAttributeIcon": "The icon of header",
3867+
"CollapseItemAttributeTitleColor": "The color of header",
3868+
"CollapseItemAttributeClass": "The class of item",
3869+
"CollapseItemAttributeHeaderClass": "The class of header",
3870+
"CollapseItemAttributeHeaderTemplate": "Header template",
3871+
"CollapseItemAttributeIsCollapsed": "The item status collapsed"
38633872
},
38643873
"BootstrapBlazor.Shared.Components.Samples.DateTimeRanges": {
38653874
"Title": "Date Time Range Picker",

src/BootstrapBlazor.Shared/Locales/zh-CN.json

+10-1
Original file line numberDiff line numberDiff line change
@@ -3859,7 +3859,16 @@
38593859
"Controllability": "可控 Controllability",
38603860
"ControllabilityItem1": "用户决策:根据场景可给予用户操作建议或安全提示,但不能代替用户进行决策;",
38613861
"ControllabilityItem2": "结果可控:用户可以自由的进行操作,包括撤销、回退和终止当前操作等。",
3862-
"ButtonText": "切换"
3862+
"ButtonText": "切换",
3863+
"HeaderTemplateTitle": "Header 模板",
3864+
"HeaderTemplateIntro": "通过设置 <code>HeaderTemplate</code> 自定义 <b>Header</b> 显示内容",
3865+
"CollapseItemAttributeText": "文本文字",
3866+
"CollapseItemAttributeIcon": "图标字符串",
3867+
"CollapseItemAttributeTitleColor": "标题颜色",
3868+
"CollapseItemAttributeClass": "样式名称",
3869+
"CollapseItemAttributeHeaderClass": "Header CSS 样式名称",
3870+
"CollapseItemAttributeHeaderTemplate": "Header 模板",
3871+
"CollapseItemAttributeIsCollapsed": "当前状态是否收缩"
38633872
},
38643873
"BootstrapBlazor.Shared.Components.Samples.DateTimeRanges": {
38653874
"Title": "DateTimeRange 日期时间段选择器",

src/BootstrapBlazor/BootstrapBlazor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.0.2-beta06</Version>
4+
<Version>9.0.2-beta07</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/Collapse/Collapse.razor

+14-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,20 @@
99
@foreach (var item in Children)
1010
{
1111
<div @key="item" class="@GetItemClassString(item)">
12-
<div class="accordion-header">
13-
<Button class="@GetButtonClassString(item)" data-bs-toggle="collapse" data-bs-target="@GetTargetIdString(item)" aria-expanded="@(item.IsCollapsed ? "false" : "true")" Color="item.TitleColor" Text="@item.Text" OnClickWithoutRender="@(() => OnClickItem(item))" Icon="@item.Icon" />
12+
<div class="@GetHeaderClassString(item)">
13+
@if (item.HeaderTemplate != null)
14+
{
15+
<div class="accordion-header-body">
16+
@item.HeaderTemplate
17+
</div>
18+
}
19+
<div class="@GetHeaderButtonClassString(item)" data-bs-toggle="collapse" data-bs-target="@GetTargetIdString(item)" aria-expanded="@(item.IsCollapsed ? "false" : "true")" @onclick="() => OnClickItem(item)">
20+
@if(!string.IsNullOrEmpty(item.Icon))
21+
{
22+
<i class="@GetItemIconString(item)"></i>
23+
}
24+
<span>@item.Text</span>
25+
</div>
1426
</div>
1527
<div class="@GetClassString(item.IsCollapsed)" id="@GetTargetId(item)" data-bs-parent="@ParentIdString">
1628
<div class="accordion-body">

src/BootstrapBlazor/Components/Collapse/Collapse.razor.cs

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,19 @@ namespace BootstrapBlazor.Components;
1010
/// </summary>
1111
public partial class Collapse
1212
{
13-
private static string? GetButtonClassString(CollapseItem item) => CssBuilder.Default("accordion-button")
13+
private static string? GetHeaderButtonClassString(CollapseItem item) => CssBuilder.Default("accordion-button")
1414
.AddClass("collapsed", item.IsCollapsed)
15+
.AddClass($"bg-{item.TitleColor.ToDescriptionString()}", item.TitleColor != Color.None)
16+
.Build();
17+
18+
private static string? GetItemIconString(CollapseItem item) => CssBuilder.Default("accordion-item-icon")
19+
.AddClass(item.Icon)
20+
.Build();
21+
22+
private static string? GetHeaderClassString(CollapseItem item) => CssBuilder.Default("accordion-header")
23+
.AddClass("collapsed", item.IsCollapsed)
24+
.AddClass($"bg-{item.TitleColor.ToDescriptionString()}", item.TitleColor != Color.None)
25+
.AddClass(item.HeaderClass)
1526
.Build();
1627

1728
private static string? GetClassString(bool collapsed) => CssBuilder.Default("accordion-collapse collapse")

src/BootstrapBlazor/Components/Collapse/Collapse.razor.scss

+25-23
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,39 @@
33
--bs-accordion-btn-padding-x: 1rem;
44
--bs-accordion-btn-padding-y: .5rem;
55

6-
.accordion-button {
7-
&.btn-primary {
8-
background-color: var(--bs-primary);
9-
}
10-
11-
&.btn-secondary {
12-
background-color: var(--bs-secondary);
13-
}
14-
15-
&.btn-success {
16-
background-color: var(--bs-success);
17-
}
6+
.accordion-header {
7+
display: flex;
8+
align-items: center;
9+
width: 100%;
10+
overflow: hidden;
1811

19-
&.btn-info {
20-
background-color: var(--bs-info);
12+
&:not(.collapsed) {
13+
background-color: var(--bs-accordion-active-bg);
2114
}
2215

23-
&.btn-warning {
24-
background-color: var(--bs-warning);
25-
}
16+
.accordion-button {
17+
--bs-accordion-inner-border-radius: 0;
18+
flex: 1 1 auto;
19+
width: 1%;
20+
cursor: pointer;
2621

27-
&.btn-danger {
28-
background-color: var(--bs-danger);
22+
.accordion-item-icon {
23+
margin-inline-end: .5rem;
24+
}
2925
}
26+
}
3027

31-
&.btn-light {
32-
background-color: var(--bs-light);
28+
.accordion-item:first-of-type {
29+
.accordion-header {
30+
border-top-left-radius: var(--bs-accordion-inner-border-radius);
31+
border-top-right-radius: var(--bs-accordion-inner-border-radius);
3332
}
33+
}
3434

35-
&.btn-dark {
36-
background-color: var(--bs-dark);
35+
.accordion-item:last-of-type {
36+
.accordion-header.collapsed {
37+
border-bottom-left-radius: var(--bs-accordion-inner-border-radius);
38+
border-bottom-right-radius: var(--bs-accordion-inner-border-radius);
3739
}
3840
}
3941
}

src/BootstrapBlazor/Components/Collapse/CollapseItem.cs

+18-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class CollapseItem : BootstrapComponentBase, IDisposable
1717
public string? Text { get; set; }
1818

1919
/// <summary>
20-
/// 获得/设置 当前状态是否激活 默认 true
20+
/// 获得/设置 当前状态是否收缩 默认 true
2121
/// </summary>
2222
[Parameter]
2323
public bool IsCollapsed { get; set; } = true;
@@ -46,11 +46,23 @@ public class CollapseItem : BootstrapComponentBase, IDisposable
4646
[Parameter]
4747
public RenderFragment? ChildContent { get; set; }
4848

49+
/// <summary>
50+
/// 获得/设置 Header CSS 样式名称 默认 null
51+
/// </summary>
52+
[Parameter]
53+
public string? HeaderClass { get; set; }
54+
55+
/// <summary>
56+
/// 获得/设置 组件 Header 模板
57+
/// </summary>
58+
[Parameter]
59+
public RenderFragment? HeaderTemplate { get; set; }
60+
4961
/// <summary>
5062
/// 获得/设置 所属 Collapse 实例
5163
/// </summary>
5264
[CascadingParameter]
53-
protected Collapse? Collpase { get; set; }
65+
protected Collapse? Collapse { get; set; }
5466

5567
/// <summary>
5668
/// OnInitialized 方法
@@ -59,7 +71,7 @@ protected override void OnInitialized()
5971
{
6072
base.OnInitialized();
6173

62-
Collpase?.AddItem(this);
74+
Collapse?.AddItem(this);
6375
}
6476

6577
/// <summary>
@@ -71,7 +83,7 @@ protected override void OnInitialized()
7183
private bool disposedValue;
7284

7385
/// <summary>
74-
///
86+
/// 资源销毁
7587
/// </summary>
7688
/// <param name="disposing"></param>
7789
protected virtual void Dispose(bool disposing)
@@ -82,13 +94,13 @@ protected virtual void Dispose(bool disposing)
8294

8395
if (disposing)
8496
{
85-
Collpase?.RemoveItem(this);
97+
Collapse?.RemoveItem(this);
8698
}
8799
}
88100
}
89101

90102
/// <summary>
91-
///
103+
/// <inheritdoc/>
92104
/// </summary>
93105
public void Dispose()
94106
{

0 commit comments

Comments
 (0)