Skip to content

Commit

Permalink
🐛 fix(Sortable): re-sort by jsinterop when items changed
Browse files Browse the repository at this point in the history
  • Loading branch information
capdiem committed Dec 23, 2024
1 parent 39ec9fd commit d7b5eff
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
18 changes: 9 additions & 9 deletions src/Masa.Blazor/Components/Sortable/MSortable.razor
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
@typeparam TItem

<MElement Class="@GetClass()"
Style="@GetStyle()"
Tag="@Tag"
id="@Id"
ReferenceCaptureAction="r => Ref = r"
@attributes="@Attributes">
Style="@GetStyle()"
Tag="@Tag"
id="@Id"
ReferenceCaptureAction="r => Ref = r"
@attributes="@Attributes">
@GenItems()
</MElement>

Expand All @@ -25,10 +25,10 @@
var dataId = ItemKey?.Invoke(item);

<MElement Tag="@ItemTag"
Class="@GetClass(_block.Element("item").Name, ItemClass)"
Style="@ItemStyle"
@key="@(dataId ?? (object?)item)"
data-id="@dataId">
Class="@GetClass(_block.Element("item").Name, ItemClass)"
Style="@ItemStyle"
@key="@(dataId ?? (object?)item)"
data-id="@dataId">
@ChildContent(item)
</MElement>
}
Expand Down
3 changes: 1 addition & 2 deletions src/Masa.Blazor/Components/Sortable/MSortableProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.AddContent(0, sb =>
{
var i = 0;
foreach (var item in Items)
{
Dictionary<string, object?> attrs = new()
{
{ "data-id", ItemKey(item) }
};
var context = new SortableItemContext<TItem>(item, attrs);
sb.AddContent(i++, ItemContent?.Invoke(context));
sb.AddContent(1, ItemContent?.Invoke(context));
}
});
}
Expand Down
48 changes: 33 additions & 15 deletions src/Masa.Blazor/Components/Sortable/MSortableProviderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ public bool Disabled
[Parameter] public EventCallback<string> OnRemove { get; set; }

private IEnumerable<TItem>? _prevItems;
private HashSet<string> _prevItemKeys;
private List<string> _internalOrder;
private HashSet<string> _prevItemKeys = [];
private string[] _prevOrder = [];

private DotNetObjectReference<SortableJSInteropHandle>? _sortableJSInteropHandle;
Expand Down Expand Up @@ -219,6 +218,23 @@ protected override void OnParametersSet()
Items.ThrowIfNull(ComponentName);
ItemKey.ThrowIfNull(ComponentName);

if (!Equals(_prevItems, Items))
{
_prevItems = Items;
_prevItemKeys = GetItemKeys();
_renderRateLimiter?.RecordRender();
SortByOrder();
}
else
{
var keys = GetItemKeys();
if (!_prevItemKeys.SetEquals(keys))
{
_prevItemKeys = keys;
SortByOrder();
}
}

if (Order is not null && !_prevOrder.SequenceEqual(Order))
{
_prevOrder = Order.ToArray();
Expand All @@ -239,12 +255,12 @@ private async Task InitAsync()
{
return;
}

if (_sortableJSInteropHandle is null || ContainerSelector is null)
{
return;
}

_jsObjectReference =
await SortableJSModule.InitAsync(ContainerSelector, GenOptions(), Order, _sortableJSInteropHandle);
}
Expand Down Expand Up @@ -277,32 +293,34 @@ private SortableOptions GenOptions()
};
}

private void UpdateOrderInternal(List<string> order)
{
_internalOrder = order;
_ = OrderChanged.InvokeAsync(order);
}

public ValueTask UpdateOrder(List<string> order)
{
UpdateOrderInternal(order);
_ = OrderChanged.InvokeAsync(order);
return ValueTask.CompletedTask;
}

public async ValueTask HandleOnAdd(string key, List<string> order)
{
UpdateOrderInternal(order);

_ = OrderChanged.InvokeAsync(order);
await OnAdd.InvokeAsync(key);
}

public async ValueTask HandleOnRemove(string key, List<string> order)
{
UpdateOrderInternal(order);

_ = OrderChanged.InvokeAsync(order);
await OnRemove.InvokeAsync(key);
}

private void SortByOrder()
{
if (_jsObjectReference is null)
{
return;
}

NextTick(() => _ = _jsObjectReference.SortAsync(Order, false).ConfigureAwait(false));
}

protected override async ValueTask DisposeAsyncCore()
{
_sortableJSInteropHandle?.Dispose();
Expand Down

0 comments on commit d7b5eff

Please sign in to comment.