RxBlazorV2.MudBlazor 1.2.5

dotnet add package RxBlazorV2.MudBlazor --version 1.2.5
                    
NuGet\Install-Package RxBlazorV2.MudBlazor -Version 1.2.5
                    
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="RxBlazorV2.MudBlazor" Version="1.2.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="RxBlazorV2.MudBlazor" Version="1.2.5" />
                    
Directory.Packages.props
<PackageReference Include="RxBlazorV2.MudBlazor" />
                    
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 RxBlazorV2.MudBlazor --version 1.2.5
                    
#r "nuget: RxBlazorV2.MudBlazor, 1.2.5"
                    
#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 RxBlazorV2.MudBlazor@1.2.5
                    
#: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=RxBlazorV2.MudBlazor&version=1.2.5
                    
Install as a Cake Addin
#tool nuget:?package=RxBlazorV2.MudBlazor&version=1.2.5
                    
Install as a Cake Tool

RxBlazorV2.MudBlazor

Reactive MudBlazor button components for RxBlazorV2. Provides automatic progress indicators, cancellation support, and confirmation dialogs for command bindings.

Installation

dotnet add package RxBlazorV2.MudBlazor

Components

Component Description
MudButtonRx Sync command button
MudButtonAsyncRx Async command button with progress/cancel
MudButtonRxOf<T> Parameterized sync command button
MudButtonAsyncRxOf<T> Parameterized async command button
MudIconButtonRx Sync icon button
MudIconButtonAsyncRx Async icon button with badge progress
MudIconButtonRxOf<T> Parameterized sync icon button
MudIconButtonAsyncRxOf<T> Parameterized async icon button
MudFabRx Sync floating action button
MudFabAsyncRx Async FAB with progress
MudFabRxOf<T> Parameterized sync FAB
MudFabAsyncRxOf<T> Parameterized async FAB
StatusDisplay Error and message display with snackbar/icon
MudSwipeoutRx<TItem> Row with reveal-on-swipe action panels (left/right), overswipe + swipe-to-delete
MudSortableSwipeoutListRx<TItem> Reactive sortable list, coordinates with child swipeouts

StatusDisplay Component

The StatusDisplay component provides reactive error and status message handling with configurable display modes.

Setup

Add the StatusDisplay component to your layout (e.g., in the AppBar):

@using RxBlazorV2.MudBlazor.Components

<MudAppBar>
    <MudSpacer />
    <StatusDisplay />
</MudAppBar>

StatusModel

Inject StatusModel into your models to report errors and messages:

public partial class MyModel : ObservableModel
{
    public partial MyModel(StatusModel statusModel);

    private void DoSomething()
    {
        StatusModel.AddMessage("Operation completed");
    }

    private void HandleError()
    {
        // Errors are automatically captured from commands via IErrorModel
        // Or add manually:
        StatusModel.HandleError(new Exception("Something went wrong"));
    }
}

Display Modes

Mode Description
SNACKBAR Show only snackbar notification
ICON Show only icon with badge and tooltip
SNACKBAR_AND_ICON Show both snackbar and icon

Message Modes

Mode Description
AGGREGATE Collect all messages (default for errors)
SINGLE Clear previous before adding new (default for messages)

Parameters

Parameter Type Default Description
ErrorDisplayMode StatusDisplayMode SNACKBAR_AND_ICON How errors are displayed
ErrorMode StatusMessageMode AGGREGATE Error accumulation mode
ErrorSnackbarOptions Action<SnackbarOptions>? Hide close icon Snackbar configuration
MessageDisplayMode StatusDisplayMode SNACKBAR How messages are displayed
MessageMode StatusMessageMode SINGLE Message accumulation mode
MessageSnackbarOptions Action<SnackbarOptions>? Hide close icon Snackbar configuration
SnackbarPositionClass string TopEnd Snackbar position

Customization Example

<StatusDisplay ErrorDisplayMode="StatusDisplayMode.ICON"
               MessageDisplayMode="StatusDisplayMode.SNACKBAR_AND_ICON"
               ErrorMode="StatusMessageMode.AGGREGATE"
               MessageMode="StatusMessageMode.SINGLE"
               SnackbarPositionClass="@Defaults.Classes.Position.BottomCenter" />

