BlazorSortable 8.0.0
See the version list below for details.
dotnet add package BlazorSortable --version 8.0.0
NuGet\Install-Package BlazorSortable -Version 8.0.0
<PackageReference Include="BlazorSortable" Version="8.0.0" />
<PackageVersion Include="BlazorSortable" Version="8.0.0" />
<PackageReference Include="BlazorSortable" />
paket add BlazorSortable --version 8.0.0
#r "nuget: BlazorSortable, 8.0.0"
#:package BlazorSortable@8.0.0
#addin nuget:?package=BlazorSortable&version=8.0.0
#tool nuget:?package=BlazorSortable&version=8.0.0
BlazorSortable
![]()
A Blazor component that wraps SortableJS, a library for drag-and-drop sorting.
Inspired by BlazorSortable and represents an improved and extended implementation.
Installation
Via NuGet Package Manager
Search for BlazorSortable in NuGet Package Manager.
Via .NET CLI
dotnet add package BlazorSortable
Via PackageReference
Add to your .csproj file:
<ItemGroup>
<PackageReference Include="BlazorSortable" Version="8.*" />
</ItemGroup>
Setup
Add BlazorSortable services in the
Program.csfile of the app where the component runs (InteractiveWebAssemblycomponents require registration in the client app):using BlazorSortable; // ... builder.Services.AddSortable();Add the using directive in
_Imports.razor:@using BlazorSortable
By default, BlazorSortable loads the bundled SortableJS 1.15.7 script and the base stylesheet automatically when the first Sortable component is initialized.
SortableOptions
AddSortable accepts an optional configuration delegate:
| Option | Type | Default | Description |
|---|---|---|---|
AutoLoadSortableJs |
bool |
true |
Loads the bundled SortableJS script automatically |
AutoLoadStylesheet |
bool |
true |
Loads the bundled BlazorSortable stylesheet automatically |
Defaults |
SortableDefaults |
new() |
Default SortableJS behavior used when a component parameter is not set |
You can also pass a preconfigured SortableOptions instance:
builder.Services.AddSortable(new SortableOptions
{
AutoLoadSortableJs = false,
AutoLoadStylesheet = false,
Defaults =
{
ForceFallback = false,
FallbackOnBody = true
}
});
SortableDefaults
| Option | Type | Default | Description |
|---|---|---|---|
Delay |
int |
150 |
Time in milliseconds before sorting starts |
DelayOnTouchOnly |
bool |
true |
Applies Delay only for touch input |
TouchStartThreshold |
int |
4 |
Minimum touch movement, in pixels, before delayed sorting is cancelled |
Animation |
int |
150 |
Animation duration in milliseconds |
ForceFallback |
bool |
true |
Forces SortableJS to use fallback drag behavior instead of native HTML5 drag and drop |
FallbackOnBody |
bool |
false |
Appends the fallback clone element to the document body |
FallbackTolerance |
int |
3 |
Minimum pointer movement, in pixels, before fallback dragging starts |
EmptyInsertThreshold |
int |
5 |
Distance, in pixels, from an empty sortable container at which an item can be inserted |
MultiDragKey |
string |
"Control" |
Key used to select multiple items in multi-drag mode. Set to an empty string to select without holding a modifier key |
Scroll |
bool |
true |
Enables automatic scrolling while dragging near scroll container edges |
RevertOnSpill |
bool |
false |
Reverts the dragged item when it is dropped outside a valid sortable target |
Manual Asset Loading
If you want to manage these assets yourself, disable automatic loading:
builder.Services.AddSortable(options =>
{
options.AutoLoadSortableJs = false;
options.AutoLoadStylesheet = false;
});
When AutoLoadSortableJs is disabled, SortableJS must be available globally as Sortable before any Sortable component initializes.
Bundled Styles
The bundled stylesheet contains only the default helper styles used by BlazorSortable:
.sortable-ghost {
visibility: hidden;
}
.sortable-fallback {
opacity: 1 !important;
}
.sortable-selected {
outline: var(--blazor-sortable-selected-outline-width, 2px) solid var(--blazor-sortable-selected-outline-color, Highlight);
outline-offset: calc(-1 * var(--blazor-sortable-selected-outline-width, 2px));
}
.sortable-swap-highlight {
outline: var(--blazor-sortable-swap-highlight-outline-width, 2px) solid var(--blazor-sortable-swap-highlight-outline-color, Highlight);
outline-offset: calc(-1 * var(--blazor-sortable-swap-highlight-outline-width, 2px));
}
You can disable it with AutoLoadStylesheet = false if you want to provide these styles yourself.
Usage Example
<div class="sortable-sample">
<Sortable Items="todoItems"
Group="tasks"
Class="sortable-column">
<div class="sortable-item">
@context
</div>
</Sortable>
<Sortable Items="doneItems"
Group="tasks"
Class="sortable-column">
<div class="sortable-item">
@context
</div>
</Sortable>
<Sortable TItem="object"
Group="delete"
PutMode="SortablePutMode.Groups"
PutGroups="@(["tasks"])"
Class="sortable-delete" />
</div>
<style>
.sortable-sample {
display: flex;
gap: 16px;
}
.sortable-column,
.sortable-delete {
width: 180px;
min-height: 96px;
padding: 12px;
border: 2px dashed #d0d7de;
border-radius: 6px;
}
.sortable-column {
display: flex;
flex-direction: column;
gap: 8px;
}
.sortable-delete {
border-color: #dc3545;
overflow: hidden;
}
.sortable-item {
padding: 10px 12px;
border: 1px solid #d0d7de;
border-radius: 6px;
background: white;
color: #24292f;
cursor: grab;
user-select: none;
}
</style>
@code {
private readonly IList<string> todoItems = ["Write docs", "Add tests", "Publish package"];
private readonly IList<string> doneItems = ["Create project"];
}
API
Sortable
| Parameter | Type | Default | Description |
|---|---|---|---|
TItem |
notnull |
- | Type of items displayed, sorted, or accepted by the component |
Items |
IList<TItem>? |
null |
Optional backing list for items displayed, sorted, or accepted by the component. When null, accepted drops are reported through events but not stored locally |
ChildContent |
RenderFragment<TItem>? |
null |
Template for rendering each item from Items. If omitted, the component does not render items. When Items is provided, accepted drops are still stored in that list |
Context |
string |
context |
Razor template context name used by ChildContent. This is a Razor template attribute, not a component parameter |
UseItemKeys |
bool |
true |
Enables Blazor @key for rendered item wrappers |
ItemKeySelector |
Func<TItem, object>? |
null |
Function for generating a stable item key. If not set, the item itself is used |
Class |
string? |
null |
CSS class for the container |
Style |
string? |
null |
Inline CSS styles for the container |
Attributes |
IReadOnlyDictionary<string, object?>? |
null |
Additional custom attributes that will be rendered by the component |
Id |
string |
Random GUID |
Unique identifier of the component. Used internally for coordination between Sortable components. Must be globally unique |
Group |
string |
Random GUID |
Name of the group for interacting with other Sortable components |
PullMode |
SortablePullMode? |
null |
Mode for pulling items from this Sortable component |
PullGroups |
string[]? |
null |
Required when PullMode="SortablePullMode.Groups". Specifies the target groups into which items from this Sortable component can be dragged |
CloneFunction |
Func<TItem, TItem>? |
null |
Required when PullMode="SortablePullMode.Clone". A factory method used to create a non-null clone of the dragged item |
PullFunction |
Predicate<SortableTransferContext<TItem>>? |
null |
Required when PullMode="SortablePullMode.Function". Function to determine whether an item can be pulled to the target Sortable component. Works only when the component runs on WebAssembly. |
PutMode |
SortablePutMode? |
null |
Mode for accepting items into this Sortable component |
PutGroups |
string[]? |
null |
Required when PutMode="SortablePutMode.Groups". Specifies the source groups from which this Sortable component can accept items |
PutFunction |
Predicate<SortableTransferContext<object>>? |
null |
Required when PutMode="SortablePutMode.Function". Function to determine whether an item can be accepted by this Sortable component. Works only when the component runs on WebAssembly. |
ConvertFunction |
SortableTryConvertFunc<TItem>? |
null |
Converts incoming items that are not assignable to the target item type. Return false when conversion is not possible |
Sort |
bool |
true |
Enables or disables sorting within this Sortable component |
Delay |
int? |
Defaults.Delay (150) |
Time in milliseconds to define when sorting should start |
DelayOnTouchOnly |
bool? |
Defaults.DelayOnTouchOnly (true) |
Whether the delay should be applied only when the user is using touch |
TouchStartThreshold |
int? |
Defaults.TouchStartThreshold (4) |
Minimum pointer movement that must occur before delayed sorting is cancelled. Values between 3 and 5 are good |
Disabled |
bool |
false |
Disables the Sortable component when set to true |
Animation |
int? |
Defaults.Animation (150) |
Animation duration in milliseconds |
Handle |
string? |
null |
CSS selector for elements that can be dragged, e.g. .my-handle |
Filter |
string? |
null |
CSS selector for elements that cannot be dragged, e.g. .ignore-elements |
DraggableItemSelector |
Predicate<TItem>? |
null |
Function to determine whether an item can be dragged |
DraggableClass |
string |
"sortable-draggable" |
CSS class applied to items that can be dragged |
GhostClass |
string |
"sortable-ghost" |
CSS class for the placeholder during drag |
ChosenClass |
string |
"sortable-chosen" |
CSS class for the chosen element |
DragClass |
string |
"sortable-drag" |
CSS class for the dragged element |
SwapThreshold |
double |
1 |
Percentage of the target that the swap zone will take up, as a float between 0 and 1 |
InvertSwap |
bool |
false |
Set to true to set the swap zone to the sides of the target, for the effect of sorting "in between" items |
InvertedSwapThreshold |
double |
1 |
Percentage of the target that the inverted swap zone will take up, as a float between 0 and 1 |
ForceFallback |
bool? |
Defaults.ForceFallback (true) |
If set to true, the fallback for non-HTML5 browsers will be used, even if an HTML5 browser is used |
FallbackClass |
string |
"sortable-fallback" |
CSS class for the element in fallback mode |
FallbackOnBody |
bool? |
Defaults.FallbackOnBody (false) |
Appends the cloned DOM element to the document body |
FallbackTolerance |
int? |
Defaults.FallbackTolerance (3) |
Emulates the native drag threshold. Specify in pixels how far the mouse should move before it is considered a drag |
EmptyInsertThreshold |
int? |
Defaults.EmptyInsertThreshold (5) |
Distance, in pixels, from an empty sortable container at which an item can be inserted |
MultiDrag |
bool |
false |
Enables multi-drag selection and moving multiple items together |
SelectedClass |
string |
"sortable-selected" |
CSS class for selected items in multi-drag mode |
MultiDragKey |
string? |
Defaults.MultiDragKey ("Control") |
Key used to select multiple items in multi-drag mode. Set to an empty string to select without holding a modifier key |
AvoidImplicitDeselect |
bool |
false |
Prevents automatic deselection when clicking selected items in multi-drag mode |
Swap |
bool |
false |
Enables swap mode. Cannot be used together with MultiDrag |
SwapClass |
string |
"sortable-swap-highlight" |
CSS class applied to items during swap highlighting |
Scroll |
bool? |
Defaults.Scroll (true) |
Enables scrolling of the container during dragging |
RevertOnSpill |
bool? |
Defaults.RevertOnSpill (false) |
Reverts the dragged item when it is dropped outside a valid sortable target |
OnUpdate |
EventCallback<SortableEventArgs<TItem>> |
default |
Raised when the order of items is changed |
OnAdd |
EventCallback<SortableEventArgs<TItem>> |
default |
Raised when an item is accepted by the component |
OnRemove |
EventCallback<SortableEventArgs<TItem>> |
default |
Raised when an item is removed from the component |
OnChange |
EventCallback<SortableEventArgs<TItem>> |
default |
Raised after update, add, or remove operations |
OnSelect |
EventCallback<SortableSelectionEventArgs<TItem>> |
default |
Raised when an item is selected in multi-drag mode |
OnDeselect |
EventCallback<SortableSelectionEventArgs<TItem>> |
default |
Raised when an item is deselected in multi-drag mode |
OnSpill |
EventCallback<SortableSpillEventArgs<TItem>> |
default |
Raised when an item is dropped outside a valid sortable target |
SortablePullMode
| Value | Description |
|---|---|
True |
Allows pulling items |
False |
Prohibits pulling items |
Groups |
Allows pulling items only into specified target groups (requires PullGroups parameter) |
Clone |
Creates a clone of the item when dragging (requires CloneFunction parameter) |
Function |
Uses a custom function to determine whether items can be pulled (requires PullFunction parameter) |
SortablePutMode
| Value | Description |
|---|---|
True |
Allows accepting items |
False |
Prohibits accepting items |
Groups |
Allows accepting items only from specified source groups (requires PutGroups parameter) |
Function |
Uses a custom function to determine whether items can be accepted (requires PutFunction parameter) |
Events
OnUpdate, OnAdd, OnRemove, and OnChange receive a SortableEventArgs<TItem> parameter.
OnSelect and OnDeselect receive a SortableSelectionEventArgs<TItem> parameter.
OnSpill receives a SortableSpillEventArgs<TItem> parameter.
Functions like PullFunction, PutFunction, and ConvertFunction use a SortableTransferContext<T> parameter.
SortableEventArgs
The SortableEventArgs<TItem> class provides information about sorting operations.
| Property | Type | Description |
|---|---|---|
Operation |
SortableChangeOperation |
The operation that changed the list: Update, Add, or Remove |
Item |
TItem |
The primary item participating in the operation |
Items |
IReadOnlyList<TItem> |
Items participating in a multi-drag operation. Empty for single-item operations |
From |
SortableInfo |
Source sortable information |
OldIndex |
int |
The previous index of the primary item in the source sortable |
OldIndexes |
IReadOnlyList<int> |
Previous indexes for a multi-drag operation. Empty for single-item operations |
To |
SortableInfo |
Target sortable information |
NewIndex |
int |
The new index of the primary item in the target sortable |
NewIndexes |
IReadOnlyList<int> |
New indexes for a multi-drag operation. Empty for single-item operations |
IsClone |
bool |
Indicates whether the operation uses a cloned dragged item |
IsSwap |
bool |
Indicates whether the dragged item was swapped with another item. The target swap item is not exposed separately |
SortableSelectionEventArgs
The SortableSelectionEventArgs<TItem> class provides information about multi-drag selection changes.
| Property | Type | Description |
|---|---|---|
Item |
TItem |
The item whose selection state changed |
SelectedItems |
IReadOnlyList<TItem> |
Selected items after the selection change |
SortableSpillEventArgs
The SortableSpillEventArgs<TItem> class provides information about a spill operation.
| Property | Type | Description |
|---|---|---|
Item |
TItem |
The primary item dropped outside a valid sortable target |
Items |
IReadOnlyList<TItem> |
Selected items for a multi-drag spill operation. Empty for single-item operations |
IsClone |
bool |
Indicates whether the spill operation uses a cloned dragged item |
SortableTransferContext
The SortableTransferContext<TItem> class represents the context of transferring an item between sortable components.
| Property | Type | Description |
|---|---|---|
Item |
TItem |
The primary item being transferred |
Items |
IReadOnlyList<TItem> |
Items associated with the transfer when a collection is available |
From |
SortableInfo |
The source sortable information |
To |
SortableInfo |
The target sortable information |
SortableInfo
The SortableInfo type provides sortable identity information.
| Property | Type | Description |
|---|---|---|
Id |
string |
Unique identifier of the Sortable component |
Group |
string |
Group name for interaction with other Sortable components |
Notes
Order of events when moving items between components:
For a non-clone move between components:
OnAddis triggered first - during this event, the item is still present in the source component.OnRemoveis triggered after.
Type mismatch / failed conversion:
If the dragged item is assignable to the target item type, it is added as-is and
ConvertFunctionis not called.
If the item is not assignable,ConvertFunctionis used when provided.
If noConvertFunctionis provided, or it returnsfalse, the item is not accepted and remains in its original position.Moving items between lists with fallback mode:
Components that exchange items should use the same effective
ForceFallbackvalue. Mixing fallback and native HTML5 drag behavior between source and target lists can produce inconsistent DOM and pointer behavior during cross-list moves.Do not create item lists inline in markup:
Pass a stable list instance from
@code. Avoid expressions that create a new list on every render, for example:<Sortable Items="@(["One", "Two", "Three"])"> @context </Sortable>Use a field or property with a stable backing collection instead:
<Sortable Items="items"> @context </Sortable> @code { private readonly IList<string> items = ["One", "Two", "Three"]; }Dragging issues on scrolled page:
If the dragged element appears misaligned when the page is scrolled inside a custom scroll container, set
ForceFallback="false"or
FallbackOnBody="true"Server-side interactivity limitation:
PullFunctionandPutFunctionrequire synchronous JS-to-.NET calls used by SortableJS, which are only available when the component runs on WebAssembly. These options are not supported with server-side interactivity and will throw aPlatformNotSupportedException.Note: Prerendering is supported, but these options require WebAssembly at runtime.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. 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 was computed. 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 was computed. 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. |
-
net6.0
- Microsoft.AspNetCore.Components.Web (>= 6.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on BlazorSortable:
| Repository | Stars |
|---|---|
|
ErsatzTV/legacy
Open-source platform that transforms your personal media library into live, custom TV channels.
|
Major release with breaking changes. See CHANGELOG.md.