Skip to content

Commit e1c5b40

Browse files
committed
feat: 增加 IsChromeStyle 参数
1 parent ab74cb4 commit e1c5b40

File tree

3 files changed

+174
-25
lines changed

3 files changed

+174
-25
lines changed

src/BootstrapBlazor/Components/Tab/Tab.razor

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,39 +45,17 @@ else
4545
}
4646
@foreach (var item in Items)
4747
{
48-
if (item.HeaderTemplate != null)
48+
@if (item.HeaderTemplate != null)
4949
{
5050
@item.HeaderTemplate(item)
5151
}
5252
else if (item.IsDisabled)
5353
{
54-
<div role="tab" class="@GetClassString(item)">
55-
@if (!string.IsNullOrEmpty(item.Icon))
56-
{
57-
<i class="@GetIconClassString(item.Icon)"></i>
58-
}
59-
<span class="tabs-item-text">@item.Text</span>
60-
</div>
54+
@RenderDisabledHeaderByStyle(item)
6155
}
6256
else
6357
{
64-
<a @key="item" href="@item.Url" role="tab" tabindex="-1" class="@GetClassString(item)" @onclick="@(() => OnClickTabItem(item))" @onclick:preventDefault="@(!ClickTabToNavigation)" draggable="@DraggableString">
65-
@if (!string.IsNullOrEmpty(item.Icon))
66-
{
67-
<i class="@GetIconClassString(item.Icon)"></i>
68-
}
69-
<span class="tabs-item-text">@item.Text</span>
70-
@if (ShowFullScreen && item.ShowFullScreen)
71-
{
72-
<FullScreenButton TargetId="@GetIdByTabItem(item)"></FullScreenButton>
73-
}
74-
@if (ShowClose && item.Closable)
75-
{
76-
<span class="tabs-item-close" @onclick:stopPropagation @onclick:preventDefault @onclick="() => RemoveTab(item)">
77-
<i class="@CloseIcon"></i>
78-
</span>
79-
}
80-
</a>
58+
@RenderHeaderByStyle(item)
8159
}
8260
}
8361
@if (IsCard || IsBorderCard)
@@ -145,4 +123,59 @@ else
145123
@<CascadingValue Value="item" IsFixed="true">
146124
@RenderTabItemContent(item)
147125
</CascadingValue>;
126+
127+
RenderFragment RenderChromeDisabledHeader(TabItem item) =>
128+
@<div @key="@item" class="@GetItemWrapClassString(item)">
129+
<div role="tab" class="@GetClassString(item)">
130+
@if (!string.IsNullOrEmpty(item.Icon))
131+
{
132+
<i class="@GetIconClassString(item.Icon)"></i>
133+
}
134+
<span class="tabs-item-text">@item.Text</span>
135+
</div>
136+
<i class="tab-corner tab-corner-left"></i>
137+
<i class="tab-corner tab-corner-right"></i>
138+
</div>;
139+
140+
RenderFragment RenderDefaultDisabledHeader(TabItem item) =>
141+
@<div @key="item" role="tab" class="@GetClassString(item)">
142+
@if (!string.IsNullOrEmpty(item.Icon))
143+
{
144+
<i class="@GetIconClassString(item.Icon)"></i>
145+
}
146+
<span class="tabs-item-text">@item.Text</span>
147+
</div>;
148+
149+
RenderFragment RenderChromeHeader(TabItem item) =>
150+
@<div @key="@item" class="@GetItemWrapClassString(item)">
151+
<a href="@item.Url" role="tab" tabindex="-1" class="@GetClassString(item)" @onclick="@(() => OnClickTabItem(item))" @onclick:preventDefault="@(!ClickTabToNavigation)" draggable="@DraggableString">
152+
@RenderHeaderContent(item)
153+
</a>
154+
<i class="tab-corner tab-corner-left"></i>
155+
<i class="tab-corner tab-corner-right"></i>
156+
</div>;
157+
158+
RenderFragment RenderDefaultHeader(TabItem item) =>
159+
@<a @key="item" href="@item.Url" role="tab" tabindex="-1" class="@GetClassString(item)" @onclick="@(() => OnClickTabItem(item))" @onclick:preventDefault="@(!ClickTabToNavigation)" draggable="@DraggableString">
160+
@RenderHeaderContent(item)
161+
</a>;
162+
163+
RenderFragment RenderHeaderContent(TabItem item) =>
164+
@<div class="tabs-item-body">
165+
@if (!string.IsNullOrEmpty(item.Icon))
166+
{
167+
<i class="@GetIconClassString(item.Icon)"></i>
168+
}
169+
<span class="tabs-item-text">@item.Text</span>
170+
@if (ShowFullScreen && item.ShowFullScreen)
171+
{
172+
<FullScreenButton TargetId="@GetIdByTabItem(item)"></FullScreenButton>
173+
}
174+
@if (ShowClose && item.Closable)
175+
{
176+
<span class="tabs-item-close" @onclick:stopPropagation @onclick:preventDefault @onclick="() => RemoveTab(item)">
177+
<i class="@CloseIcon"></i>
178+
</span>
179+
}
180+
</div>;
148181
}

