From 76dc1e21a3fb777c0f0bd831fec69f48654465d4 Mon Sep 17 00:00:00 2001 From: Kebechet Date: Sat, 25 Jul 2026 19:33:52 +0200 Subject: [PATCH 1/2] Document that SortableItemTemplate roots need a @key --- README.MD | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.MD b/README.MD index 9c15ae5..f0f484f 100644 --- a/README.MD +++ b/README.MD @@ -107,6 +107,24 @@ protected override async Task OnInitializedAsync() The `SortableItemTemplate` can contain any markup or components that you want. `SortList` implementation see below. +### Put a `@key` on the root of your item template + +After a drag, the JS interop layer moves the dragged node back to its original position so that the DOM matches the .NET model again, and the model change then triggers a normal Blazor re-render. That is a DOM mutation Blazor's renderer did not perform itself, so without a key its diff matches the reused elements up positionally and can associate the wrong element with the wrong item - typically showing up as stale text, a lost input value, or focus jumping to a neighbouring row. + +Give the outermost element or component inside `SortableItemTemplate` a [`@key`](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/rendering#the-key-directive-attribute) bound to something stable per item: + +```html + + +
+

@item.Name

+
+
+
+``` + +The component cannot apply the key on your behalf: `@key` is a directive attribute that has to sit on an element or component frame, and `SortableList` only ever invokes the template as an opaque `RenderFragment`. Keying it internally would mean wrapping every item in an extra element, which would change the markup and CSS of existing consumers. + ## Attributes ### Properties From 1e89dc5a2b70ad476734e7533648f7632f69a24b Mon Sep 17 00:00:00 2001 From: Kebechet Date: Sat, 25 Jul 2026 19:39:29 +0200 Subject: [PATCH 2/2] Address review: clarify the diff-pairing wording --- README.MD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.MD b/README.MD index f0f484f..cdb35b6 100644 --- a/README.MD +++ b/README.MD @@ -109,7 +109,7 @@ The `SortableItemTemplate` can contain any markup or components that you want. ` ### Put a `@key` on the root of your item template -After a drag, the JS interop layer moves the dragged node back to its original position so that the DOM matches the .NET model again, and the model change then triggers a normal Blazor re-render. That is a DOM mutation Blazor's renderer did not perform itself, so without a key its diff matches the reused elements up positionally and can associate the wrong element with the wrong item - typically showing up as stale text, a lost input value, or focus jumping to a neighbouring row. +After a drag, the JS interop layer moves the dragged node back to its original position so that the DOM matches the .NET model again, and the model change then triggers a normal Blazor re-render. That is a DOM mutation Blazor's renderer did not perform itself, so without a key its diff pairs up the reused elements by position and can associate the wrong element with the wrong item - typically showing up as stale text, a lost input value, or focus jumping to a neighbouring row. Give the outermost element or component inside `SortableItemTemplate` a [`@key`](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/rendering#the-key-directive-attribute) bound to something stable per item: