Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 23 additions & 15 deletions src/BootstrapBlazor.Server/Components/Samples/Tabs.razor
Original file line number Diff line number Diff line change
Expand Up @@ -423,21 +423,7 @@ private void Navigation()
</DemoBlock>

<DemoBlock Title="@Localizer["TabsDragTitle"]" Introduction="@Localizer["TabsDragIntro"]" Name="AllowDrag">
<Tab IsBorderCard="true" AllowDrag="true" ShowToolbar="true">
<TabItem Text="@Localizer["TabItem1Text"]">
<div>@Localizer["TabItem1Content"]</div>
</TabItem>
<TabItem Text="@Localizer["TabItem2Text"]">
<div>@Localizer["TabItem2Content"]</div>
</TabItem>
<TabItem Text="@Localizer["TabItem3Text"]">
<div>@Localizer["TabItem3Content"]</div>
</TabItem>
</Tab>
</DemoBlock>

<DemoBlock Title="@Localizer["TabsDragTitle"]" Introduction="@Localizer["TabsDragIntro"]" Name="AllowDrag">
<Tab IsBorderCard="true" AllowDrag="true" ShowToolbar="true">
<Tab IsBorderCard="true" AllowDrag="true">
<TabItem Text="@Localizer["TabItem1Text"]">
<div>@Localizer["TabItem1Content"]</div>
</TabItem>
Expand Down Expand Up @@ -485,6 +471,28 @@ private void Navigation()
</Tab>
</DemoBlock>

<DemoBlock Title="@Localizer["TabsToolbarTitle"]" Introduction="@Localizer["TabsToolbarIntro"]" Name="Toolbar">
<Tab IsCard="true" ShowClose="true" TabStyle="TabStyle.Chrome" ShowToolbar="true">
<ChildContent>
<TabItem Text="@Localizer["TabItem1Text"]" Icon="fa-solid fa-user">
<div>@Localizer["TabItem1Content"]</div>
</TabItem>
<TabItem Text="@Localizer["TabItem2Text"]" Icon="fa-solid fa-gauge-high">
<div>@Localizer["TabItem2Content"]</div>
</TabItem>
<TabItem Text="@Localizer["TabItem3Text"]" Icon="fa-solid fa-sitemap">
<div>@Localizer["TabItem3Content"]</div>
</TabItem>
<TabItem Text="@Localizer["TabItem4Text"]" Icon="fa-solid fa-building-columns">
<div>@Localizer["TabItem4Content"]</div>
</TabItem>
</ChildContent>
<ToolbarTemplate>
<TabToolbarButton Icon="fa fa-home" TooltipText="Home"></TabToolbarButton>
</ToolbarTemplate>
</Tab>
</DemoBlock>

<AttributeTable Items="@GetAttributes()" Title="@Localizer["AttTitle"]" />

<MethodTable Items="@GetMethods()" Title="@Localizer["MethodTitle"]" />
64 changes: 64 additions & 0 deletions src/BootstrapBlazor.Server/Components/Samples/Tabs.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,70 @@ private AttributeItem[] GetAttributes() =>
Type = "RenderFragment",
ValueList = " — ",
DefaultValue = " — "
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider creating a helper method to construct the attribute definitions to reduce repetition and improve maintainability of the code.

To reduce repetition and improve maintainability, consider extracting a helper method to construct these attribute definitions. For example, you could create a helper that takes the specific parameters and returns the new attribute instance:

private AttributeItem CreateAttributeItem(string name, string descriptionKey, string type, string valueList, string defaultValue)
{
    return new AttributeItem
    {
        Name = name,
        Description = Localizer[descriptionKey].Value,
        Type = type,
        ValueList = valueList,
        DefaultValue = defaultValue
    };
}

Then, you can simplify the array initialization:

var attributes = new[]
{
    CreateAttributeItem(nameof(Tab.ShowToolbar), "AttributeShowToolbar", "bool", "true|false", "false"),
    CreateAttributeItem(nameof(Tab.ToolbarTemplate), "AttributeToolbarTemplate", "RenderFragment", " — ", " — "),
    CreateAttributeItem(nameof(Tab.ShowRefreshToolbarButton), "AttributeShowRefreshToolbarButton", "bool", "true|false", "true"),
    CreateAttributeItem(nameof(Tab.ShowFullscreenToolbarButton), "AttributeShowFullscreenToolbarButton", "bool", "true|false", "true"),
    CreateAttributeItem(nameof(Tab.RefreshToolbarTooltipText), "AttributeRefreshToolbarTooltipText", "string?", " — ", " — "),
    CreateAttributeItem(nameof(Tab.FullscreenToolbarTooltipText), "AttributeFullscreenToolbarTooltipText", "string?", " — ", " — "),
    CreateAttributeItem(nameof(Tab.RefreshToolbarButtonIcon), "AttributeRefreshToolbarButtonIcon", "string?", " — ", " — "),
    CreateAttributeItem(nameof(Tab.FullscreenToolbarButtonIcon), "AttributeFullscreenToolbarButtonIcon", "string?", " — ", " — ")
};

