Getting started
One package and one service registration - then a BdndProvider around any interactively
rendered region, with draggables and drop targets inside it. You drag data of a type,
not a view, and the drag state lives in C#.
Install
In a Blazor Web App with an interactive client, the package belongs in the .Client project,
next to the pages that drag.
dotnet add package Bit.Bdnd
Register the service
It registers BdndInterop, the scoped wrapper around the script module that every draggable and
drop target injects. The drag-and-drop manager itself is not a service: each BdndProvider
creates its own and shares it with the components inside it. In a Blazor Web App, register it in both
Program.cs files - the pages are prerendered on the server before they run in the browser.
// Program.cs - in every project that renders the components
builder.Services.AddBitBdndServices();
And the namespace, in _Imports.razor:
@using Bit.Bdnd
_content/Bit.Bdnd/bit-bdnd.js, themselves the first time they need it.
A first drag and drop
Wrap the region in a BdndProvider and declare sources and targets inside it. A draggable's
Type is what a target matches against its Accept list, and its Item
is what the target's OnDrop receives. Each one's child content gets the collected state -
IsDragging for a source, IsOver and CanDrop for a target - to
render from.
<BdndProvider> @foreach (var name in _boxes) { <BdndDraggable TItem="string" Type="box" Item="name" Context="drag"> <div class="box" style="opacity: @(drag.IsDragging ? 0.4 : 1)"> @name </div> </BdndDraggable> } <BdndDropTarget TItem="string" Accept="box" OnDrop="HandleDrop" Context="drop"> <div class="dustbin" style="background: @(drop.IsOver ? "#15803d" : "#1f2430")"> @(drop.IsOver ? "Release to drop" : _label) </div> </BdndDropTarget> </BdndProvider> @code { private readonly string[] _boxes = ["Glass", "Banana", "Paper"]; private string _label = "Drag a box here"; private void HandleDrop(BdndDropEventArgs<string> e) => _label = $"Dropped: {e.Item}"; }
BdndProvider; the draggable's
Type is one of the types the target lists in Accept; and the page is interactive,
because a statically rendered page never wires up drag events.
Core concepts
Bdnd brings React DnD's data-driven model to Blazor as components rather than hooks.
| Concept | In Bdnd |
|---|---|
| Items and types | You drag an item - any C# object - of a type, a string. A target accepts the types it lists in Accept or AcceptTypes; the item's .NET type does not take part. |
| Components | BdndProvider, BdndDraggable, BdndDropTarget, BdndDragLayer and BdndDragHandle - React DnD's provider, useDrag, useDrop, useDragLayer and a drag handle. |
| Collected state | What a component's child content renders from: IsDragging, IsOver, IsOverShallow, CanDrop, the item and the offsets. |
| Monitor | IBdndMonitor, a read-only view of the live drag state, on every collected state and callback argument as Monitor. |
| Backend | The browser's native HTML5 drag events, so files, text and links dragged in from outside the browser drop too. |