AngryMonkey.CloudComponents.DataGrid 4.2.1

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

CloudComponents.DataGrid

Website GitHub repository NuGet NuGet downloads .NET Blazor License

Production-ready Blazor data grid for .NET 10 with strongly typed models, server-driven data loading, paging modes, sorting, selection, row actions, reordering, export, and theme-friendly CSS variables.

CloudDataGrid is the single entry point. It composes header, body, and footer internally and is driven by one required DataProvider callback.


Table of contents


Features

  • Pure Blazor interaction model for grid UX (sorting, resizing, selection, reordering)
  • Required async DataProvider pattern for consistent load/search/sort/page orchestration
  • Optional toolbar (CloudDataGridHeaderOptions) with built-in Search, Refresh, Export
  • Header actions + row actions + bulk actions + more-menu actions
  • Paging modes:
    • Pages
    • LoadMore
    • InfiniteScroll (via built-in Blazor virtualization)
  • Runtime CSV export for:
    • current page
    • all records (respecting active search/sort)
    • selected records
  • Row link support + row-level arbitrary HTML attributes
  • CSS-variable theming + predictable class naming

Installation

NuGet

dotnet add package AngryMonkey.CloudComponents.DataGrid

Project reference

Reference CloudComponents.DataGrid from your Blazor app.

Namespace import

Add where needed:

@using CloudComponents.DataGrid.Components
@using CloudComponents.DataGrid.Models

Quick start

@using CloudComponents.DataGrid.Components
@using CloudComponents.DataGrid.Models

<CloudDataGrid Columns="_columns"
           DataProvider="LoadAsync"
           Header="_header"
           AllowSelection="true"
           @bind-SelectedRecords="_selected"
           RowsPerPage="25"
           PagingMode="CloudDataGridPagingMode.Pages" />

@code {
    private readonly List<Guid> _selected = [];

    private readonly List<CloudDataGridColumn> _columns =
    [
        new() { Label = "Photo", Key = "photo", IsImage = true, Sortable = false, Width = 84 },
        new() { Label = "Name", Key = "name", Width = 220 },
        new() { Label = "Email", Key = "email", Width = 280 },
        new() { Label = "Status", Key = "status", Width = 120 }
    ];

    private readonly CloudDataGridHeaderOptions _header = new()
    {
        Label = "Contacts",
        AllowSearch = true,
        AllowRefresh = true,
        AllowExport = true
    };

    private async Task<CloudDataGridDataResult?> LoadAsync(CloudDataGridDataRequest request)
    {
        // Query your backend with request.Page, request.PageSize, request.Search, request.Sort
        await Task.Delay(100);

        return new CloudDataGridDataResult
        {
            Page = request.Page,
            PageSize = request.PageSize,
            Total = 2,
            Rows =
            [
                new()
                {
                    Id = Guid.NewGuid(),
                    Link = "/contacts/1",
                    Cells = ["/images/p1.jpg", "Mia Carter", "mia@domain.com", "Active"]
                },
                new()
                {
                    Id = Guid.NewGuid(),
                    Link = "/contacts/2",
                    Cells = ["/images/p2.jpg", "Noah Brooks", "noah@domain.com", "Inactive"]
                }
            ]
        };
    }
}

Data flow (DataProvider)

CloudDataGrid always calls a required callback:

Func<CloudDataGridDataRequest, Task<CloudDataGridDataResult?>> DataProvider

Called on:

  • initial load
  • search query changes
  • sort changes
  • page changes
  • reload/refresh

CloudDataGridDataRequest includes:

  • Page
  • PageSize
  • Search
  • Sort
  • IsAppend
  • Total

Return a CloudDataGridDataResult with Rows, Page, PageSize, Total, and optional ErrorMessage.


Component API

CloudDataGrid parameters