This approach retains all functionality and significantly reduces the duplicated patterns in your code.

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 = " — "
}
];

Expand Down
12 changes: 11 additions & 1 deletion src/BootstrapBlazor.Server/Locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,17 @@
"TabsChromeStyleIntro": "Set the Chrome browser tab style by setting <code>TabStyle=\"TabStyle.Chrome\"</code>. Currently only supports <code>Placement=\"Placement.Top\"</code> mode",
"TabAtt2TabStyle": "Set the tab style",
"TabsCapsuleStyleTitle": "Capsule Style",
"TabsCapsuleStyleIntro": "Set the capsule tab style by setting <code>TabStyle=\"TabStyle.Capsule\"</code>. Currently only supports <code>Placement=\"Placement.Top\"</code> <code>Placement=\"Placement.Bottom\"</code> mode"
"TabsCapsuleStyleIntro": "Set the capsule tab style by setting <code>TabStyle=\"TabStyle.Capsule\"</code>. Currently only supports <code>Placement=\"Placement.Top\"</code> <code>Placement=\"Placement.Bottom\"</code> mode",
"AttributeToolbarTemplate": "The template for Toolbar",
"TabsToolbarTitle": "Toolbar",
"TabsToolbarIntro": "By setting <code>ShowToolbar</code>, you can display the tab toolbar. By default, the <b>Refresh</b> and <b>Fullscreen</b> buttons are displayed. You can control whether to display them by <code>ShowRefreshToolbarButton</code> and <code>ShowFullscreenToolbarButton</code>",
"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 <code>TabItem</code> by click the button",
Expand Down
12 changes: 11 additions & 1 deletion src/BootstrapBlazor.Server/Locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,17 @@
"TabsChromeStyleIntro": "通过设置 <code>TabStyle=\"TabStyle.Chrome\"</code> 设置 Chrome 浏览器标签页样式,目前仅支持 <code>Placement=\"Placement.Top\"</code> 模式",
"TabAtt2TabStyle": "设置标签页样式",
"TabsCapsuleStyleTitle": "胶囊样式",
"TabsCapsuleStyleIntro": "通过设置 <code>TabStyle=\"TabStyle.Capsule\"</code> 设置标签页为胶囊样式,目前仅支持 <code>Placement=\"Placement.Top\"</code> <code>Placement=\"Placement.Bottom\"</code> 模式"
"TabsCapsuleStyleIntro": "通过设置 <code>TabStyle=\"TabStyle.Capsule\"</code> 设置标签页为胶囊样式,目前仅支持 <code>Placement=\"Placement.Top\"</code> <code>Placement=\"Placement.Bottom\"</code> 模式",
"AttributeToolbarTemplate": "Toolbar 模板",
"TabsToolbarTitle": "工具栏",
"TabsToolbarIntro": "通过设置 <code>ShowToolbar</code> 显示标签页工具栏,默认显示 <b>刷新</b> <b>全屏</b> 按钮,可以通过 <code>ShowRefreshToolbarButton</code> <code>ShowFullscreenToolbarButton</code> 控制是否显示",
"AttributeShowToolbar": "是否显示工具栏",
"AttributeShowRefreshToolbarButton": "是否显示工具栏刷新按钮",
"AttributeShowFullscreenToolbarButton": "是否显示工具栏全屏按钮",
"AttributeRefreshToolbarTooltipText": "工具栏刷新按钮提示框文字",
"AttributeFullscreenToolbarTooltipText": "工具栏全屏按钮提示框文字",
"AttributeRefreshToolbarButtonIcon": "工具栏刷新按钮图标",
"AttributeFullscreenToolbarButtonIcon": "工具栏全屏按钮图标"
},
"BootstrapBlazor.Server.Components.Components.DemoTabItem": {
"Info": "点击下方按钮,本 <code>TabItem</code> 标题更改为当前分钟与秒",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
@namespace BootstrapBlazor.Components
@inherits ButtonBase

<a @attributes="AdditionalAttributes" id="@Id" class="@ClassString" @onclick="ToggleFullScreen">
<a @attributes="AdditionalAttributes" id="@Id" class="@ClassString" data-bs-placement="@PlacementString" @onclick="ToggleFullScreen">
<i class="@ButtonIconString"></i>
<i class="@FullScreenExitIconString"></i>
@if (!string.IsNullOrEmpty(Text))
Expand Down
25 changes: 19 additions & 6 deletions src/BootstrapBlazor/Components/Tab/Tab.razor
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ else
<div class="@WrapClassString">
@if (BeforeNavigatorTemplate != null)
{
@BeforeNavigatorTemplate
<CascadingValue Value="this" IsFixed="true">
@BeforeNavigatorTemplate
</CascadingValue>
}
@if (ShowNavigatorButtons)
{
Expand Down Expand Up @@ -71,23 +73,34 @@ else
</div>
@if (ButtonTemplate != null)
{
@ButtonTemplate
<CascadingValue Value="this" IsFixed="true">
@ButtonTemplate
</CascadingValue>
}
@if (ShowToolbar)
{
<div class="tabs-nav-toolbar">
@if (ShowRefreshToolbarButton)
{
<div class="tabs-nav-toolbar-button tabs-nav-toolbar-refresh">
<TabToolbarRefreshButton Icon="@RefreshToolbarButtonIcon" OnClickAsync="OnRefreshAsync"></TabToolbarRefreshButton>
</div>
<TabToolbarButton class="tabs-nav-toolbar-refresh"
Icon="@RefreshToolbarButtonIcon" OnClickAsync="OnRefreshAsync"
TooltipText="@RefreshToolbarTooltipText"></TabToolbarButton>
}
@if (ShowFullscreenToolbarButton)
{
<div class="tabs-nav-toolbar-button tabs-nav-toolbar-fs">
<FullScreenButton TargetId="@Id"></FullScreenButton>
<FullScreenButton TargetId="@Id"
Icon="@FullscreenToolbarButtonIcon"
TooltipText="@FullscreenToolbarTooltipText"
TooltipPlacement="Placement.Bottom"></FullScreenButton>
</div>
}
@if (ToolbarTemplate != null)
{
<CascadingValue Value="this" IsFixed="true">
@ToolbarTemplate
</CascadingValue>
}
</div>
}
@if (ShowNavigatorButtons)
Expand Down
26 changes: 26 additions & 0 deletions src/BootstrapBlazor/Components/Tab/Tab.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ public partial class Tab : IHandlerException
[Parameter]
public RenderFragment? ButtonTemplate { get; set; }

/// <summary>
/// Gets or sets the template of the toolbar button. Default is null.
/// </summary>
[Parameter]
public RenderFragment? ToolbarTemplate { get; set; }

/// <summary>
/// 获得/设置 标签页前置模板 默认 null
/// <para>在向前移动标签页按钮前</para>
Expand Down Expand Up @@ -302,6 +308,18 @@ public partial class Tab : IHandlerException
[Parameter]
public bool ShowFullscreenToolbarButton { get; set; } = true;

/// <summary>
/// Gets or sets the full screen toolbar button icon string. Default is null.
/// </summary>
[Parameter]
public string? FullscreenToolbarButtonIcon { get; set; }

/// <summary>
/// Gets or sets the full screen toolbar button tooltip string. Default is null.
/// </summary>
[Parameter]
public string? FullscreenToolbarTooltipText { get; set; }

/// <summary>
/// Gets or sets whether show the full screen button. Default is true.
/// </summary>
Expand All @@ -314,6 +332,12 @@ public partial class Tab : IHandlerException
[Parameter]
public string? RefreshToolbarButtonIcon { get; set; }

/// <summary>
/// Gets or sets the refresh toolbar button tooltip string. Default is null.
/// </summary>
[Parameter]
public string? RefreshToolbarTooltipText { get; set; }

[CascadingParameter]
private Layout? Layout { get; set; }

Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions src/BootstrapBlazor/Components/Tab/Tab.razor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions src/BootstrapBlazor/Components/Tab/TabToolbarButton.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@namespace BootstrapBlazor.Components
@inherits BootstrapModuleComponentBase

<Tooltip Title="@TooltipText" Placement="Placement.Bottom">
<div @attributes="@AdditionalAttributes" class="@ClassString" @onclick="OnClick">
<i class="@Icon"></i>
</div>
</Tooltip>
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
namespace BootstrapBlazor.Components;

/// <summary>
/// TabToolbarRefreshButton component
/// TabToolbarButton component
/// </summary>
public partial class TabToolbarRefreshButton
public partial class TabToolbarButton
{
/// <summary>
/// Gets or sets the button icon string. Default is null.
Expand All @@ -22,6 +22,16 @@ public partial class TabToolbarRefreshButton
[Parameter]
public Func<Task>? OnClickAsync { get; set; }

/// <summary>
/// Gets or sets the tooltip text. Default is null.
/// </summary>
[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)
Expand Down

This file was deleted.

4 changes: 3 additions & 1 deletion src/BootstrapBlazor/Locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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 ...",
Expand Down
4 changes: 3 additions & 1 deletion src/BootstrapBlazor/Locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@
"CloseCurrentTabText": "关闭当前标签",
"CloseOtherTabsText": "关闭其他标签",
"CloseAllTabsText": "关闭所有标签",
"NotFoundTabText": "未找到"
"NotFoundTabText": "未找到",
"RefreshToolbarTooltipText": "刷新",
"FullscreenToolbarTooltipText": "全屏"
},
"BootstrapBlazor.Components.MultiFilter": {
"MultiFilterSearchPlaceHolderText": "请输入 ...",
Expand Down
Loading