Usage

Basic Async Button with Progress

<MudButtonAsyncRx Command="@Model.SaveCommand"
                  Variant="Variant.Filled"
                  Color="Color.Primary">
    Save
</MudButtonAsyncRx>

With Cancellation Support

<MudButtonAsyncRx Command="@Model.LongRunningCommand"
                  CancelText="Cancel"
                  CancelColor="Color.Warning">
    Start Process
</MudButtonAsyncRx>

With Confirmation Dialog

<MudButtonAsyncRx Command="@Model.DeleteCommand"
                  ConfirmExecutionAsync="@ConfirmDeleteAsync"
                  Color="Color.Error">
    Delete
</MudButtonAsyncRx>

@code {
    private async Task<bool> ConfirmDeleteAsync()
    {
        return await DialogService.ShowMessageBox(
            "Confirm Delete",
            "Are you sure you want to delete this item?",
            yesText: "Delete", cancelText: "Cancel") == true;
    }
}

Parameterized Command

@foreach (var item in Items)
{
    <MudButtonAsyncRxOf T="ItemModel"
                        Command="@Model.ProcessItemCommand"
                        Parameter="@item">
        Process @item.Name
    </MudButtonAsyncRxOf>
}

Icon Button with Progress Badge

<MudIconButtonAsyncRx Command="@Model.RefreshCommand"
                      Icon="@Icons.Material.Filled.Refresh"
                      HasProgress="true" />

Parameters

All async button components support:

Parameter Type Description
Command IObservableCommandAsync Required. The command to execute
CanExecute Func<bool> Additional execution guard
ConfirmExecutionAsync Func<Task<bool>> Confirmation before execution
CancelText string Text for cancel mode (enables cancellation)
CancelColor Color Button color during cancel mode
HasProgress bool Show progress spinner (default: true)

Parameterized versions (*RxOf<T>) also require:

Parameter Type Description
Parameter T The value to pass to the command

Sortable + Swipeout

MudSortableSwipeoutListRx<TItem> and MudSwipeoutRx<TItem> add iOS-Mail-style swipe action panels and drag-to-reorder to a reactive list.

Setup

The components ship with a stylesheet and a JS module. Reference the stylesheet from your index.html:

<link href="_content/RxBlazorV2.MudBlazor/SwipeoutSortable.css" rel="stylesheet" />

The JS module is loaded automatically on first render — no extra <script> tag needed.

Basic usage

<MudSortableSwipeoutListRx TItem="TaskItem"
                           Items="@Model.Tasks"
                           KeySelector="@(t => t.Id)"
                           Reorder="@(p => Model.ReorderCommand.ExecuteAsync(p))"
                           ActivationMode="SortActivation.DRAG_HANDLE">
    <ItemTemplate Context="task">
        <MudSwipeoutRx TItem="TaskItem" Item="task"
                       LeftActions="@BuildLeftActions(task)"
                       RightActions="@BuildRightActions(task)">
            <ChildContent Context="t">
                <MudPaper Class="pa-3 d-flex align-center" Elevation="0" Square="true">
                    <MudIcon Icon="@Icons.Material.Filled.DragIndicator" data-rxb-sort-handle Class="mr-3" />
                    <MudText>@t.Title</MudText>
                </MudPaper>
            </ChildContent>
        </MudSwipeoutRx>
    </ItemTemplate>
</MudSortableSwipeoutListRx>
private IReadOnlyList<SwipeoutAction<TaskItem>> BuildRightActions(TaskItem task) => new[]
{
    new SwipeoutAction<TaskItem>
    {
        Icon = Icons.Material.Outlined.Archive,
        AriaLabel = "Archive",
        CommandAsyncOfItem = Model.ArchiveCommand
    },
    new SwipeoutAction<TaskItem>
    {
        Icon = Icons.Material.Filled.Delete,
        Color = Color.Error,
        AriaLabel = "Delete",
        IsDelete = true,                           // outermost action only
        CommandAsyncOfItem = Model.DeleteCommand
    }
};

Action descriptor

SwipeoutAction<TItem> is a plain init-only record. Set exactly one command property:

