MyBlazorUI 0.3.1

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package MyBlazorUI --version 0.3.1
                    
NuGet\Install-Package MyBlazorUI -Version 0.3.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MyBlazorUI" Version="0.3.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MyBlazorUI" Version="0.3.1" />
                    
Directory.Packages.props
<PackageReference Include="MyBlazorUI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MyBlazorUI --version 0.3.1
                    
#r "nuget: MyBlazorUI, 0.3.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MyBlazorUI@0.3.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MyBlazorUI&version=0.3.1
                    
Install as a Cake Addin
#tool nuget:?package=MyBlazorUI&version=0.3.1
                    
Install as a Cake Tool

MyBlazorUI

MyBlazorUI is an original Blazor UI component framework built as a Razor Class Library. It uses .NET 10, nullable reference types, code-behind component logic, CSS isolation, design-token themes, and small JavaScript ES modules for browser behaviors that need JS interop.

The library is intentionally developed in phases. Phase 7 evolves the lightweight Grid into a stronger v3 foundation with row selection, text filtering, column width and visibility controls, density modes, improved paging, row actions, and application-managed state persistence while keeping advanced enterprise grid features deferred to future work.

Implemented Components

Phase 1:

  • MyButton
  • MyIconButton
  • MyTextBox
  • MyCheckBox
  • MyPopup

Phase 2:

  • MySelect
  • MyToastService, MyToastProvider, MyToastContainer
  • MyCard
  • MyTabs, MyTabPage
  • MyDropdown
  • MyFormLayout, MyFormLayoutItem

Phase 4, Phase 5, and Phase 7:

  • MyGrid<TItem>
  • MyGridColumn<TItem>
  • Single and multiple row selection
  • Optional checkbox selection column
  • Text filter row
  • Column width, min width, max width, and visibility
  • Compact, normal, and comfortable density modes
  • Page size selector and pager summary
  • Persistent grid state snapshot/apply foundation
  • Grid state and server-side data request/result APIs

Architecture Principles

  • Original implementation with stable, discoverable My* public APIs.
  • Razor markup stays focused on rendering; component logic lives in .razor.cs partial classes.
  • Component visuals use .razor.css isolation and shared CSS variables.
  • Static assets are served from _content/MyBlazorUI/.
  • Browser behavior uses component-focused JS modules, not global scripts.
  • Inputs integrate with EditForm through InputBase<TValue>.
  • Public services are registered through builder.Services.AddMyBlazorUI().

Solution Structure

src/
  MyBlazorUI/
    Components/
      Button/
      IconButton/
      TextBox/
      CheckBox/
      Popup/
      Select/
      Toast/
      Card/
      Tabs/
      Dropdown/
      FormLayout/
      Grid/
    Core/
      Data/
    Services/
    Interop/
    Themes/
    Utilities/
    Extensions/
    wwwroot/
      themes/
      js/
  MyBlazorUI.Docs/
  MyBlazorUI.Playground/
tests/
  MyBlazorUI.BUnitTests/

Core/Data contains a minimal internal data request/sort foundation for future data components. The public Grid v3 APIs live under Components/Grid.

Installation

Reference the Razor Class Library from a Blazor app:

dotnet add <YourApp>.csproj reference src/MyBlazorUI/MyBlazorUI.csproj

Register services in Program.cs:

using MyBlazorUI.Extensions;

builder.Services.AddMyBlazorUI();

AddMyBlazorUI() registers:

  • MyJsModuleService
  • MyToastService

Static Web Assets And Themes

Include one theme and the shared base stylesheet in your app document:

<link rel="stylesheet" href="_content/MyBlazorUI/themes/light.css" />
<link rel="stylesheet" href="_content/MyBlazorUI/myblazorui.css" />

Use the dark theme by swapping the theme file:

<link rel="stylesheet" href="_content/MyBlazorUI/themes/dark.css" />

JavaScript modules are loaded by components through MyJsModuleService:

  • _content/MyBlazorUI/js/popup.js
  • _content/MyBlazorUI/js/dropdown.js

Usage Examples

<MyButton OnClick="SaveAsync">Save</MyButton>

<MyIconButton AriaLabel="Refresh">
    <Icon><span>R</span></Icon>
</MyIconButton>

<MyTextBox @bind-Value="model.Name" Placeholder="Name" ShowClearButton="true" />