Parameter Type Default Description
Header CloudDataGridHeaderOptions? null Shows toolbar when provided.
Columns List<CloudDataGridColumn> [] Column definitions in render order.
DataProvider Func<CloudDataGridDataRequest, Task<CloudDataGridDataResult?>> required Data source callback for all grid state transitions.
AllowSelection bool false Enables checkbox column + select-all behavior.
SelectedRecords List<Guid>? null Selected row IDs (supports @bind-SelectedRecords).
SelectedRecordsChanged EventCallback<List<Guid>> Raised on selection updates.
AllowReordering bool false Enables row drag handle and drop reordering.
OnRowsReordered EventCallback<CloudDataGridRowReorder> Fired after a row is dropped in a new position.
OnActionClicked EventCallback<CloudDataGridActionEventArgs> Fired for button actions (row/header/bulk).
RowActions List<CloudDataGridAction>? null Explicit row actions (merged with Header.Actions that set ShowOnRow).
ActionFilter Func<CloudDataGridRow, CloudDataGridAction, bool>? null Per-row action visibility filter.
CssClass string? null Additional classes appended to .cloudgrid.
LinkTarget string _parent Target for row links (CloudDataGridRow.Link).
LoadingText string retrieving data... Loading status text.
SearchingText string searching... Searching status text.
EmptyCellText string -- Placeholder for null/empty cells.
ColumnFooterRows List<CloudDataGridFooterRow> [] Summary rows aligned with the data columns.
FixedColumnFooter bool true Keeps column summary rows visible at the bottom of the table viewport.
RowHeight double? null Overrides --cloudgrid-row-height in px.
RowNoteHeight double 24 Fixed note-line height used by virtualization.
ReserveRowNoteSpace bool false Reserves note space before later infinite-scroll pages with notes are loaded.
ShowRowNotes bool true Shows or hides notes supplied by rows.
EnableRowCategories bool true Groups rows that provide CategoryKey.
AllowCategoryCollapse bool true Lets users collapse and expand category headers.
CollapsedCategories HashSet<string>? null Collapsed category keys; supports @bind-CollapsedCategories.
CollapsedCategoriesChanged EventCallback<HashSet<string>> Raised when category expansion changes.
CategoryHeaderTemplate RenderFragment<CloudDataGridCategoryContext>? null Custom category header content.
RowsPerPage int? null Desired body rows in viewport and page size sent to provider.
HeightMode CloudDataGridHeightMode FullHeight How the grid is sized vertically: FullHeight (default, fills parent), RowHeight (fixed to RowsPerPage rows), or Auto (grows with content, optionally capped by MaxHeight).
MaxHeight double? null Maximum height in pixels when HeightMode is Auto. Ignored for other modes.
PagingMode CloudDataGridPagingMode Pages Pages, LoadMore, or InfiniteScroll.
LoadMoreText string load more Label for load-more button mode.
AdditionalAttributes Dictionary<string, object>? null Captures unmatched attributes on root element.

CloudDataGridHeaderOptions

Property Type Default Description
Label string? null Header title.
Actions List<CloudDataGridAction> [] Unified action list for header/bulk/row/more menu placement.
OnActionClicked EventCallback<CloudDataGridActionEventArgs> Callback for button action clicks.
AllowSearch bool false Enables built-in search element action.
SearchDebounceMilliseconds int 300 Debounce delay for search callback.
OnSearchChanged EventCallback<string?> Debounced search query callback.
AllowRefresh bool true Enables built-in refresh button action.
OnRefresh EventCallback Callback for built-in refresh click.
AllowExport bool true Injects built-in export action in More menu.
ExtraActions RenderFragment? null Optional custom trailing content in header action area.

Models reference

Core data models

  • CloudDataGridColumn
    • Label, Key, Width, MinWidth, Sortable, Resizable, IsImage
    • Pinned (None, Left, Right), CssClass, Style, HeaderCssClass, HeaderStyle
    • CellTemplate (RenderFragment<CloudDataGridCellContext>) for custom Razor components
  • CloudDataGridRow
    • Id, Link, Cells, Attributes, CssClass, Style
    • Note, NoteCssClass, NoteStyle for a viewport-anchored line beneath the row
    • CategoryKey, CategoryLabel for collapsible grouping
  • CloudDataGridCell
    • Optional wrapper around a value with CssClass, Style, Attributes, and a per-cell Template
  • CloudDataGridFooterRow
    • Column-aligned footer Cells, plus row-level styling and attributes
  • CloudDataGridDataRequest
    • Page, PageSize, Search, Sort, IsAppend, Total
  • CloudDataGridDataResult
    • Rows, Page, PageSize, Total, ErrorMessage
  • CloudDataGridSort
    • Column, ColumnIndex, Direction, Key