Property Use for
Command IObservableCommand (sync, no parameter)
CommandOfItem IObservableCommand<TItem> (sync, item as parameter)
CommandAsync IObservableCommandAsync (async, no parameter)
CommandAsyncOfItem IObservableCommandAsync<TItem> (async, item as parameter)

Plus visual properties: Icon (required), Color, AriaLabel, ConfirmExecutionAsync, IsDelete.

Overswipe and swipe-to-delete

  • Up to 3 actions per side.
  • The outermost action — index 0 on the left, the last index on the right — is automatically the overswipe target. Drag past actionsWidth + 60 px and release to fire it.
  • Set IsDelete = true on the outermost right-side action to enable swipe-to-delete: the row sweeps fully across before the click fires. Your command should remove the item from the model so Blazor re-renders without the row.

Activation modes for sortable

Mode Use when
DRAG_HANDLE (default) Element with data-rxb-sort-handle is the only drag start — best for desktop
TAP_HOLD Long-press anywhere on a row starts a sort — best for touch
ALWAYS Vertical movement on the row starts a sort — coexists with swipeout (which owns horizontal)

Reactivity

  • Items is plain IEnumerable<TItem>. The component re-renders when its ObservableComponent parent does — typically after a property change in your ObservableModel.
  • The Reorder callback fires with a SortableMove record (covers both intra-list and cross-list cases — see below). Your model owns the list mutation.
  • Action commands run through the same MudIconButton[Async]Rx pipeline as everywhere else, including ConfirmExecutionAsync. Overswipe and delete just dispatch a synthetic click on the marked button.
  • KeySelector is required for stable Blazor keys so swipeout JS instances stay attached to the correct DOM nodes after a reorder.

Cross-list drag (groups)

Two lists with the same SortableGroup.Name can exchange items, subject to per-list pull/put rules. Useful for contact groups, tag baskets, kanban columns.

@code {
    // Source: items stay here when dragged out (clone semantics); doesn't accept incoming.
    private readonly SortableGroup _allGroup = new()
    {
        Name = "contacts",
        Pull = SortablePull.CLONE,
        Put = false
    };

    // Target: items dragged out are removed; accepts items from any list in the "contacts" group.
    private readonly SortableGroup _vipGroup = new()
    {
        Name = "contacts",
        Pull = SortablePull.MOVE,
        Put = true
    };
}

<MudSortableSwipeoutListRx TItem="Contact"
                           ListId="all-contacts"
                           Items="@Model.AllContacts"
                           KeySelector="@(c => c.Id)"
                           Reorder="@(p => Model.ReorderCommand.ExecuteAsync(p))"
                           Group="@_allGroup">
    <ItemTemplate Context="c">@ContactRow(c)</ItemTemplate>
</MudSortableSwipeoutListRx>

<MudSortableSwipeoutListRx TItem="Contact"
                           ListId="vip-group"
                           Items="@Model.VipContacts"
                           KeySelector="@(c => c.Id)"
                           Reorder="@(p => Model.ReorderCommand.ExecuteAsync(p))"
                           Group="@_vipGroup">
    <ItemTemplate Context="c">@ContactRow(c)</ItemTemplate>
</MudSortableSwipeoutListRx>

Pull modes (SortablePull):

Mode Effect
MOVE (default) Items dragged out are removed from this list (handler should RemoveAt on the source)
CLONE Items dragged out stay in this list; handler inserts a copy in the target. The SortableMove.IsClone flag is true on cross-list drops
NONE Items cannot be dragged out at all

Single handler, two semantics — the SortableMove record covers both cases:

private async Task ReorderAsync(SortableMove move)
{
    var src = ListById(move.SourceListId);
    var tgt = ListById(move.TargetListId);

    if (move.SourceListId == move.TargetListId)
    {
        // Intra-list reorder.
        var item = src[move.FromIndex];
        src.RemoveAt(move.FromIndex);
        src.Insert(move.ToIndex, item);
    }
    else
    {
        // Cross-list — fires on the source list's component.
        var item = src[move.FromIndex];
        if (!move.IsClone) src.RemoveAt(move.FromIndex);
        tgt.Insert(move.ToIndex, item);
    }
}

Reorder fires once per drop, on the source list's component. Wire the same handler on every list — move.SourceListId / move.TargetListId tell you which lists are involved.

Input handling

