@inject IJSRuntime js @code { [Parameter, Required] public FeLibrary CurrentLibrary { get; set; } [Parameter] public EventCallback OnValueChanged { get; set; } }
Library (@FnzDataSet.AllLibrary.Length): 
Library (@FnzDataSet.AllLibrary.Length): 
Filter: 
@foreach (var lib in (ListDataSource).KeepNoEmpty()) { if (lib == null) { } else { } }
@code { private ValueTask ExpandLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList", true); private ValueTask CollapseLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList", false); private ValueTask ToggleLibraryList() => js.InvokeVoidAsync("ShowLibSelectorList"); private string SearchValue { get; set; } private FeLibrary[] ListDataSource => FnzDataSet.AllLibrary?.OrderBy(p => p.Key).Where(p => string.IsNullOrEmpty(SearchValue) || p.Name.Contains(SearchValue, StringComparison.OrdinalIgnoreCase)).ToArray(); private async Task ShowLibraryList() { await ExpandLibraryList(); } private async Task HideLibraryList() { await CollapseLibraryList(); } private void SearchChanged(ChangeEventArgs e) { SearchValue = e.Value.ToString(); StateHasChanged(); } private void SearchKeydown(KeyboardEventArgs e) { if (e.Code == "Enter") { var arr = ListDataSource; if (arr?.Any() == true) { SelectLib(arr.First()); } } } private void SelectLib(FeLibrary lib) { OnValueChanged.InvokeAsync(lib); CollapseLibraryList(); StateHasChanged(); } private async Task> FilterLibrary(IReadOnlyCollection source, string input, CancellationToken ct) { var result = new List(); foreach (var item in source.Where(p => p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase))) result.Add(item); foreach (var item in source.Where(p => !p.Name.StartsWith(input, StringComparison.OrdinalIgnoreCase) && p.Name.Contains(input, StringComparison.OrdinalIgnoreCase))) result.Add(item); return result; } }