BlazorBasics.DraggableGrid 1.1.3

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

Nuget Nuget

BlazorBasics.DraggableGrid

A lightweight, customizable, and fully-featured draggable grid component for Blazor applications. Perfect for building dashboards, admin panels, and any interface that requires rearrangeable layouts.

Features

  • Drag & Drop - Intuitive drag and drop with visual feedback
  • Collision Detection - Prevents overlapping items automatically
  • Fully Customizable - CSS variables and theme support
  • Keyboard Controls - Navigate and manipulate with keyboard
  • Generic Data Support - Works with any data type via TData
  • Multiple Themes - Built-in dark and pastel themes
  • Selection Management - Built-in item selection system
  • Resizable Items - Programmatically resize items
  • Accessible - Focus management and keyboard navigation

Installation

Install-Package BlazorBasics.DraggableGrid
dotnet add package BlazorBasics.DraggableGrid

Quick Start

In your _Imports.razor:

@using BlazorBasics.DraggableGrid
@using BlazorBasics.DraggableGrid.Models
@using BlazorBasics.DraggableGrid.ValueObjects

Create a sample page

@page "/dashboard"
@using BlazorBasics.DraggableGrid
@using BlazorBasics.DraggableGrid.Models
@using BlazorBasics.DraggableGrid.ValueObjects

<PageTitle>Dashboard</PageTitle>

<h1>My Dashboard</h1>

<GridVisualization TData="WidgetData"
                   Layout="@_layout"
                   SelectedItem="@_selectedItem"
                   SelectedItemChanged="OnSelectedItemChanged"
                   LayoutChanged="OnLayoutChanged"
                   OnItemRemoved="OnItemRemoved"
                   Theme="@GridTheme.DarkTheme">
    
    <ChildContent Context="widget">
        <div class="widget-content">
            <h3>@widget.Title</h3>
            <p>@widget.Description</p>
            <small>Size: @widget.Size</small>
        </div>
    </ChildContent>
    
</GridVisualization>