Action models

  • CloudDataGridAction
    • Supports Link, Button, Element modes via CloudDataGridActionType
    • Placement flags: ShowOnHeader, ShowInMore, ShowOnBulkHeader, ShowOnRow
    • Optional icon/text/tooltips and deactivation hooks for element actions
  • CloudDataGridActionEventArgs
    • Action, RecordIds

Enums

  • CloudDataGridPagingMode: Pages, LoadMore, InfiniteScroll
  • CloudDataGridPaginationType: LeftArrow, RightArrow
  • CloudDataGridSortDirection: Ascending, Descending
  • CloudDataGridActionType: Link, Button, Element

Paging modes

Pages (default)

  • Footer shows previous/next paging controls
  • New page replaces current rows
  • Best for classic server paging

LoadMore

  • Renders a load-more button at list end
  • Emits next-page request and expects rows to be appended

InfiniteScroll

  • Uses Blazor virtualization to fetch next page near list end
  • Also expects append behavior

In append modes, ensure your DataProvider returns incremented Page and updated Total.


Pinning, styling, templates, totals, and row notes

Plain values in CloudDataGridRow.Cells remain supported. Wrap only the cells that need individual customization:

<CloudDataGrid Columns="_columns"
               DataProvider="LoadAsync"
               PagingMode="CloudDataGridPagingMode.InfiniteScroll"
               ReserveRowNoteSpace="true"
               ColumnFooterRows="_totals" />

@code {
    private List<CloudDataGridColumn> _columns =
    [
        new() { Label = "Name", Pinned = CloudDataGridPinnedPosition.Left },
        new() { Label = "Amount", Pinned = CloudDataGridPinnedPosition.Right },
        new() { Label = "Status", CellTemplate = StatusTemplate }
    ];

    private RenderFragment<CloudDataGridCellContext> StatusTemplate => context =>
        @<StatusBadge Value="@(context.Value is true)" />;

    private List<CloudDataGridFooterRow> _totals =
    [
        new() { Cells = ["Total", new CloudDataGridCell { Value = 1234, Style = "font-weight:700" }] }
    ];

    private CloudDataGridRow ToRow(Order order) => new()
    {
        Id = order.Id,
        CssClass = order.IsLate ? "late" : null,
        Style = order.IsPriority ? "background:#fff7ed" : null,
        Note = order.Note,
        Cells =
        [
            order.Name,
            new CloudDataGridCell { Value = order.Amount, Style = "color:#166534" },
            order.IsActive
        ]
    };
}

Column styles are defaults; a CloudDataGridCell style is appended afterward and can override them. The row note uses a fixed height so Blazor's virtualizer can calculate exact item positions. For infinite data where the first page has no notes but later pages might, set ReserveRowNoteSpace="true".

Collapsible row categories

Assign the same stable key to related rows. The grid inserts category headers into the same virtualized item stream as data rows:

<CloudDataGrid DataProvider="LoadAsync"
               EnableRowCategories="true"
               AllowCategoryCollapse="true"
               @bind-CollapsedCategories="_collapsed"
               CategoryHeaderTemplate="CategoryHeader" />

@code {
    private HashSet<string> _collapsed = [];

    private CloudDataGridRow ToRow(Employee employee) => new()
    {
        Id = employee.Id,
        CategoryKey = employee.DepartmentId,
        CategoryLabel = employee.DepartmentName,
        Cells = [employee.Name, employee.Email]
    };

    private RenderFragment<CloudDataGridCategoryContext> CategoryHeader => category => @<text>
        <strong>@category.Label</strong>
        <span>@category.VisibleRowCount loaded</span>
    </text>;
}

EnableRowCategories can be switched at runtime. CollapsedCategories uses stable keys, so expansion state survives data refreshes and paging.


Body height modes

FullHeight (default)

  • Grid fills the full height of its parent container
  • Header and footer stay fixed, only the row area between them scrolls
  • Requires a parent with a definite height (e.g., a fixed-height wrapper or a flex/grid item that stretches)
  • Best for admin dashboards, split-pane layouts, or full-page grids
<div style="height: 600px;">
    <CloudDataGrid HeightMode="CloudDataGridHeightMode.FullHeight" ... />
</div>

RowHeight

  • Grid is exactly tall enough to show RowsPerPage rows (no more, no less)
  • Calculated as RowsPerPage × var(--cloudgrid-row-height)
  • The body scrolls internally if accumulating paging (LoadMore/InfiniteScroll) appends beyond that height
  • Best for embedding a grid in a content flow without forcing a container height
