Enterprise-level component library based on Bootstrap and Blazor

star nuget license download repo commit master coverage

Tabs

A collection of data that is associated with the separation content but belongs to a different category.

Tab components are designed in the form of templates, and this component is used by adding TabItem subcomponents to the tabItems in the template

Set additional information during tab navigation

  • InfoItem1
  • Tab properties can be set when navigating using the built-in extension method Navigator.NavigateTo("url", "text", "icon", "closable")
  • InfoItem3
  • Setting @attribute [TabItemOption(Text = "LayoutPage", Icon = "fa fa-fa")] in razor page

Basic, concise tabs.

Demo
I am a user manager
I am menu management
I am roles management
I am department management

Set tab-style tabs by isCard='true'.

Demo
I am a user manager
I am menu management
I am roles management
I am department management

Set tab-style tabs by IsBorderCard='true'.

Demo
I am a user manager
I am menu management
I am roles management
I am department management

Set the tab icon by setting the Icon property of the TabItem component

Demo
I am a user manager
I am menu management
I am roles management
I am department management

Show the close button to the tab by setting the ShowClose property

Demo
I am a user manager
I am menu management
I am roles management
I am department management

By setting the Placement property to change the label position, a small arrow scrolls up and down to TabItem switch when you change to left or right

Demo

I am a user manager
I am menu management
I am roles management
I am a system log
I am Sign log management
I am a timed task manager
Split Line
I am a user manager
I am menu management
I am roles management
I am a system log
I am Sign log management
I am a timed task manager
Split Line
I am a user manager
I am menu management
I am roles management
I am a system log
I am Sign log management
I am a timed task manager

Dynamically add/remove TabItem by calling the component api

Demo

I am a user manager
I am menu management
I am roles management
I am department management
I am a timed task manager

other components are built into the TabItem

Demo

Tab The contents of each panel of the component remain state by default, and in this case the original data is maintained when the panel switches

Counter

Current count: 0

Weather forecast

This component demonstrates fetching data from a service.

Date Temp. (C) Temp. (F) Summary
1/21/2022 -16 4 Warm
1/22/2022 20 67 Mild
1/23/2022 45 112 Bracing
1/24/2022 27 80 Chilly
1/25/2022 51 123 Hot

This feature allows you to click on the menu link in the sidebar and render multiple labels at the top of the data area on the right

Demo

In this example, the right the Tab the inside of the panel remains in state, and the component reloads when it is closed and reopened

Header

By setting the ShowExtendButtons property to true, turning on the left and right buttons of the component and closing the drop-down menu, it is very useful in practice

Demo

I am a user manager
I am menu management
I am roles management
I am department management
I am a timed task manager

By setting the isOnlyRenderActiveTab parameter, the component renders only the current active label

Demo

Counter

Current count: 0

Attributes

Loading...

Method

Loading...
@page "/tabs"
@inject IStringLocalizer<Tabs> Localizer

<h3>Tabs</h3>

<h4>A collection of data that is associated with the separation content but belongs to a different category.</h4>

<p>Tab components are designed in the form of templates, and this component is used by adding <code>TabItem</code> subcomponents to the <code>tabItems</code> in the template</p>

<Tips>
    <p>
        <code>Tab</code> components are generally used in two ways:
        <ul class="ul-demo">
            <li>Split as data</li>
            <li>Page navigation</li>
        </ul>
        <div>The default behavior of this component is data segmentation,Clicking on the <code>TabItem</code> title does not navigate, and if you need to navigate the address bar, set the <code>ClickTabToNavigation</code> property to <code>true</code>,When you click on the <code>TabItem</code> title, the address bar redirects navigation, mostly for the background management system to be used in conjunction with the <code>Menu</code> components,The actual combat can refer to the <code>multi-label</code> mode in the <a href='layout-page' target='_blank'>background template simulator</a>,  When you have <code>Razor Component</code> in the additional Assemblies, set the <code>AdditionalAssemblies</code> property value correctly so that the route within the label component is resolved correctly, and the relevant documentation <a href='https://docs.microsoft.com/zh-cn/aspnet/core/blazor/fundamentals/routing?WT.mc_id-DT-MVP-5004174-view-aspnetcore-3.1-route-to-components-from-multiple-assemblies' target'_blank'>[Portal]</a></div>
    </p>
    <p>This component adapts to width height, etc., and scroll arrows can appear left and right or up and down when appropriate</p>
