Skip to content

Commit 00db538

Browse files
committed
refactor: 移动 Tab 右键菜单逻辑到内部
1 parent 3531e98 commit 00db538

File tree

7 files changed

+133
-55
lines changed

7 files changed

+133
-55
lines changed

src/BootstrapBlazor/Components/Layout/Layout.razor

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -116,31 +116,7 @@
116116
@<main class="layout-main">
117117
@if (UseTabSet)
118118
{
119-
@if (ShowTabContextMenu)
120-
{
121-
<ContextMenuZone>
122-
@RenderTab
123-
<ContextMenu>
124-
@if (BeforeTabContextMenuTemplate != null)
125-
{
126-
@BeforeTabContextMenuTemplate(_tab)
127-
}
128-
<ContextMenuItem Icon="@TabContextMenuRefreshIcon" Text="@Localizer["ContextRefresh"]" OnClick="OnRefrsh"></ContextMenuItem>
129-
<ContextMenuDivider></ContextMenuDivider>
130-
<ContextMenuItem Icon="@TabContextMenuCloseIcon" Text="@Localizer["ContextClose"]" OnClick="OnClose"></ContextMenuItem>
131-
<ContextMenuItem Icon="@TabContextMenuCloseOtherIcon" Text="@Localizer["ContextCloseOther"]" OnClick="OnCloseOther"></ContextMenuItem>
132-
<ContextMenuItem Icon="@TabContextMenuCloseAllIcon" Text="@Localizer["ContextCloseAll"]" OnClick="OnCloseAll"></ContextMenuItem>
133-
@if (TabContextMenuTemplate != null)
134-
{
135-
@TabContextMenuTemplate(_tab)
136-
}
137-
</ContextMenu>
138-
</ContextMenuZone>
139-
}
140-
else
141-
{
142-
@RenderTab
143-
}
119+
@RenderTab
144120
}
145121
else
146122
{
@@ -153,6 +129,9 @@
153129
ShowExtendButtons="ShowTabExtendButtons" ShowClose="ShowTabItemClose" AllowDrag="AllowDragTab"
154130
DefaultUrl="@TabDefaultUrl" ExcludeUrls="@ExcludeUrls" IsOnlyRenderActiveTab="IsOnlyRenderActiveTab"
155131
TabStyle="TabStyle" ShowToolbar="@ShowToolbar" ToolbarTemplate="@ToolbarTemplate"
132+
ShowContextMenu="ShowTabContextMenu"
133+
ContextMenuRefreshIcon="@TabContextMenuRefreshIcon" ContextMenuCloseIcon="@TabContextMenuCloseIcon"
134+
ContextMenuCloseOtherIcon="@TabContextMenuCloseOtherIcon" ContextMenuCloseAllIcon="@TabContextMenuCloseAllIcon"
156135
ShowRefreshToolbarButton="ShowRefreshToolbarButton" ShowFullscreenToolbarButton="ShowFullscreenToolbarButton"
157136
RefreshToolbarButtonIcon="@RefreshToolbarButtonIcon" FullscreenToolbarButtonIcon="@FullscreenToolbarButtonIcon"
158137
RefreshToolbarTooltipText="@RefreshToolbarTooltipText" FullscreenToolbarTooltipText="@FullscreenToolbarTooltipText"

src/BootstrapBlazor/Components/Layout/Layout.razor.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,6 @@ protected override void OnParametersSet()
509509

510510
TooltipText ??= Localizer[nameof(TooltipText)];
511511
MenuBarIcon ??= IconTheme.GetIconByKey(ComponentIcons.LayoutMenuBarIcon);
512-
TabContextMenuRefreshIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuRefreshIcon);
513-
TabContextMenuCloseIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseIcon);
514-
TabContextMenuCloseOtherIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseOtherIcon);
515-
TabContextMenuCloseAllIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseAllIcon);
516512
}
517513