<MyCheckBox @bind-Value="model.IsActive" Label="Active" />
<MyPopup @bind-Visible="isPopupVisible" Title="Confirm" ShowFooter="true">
    <ChildContent>
        <p>Continue with this action?</p>
    </ChildContent>
    <FooterTemplate>
        <MyButton Variant="MyButtonVariant.Secondary" OnClick="Cancel">Cancel</MyButton>
        <MyButton OnClick="Confirm">Confirm</MyButton>
    </FooterTemplate>
</MyPopup>
<MySelect Items="countries"
          TextSelector="country => country.Name"
          ValueSelector="country => country.Code"
          @bind-Value="selectedCountryCode"
          Placeholder="Choose a country" />
<MyToastProvider>
    @Body
</MyToastProvider>

@code {
    [Inject] private MyToastService Toasts { get; set; } = default!;

    private void Notify() => Toasts.ShowSuccess("Profile saved.", "Saved");
}
<MyCard Title="Account" Subtitle="Profile details">
    <p>Account content goes here.</p>
</MyCard>

<MyTabs @bind-ActiveIndex="activeTab">
    <MyTabPage Title="General">General content</MyTabPage>
    <MyTabPage Title="Security">Security content</MyTabPage>
</MyTabs>
<MyDropdown>
    <TriggerTemplate>
        <MyButton>Open menu</MyButton>
    </TriggerTemplate>
    <ChildContent>
        <button type="button">Profile</button>
        <button type="button">Settings</button>
    </ChildContent>
</MyDropdown>

<MyFormLayout Columns="2">
    <MyFormLayoutItem Label="First name">
        <MyTextBox @bind-Value="model.FirstName" />
    </MyFormLayoutItem>
    <MyFormLayoutItem Label="Last name">
        <MyTextBox @bind-Value="model.LastName" />
    </MyFormLayoutItem>
</MyFormLayout>
<MyGrid TItem="UserDto" Items="users" PageSize="10">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" />
        <MyGridColumn TItem="UserDto" Title="Email" Field="user => user.Email" />
        <MyGridColumn TItem="UserDto" Title="Role" Field="user => user.Role" />
    </Columns>
</MyGrid>
<MyGrid TItem="UserDto" Items="users">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name">
            <CellTemplate Context="user">
                <strong>@user.Name</strong>
            </CellTemplate>
        </MyGridColumn>

        <MyGridColumn TItem="UserDto" Title="Actions" Sortable="false" Filterable="false">
            <CellTemplate Context="user">
                <span @onclick:stopPropagation="true">
                    <MyButton Size="MyButtonSize.Small">Edit</MyButton>
                </span>
            </CellTemplate>
        </MyGridColumn>
    </Columns>
</MyGrid>
<MyGrid TItem="UserDto"
        Items="users"
        SelectionMode="MyGridSelectionMode.Multiple"
        ShowSelectionColumn="true"
        @bind-SelectedItems="selectedUsers"
        KeySelector="user => user.Id">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" />
        <MyGridColumn TItem="UserDto" Title="Email" Field="user => user.Email" />
        <MyGridColumn TItem="UserDto" Title="Role" Field="user => user.Role" />
    </Columns>
</MyGrid>
<MyGrid TItem="UserDto"
        Items="users"
        FilterMode="MyGridFilterMode.FilterRow"
        FiltersChanged="HandleFiltersChanged">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" />
        <MyGridColumn TItem="UserDto" Title="Role" Field="user => user.Role" />
        <MyGridColumn TItem="UserDto" Title="Actions" Sortable="false" Filterable="false">
            <CellTemplate Context="user">
                <span @onclick:stopPropagation="true">
                    <MyButton Size="MyButtonSize.Small" Variant="MyButtonVariant.Secondary">Edit</MyButton>
                    <MyButton Size="MyButtonSize.Small" Variant="MyButtonVariant.Danger">Delete</MyButton>
                </span>
            </CellTemplate>
        </MyGridColumn>
    </Columns>
</MyGrid>
<label>
    <input type="checkbox" @bind="showEmailColumn" />
    Show Email
</label>