</Tips>

<p>
    <b>Set additional information during tab navigation</b>
</p>

<ul class="ul-demo">
    <li>@((MarkupString)Localizer["InfoItem1"].Value)</li>
    <li>Tab properties can be set when navigating using the built-in extension method <code>Navigator.NavigateTo("url", "text", "icon", "closable")</code></li>
    <li>@((MarkupString)Localizer["InfoItem3"].Value)</li>
    <li>Setting <code>@attribute [TabItemOption(Text = "LayoutPage", Icon = "fa fa-fa")]</code> in <code>razor</code> page</li>
</ul>

<DemoBlock Title="Basic usage" Introduction="Basic, concise tabs." Name="Normal">
    <Tab>
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department ">
            <div>I am department management</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Tab style " Introduction="Set tab-style tabs by <code>isCard='true'</code>." Name="Card">
    <Tab IsCard="true">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department ">
            <div>I am department management</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Carding" Introduction="Set tab-style tabs by <code>IsBorderCard='true'</code>." Name="Border">
    <Tab IsBorderCard="true">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department ">
            <div>I am department management</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Icon" Introduction="Set the tab icon by setting the <code>Icon</code> property of the <code>TabItem</code> component" Name="Icon">
    <Tab IsCard="true">
        <TabItem Text="User" Icon="fa fa-user">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu" Icon="fa fa-dashboard">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles" Icon="fa fa-sitemap">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department " Icon="fa fa-bank">
            <div>I am department management</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Close" Introduction="Show the close button to the tab by setting the <code>ShowClose</code> property" Name="Closable">
    <Tips>
        <p><code>Tab</code> component turns on the <code>showClose</code> , <code>TabItem</code> property <code>Closable</code> can be set individually to close tab, <b>defaulting to </b><code>true</code>;In this example <b> User </b> Tabs do not provide a to turn off functionality</p>
    </Tips>
    <Tab IsCard="true" ShowClose="true">
        <TabItem Text="User" Icon="fa fa-user" Closable="false">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu" Icon="fa fa-dashboard">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles" Icon="fa fa-sitemap">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department " Icon="fa fa-bank">
            <div>I am department management</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Position" Introduction="By setting the <code>Placement</code> property to change the label position, a small arrow scrolls up and down to <code>TabItem</code> switch when you change to left or right" Name="Placement">
    <p class="text-center">
        <div class="btn-group">
            <button class="btn btn-primary" @onclick="e => SetPlacement(Placement.Top)">Top</button>
            <button class="btn btn-primary" @onclick="e => SetPlacement(Placement.Right)">Right</button>
            <button class="btn btn-primary" @onclick="e => SetPlacement(Placement.Bottom)">Bottom</button>
            <button class="btn btn-primary" @onclick="e => SetPlacement(Placement.Left)">Left</button>
        </div>
    </p>
    <Tab Placement="@BindPlacement" Height="200">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="System logs">
            <div>I am a system log</div>
        </TabItem>
        <TabItem Text="Sign log">
            <div>I am Sign log management</div>
        </TabItem>
        <TabItem Text="Timed task">
            <div>I am a timed task manager</div>
        </TabItem>
    </Tab>
    <Divider Text="Split Line"></Divider>
    <Tab Placement="@BindPlacement" IsCard="true" Height="200">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="System logs">
            <div>I am a system log</div>
        </TabItem>
        <TabItem Text="Sign log">
            <div>I am Sign log management</div>
        </TabItem>
        <TabItem Text="Timed task">
            <div>I am a timed task manager</div>
        </TabItem>
    </Tab>
    <Divider Text="Split Line"></Divider>
    <Tab Placement="@BindPlacement" IsBorderCard="true" Height="200">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="System logs">
            <div>I am a system log</div>
        </TabItem>
        <TabItem Text="Sign log">
            <div>I am Sign log management</div>
        </TabItem>
        <TabItem Text="Timed task">
            <div>I am a timed task manager</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Custom add tab triggers" Introduction="Dynamically add/remove <code>TabItem</code> by calling the component api" Name="AddTabItem">
    <p>
        <Button Icon="fa fa-plus-circle" OnClickWithoutRender="@(() => AddTab(TabSet))" Text="Add">
        </Button>
        <Button Color="Color.Danger" Icon="fa fa-minus-circle" IsDisabled="@RemoveEndable" OnClickWithoutRender="@(() => RemoveTab(TabSet))" Text="Rmove">
        </Button>
        <Button Icon="fa fa-fa" OnClickWithoutRender="@(() => Active(TabSet))" Text="Activate the first one">
        </Button>
    </p>
    <Tab IsBorderCard="true" @ref="TabSet">
        <TabItem Text="User">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department ">
            <div>I am department management</div>
        </TabItem>
        <TabItem Text="Timed task">
            <div>I am a timed task manager</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Additional components are built in" Introduction="other components are built into the <code>TabItem</code>" Name="Component">
    <p>
        <code>Tab</code> The contents of each panel of the component remain state by default, and in this case the original data is maintained when the panel switches
    </p>
    <Tab IsBorderCard="true">
        <TabItem Text="Count">
            <Counter></Counter>
        </TabItem>
        <TabItem Text="Weather forecast">
            <FetchData></FetchData>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="The program dynamically adds the TabItem panel" Introduction="This feature allows you to click on the menu link in the sidebar and render multiple labels at the top of the data area on the right" Name="DynamicTabItem">
    <p>
        In this example, the right the <code>Tab</code> the inside of the panel remains in state, and the component reloads when it is closed and reopened
    </p>
    <Layout SideWidth="120px" style="min-height: 180px; border: 1px solid #ddd; border-radius: 4px;">
        <Header>
            <div class="header">Header</div>
        </Header>
        <Side>
            <div style="border-right: 1px solid #e6e6e6; height: 100%; overflow: auto; padding: 1rem 0; background-color: #f8f9fa;">
                <Menu Items="@GetSideMenuItems()" IsVertical="true" OnClick="@OnClickMenuItem" @ref="TabMenu" />
            </div>
        </Side>
        <Main>
            <div class="tab-main-demo">
                <Tab @ref="TabSetMenu" ShowClose="true">
                </Tab>
            </div>
        </Main>
    </Layout>