@code {
    private GridLayout _layout = new()
    {
        Columns = 8,
        Rows = 10,
        Gap = "24px",
        ColumnSize = "minmax(50px, 1fr)",
        RowSize = "auto"
        Items = new List<GridItem>
        {
            new(new Grid Position(0,0), new Grid Size(2,2)) {
            Data = "Main Title" // This is an object type to store any type of data.
            },
            new(new Grid Position(0,2), new Grid Size(2,2)) {
            Data = "Subtitle or brief description"
            },
            new(new Grid Position(2,0), new Grid Size(2,2)) {
            Data = "Main content that can be longer and occupy multiple cells. Ideal for displaying detailed information."
            },
            new(new Grid Position(2,2), new Grid Size(2,2)) {
            Data = "Side panel or sidebar with additional information"
            },
        }
    };
    
    private GridItem? _selectedItem;
    
    private void OnSelectedItemChanged(GridItem? item)
    {
        _selectedItem = item;
        Console.WriteLine($"Selected item: {item?.Id}");
    }
    
    private void OnLayoutChanged(GridLayout layout)
    {
        _layout = layout;
        Console.WriteLine("Layout changed!");
        // Here you would typically save the layout to your database
    }
    
    private void OnItemRemoved(GridItem item)
    {
        _layout.Items.Remove(item);
        Console.WriteLine($"Removed item: {item.Id}");
    }
    
    public class WidgetData
    {
        public string Title { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public string Size { get; set; } = "Medium";
    }
}

Customization

Using Built-in Themes


<GridVisualization Theme="@GridTheme.Default" ...>


<GridVisualization Theme="@GridTheme.DarkTheme" ...>


<GridVisualization Theme="@GridTheme.PastelTheme" ...>

Creating Custom Themes

var myCustomTheme = new GridTheme
{
    GridBackground = "#f0f8ff",          // Light blue background
    GridBorderColor = "#cce5ff",         // Light blue border
    ItemBorderColor = "#6c757d",         // Gray border for items
    SelectedColor = "#28a745",           // Green selection
    SelectedGlowColor = "rgba(40, 167, 69, 0.3)",
    DraggingColor = "#dc3545",           // Red dragging
    DraggingGlowColor = "rgba(220, 53, 69, 0.3)",
    DropAreaColor = "#17a2b8",           // Teal drop area
    DropAreaBackground = "rgba(23, 162, 184, 0.15)"
};

Custom CSS Variables

You can also override CSS variables directly:

/* In your own CSS file */
.draggable-grid-container {
    --grid-bg: #f8f9fa;
    --grid-border: #dee2e6;
    --item-border: #333;
    --item-shadow: rgba(0, 0, 0, 0.1);
    --hover-shadow: rgba(0, 0, 0, 0.15);
    --selected-color: #007bff;
    --selected-glow: rgba(0, 123, 255, 0.3);
    --dragging-color: #ff6b6b;
    --dragging-glow: rgba(255, 107, 107, 0.3);
    --drop-area-color: #00b7ff;
    --drop-area-bg: rgba(0, 183, 255, 0.2);
    --drop-area-glow: rgba(0, 183, 255, 0.3);
    --drop-area-light-glow: rgba(0, 183, 255, 0.1);
}

Keyboard Controls

The component supports keyboard navigation when AllowKeyboardControls="true":

  • Arrow Keys: Move selected item
  • Space: Select/deselect items
  • Delete/Backspace: Remove selected item
  • Escape: Deselect current item

API Reference

GridVisualization Component

Parameter Type Description Default
Layout GridLayout Grid configuration and items new GridLayout()
ChildContent RenderFragment<TData> Template for rendering item content null
SelectedItem GridItem? Currently selected item null
SelectedItemChanged EventCallback<GridItem?> Fires when selection changes -
LayoutChanged EventCallback<GridLayout> Fires when layout changes -
OnItemRemoved EventCallback<GridItem> Fires when an item is removed -
AllowDragAndDrop bool Enable drag and drop true
AllowKeyboardControls bool Enable keyboard navigation false
Theme GridTheme Color theme configuration GridTheme.Default

GridLayout Model

Property Type Description Default
Columns int Number of grid columns 10
Rows int Number of grid rows 10
ColumnSize string Width of each cell in pixels minmax(50px, 1fr)
RowSize string Height of each cell in pixels minmax(150px, auto)
Gap string Gap between cells in pixels 0
Overflow string Overflow CSS value auto
Items List<GridItem> Collection of grid items new()

GridItem Model inherits GridObject

Property Type Description
Data object Item data (use GetData<T>() to retrieve typed data) ### Methods

Methods

Name Type Description
GetData<T>() T Recover the data from the object matching the T type
IsDataOfType<T>() bool Check if data match with the T type

GridObject Model

Property Type Description
Id srting Unique identifier
Position GridPosition Starting column 0 row 0
Size GridSize Starting 1x1

Methods

Name Type Description
IsEmptyObject() bool Inidicate this object it's only to set position is occuped
Resize(GridSize) void Update size
MoveTo(GridPosition) void Move object to new position
CanReplace(GridGridObjectSize, GridPosition) bool Know if object can be replace by sender in exact position. Can swap

GridPosition ValueObject

Property Type Description
Column int Starting column (0-based)
Row int Starting row (0-based)

GridSize ValueObject

Property Type Description
Width int Number of columns
Height int Number of rows

Public Methods

// Programmatically move items
await gridRef.MoveItem(3, 4);            // Move to column 3, row 4
await gridRef.MoveItemByDelta(1, 0);     // Move right by 1 cell

// Resize items
await gridRef.ResizeItemWidth(item, 1);  // Increase width by 1
await gridRef.ResizeItemHeight(item, -1);// Decrease height by 1

// Selection
await gridRef.DeselectItem();            // Deselect current item

Advanced Usage

Dynamic Item Creation

private void AddNewItem()
{
    var newItem = new GridItem(new GridPosition(0,0), new GridSize(2,2))
    {
        Data = new MyDataType { /* your data */ }
    };
    
    _layout.Items.Add(newItem);
    StateHasChanged();
}

Handling Events

<GridVisualization ...
                   @onitemclick="OnItemClick"
                   @onitemmoved="OnItemMoved"
                   @onitemresized="OnItemResized">
                   
@code {
    private void OnItemClick(GridItem item)
    {
        // Handle item click
    }
    
    private void OnItemMoved(GridItem item, int oldCol, int oldRow)
    {
        // Handle item movement
    }
    
    private void OnItemResized(GridItem item, int oldWidth, int oldHeight)
    {
        // Handle item resize
    }
}

Examples

Dashboard with Multiple Widget Types

<GridVisualization TData="object"
                   Layout="@_dashboardLayout"
                   Theme="@GridTheme.DarkTheme">
    
    <ChildContent Context="widgetData">
        @if (widgetData is ChartData chart)
        {
            <ChartWidget Data="@chart" />
        }
        else if (widgetData is StatsData stats)
        {
            <StatsWidget Data="@stats" />
        }
        else if (widgetData is ListData list)
        {
            <ListWidget Data="@list" />
        }
    </ChildContent>
    
</GridVisualization>

Admin Panel with Toolbar

<div class="admin-panel">
    <div class="toolbar">
        <button @onclick="AddWidget">Add Widget</button>
        <button @onclick="ResetLayout">Reset</button>
        <button @onclick="SaveLayout">Save</button>
    </div>
    
    <GridVisualization @ref="_gridRef"
                       TData="AdminWidget"
                       Layout="@_adminLayout">
        
        <ChildContent Context="widget">
            <div class="admin-widget">
                <div class="widget-header">
                    <span>@widget.Name</span>
                    <button @onclick="() => RemoveWidget(widget)">X</button>
                </div>
                <div class="widget-body">
                    @widget.Content
                </div>
            </div>
        </ChildContent>
        
    </GridVisualization>
</div>

@code {
    private GridVisualization<AdminWidget> _gridRef;
    
    private async Task AddWidget()
    {
        // Add new widget logic
    }
    
    private async Task RemoveWidget(AdminWidget widget)
    {
        await _gridRef.DeselectItem();
        _adminLayout.Items.RemoveAll(i => i.GetData<AdminWidget>() == widget);
    }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  • Fork the repository
  • Create your feature branch (git checkout -b feature/AmazingFeature)
  • Commit your changes (git commit -m 'Add some AmazingFeature')
  • Push to the branch (git push origin feature/AmazingFeature)
  • Open a Pull Request

License

This project is licensed under the MIT License.

Acknowledgments

  • Built with love for the Blazor community
  • Inspired by the need for simple, effective dashboard components
  • Thanks to all contributors and users

Made with love by DrUalcman

If you find this component useful, please consider giving it a star on GitHub!

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  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
1.1.3 189 12/23/2025
1.1.2 184 12/22/2025
1.0.1 450 12/10/2025
1.0.0 451 12/9/2025

Improved events calbacks. Fixed issue when select/unselect item with space bar. Removed debug console lines.