diff --git a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
index cf06face498..26b4e5d6068 100644
--- a/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
+++ b/src/BootstrapBlazor.Server/BootstrapBlazor.Server.csproj
@@ -62,7 +62,7 @@
-
+
diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor
index fd3fb2ca47d..6d8015f47d7 100644
--- a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor
+++ b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor
@@ -437,7 +437,7 @@ private void Navigation()
-
+
@Localizer["TabItem1Content"]
@@ -514,11 +514,11 @@ private void Navigation()
-
+
-
-
-
+
+
+
diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json
index 024244ffdbe..ffc0befac1c 100644
--- a/src/BootstrapBlazor.Server/Locales/en-US.json
+++ b/src/BootstrapBlazor.Server/Locales/en-US.json
@@ -5033,7 +5033,7 @@
"ShowUnsetGroupItemsOnTopAttr": "Whether ungrouped edits are rendered at the beginning",
"ShowSkeletonAttr": "Whether to display skeleton screen when first render",
"ShowLoadingInFirstRenderAttr": "Whether to display the loading animation when first render",
- "ShowColumnListAttr": "Show columnshow/hide control buttons",
+ "ShowColumnListAttr": "Show Column show/hide control buttons",
"OnColumnVisibleChangedAttr": "Trigger this callback when switch show/hide column in the list",
"ShowEmptyAttr": "Show no data prompts",
"ShowToastAfterSaveOrDeleteModelAttr": "Do you show a toast prompt box after a save/delete failure",
diff --git a/src/BootstrapBlazor/Components/Tab/Tab.razor b/src/BootstrapBlazor/Components/Tab/Tab.razor
index 8a67edeae58..e1fafcdbe15 100644
--- a/src/BootstrapBlazor/Components/Tab/Tab.razor
+++ b/src/BootstrapBlazor/Components/Tab/Tab.razor
@@ -19,7 +19,13 @@ else
}
@if (ShowNavigatorButtons)
{
-
+
}
- @if (ButtonTemplate != null)
- {
-
+
+ @if (ButtonTemplate != null)
+ {
@ButtonTemplate
-
- }
- @if (ShowToolbar)
- {
-
+ }
+ @if (ShowNavigatorButtons)
+ {
+
+ }
+ @if (ShouldShowExtendButtons())
+ {
+
+
+
@CloseCurrentTabText
+
@CloseOtherTabsText
+
@CloseAllTabsText
+
+ }
+ @if (AfterNavigatorTemplate != null)
+ {
+ @AfterNavigatorTemplate
+ }
+
diff --git a/src/BootstrapBlazor/Components/Tab/Tab.razor.cs b/src/BootstrapBlazor/Components/Tab/Tab.razor.cs
index 4c50e196e96..8e9443e82d8 100644
--- a/src/BootstrapBlazor/Components/Tab/Tab.razor.cs
+++ b/src/BootstrapBlazor/Components/Tab/Tab.razor.cs
@@ -167,7 +167,6 @@ public partial class Tab : IHandlerException
/// 获得/设置 NotFound 标签文本 默认 null NET6.0/7.0 有效
///
[Parameter]
- [NotNull]
public string? NotFoundTabText { get; set; }
///
@@ -205,21 +204,18 @@ public partial class Tab : IHandlerException
/// 获得/设置 关闭当前 TabItem 菜单文本
///
[Parameter]
- [NotNull]
public string? CloseCurrentTabText { get; set; }
///
/// 获得/设置 关闭所有 TabItem 菜单文本
///
[Parameter]
- [NotNull]
public string? CloseAllTabsText { get; set; }
///
/// 获得/设置 关闭其他 TabItem 菜单文本
///
[Parameter]
- [NotNull]
public string? CloseOtherTabsText { get; set; }
///
@@ -345,6 +341,24 @@ public partial class Tab : IHandlerException
[Parameter]
public Func? OnToolbarRefreshCallback { get; set; }
+ ///
+ /// Gets or sets the previous tab navigation link tooltip text. Default is null.
+ ///
+ [Parameter]
+ public string? PrevTabNavLinkTooltipText { get; set; }
+
+ ///
+ /// Gets or sets the next tab navigation link tooltip text. Default is null.
+ ///
+ [Parameter]
+ public string? NextTabNavLinkTooltipText { get; set; }
+
+ ///
+ /// Gets or sets the close tab navigation link tooltip text. Default is null.
+ ///
+ [Parameter]
+ public string? CloseTabNavLinkTooltipText { get; set; }
+
[CascadingParameter]
private Layout? Layout { get; set; }
@@ -415,6 +429,9 @@ protected override void OnParametersSet()
NotFoundTabText ??= Localizer[nameof(NotFoundTabText)];
RefreshToolbarTooltipText ??= Localizer[nameof(RefreshToolbarTooltipText)];
FullscreenToolbarTooltipText ??= Localizer[nameof(FullscreenToolbarTooltipText)];
+ PrevTabNavLinkTooltipText ??= Localizer[nameof(PrevTabNavLinkTooltipText)];
+ NextTabNavLinkTooltipText ??= Localizer[nameof(NextTabNavLinkTooltipText)];
+ CloseTabNavLinkTooltipText ??= Localizer[nameof(CloseTabNavLinkTooltipText)];
PreviousIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabPreviousIcon);
NextIcon ??= IconTheme.GetIconByKey(ComponentIcons.TabNextIcon);
diff --git a/src/BootstrapBlazor/Components/Tab/Tab.razor.scss b/src/BootstrapBlazor/Components/Tab/Tab.razor.scss
index 167bbcfc76b..1c13fa19e36 100644
--- a/src/BootstrapBlazor/Components/Tab/Tab.razor.scss
+++ b/src/BootstrapBlazor/Components/Tab/Tab.razor.scss
@@ -548,9 +548,34 @@
.tab-drag-over .tabs-item .tabs-item-body {
animation: drag-tab-item 1s linear infinite;
}
+
+ .nav-link-bar {
+ padding: 3px 0.5rem;
+
+ .nav-link-bar-button {
+ cursor: pointer;
+ padding: 0 .75rem;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ border-radius: var(--bs-border-radius);
+
+ &:hover {
+ background-color: var(--bb-tabs-item-hover-bg-color);
+ }
+ }
+
+ > [data-bs-toggle="tooltip"] {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ }
+ }
}
.tabs-chrome > .tabs-header {
+ padding: 0 .25rem;
+
.tabs-item-wrap {
overflow: hidden;
position: relative;
diff --git a/src/BootstrapBlazor/Locales/en.json b/src/BootstrapBlazor/Locales/en.json
index e0687cd1daa..606054d4f5e 100644
--- a/src/BootstrapBlazor/Locales/en.json
+++ b/src/BootstrapBlazor/Locales/en.json
@@ -175,7 +175,10 @@
"CloseAllTabsText": "Close All",
"NotFoundTabText": "NotFound",
"RefreshToolbarTooltipText": "Refresh",
- "FullscreenToolbarTooltipText": "Fullscreen"
+ "FullscreenToolbarTooltipText": "Fullscreen",
+ "PrevTabNavLinkTooltipText": "Prev Tab",
+ "NextTabNavLinkTooltipText": "Next Tab",
+ "CloseTabNavLinkTooltipText": "Close"
},
"BootstrapBlazor.Components.MultiFilter": {
"MultiFilterSearchPlaceHolderText": "Please enter ...",
diff --git a/src/BootstrapBlazor/Locales/zh.json b/src/BootstrapBlazor/Locales/zh.json
index 4ef25b24f36..d934483d50c 100644
--- a/src/BootstrapBlazor/Locales/zh.json
+++ b/src/BootstrapBlazor/Locales/zh.json
@@ -175,7 +175,10 @@
"CloseAllTabsText": "关闭所有标签",
"NotFoundTabText": "未找到",
"RefreshToolbarTooltipText": "刷新",
- "FullscreenToolbarTooltipText": "全屏"
+ "FullscreenToolbarTooltipText": "全屏",
+ "PrevTabNavLinkTooltipText": "上一个标签",
+ "NextTabNavLinkTooltipText": "下一个标签",
+ "CloseTabNavLinkTooltipText": "关闭"
},
"BootstrapBlazor.Components.MultiFilter": {
"MultiFilterSearchPlaceHolderText": "请输入 ...",
diff --git a/test/UnitTest/Components/TabTest.cs b/test/UnitTest/Components/TabTest.cs
index 48c013f74f4..b78809bb9ed 100644
--- a/test/UnitTest/Components/TabTest.cs
+++ b/test/UnitTest/Components/TabTest.cs
@@ -226,14 +226,14 @@ public void ClickTab_Ok()
Assert.True(clicked);
// Click Prev
- var button = cut.Find(".nav-link-bar.left");
+ var button = cut.Find(".nav-link-bar.left .nav-link-bar-button");
button.Click();
button.Click();
button.Click();
Assert.Equal("Tab1-Content", cut.Find(".tabs-body .d-none").InnerHtml);
// Click Next
- button = cut.Find(".nav-link-bar.right");
+ button = cut.Find(".nav-link-bar.right .nav-link-bar-button");
button.Click();
button.Click();
button.Click();
@@ -284,11 +284,11 @@ public void ClickTabToNavigation_True()
cut.InvokeAsync(() => cut.Instance.AddTab("/Cat", null!));
// Click Prev
- var button = cut.Find(".nav-link-bar.left");
+ var button = cut.Find(".nav-link-bar.left .nav-link-bar-button");
button.Click();
// Click Next
- button = cut.Find(".nav-link-bar.right");
+ button = cut.Find(".nav-link-bar.right .nav-link-bar-button");
button.Click();
button = cut.Find(".tabs-item-close");