</DemoBlock>

<DemoBlock Title="Live Tab components" Introduction="By setting  the <code>ShowExtendButtons</code> property to <code>true</code>, turning on the left and right buttons of the component and closing the drop-down menu, it is very useful in practice" Name="App">
    <Tips>Dynamically adjust the number of <code>TabItem</code> by  <b> adding </b> , <b> delete </b> buttons  to view the left and right effects beyond the number of containers, <b> user management </b> is set to not close, and the feature button cannot close this tab</Tips>
    <p>
        <button type="button" class="btn btn-outline-primary" @onclick="@(e => AddTab(TabSet2))">
            <i class="fa fa-plus-circle"></i>
            <span>Add</span>
        </button>
        <button type="button" class="btn btn-outline-danger" disabled="@((TabSet2?.Items.Count() > 4) ? null : "true")" @onclick="@(e => RemoveTab(TabSet2!))">
            <i class="fa fa-minus-circle"></i>
            <span>Rmove</span>
        </button>
    </p>
    <Tab ShowExtendButtons="true" ShowClose="true" @ref="TabSet2">
        <TabItem Text="User" Closable="false">
            <div>I am a user manager</div>
        </TabItem>
        <TabItem Text="Menu">
            <div>I am menu management</div>
        </TabItem>
        <TabItem Text="Roles">
            <div>I am roles management</div>
        </TabItem>
        <TabItem Text="Department ">
            <div>I am department management</div>
        </TabItem>
        <TabItem Text="Timed task">
            <div>I am a timed task manager</div>
        </TabItem>
    </Tab>