<MyGrid TItem="UserDto"
        Items="users"
        Density="MyGridDensity.Compact"
        PageSize="10"
        PageSizeOptions="new[] { 10, 20, 50 }">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" Width="220px" MinWidth="160px" />
        <MyGridColumn TItem="UserDto" Title="Email" Field="user => user.Email" Visible="showEmailColumn" MinWidth="240px" />
        <MyGridColumn TItem="UserDto" Title="Role" Field="user => user.Role" Width="140px" />
    </Columns>
</MyGrid>
<MyGrid @ref="grid"
        TItem="UserDto"
        Items="users"
        FilterMode="MyGridFilterMode.FilterRow">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" />
        <MyGridColumn TItem="UserDto" Title="Email" Field="user => user.Email" />
    </Columns>
</MyGrid>

@code {
    private MyGrid<UserDto>? grid;
    private MyGridPersistentState? capturedState;

    private void CaptureState() => capturedState = grid?.GetPersistentState();

    private async Task ApplyStateAsync()
    {
        if (grid is not null && capturedState is not null)
        {
            await grid.ApplyPersistentStateAsync(capturedState);
        }
    }
}
<MyGrid TItem="UserDto"
        DataProvider="LoadUsersAsync"
        PageSize="20">
    <Columns>
        <MyGridColumn TItem="UserDto" Title="Name" Field="user => user.Name" />
        <MyGridColumn TItem="UserDto" Title="Email" Field="user => user.Email" />
    </Columns>
</MyGrid>

@code {
    private Task<MyGridDataResult<UserDto>> LoadUsersAsync(MyGridDataRequest request)
    {
        var query = users.AsEnumerable();

        foreach (var filter in request.Filters)
        {
            if (filter.FieldName == nameof(UserDto.Name) && !string.IsNullOrWhiteSpace(filter.Value))
            {
                query = query.Where(user => user.Name.Contains(filter.Value, StringComparison.OrdinalIgnoreCase));
            }
        }

        if (request.SortField == nameof(UserDto.Name))
        {
            query = request.SortDirection == MyGridSortDirection.Descending
                ? query.OrderByDescending(user => user.Name)
                : query.OrderBy(user => user.Name);
        }

        var totalCount = query.Count();

        return Task.FromResult(new MyGridDataResult<UserDto>
        {
            Items = query.Skip(request.PageIndex * request.PageSize).Take(request.PageSize).ToArray(),
            TotalCount = totalCount
        });
    }
}

MyGrid supports client-side filtering, sorting, paging, single selection, multiple selection, column visibility, column sizing, density classes, page size selection, and persistent state snapshots when Items is used. When DataProvider is supplied, it takes precedence and receives MyGridDataRequest values for page index, page size, sort field, sort direction, and active text filters.

Commands

Build the solution:

dotnet build

Run tests:

dotnet test

Run the docs app:

dotnet run --project src/MyBlazorUI.Docs

Run the playground app:

dotnet run --project src/MyBlazorUI.Playground

Pack the Razor Class Library:

dotnet pack src/MyBlazorUI/MyBlazorUI.csproj -c Release

Packaging Notes

The RCL project includes NuGet metadata, XML documentation generation, README packaging, and static web assets under wwwroot. The package is prepared for local packing, but it is not published by this repository.

Known Limitations

  • Grid v3 is intentionally lightweight.
  • Grid localStorage persistence, full column chooser UI, drag column resizing, column reordering, advanced filter menus, date/number filters, editing, grouping, virtualization, export, frozen columns, master-detail, and advanced keyboard navigation are not implemented yet.
  • Scheduler, Chart, Upload, RichTextEditor, and TreeView are not implemented.
  • MySelect currently uses native <select> behavior rather than a custom virtualized listbox.
  • MyDropdown uses simple trigger-relative positioning.
  • Toast behavior is scoped to basic service-driven notifications.

Roadmap

Near-term hardening can continue with accessibility audits, visual regression coverage, package signing/publishing workflow, and richer examples. Future grid work can add localStorage state persistence, a column chooser component, drag resizing, column reordering, advanced filter operators per column, date and number filters, filter menus, editing, grouping, virtualization, export, frozen columns, and richer keyboard interaction without changing the basic Grid v3 API shape.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated

Phase 7 release. Adds and hardens the MyGrid component with sorting, paging, templates, loading and empty states, selection, filtering, row actions, density modes, column width and visibility support, page size selector, pager summary, persistent grid state foundation, documentation, playground examples, and bUnit coverage.