diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor index 9076971d8ed..94b5c192492 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor +++ b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor @@ -423,21 +423,7 @@ private void Navigation() - - -
@Localizer["TabItem1Content"]
-
- -
@Localizer["TabItem2Content"]
-
- -
@Localizer["TabItem3Content"]
-
-
-
- - - +
@Localizer["TabItem1Content"]
@@ -485,6 +471,28 @@ private void Navigation()
+ + + + +
@Localizer["TabItem1Content"]
+
+ +
@Localizer["TabItem2Content"]
+
+ +
@Localizer["TabItem3Content"]
+
+ +
@Localizer["TabItem4Content"]
+
+
+ + + +
+
+ diff --git a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor.cs b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor.cs index f2931ce1af5..c4288da0bd9 100644 --- a/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor.cs +++ b/src/BootstrapBlazor.Server/Components/Samples/Tabs.razor.cs @@ -384,6 +384,70 @@ private AttributeItem[] GetAttributes() => Type = "RenderFragment", ValueList = " — ", DefaultValue = " — " + }, + new() + { + Name = nameof(Tab.ShowToolbar), + Description = Localizer["AttributeShowToolbar"].Value, + Type = "bool", + ValueList = "true|false", + DefaultValue = "false" + }, + new() + { + Name = nameof(Tab.ToolbarTemplate), + Description = Localizer["AttributeToolbarTemplate"].Value, + Type = "RenderFragment", + ValueList = " — ", + DefaultValue = " — " + }, + new() + { + Name = nameof(Tab.ShowRefreshToolbarButton), + Description = Localizer["AttributeShowRefreshToolbarButton"].Value, + Type = "bool", + ValueList = "true|false", + DefaultValue = "true" + }, + new() + { + Name = nameof(Tab.ShowFullscreenToolbarButton), + Description = Localizer["AttributeShowFullscreenToolbarButton"].Value, + Type = "bool", + ValueList = "true|false", + DefaultValue = "true" + }, + new() + { + Name = nameof(Tab.RefreshToolbarTooltipText), + Description = Localizer["AttributeRefreshToolbarTooltipText"].Value, + Type = "string?", + ValueList = " — ", + DefaultValue = " — " + }, + new() + { + Name = nameof(Tab.FullscreenToolbarTooltipText), + Description = Localizer["AttributeFullscreenToolbarTooltipText"].Value, + Type = "string?", + ValueList = " — ", + DefaultValue = " — " + }, + new() + { + Name = nameof(Tab.RefreshToolbarButtonIcon), + Description = Localizer["AttributeRefreshToolbarButtonIcon"].Value, + Type = "string?", + ValueList = " — ", + DefaultValue = " — " + }, + new() + { + Name = nameof(Tab.FullscreenToolbarButtonIcon), + Description = Localizer["AttributeFullscreenToolbarButtonIcon"].Value, + Type = "string?", + ValueList = " — ", + DefaultValue = " — " } ]; diff --git a/src/BootstrapBlazor.Server/Locales/en-US.json b/src/BootstrapBlazor.Server/Locales/en-US.json index 3685dbb0d70..f49c380c855 100644 --- a/src/BootstrapBlazor.Server/Locales/en-US.json +++ b/src/BootstrapBlazor.Server/Locales/en-US.json @@ -2120,7 +2120,17 @@ "TabsChromeStyleIntro": "Set the Chrome browser tab style by setting TabStyle=\"TabStyle.Chrome\". Currently only supports Placement=\"Placement.Top\" mode", "TabAtt2TabStyle": "Set the tab style", "TabsCapsuleStyleTitle": "Capsule Style", - "TabsCapsuleStyleIntro": "Set the capsule tab style by setting TabStyle=\"TabStyle.Capsule\". Currently only supports Placement=\"Placement.Top\" Placement=\"Placement.Bottom\" mode" + "TabsCapsuleStyleIntro": "Set the capsule tab style by setting TabStyle=\"TabStyle.Capsule\". Currently only supports Placement=\"Placement.Top\" Placement=\"Placement.Bottom\" mode", + "AttributeToolbarTemplate": "The template for Toolbar", + "TabsToolbarTitle": "Toolbar", + "TabsToolbarIntro": "By setting ShowToolbar, you can display the tab toolbar. By default, the Refresh and Fullscreen buttons are displayed. You can control whether to display them by ShowRefreshToolbarButton and ShowFullscreenToolbarButton", + "AttributeShowToolbar": "Whether to display the toolbar", + "AttributeShowRefreshToolbarButton": "Whether to display the toolbar refresh button", + "AttributeShowFullscreenToolbarButton": "Whether to display the toolbar full screen button", + "AttributeRefreshToolbarTooltipText": "Toolbar refresh button tooltip text", + "AttributeFullscreenToolbarTooltipText": "Toolbar full screen button tooltip text", + "AttributeRefreshToolbarButtonIcon": "Toolbar refresh button icon", + "AttributeFullscreenToolbarButtonIcon": "Toolbar full screen button icon" }, "BootstrapBlazor.Server.Components.Components.DemoTabItem": { "Info": "Reset the title of this TabItem by click the button", diff --git a/src/BootstrapBlazor.Server/Locales/zh-CN.json b/src/BootstrapBlazor.Server/Locales/zh-CN.json index 606db14d02e..2455cc8c013 100644 --- a/src/BootstrapBlazor.Server/Locales/zh-CN.json +++ b/src/BootstrapBlazor.Server/Locales/zh-CN.json @@ -2120,7 +2120,17 @@ "TabsChromeStyleIntro": "通过设置 TabStyle=\"TabStyle.Chrome\" 设置 Chrome 浏览器标签页样式,目前仅支持 Placement=\"Placement.Top\" 模式", "TabAtt2TabStyle": "设置标签页样式", "TabsCapsuleStyleTitle": "胶囊样式", - "TabsCapsuleStyleIntro": "通过设置 TabStyle=\"TabStyle.Capsule\" 设置标签页为胶囊样式,目前仅支持 Placement=\"Placement.Top\" Placement=\"Placement.Bottom\" 模式" + "TabsCapsuleStyleIntro": "通过设置 TabStyle=\"TabStyle.Capsule\" 设置标签页为胶囊样式,目前仅支持 Placement=\"Placement.Top\" Placement=\"Placement.Bottom\" 模式", + "AttributeToolbarTemplate": "Toolbar 模板", + "TabsToolbarTitle": "工具栏", + "TabsToolbarIntro": "通过设置 ShowToolbar 显示标签页工具栏,默认显示 刷新 全屏 按钮,可以通过 ShowRefreshToolbarButton ShowFullscreenToolbarButton 控制是否显示", + "AttributeShowToolbar": "是否显示工具栏", + "AttributeShowRefreshToolbarButton": "是否显示工具栏刷新按钮", + "AttributeShowFullscreenToolbarButton": "是否显示工具栏全屏按钮", + "AttributeRefreshToolbarTooltipText": "工具栏刷新按钮提示框文字", + "AttributeFullscreenToolbarTooltipText": "工具栏全屏按钮提示框文字", + "AttributeRefreshToolbarButtonIcon": "工具栏刷新按钮图标", + "AttributeFullscreenToolbarButtonIcon": "工具栏全屏按钮图标" }, "BootstrapBlazor.Server.Components.Components.DemoTabItem": { "Info": "点击下方按钮,本 TabItem 标题更改为当前分钟与秒", diff --git a/src/BootstrapBlazor/Components/FullScreen/FullScreenButton.razor b/src/BootstrapBlazor/Components/FullScreen/FullScreenButton.razor index e9f3bb75f48..dc76311ea88 100644 --- a/src/BootstrapBlazor/Components/FullScreen/FullScreenButton.razor +++ b/src/BootstrapBlazor/Components/FullScreen/FullScreenButton.razor @@ -1,7 +1,7 @@ @namespace BootstrapBlazor.Components @inherits ButtonBase - + @if (!string.IsNullOrEmpty(Text)) diff --git a/src/BootstrapBlazor/Components/Tab/Tab.razor b/src/BootstrapBlazor/Components/Tab/Tab.razor index c5ddbba0d20..ea014eceee2 100644 --- a/src/BootstrapBlazor/Components/Tab/Tab.razor +++ b/src/BootstrapBlazor/Components/Tab/Tab.razor @@ -13,7 +13,9 @@ else
@if (BeforeNavigatorTemplate != null) { - @BeforeNavigatorTemplate + + @BeforeNavigatorTemplate + } @if (ShowNavigatorButtons) { @@ -71,23 +73,34 @@ else
@if (ButtonTemplate != null) { - @ButtonTemplate + + @ButtonTemplate + } @if (ShowToolbar) {
@if (ShowRefreshToolbarButton) { -
- -
+ } @if (ShowFullscreenToolbarButton) {
- +
} + @if (ToolbarTemplate != null) + { + + @ToolbarTemplate + + }
} @if (ShowNavigatorButtons) diff --git a/src/BootstrapBlazor/Components/Tab/Tab.razor.cs b/src/BootstrapBlazor/Components/Tab/Tab.razor.cs index 187adc45325..09528ad0228 100644 --- a/src/BootstrapBlazor/Components/Tab/Tab.razor.cs +++ b/src/BootstrapBlazor/Components/Tab/Tab.razor.cs @@ -227,6 +227,12 @@ public partial class Tab : IHandlerException [Parameter] public RenderFragment? ButtonTemplate { get; set; } + /// + /// Gets or sets the template of the toolbar button. Default is null. + /// + [Parameter] + public RenderFragment? ToolbarTemplate { get; set; } + /// /// 获得/设置 标签页前置模板 默认 null /// 在向前移动标签页按钮前 @@ -302,6 +308,18 @@ public partial class Tab : IHandlerException [Parameter] public bool ShowFullscreenToolbarButton { get; set; } = true; + /// + /// Gets or sets the full screen toolbar button icon string. Default is null. + /// + [Parameter] + public string? FullscreenToolbarButtonIcon { get; set; } + + /// + /// Gets or sets the full screen toolbar button tooltip string. Default is null. + /// + [Parameter] + public string? FullscreenToolbarTooltipText { get; set; } + /// /// Gets or sets whether show the full screen button. Default is true. /// @@ -314,6 +332,12 @@ public partial class Tab : IHandlerException [Parameter] public string? RefreshToolbarButtonIcon { get; set; } + /// + /// Gets or sets the refresh toolbar button tooltip string. Default is null. + /// + [Parameter] + public string? RefreshToolbarTooltipText { get; set; } + [CascadingParameter] private Layout? Layout { get; set; } @@ -377,6 +401,8 @@ protected override void OnParametersSet() CloseAllTabsText ??= Localizer[nameof(CloseAllTabsText)]; CloseCurrentTabText ??= Localizer[nameof(CloseCurrentTabText)]; NotFoundTabText ??= Localizer[nameof(NotFoundTabText)]; + RefreshToolbarTooltipText ??= Localizer[nameof(RefreshToolbarTooltipText)]; + FullscreenToolbarTooltipText ??= Localizer[nameof(FullscreenToolbarTooltipText)]; 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 82fa992a942..acbe3ee6af8 100644 --- a/src/BootstrapBlazor/Components/Tab/Tab.razor.scss +++ b/src/BootstrapBlazor/Components/Tab/Tab.razor.scss @@ -671,6 +671,12 @@ height: 100%; padding: 3px 0.5rem; + > [data-bs-toggle="tooltip"] { + height: 100%; + display: flex; + align-items: center; + } + .tabs-nav-toolbar-button { cursor: pointer; padding: 0 .75rem; diff --git a/src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor b/src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor new file mode 100644 index 00000000000..6ba72420030 --- /dev/null +++ b/src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor @@ -0,0 +1,8 @@ +@namespace BootstrapBlazor.Components +@inherits BootstrapModuleComponentBase + + +
+ +
+
diff --git a/src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor.cs b/src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor.cs similarity index 68% rename from src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor.cs rename to src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor.cs index a77d56e80e1..47d1e089b73 100644 --- a/src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor.cs +++ b/src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor.cs @@ -6,9 +6,9 @@ namespace BootstrapBlazor.Components; /// -/// TabToolbarRefreshButton component +/// TabToolbarButton component /// -public partial class TabToolbarRefreshButton +public partial class TabToolbarButton { /// /// Gets or sets the button icon string. Default is null. @@ -22,6 +22,16 @@ public partial class TabToolbarRefreshButton [Parameter] public Func? OnClickAsync { get; set; } + /// + /// Gets or sets the tooltip text. Default is null. + /// + [Parameter] + public string? TooltipText { get; set; } + + private string? ClassString => CssBuilder.Default("tabs-nav-toolbar-button") + .AddClassFromAttributes(AdditionalAttributes) + .Build(); + private async Task OnClick() { if (OnClickAsync != null) diff --git a/src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor b/src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor deleted file mode 100644 index 69e9e9577d9..00000000000 --- a/src/BootstrapBlazor/Components/Tab/TabToolbarRefreshButton.razor +++ /dev/null @@ -1,3 +0,0 @@ -@namespace BootstrapBlazor.Components - - diff --git a/src/BootstrapBlazor/Locales/en.json b/src/BootstrapBlazor/Locales/en.json index 7166f59fed2..e0687cd1daa 100644 --- a/src/BootstrapBlazor/Locales/en.json +++ b/src/BootstrapBlazor/Locales/en.json @@ -173,7 +173,9 @@ "CloseCurrentTabText": "Close", "CloseOtherTabsText": "Close Other", "CloseAllTabsText": "Close All", - "NotFoundTabText": "NotFound" + "NotFoundTabText": "NotFound", + "RefreshToolbarTooltipText": "Refresh", + "FullscreenToolbarTooltipText": "Fullscreen" }, "BootstrapBlazor.Components.MultiFilter": { "MultiFilterSearchPlaceHolderText": "Please enter ...", diff --git a/src/BootstrapBlazor/Locales/zh.json b/src/BootstrapBlazor/Locales/zh.json index ecc46d43db4..4ef25b24f36 100644 --- a/src/BootstrapBlazor/Locales/zh.json +++ b/src/BootstrapBlazor/Locales/zh.json @@ -173,7 +173,9 @@ "CloseCurrentTabText": "关闭当前标签", "CloseOtherTabsText": "关闭其他标签", "CloseAllTabsText": "关闭所有标签", - "NotFoundTabText": "未找到" + "NotFoundTabText": "未找到", + "RefreshToolbarTooltipText": "刷新", + "FullscreenToolbarTooltipText": "全屏" }, "BootstrapBlazor.Components.MultiFilter": { "MultiFilterSearchPlaceHolderText": "请输入 ...", diff --git a/test/UnitTest/Components/TabTest.cs b/test/UnitTest/Components/TabTest.cs index 1e6085e55a9..3bc049d6ad6 100644 --- a/test/UnitTest/Components/TabTest.cs +++ b/test/UnitTest/Components/TabTest.cs @@ -25,6 +25,53 @@ protected override void ConfigureServices(IServiceCollection services) }); } + [Fact] + public void ToolbarTemplate_Ok() + { + var cut = Context.RenderComponent(pb => + { + pb.AddChildContent(pb => + { + pb.Add(a => a.Text, "Tab1"); + pb.Add(a => a.Url, "/Index"); + pb.Add(a => a.Closable, true); + pb.Add(a => a.Icon, "fa-solid fa-font-awesome"); + pb.Add(a => a.ChildContent, "Tab1-Content"); + }); + pb.Add(a => a.ToolbarTemplate, builder => builder.AddContent(0, "test-toolbar-template")); + }); + cut.DoesNotContain("test-toolbar-template"); + + cut.SetParametersAndRender(pb => + { + pb.Add(a => a.ShowToolbar, true); + }); + cut.Contains("test-toolbar-template"); + } + + [Fact] + public void ToolbarTooltipText_Ok() + { + var cut = Context.RenderComponent(pb => + { + pb.AddChildContent(pb => + { + pb.Add(a => a.Text, "Tab1"); + pb.Add(a => a.Url, "/Index"); + pb.Add(a => a.Closable, true); + pb.Add(a => a.Icon, "fa-solid fa-font-awesome"); + pb.Add(a => a.ChildContent, "Tab1-Content"); + }); + pb.Add(a => a.ShowToolbar, true); + pb.Add(a => a.RefreshToolbarButtonIcon, "test-refresh-icon"); + pb.Add(a => a.RefreshToolbarTooltipText, "test-refresh-tooltip-text"); + pb.Add(a => a.FullscreenToolbarButtonIcon, "test-fullscreen-icon"); + pb.Add(a => a.FullscreenToolbarTooltipText, "test-fullscreen-tooltip-text"); + }); + cut.Contains("test-refresh-icon"); + cut.Contains("test-refresh-tooltip-text"); + } + [Fact] public void TabItem_Ok() {