</DemoBlock>

<DemoBlock Title="Only the current label is rendered" Introduction="By setting the <code>isOnlyRenderActiveTab</code> parameter, the component renders only the current active label" Name="IsOnlyRenderActive">
    <Tab IsBorderCard="true" IsOnlyRenderActiveTab="true">
        <TabItem Text="Count">
            <Counter></Counter>
        </TabItem>
        <TabItem Text="Weather forecast">
            <FetchData></FetchData>
        </TabItem>
    </Tab>
</DemoBlock>

<AttributeTable Items="@GetAttributes()" Title="Attributes" />

<MethodTable Items="@GetMethods()" Title="Method" />
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Common;
using BootstrapBlazor.Shared.Components;
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

namespace BootstrapBlazor.Shared.Samples;

/// <summary>
/// 
/// </summary>
public sealed partial class Tabs
{
    [NotNull]
    private Tab? TabSet { get; set; }

    [NotNull]
    private Tab? TabSet2 { get; set; }

    /// <summary>
    /// OnInitialized 方法
    /// </summary>
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            var menuItem = TabMenu?.Items.FirstOrDefault();
            if (menuItem != null)
            {
                await InvokeAsync(() =>
                {
                    var _ = TabMenu?.OnClick?.Invoke(menuItem);
                });
            }
        }
    }

    private Task AddTab(Tab tabset)
    {
        var text = $"Tab {tabset.Items.Count() + 1}";
        tabset.AddTab(new Dictionary<string, object?>
        {
            [nameof(TabItem.Text)] = text,
            [nameof(TabItem.IsActive)] = true,
            [nameof(TabItem.ChildContent)] = new RenderFragment(builder =>
            {
                var index = 0;
                builder.OpenElement(index++, "div");
                builder.AddContent(index++, Localizer["BackAddTabText", text]);
                builder.CloseElement();
            })
        });
        return Task.CompletedTask;
    }

    private static Task Active(Tab tabset)
    {
        tabset.ActiveTab(0);
        return Task.CompletedTask;
    }

    private bool RemoveEndable => (TabSet?.Items.Count() ?? 4) < 4;

    private static Task RemoveTab(Tab tabset)
    {
        if (tabset.Items.Count() > 4)
        {
            var item = tabset.Items.Last();
            tabset.RemoveTab(item);
        }
        return Task.CompletedTask;
    }

    private Placement BindPlacement = Placement.Top;

    private void SetPlacement(Placement placement)
    {
        BindPlacement = placement;
    }

    private IEnumerable<MenuItem> GetSideMenuItems()
    {
        return new List<MenuItem>
            {
                new MenuItem() { Text = Localizer["BackText1"]  },
                new MenuItem() { Text = Localizer["BackText2"] }
            };
    }

    [NotNull]
    private Tab? TabSetMenu { get; set; }

    [NotNull]
    private Menu? TabMenu { get; set; }

    private Task OnClickMenuItem(MenuItem item)
    {
        var text = item.Text;
        var tabItem = TabSetMenu.Items.FirstOrDefault(i => i.Text == text);
        if (tabItem == null) AddTabItem(text ?? "");
        else TabSetMenu.ActiveTab(tabItem);
        return Task.CompletedTask;
    }

    private void AddTabItem(string text) => TabSetMenu.AddTab(new Dictionary<string, object?>
    {
        [nameof(TabItem.Text)] = text,
        [nameof(TabItem.IsActive)] = true,
        [nameof(TabItem.ChildContent)] = text == Localizer["BackText1"] ? BootstrapDynamicComponent.CreateComponent<Counter>().Render() : BootstrapDynamicComponent.CreateComponent<FetchData>().Render()
    });

    /// <summary>
    /// 获得属性方法
    /// </summary>
    /// <returns></returns>
    private IEnumerable<AttributeItem> GetAttributes() => new AttributeItem[]
    {
        // TODO: 移动到数据库中
        new AttributeItem() {
            Name = "IsBorderCard",
            Description = Localizer["Att1"].Value,
            Type = "boolean",
            ValueList = "true/false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "IsCard",
            Description = Localizer["Att2"].Value,
            Type = "boolean",
            ValueList = "true/false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "IsOnlyRenderActiveTab",
            Description = Localizer["Att3"].Value,
            Type = "boolean",
            ValueList = "true/false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowClose",
            Description = Localizer["Att4"].Value,
            Type = "boolean",
            ValueList = "true/false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ShowExtendButtons",
            Description = Localizer["Att5"].Value,
            Type = "boolean",
            ValueList = " — ",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "ClickTabToNavigation",
            Description = Localizer["Att6"].Value,
            Type = "boolean",
            ValueList = "true/false",
            DefaultValue = "false"
        },
        new AttributeItem() {
            Name = "Placement",
            Description = Localizer["Att7"].Value,
            Type = "Placement",
            ValueList = "Top|Right|Bottom|Left",
            DefaultValue = "Top"
        },
        new AttributeItem() {
            Name = "Height",
            Description = Localizer["Att8"].Value,
            Type = "int",
            ValueList = " — ",
            DefaultValue = "0"
        },
        new AttributeItem() {
            Name = "Items",
            Description = Localizer["Att9"].Value,
            Type = "IEnumerable<TabItemBase>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "DefaultUrl",
            Description = Localizer["DefaultUrl"].Value,
            Type = "string",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "ChildContent",
            Description = Localizer["Att10"].Value,
            Type = "RenderFragment",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "AdditionalAssemblies",
            Description = Localizer["Att11"].Value,
            Type = "IEnumerable<Assembly>",
            ValueList = " — ",
            DefaultValue = " — "
        },
        new AttributeItem() {
            Name = "OnClickTab",
            Description = Localizer["Att12"].Value,
            Type = "Func<TabItem, Task>",
            ValueList = " — ",
            DefaultValue = " — "
        }
    };

    /// <summary>
    /// 获得方法
    /// </summary>
    /// <returns></returns>
    private IEnumerable<MethodItem> GetMethods() => new MethodItem[]
    {
        // TODO: 移动到数据库中
        new MethodItem() {
            Name = "AddTab",
            Description = Localizer["Method1"].Value,
            Parameters = "TabItem",
            ReturnValue = " — "
        },
        new MethodItem() {
            Name = "RemoveTab",
            Description = Localizer["Method2"].Value,
            Parameters = "TabItem",
            ReturnValue = " — "
        },
        new MethodItem() {
            Name = "ActiveTab",
            Description = Localizer["Method3"].Value,
            Parameters = "TabItem",
            ReturnValue = " — "
        },
        new MethodItem() {
            Name = "ClickPrevTab",
            Description = Localizer["Method4"].Value,
            Parameters = "",
            ReturnValue = "Task"
        },
        new MethodItem() {
            Name = "ClickNextTab",
            Description = Localizer["Method5"].Value,
            Parameters = "",
            ReturnValue = "Task"
        },
        new MethodItem() {
            Name = "CloseCurrentTab",
            Description = Localizer["Method6"].Value,
            Parameters = "",
            ReturnValue = "Task"
        },
        new MethodItem() {
            Name = "CloseOtherTabs",
            Description = Localizer["Method7"].Value,
            Parameters = "",
            ReturnValue = "Task"
        },
        new MethodItem() {
            Name = "CloseAllTabs",
            Description = Localizer["Method8"].Value,
            Parameters = "",
            ReturnValue = "Task"
        },
        new MethodItem() {
            Name = nameof(Tab.GetActiveTab),
            Description = Localizer["Method9"].Value,
            Parameters = "",
            ReturnValue = "Tabitem"
        }
    };
}

B 站相关视频链接

暂无

交流群

QQ Group:BootstrapAdmin & Blazor 795206915 675147445 Welcome to join the group discussion
Themes
Bootstrap
Motronic
Ant Design (完善中)
LayUI (完善中)
An error has occurred. This application may no longer respond until reloaded. Reload