<CloudDataGrid HeightMode="CloudDataGridHeightMode.RowHeight" RowsPerPage="10" ... />

Auto

  • Grid grows vertically to fit its content (all rows visible, no internal scroll by default)
  • Optional MaxHeight parameter caps the grid's height — once content exceeds the cap, it behaves like FullHeight
  • Best for small record sets or dynamic-height scenarios where you want to avoid an artificial viewport

<CloudDataGrid HeightMode="CloudDataGridHeightMode.Auto" MaxHeight="500" ... />

Sorting behavior

If OnSortChanged is handled:

  • grid updates visual sort indicator
  • consumer reloads data server-side using CloudDataGridSort.Key + Direction

If no handler is attached:

  • grid sorts currently loaded rows locally
  • nulls are pushed last
  • mixed values are compared as case-insensitive text

Actions (header, row, bulk, more)

You can define one CloudDataGridAction list and control placement using flags.

new CloudDataGridAction
{
    Key = "delete-selected",
    Text = "Delete",
    Type = CloudDataGridActionType.Button,
    ShowOnBulkHeader = true,
    ShowOnHeader = false
}

Placement guidance:

  • ShowOnHeader = true: direct header action area
  • ShowInMore = true: appears in More (⋯) menu
  • ShowOnBulkHeader = true: appears only when rows are selected
  • ShowOnRow = true: appears per row

Element actions can expand inline content and are cancellable.


Selection

Enable row selection:

<CloudDataGrid ... AllowSelection="true" @bind-SelectedRecords="_selected" />

Details:

  • select-all operates on currently loaded rows
  • selected IDs are exposed through two-way binding
  • hidden input #SelectedRecords is rendered for legacy integrations

Row reordering

Enable and listen:

<CloudDataGrid ... AllowReordering="true" OnRowsReordered="HandleReorder" />

CloudDataGridRowReorder provides:

  • moved RecordId
  • OldIndex, NewIndex
  • full OrderedRecordIds after drop

Export

When Header.AllowExport = true (default), grid injects an export action in the More menu.

Built-in export options:

  • Current page
  • All records (using current search/sort)
  • Selection (only shown when rows are selected)

Files are downloaded as CSV using the package JS module.


Styling and theming

The component uses scoped styles authored in *.razor.less and compiled to *.razor.css.

Core classes

  • .cloudgrid
  • .cloudgrid-head, .cloudgrid-headcell
  • .cloudgrid-row, .cloudgrid-cell
  • .cloudgrid-status
  • .cloudgridheader, .cloudgridheader-action

State classes

  • ._busy
  • ._resizing
  • ._rowdragging
  • ._selectable
  • sorted state adjectives on head cells

CSS variables

Variable Default
--cloudgrid-font-size 14px
--cloudgrid-row-height 32px
--cloudgrid-color #505050
--cloudgrid-background #fff
--cloudgrid-accent-color #000
--cloudgrid-border-color rgba(0,0,0,0.15)
--cloudgrid-head-background #f8f8f8
--cloudgrid-hover-background #e8e8e8
--cloudgrid-selected-background #f8f8f8

Header-specific variables (--cloudgridheader-*) fall back to matching --cloudgrid-* values.

Example:

:root {
    --cloudgrid-accent-color: #0a5dc2;
    --cloudgrid-row-height: 40px;
}

Troubleshooting

“Grid never loads data”

  • Confirm DataProvider is assigned.
  • Verify callback returns non-null CloudDataGridDataResult.

“Sorting doesn’t affect backend data”

  • Implement OnSortChanged and apply request.Sort in your server query.

“LoadMore/InfiniteScroll keeps requesting”

  • In append mode, stop adding rows once end is reached; keep Total accurate.

“No export action visible”

  • Ensure Header is set and AllowExport is true.

License

See repository licensing terms.


Angry Monkey Cloud

This project is part of the Angry Monkey Cloud open-source ecosystem. Follow the shared AI development instructions and browse the project catalog and GitHub organization.

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

Showing the top 2 NuGet packages that depend on AngryMonkey.CloudComponents.DataGrid:

Package Downloads
AngryMonkey.CloudLogin.Components

Package Description

AngryMonkey.CDM.Components

Package Description

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.2.1 38 7/20/2026
4.2.0 211 7/12/2026