feat(ui): add sessionStorage persistence for TreeView expansion state (R11)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
@* Reusable hierarchical tree view with expand/collapse, ARIA roles, and guide lines *@
|
||||
@typeparam TItem
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
@if (_items is null || _items.Count == 0)
|
||||
{
|
||||
@@ -58,6 +59,7 @@ else
|
||||
private IReadOnlyList<TItem>? _items;
|
||||
private HashSet<object> _expandedKeys = new();
|
||||
private bool _initialExpansionApplied;
|
||||
private bool _storageLoaded;
|
||||
|
||||
[Parameter, EditorRequired] public IReadOnlyList<TItem> Items { get; set; } = [];
|
||||
[Parameter, EditorRequired] public Func<TItem, IReadOnlyList<TItem>> ChildrenSelector { get; set; } = default!;
|
||||
@@ -72,6 +74,7 @@ else
|
||||
[Parameter] public object? SelectedKey { get; set; }
|
||||
[Parameter] public EventCallback<object?> SelectedKeyChanged { get; set; }
|
||||
[Parameter] public string SelectedCssClass { get; set; } = "bg-primary bg-opacity-10";
|
||||
[Parameter] public string? StorageKey { get; set; }
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
@@ -79,8 +82,40 @@ else
|
||||
|
||||
if (!_initialExpansionApplied && InitiallyExpanded != null && _items is { Count: > 0 })
|
||||
{
|
||||
_initialExpansionApplied = true;
|
||||
ApplyInitialExpansion(_items);
|
||||
// Only apply InitiallyExpanded when there is no StorageKey, or storage
|
||||
// has already been checked and returned nothing (no prior state).
|
||||
if (StorageKey == null || (_storageLoaded && _expandedKeys.Count == 0))
|
||||
{
|
||||
_initialExpansionApplied = true;
|
||||
ApplyInitialExpansion(_items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender && StorageKey != null)
|
||||
{
|
||||
var json = await JSRuntime.InvokeAsync<string?>("treeviewStorage.load", StorageKey);
|
||||
_storageLoaded = true;
|
||||
|
||||
if (json != null)
|
||||
{
|
||||
var keys = System.Text.Json.JsonSerializer.Deserialize<List<string>>(json);
|
||||
if (keys != null)
|
||||
{
|
||||
_expandedKeys = new HashSet<object>(keys);
|
||||
_initialExpansionApplied = true;
|
||||
}
|
||||
}
|
||||
else if (InitiallyExpanded != null && _items is { Count: > 0 } && !_initialExpansionApplied)
|
||||
{
|
||||
// Storage returned null (no prior state) — fall back to InitiallyExpanded
|
||||
_initialExpansionApplied = true;
|
||||
ApplyInitialExpansion(_items);
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +142,18 @@ else
|
||||
{
|
||||
_expandedKeys.Add(key);
|
||||
}
|
||||
|
||||
PersistExpandedState();
|
||||
}
|
||||
|
||||
private void PersistExpandedState()
|
||||
{
|
||||
if (StorageKey != null)
|
||||
{
|
||||
var keys = _expandedKeys.Select(k => k.ToString()!).ToList();
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(keys);
|
||||
_ = JSRuntime.InvokeVoidAsync("treeviewStorage.save", StorageKey, json);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnContentClick(object key)
|
||||
|
||||
Reference in New Issue
Block a user