The gesture engine listens to two parallel input paths:

  • Pointer Events for mouse and pen — uses setPointerCapture so a pointer that leaves the row mid-drag still reports back to the row. Pointer events with pointerType === "touch" are filtered out by both engines.
  • Touch Events for finger input — touchmove is registered non-passive so preventDefault() on the first move wins the gesture from the browser's scroll heuristic. Pointer events on touch devices are unreliable for early-threshold disambiguation on iOS Safari, so finger gestures take this path instead.

Drag state lives entirely in JS; only OpenedSide and the SortableMove cross to .NET. Honours prefers-reduced-motion.

Touch and scrolling

.rxb-swipeout is touch-action: none by default — combined with preventDefault on every touchmove, JS owns every gesture that starts on a row. The trade-off is:

  • Page scrolling comes from outside the rows — the surrounding scroll container (MudPaper, MudContainer, the page body, etc.). Touching gutters / headers / empty space scrolls normally.
  • Inside a row, touch-scrolling is not available. Vertical drag goes to the sortable (in ALWAYS mode), horizontal drag goes to the swipeout.

If a specific list really needs row-internal touch scroll (typically DRAG_HANDLE mode with no swipeout), opt back in via the CSS variable:

.my-list .rxb-swipeout {
    --rxb-touch-action: pan-y;   /* let the browser scroll the row; swipe will be unreliable on touch */
}

The drag handle ([data-rxb-sort-handle]) carries touch-action: none regardless — handle-grabs always work on touch.

Requirements

License & Acknowledgements

MIT License — see LICENSE.

The swipeout + sortable gesture algorithms in MudSwipeoutRx / MudSortableSwipeoutListRx (elasticity, velocity-snap, overswipe, swipe-to-delete sweep, midpoint-cross sortable, edge auto-scroll, tap-hold activation) are derived from Framework7 © 2014 Vladimir Kharlampidi (MIT). The cross-list group API (pull / put / clone semantics) follows the SortableJS model, with BlazorSortable © 2023 The Urlist (MIT) as a reference for Blazor interop conventions. The implementation here is a clean re-port in plain DOM with Pointer Events + Touch Events. See NOTICE for full attribution.

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 (4)

Showing the top 4 NuGet packages that depend on RxBlazorV2.MudBlazor:

Package Downloads
BlazorPRF.Noble.UI

MudBlazor UI components for PRF-based deterministic encryption

BlazorPRF.BC.UI

MudBlazor UI components for PRF-based deterministic encryption

BlazorPRF.UI

MudBlazor UI components for PRF-based deterministic encryption

SqliteWasmBlazor.Crypto.UI

Base-plane RxBlazorV2 + MudBlazor panels for SqliteWasmBlazor: WebAuthn-PRF authentication / registration, database boot-error alert, session-expired popover. Hosts wire IPrfAuthenticator / ISessionAuthenticator / IDatabaseResetService seams.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.5 136 5/7/2026
1.2.4 99 5/2/2026
1.2.3 96 4/30/2026
1.2.2 103 4/27/2026
1.2.1 104 4/16/2026
1.2.0 121 4/15/2026 1.2.0 is deprecated because it has critical bugs.
1.1.5 140 4/3/2026
1.1.4 105 4/2/2026
1.1.3 117 4/1/2026
1.1.2 174 12/20/2025
1.1.1 206 12/20/2025 1.1.1 is deprecated because it has critical bugs.
1.1.0 208 12/20/2025 1.1.0 is deprecated because it has critical bugs.
1.0.9 210 12/20/2025 1.0.9 is deprecated because it has critical bugs.
1.0.8 295 12/18/2025
1.0.7 300 12/18/2025
1.0.6 349 12/17/2025
1.0.5 315 12/15/2025
1.0.4 169 12/11/2025
1.0.3 256 12/4/2025
1.0.1 236 12/3/2025
Loading failed

v1.0.0 - Initial Release
     - MudButtonRx and MudButtonAsyncRx for command binding
     - MudIconButtonRx and MudIconButtonAsyncRx with badge-based progress
     - MudFabRx and MudFabAsyncRx floating action buttons
     - Automatic progress spinner during async execution
     - Cancel badge/button when operation supports cancellation
     - Optional confirmation dialog before execution