518514
/// <summary>
@@ -627,7 +623,7 @@ public virtual Task HandlerException(Exception ex, RenderFragment<Exception> err
627623

628624
private string? GetTargetString() => IsFixedTabHeader ? ".tabs-body" : null;
629625

630-
private async Task OnRefrsh(ContextMenuItem item, object? context)
626+
private async Task OnRefresh(ContextMenuItem item, object? context)
631627
{
632628
if (context is TabItem tabItem)
633629
{

src/BootstrapBlazor/Components/Tab/Tab.razor

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,35 @@
66
{
77
@Body
88
}
9+
else if (ShowContextMenu)
10+
{
11+
<ContextMenuZone @ref="_contextMenuZone">
12+
@RenderTab
13+
<ContextMenu>
14+
@if (BeforeContextMenuTemplate != null)
15+
{
16+
@BeforeContextMenuTemplate(this)
17+
}
18+
<ContextMenuItem Icon="@ContextMenuRefreshIcon" Text="@Localizer["ContextRefresh"]" OnClick="OnRefresh"></ContextMenuItem>
19+
<ContextMenuDivider></ContextMenuDivider>
20+
<ContextMenuItem Icon="@ContextMenuCloseIcon" Text="@Localizer["ContextClose"]" OnClick="OnClose"></ContextMenuItem>
21+
<ContextMenuItem Icon="@ContextMenuCloseOtherIcon" Text="@Localizer["ContextCloseOther"]" OnClick="OnCloseOther"></ContextMenuItem>
22+
<ContextMenuItem Icon="@ContextMenuCloseAllIcon" Text="@Localizer["ContextCloseAll"]" OnClick="OnCloseAll"></ContextMenuItem>
23+
@if (ContextMenuTemplate != null)
24+
{
25+
@ContextMenuTemplate(this)
26+
}
27+
</ContextMenu>
28+
</ContextMenuZone>
29+
}
930
else
1031
{
11-
<div @attributes="@AdditionalAttributes" id="@Id" class="@ClassString" style="@StyleString">
32+
@RenderTab
33+
}
34+
35+
@code {
36+
RenderFragment RenderTab =>
37+
@<div @attributes="@AdditionalAttributes" id="@Id" class="@ClassString" style="@StyleString">
1238
<div class="tabs-header">
1339
<div class="@WrapClassString">
1440
@if (BeforeNavigatorTemplate != null)
@@ -155,10 +181,8 @@ else
155181
}
156182
</CascadingValue>
157183
</div>
158-
</div>
159-
}
160-
161-
@code {
184+
</div>;
185+
162186
RenderFragment<TabItem> RenderTabItem => item =>
163187
@<CascadingValue Value="item" IsFixed="true">
164188
@RenderTabItemContent(item)

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

Lines changed: 85 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,49 @@ public partial class Tab : IHandlerException
358358
/// </summary>
359359
[Parameter]
360360
public string? CloseTabNavLinkTooltipText { get; set; }
361+
362+
/// <summary>
363+
/// Gets or sets whether enable tab context menu. Default is false.
364+
/// </summary>
365+
[Parameter]
366+
public bool ShowContextMenu { get; set; }
367+
368+
/// <summary>
369+
/// Gets or sets the template of before context menu. Default is null.
370+
/// </summary>
371+
[Parameter]
372+
public RenderFragment<Tab>? BeforeContextMenuTemplate { get; set; }
373+
374+
/// <summary>
375+
/// Gets or sets the template of context menu. Default is null.
376+
/// </summary>
377+
[Parameter]
378+
public RenderFragment<Tab>? ContextMenuTemplate { get; set; }
379+
380+
/// <summary>
381+
/// Gets or sets the icon of tab item context menu refresh button. Default is null.
382+
/// </summary>
383+
[Parameter]
384+
public string? ContextMenuRefreshIcon { get; set; }
385+
386+
/// <summary>
387+
/// Gets or sets the icon of tab item context menu close button. Default is null.
388+
/// </summary>
389+
[Parameter]
390+
public string? ContextMenuCloseIcon { get; set; }
361391

392+
/// <summary>
393+
/// Gets or sets the icon of tab item context menu close other button. Default is null.
394+
/// </summary>
395+
[Parameter]
396+
public string? ContextMenuCloseOtherIcon { get; set; }
397+
398+
/// <summary>
399+
/// Gets or sets the icon of tab item context menu close all button. Default is null.
400+
/// </summary>
401+
[Parameter]
402+
public string? ContextMenuCloseAllIcon { get; set; }
403+
362404
[CascadingParameter]
363405
private Layout? Layout { get; set; }
364406

@@ -384,10 +426,9 @@ public partial class Tab : IHandlerException
384426

385427
[Inject, NotNull]
386428
private DialogService? DialogService { get; set; }
387-
388-
[CascadingParameter]
389-
private ContextMenuZone? ContextMenuZone { get; set; }
390-
429+
430+
private ContextMenuZone? _contextMenuZone;
431+
391432
private ConcurrentDictionary<TabItem, bool> LazyTabCache { get; } = new();
392433

393434
private bool HandlerNavigation { get; set; }
@@ -400,7 +441,7 @@ public partial class Tab : IHandlerException
400441

401442
private readonly ConcurrentDictionary<TabItem, TabItemContent> _cache = [];
402443

403-
private bool IsPreventDefault => ContextMenuZone != null;
444+
private bool IsPreventDefault => _contextMenuZone != null;
404445

405446
/// <summary>
406447
/// <inheritdoc/>
@@ -439,6 +480,11 @@ protected override void OnParametersSet()
439480
CloseIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabCloseIcon);
440481
RefreshToolbarButtonIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabRefreshButtonIcon);
441482

483+
ContextMenuRefreshIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuRefreshIcon);
484+
ContextMenuCloseIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseIcon);
485+
ContextMenuCloseOtherIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseOtherIcon);
486+
ContextMenuCloseAllIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabContextMenuCloseAllIcon);
487+
442488
if (AdditionalAssemblies is null)
443489
{
444490
var entryAssembly = Assembly.GetEntryAssembly();
@@ -989,6 +1035,38 @@ public async Task Refresh(TabItem item)
9891035
await OnToolbarRefreshCallback();
9901036
}
9911037
}
1038+
1039+
private async Task OnRefresh(ContextMenuItem item, object? context)
1040+
{
1041+
if (context is TabItem tabItem)
1042+
{
1043+
await Refresh(tabItem);
1044+
}
1045+
}
1046+
1047+
private async Task OnClose(ContextMenuItem item, object? context)
1048+
{
1049+
if (context is TabItem tabItem)
1050+
{
1051+
await RemoveTab(tabItem);
1052+
}
1053+
}
1054+
1055+
private Task OnCloseOther(ContextMenuItem item, object? context)
1056+
{
1057+
if (context is TabItem tabItem)
1058+
{
1059+
ActiveTab(tabItem);
1060+
}
1061+
CloseOtherTabs();
1062+
return Task.CompletedTask;
1063+
}
1064+
1065+
private Task OnCloseAll(ContextMenuItem item, object? context)
1066+
{
1067+
CloseAllTabs();
1068+
return Task.CompletedTask;
1069+
}
9921070

