Tab Komponente mit Blazor

Eine Tab Komponente mit Blazor zu erstellen ist recht einfach.

Zuerst erstellen wir den Container. Ich habe die Datei Tab.razor genannt


<div style="display: grid; grid-template-rows: 2rem auto;">
    <div style="display: flex;">
        <CascadingValue Value="this">
            @ChildContent
        </CascadingValue>
    </div>
    <div class="@TabBodyClass">
        @ActiveTabItem?.ChildContent
    </div>
</div>


@code {

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    [Parameter]
    public string TabButtonClass { get; set; }

    [Parameter]
    public string TabButtonActivClass { get; set; }

    [Parameter]
    public string TabBodyClass { get; set; }

    public TabItem ActiveTabItem { get; set; }

    private List<TabItem> _tabItems = new List<TabItem>();

    public void AddTab(TabItem tabItem)
    {
        _tabItems.Add(tabItem);
        if (ActiveTabItem == null)
        {
            ActiveTabItem = tabItem;
            StateHasChanged();
        }
    }

    public void SetTab(TabItem item)
    {
        ActiveTabItem = item;
        StateHasChanged();
    }
}

Jetzt noch die TabItems. Diese Datei habe ich TabItems.razor genannt

@if (Parent?.ActiveTabItem == this)
{
    <button class="@Parent.TabButtonActivClass">@Title</button>
}
else
{
    <button class="@Parent.TabButtonClass" @onclick="(() => Parent.SetTab(this))">@Title</button>
}

@code {

    [CascadingParameter]
    public Tab Parent { get; set; }

    [Parameter]
    public string Title { get; set; }

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override void OnInitialized()
    {
        Parent.AddTab(this);
    }
}

Das wars auch schon. An TabBodyClass, TabButtonClass und TabButtonActivClass kann man seine eigenen CSS-Klassen für den Style übergeben. Der richtige Namespace muss angegeben werden. Einfach <Tab></Tab> wird nicht gehen. Der Namespace setzt sich aus dem Projektnamen und der Ordnerstruktur zur Datei zusammen. Wenn ein Projekt z.B. TestBlazor heißt und die Tab.razor im Unterordner TestBlazor/Comp liegt, wäre der Namespace <TestBlazor.Comp.Tab>

.tabButtonTest {
    padding: 4px 16px;
    border: none;
    background-color: black;
    color: white;
}

.tabButtonActiveTest {
    padding: 4px 16px;
    border: none;
    background-color: #414345;
    color: white;
}

.tabBodyTest {
    padding: 8px;
    background-color: #414345;
    color: white;
}

<Tab TabBodyClass="tabBodyTest" TabButtonActivClass="tabButtonActiveTest" TabButtonClass="tabButtonTest">
    <TabItem Title="Tab 1">
        Das ist Tab 1
    </TabItem>
    <TabItem Title="Tab 2">
        Das ist Tab 2
    </TabItem>
</Tab>