diff --git a/src/MudBlazor.Docs/Shared/Appbar.razor b/src/MudBlazor.Docs/Shared/Appbar.razor index 4318e06f84a..09cfbbe27b6 100644 --- a/src/MudBlazor.Docs/Shared/Appbar.razor +++ b/src/MudBlazor.Docs/Shared/Appbar.razor @@ -69,7 +69,9 @@ @if (DisplaySearchBar) { - + @result.Title @result.SubTitle @@ -86,16 +88,26 @@ - - + - + @result.Title @result.SubTitle -
- Nothing found, do a search -
+ + @* This text element will always be rendered but it's easier to write it this way *@ + + @if (!_searchDialogAutocompleteOpen) + { + @("Use the box above to search the docs") + } + else if (_searchDialogReturnedItemsCount == 0) + { + @("No results found") + } +
diff --git a/src/MudBlazor.Docs/Shared/Appbar.razor.cs b/src/MudBlazor.Docs/Shared/Appbar.razor.cs index e805fe4bb67..47fb73156df 100644 --- a/src/MudBlazor.Docs/Shared/Appbar.razor.cs +++ b/src/MudBlazor.Docs/Shared/Appbar.razor.cs @@ -15,6 +15,8 @@ namespace MudBlazor.Docs.Shared; public partial class Appbar { private bool _searchDialogOpen; + private bool _searchDialogAutocompleteOpen; + private int _searchDialogReturnedItemsCount; private string _badgeTextSoon = "coming soon"; private MudAutocomplete _searchAutocomplete = null!; private DialogOptions _dialogOptions = new() { Position = DialogPosition.TopCenter, NoHeader = true }; @@ -91,6 +93,17 @@ public partial class Appbar } ]; + public bool IsSearchDialogOpen + { + get => _searchDialogOpen; + set + { + _searchDialogAutocompleteOpen = default; + _searchDialogReturnedItemsCount = default; + _searchDialogOpen = value; + } + } + [Inject] private NavigationManager NavigationManager { get; set; } = null!; @@ -130,5 +143,5 @@ private Task> Search(string text) return ApiLinkService.Search(text); } - private void OpenSearchDialog() => _searchDialogOpen = true; + private void OpenSearchDialog() => IsSearchDialogOpen = true; } diff --git a/src/MudBlazor.UnitTests/Components/AutocompleteTests.cs b/src/MudBlazor.UnitTests/Components/AutocompleteTests.cs index 7714543a43c..abac476c16b 100644 --- a/src/MudBlazor.UnitTests/Components/AutocompleteTests.cs +++ b/src/MudBlazor.UnitTests/Components/AutocompleteTests.cs @@ -264,6 +264,8 @@ public async Task AutocompleteTest6() var mudText = comp.FindAll("p.mud-typography"); mudText[mudText.Count - 1].InnerHtml.Should().Contain("Not all items are shown"); //ensure the text is shown + + comp.FindAll("div.mud-popover .mud-autocomplete-more-items").Count.Should().Be(1); } /// @@ -280,6 +282,8 @@ public async Task AutocompleteTest7() var mudText = comp.FindAll("p.mud-typography"); mudText[mudText.Count - 1].InnerHtml.Should().Contain("No items found, try another search"); //ensure the text is shown + + comp.FindAll("div.mud-popover .mud-autocomplete-no-items").Count.Should().Be(1); } /// @@ -1237,6 +1241,8 @@ public async Task Autocomplete_Should_LoadListStartWhenSetAndThereAreItems() var mudText = comp.FindAll("p.mud-typography"); mudText[0].InnerHtml.Should().Contain("StartList_Content"); //ensure the text is shown + + comp.FindAll("div.mud-popover .mud-autocomplete-before-items").Count.Should().Be(1); } /// @@ -1253,6 +1259,8 @@ public async Task Autocomplete_Should_LoadListEndWhenSetAndThereAreItems() var mudText = comp.FindAll("p.mud-typography"); mudText[mudText.Count - 1].InnerHtml.Should().Contain("EndList_Content"); //ensure the text is shown + + comp.FindAll("div.mud-popover .mud-autocomplete-after-items").Count.Should().Be(1); } /// @@ -1299,5 +1307,33 @@ public async Task Autocomplete_Should_ApplyListItemClass() comp.WaitForAssertion(() => comp.Find("div.mud-list-item").ClassList.Should().Contain(listItemClassTest)); } + + [Test] + public async Task Autocomplete_ReturnedItemsCount_Should_Be_Accurate() + { + Task> search(string value) + { + var values = new string[] { "Lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit" }; + return Task.FromResult(values.Where(x => x.Contains(value, StringComparison.InvariantCultureIgnoreCase))); + } + + var comp = Context.RenderComponent>(); + comp.SetParametersAndRender(p => p + .Add(x => x.Value, "nothing will ever match this") + .Add(x => x.SearchFunc, search) + .Add(x => x.DebounceInterval, 0)); + + int? count = null; + comp.Instance.ReturnedItemsCountChanged = new EventCallbackFactory().Create(this, v => count = v); + + comp.Find("input").Input("Lorem"); + comp.WaitForAssertion(() => count.Should().Be(1)); + ; + comp.Find("input").Input("ip"); + comp.WaitForAssertion(() => count.Should().Be(2)); + ; + comp.Find("input").Input("wtf"); + comp.WaitForAssertion(() => count.Should().Be(0)); + } } } diff --git a/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor b/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor index ee7e01a98c7..b90a910abce 100644 --- a/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor +++ b/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor @@ -48,7 +48,7 @@ @if (BeforeItemsTemplate != null) { -
+
@BeforeItemsTemplate
} @@ -80,15 +80,15 @@ } } - @if (MoreItemsTemplate != null && _itemsReturned > MaxItems) + @if (MoreItemsTemplate != null && _returnedItemsCount > MaxItems) { -
+
@MoreItemsTemplate
} @if (AfterItemsTemplate != null) { -
+
@AfterItemsTemplate
} @@ -96,7 +96,7 @@ } else if (NoItemsTemplate != null) { -
+
@NoItemsTemplate
} diff --git a/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor.cs b/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor.cs index 3e2f6a07c70..9cdd26d3da3 100644 --- a/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor.cs +++ b/src/MudBlazor/Components/Autocomplete/MudAutocomplete.razor.cs @@ -26,7 +26,7 @@ public partial class MudAutocomplete : MudBaseInput, IDisposable private bool _isProcessingValue; private int _selectedListItemIndex = 0; private int _elementKey = 0; - private int _itemsReturned; //the number of items returned by the search function + private int _returnedItemsCount; private bool _isOpen; private MudInput _elementReference; private CancellationTokenSource _cancellationTokenSrc; @@ -354,6 +354,16 @@ public partial class MudAutocomplete : MudBaseInput, IDisposable [Parameter] public EventCallback OnClearButtonClick { get; set; } + /// + /// An event triggered when the number of items returned by the search query has changed. + /// + /// If the number is 0, will be shown.
+ /// If the number is beyond , will be shown. + ///
+ ///
+ [Parameter] + public EventCallback ReturnedItemsCountChanged { get; set; } + /// /// Returns the open state of the drop-down. /// @@ -494,6 +504,12 @@ private void CancelToken() } } + private Task SetReturnedItemsCountAsync(int value) + { + _returnedItemsCount = value; + return ReturnedItemsCountChanged.InvokeAsync(value); + } + /// /// This async method needs to return a task and be awaited in order for /// unit tests that trigger this method to work correctly. @@ -542,7 +558,7 @@ private async Task OnSearchAsync() Logger.LogWarning("The search function failed to return results: " + e.Message); } - _itemsReturned = searchedItems.Length; + await SetReturnedItemsCountAsync(searchedItems.Length); if (MaxItems.HasValue) { searchedItems = searchedItems.Take(MaxItems.Value).ToArray();