src/BootstrapBlazor/Components/Tab/Tab.razor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ public partial class Tab : IHandlerException
2424
.AddClass("extend", ShouldShowExtendButtons())
2525
.Build();
2626

27+
private string? GetItemWrapClassString(TabItem item) => CssBuilder.Default("tabs-item-wrap")
28+
.AddClass("active", item.IsActive)
29+
.Build();
30+
2731
private string? GetClassString(TabItem item) => CssBuilder.Default("tabs-item")
2832
.AddClass("active", item.IsActive)
2933
.AddClass("disabled", item.IsDisabled)
@@ -283,6 +287,12 @@ public partial class Tab : IHandlerException
283287
[Parameter]
284288
public Func<TabItem, Task>? OnDragItemEndAsync { get; set; }
285289

290+
/// <summary>
291+
/// Gets or sets Whether the tab style is Chrome. Default is false.
292+
/// </summary>
293+
[Parameter]
294+
public bool IsChromeStyle { get; set; }
295+
286296
[CascadingParameter]
287297
private Layout? Layout { get; set; }
288298

@@ -854,6 +864,10 @@ public async Task DragItemCallback(int originIndex, int currentIndex)
854864

855865
private string? GetIdByTabItem(TabItem item) => (ShowFullScreen && item.ShowFullScreen) ? ComponentIdGenerator.Generate(item) : null;
856866

867+
private RenderFragment RenderDisabledHeaderByStyle(TabItem item) => IsChromeStyle ? RenderChromeDisabledHeader(item) : RenderDefaultDisabledHeader(item);
868+
869+
private RenderFragment RenderHeaderByStyle(TabItem item) => IsChromeStyle ? RenderChromeHeader(item) : RenderDefaultHeader(item);
870+
857871
/// <summary>
858872
/// <inheritdoc/>
859873
/// </summary>

src/BootstrapBlazor/Components/Tab/Tab.razor.scss

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,3 +487,105 @@
487487
background-color: var(--bs-primary);
488488
}
489489
}
490+
491+
.tabs-item-wrap {
492+
--bb-tabs-header-bg-color: var(--bs-border-color);
493+
--bb-tabs-item-hover-bg-color: #b1cbe6;
494+
--bb-tabs-item-active-bg-color: var(--bs-body-color);
495+
--bb-tabs-item-active-color: var(--bs-body-color);
496+
--bb-tabs-item-hover-color: var(--bs-body-color);
497+
overflow: hidden;
498+
position: relative;
499+
background-color: var(--bb-tabs-header-bg-color);
500+
display: flex;
501+
align-items: flex-end;
502+
padding: 0 1rem;
503+
z-index: 1;
504+
505+
.tab-corner {
506+
height: 2rem;
507+
width: 2rem;
508+
display: inline-flex;
509+
justify-content: center;
510+
align-items: center;
511+
position: absolute;
512+
background-color: var(--bb-tabs-header-bg-color);
513+
514+
&::after {
515+
content: '';
516+
position: absolute;
517+
height: 100%;
518+
width: 100%;
519+
background-color: var(--bb-tabs-header-bg-color);
520+
}
521+
}
522+
523+
.tab-corner-left {
524+
bottom: 0;
525+
left: -1rem;
526+
527+
&::after {
528+
border-bottom-right-radius: 50%;
529+
}
530+
}
531+
532+
.tab-corner-right {
533+
bottom: 0;
534+
right: -1rem;
535+
536+
&::after {
537+
border-bottom-left-radius: 50%;
538+
}
539+
}
540+
541+
.tabs-item {
542+
background-color: var(--bb-tabs-header-bg-color);
543+
border: none !important;
544+
border-top-left-radius: 10px;
545+
border-top-right-radius: 10px;
546+
height: 36px !important;
547+
548+
.active {
549+
background-color: var(--bb-tabs-item-active-bg-color);
550+
}
551+
552+
.tabs-item-body {
553+
padding: 4px 10px;
554+
display: flex;
555+
align-items: center;
556+
flex-wrap: nowrap;
557+
margin-bottom: 4px;
558+
559+
.tabs-item-text {
560+
padding: 0 .25rem;
561+
}
562+
563+
.tabs-item-close {
564+
display: block;
565+
position: unset;
566+
width: 1em;
567+
}
568+
}
569+
}
570+
571+
&:not(.active) {
572+
.tabs-item .tabs-item-body {
573+
&:hover {
574+
border-radius: 20px;
575+
background-color: var(--bb-tabs-item-hover-bg-color);
576+
}
577+
}
578+
}
579+
580+
&:not(:first-child) {
581+
margin-left: -2rem;
582+
}
583+
584+
&.active {
585+
z-index: 5;
586+
587+
.tab-corner {
588+
background-color: var(--bs-body-bg);
589+
}
590+
}
591+
}

0 commit comments

Comments
 (0)