9931071
/// <summary>
9941072
/// <inheritdoc/>
@@ -1006,9 +1084,9 @@ protected override async ValueTask DisposeAsync(bool disposing)
10061084

10071085
private async Task OnContextMenu(MouseEventArgs e, TabItem item)
10081086
{
1009-
if (ContextMenuZone != null)
1087+
if (_contextMenuZone != null)
10101088
{
1011-
await ContextMenuZone.OnContextMenu(e, item);
1089+
await _contextMenuZone.OnContextMenu(e, item);
10121090
}
10131091
}
10141092
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,7 @@
700700
display: flex;
701701
align-items: center;
702702
border-radius: var(--bs-border-radius);
703+
user-select: none;
703704

704705
&:not(.disabled):not(:disabled):hover {
705706
background-color: var(--bb-tabs-item-hover-bg-color);

src/BootstrapBlazor/Locales/en.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,7 @@
105105
"TooltipText": "Go top"
106106
},
107107
"BootstrapBlazor.Components.Layout": {
108-
"TooltipText": "Click to Expand/Collapse sidebar",
109-
"ContextRefresh": "Refresh",
110-
"ContextClose": "Close",
111-
"ContextCloseOther": "Close Other Tabs",
112-
"ContextCloseAll": "Close All Tabs"
108+
"TooltipText": "Click to Expand/Collapse sidebar"
113109
},
114110
"BootstrapBlazor.Components.Logout": {
115111
"PrefixDisplayNameText": "Welcome",
@@ -119,7 +115,7 @@
119115
"Text": "Logout"
120116
},
121117
"BootstrapBlazor.Components.Menu": {
122-
"InvalidOperationExceptionMessage": "Sidemenu component cannot be used independently. Please use Menu component to set IsVertical = true"
118+
"InvalidOperationExceptionMessage": "SideMenu component cannot be used independently. Please use Menu component to set IsVertical = true"
123119
},
124120
"BootstrapBlazor.Components.ModalDialog": {
125121
"CloseButtonText": "Close",
@@ -182,7 +178,11 @@
182178
"FullscreenToolbarTooltipText": "Fullscreen",
183179
"PrevTabNavLinkTooltipText": "Prev Tab",
184180
"NextTabNavLinkTooltipText": "Next Tab",
185-
"CloseTabNavLinkTooltipText": "Close"
181+
"CloseTabNavLinkTooltipText": "Close",
182+
"ContextRefresh": "Refresh",
183+
"ContextClose": "Close",
184+
"ContextCloseOther": "Close Other Tabs",
185+
"ContextCloseAll": "Close All Tabs"
186186
},
187187
"BootstrapBlazor.Components.MultiFilter": {
188188
"MultiFilterSearchPlaceHolderText": "Please enter ...",

src/BootstrapBlazor/Locales/zh.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,7 @@
105105
"TooltipText": "返回顶端"
106106
},
107107
"BootstrapBlazor.Components.Layout": {
108-
"TooltipText": "点击展开收缩左侧菜单",
109-
"ContextRefresh": "刷新",
110-
"ContextClose": "关闭",
111-
"ContextCloseOther": "关闭其他",
112-
"ContextCloseAll": "关闭全部"
108+
"TooltipText": "点击展开收缩左侧菜单"
113109
},
114110
"BootstrapBlazor.Components.Logout": {
115111
"PrefixDisplayNameText": "欢迎",
@@ -182,7 +178,11 @@
182178
"FullscreenToolbarTooltipText": "全屏",
183179
"PrevTabNavLinkTooltipText": "上一个标签",
184180
"NextTabNavLinkTooltipText": "下一个标签",
185-
"CloseTabNavLinkTooltipText": "关闭"
181+
"CloseTabNavLinkTooltipText": "关闭",
182+
"ContextRefresh": "刷新",
183+
"ContextClose": "关闭",
184+
"ContextCloseOther": "关闭其他",
185+
"ContextCloseAll": "关闭全部"
186186
},
187187
"BootstrapBlazor.Components.MultiFilter": {
188188
"MultiFilterSearchPlaceHolderText": "请输入 ...",

0 commit comments

Comments
 (0)