diff --git a/BlazorAppTest/Pages/HxSearchBoxTest.razor b/BlazorAppTest/Pages/HxSearchBoxTest.razor index 086ec901..b3b51bb1 100644 --- a/BlazorAppTest/Pages/HxSearchBoxTest.razor +++ b/BlazorAppTest/Pages/HxSearchBoxTest.razor @@ -1,6 +1,12 @@ @page "/HxSearchBoxTest" - + + +
Search for Mouse, Table or Door...
+
+
+ +
Search for Mouse, Table or Door...
@@ -9,6 +15,35 @@
+ + +
Search for Mouse, Table or Door...
+
+
+ + + + + + + + + +
Search for Mouse, Table or Door...
+
+ +
+ Not found. +
+
+
+ + + +
Search for Mouse, Table or Door...
+
+
+ @code { List Data { get; set; } = new() { diff --git a/Havit.Blazor.Components.Web.Bootstrap.Documentation/Pages/Components/HxSearchBoxDoc/HxSearchBox_Demo.razor b/Havit.Blazor.Components.Web.Bootstrap.Documentation/Pages/Components/HxSearchBoxDoc/HxSearchBox_Demo.razor index 581b9a0e..99040bd6 100644 --- a/Havit.Blazor.Components.Web.Bootstrap.Documentation/Pages/Components/HxSearchBoxDoc/HxSearchBox_Demo.razor +++ b/Havit.Blazor.Components.Web.Bootstrap.Documentation/Pages/Components/HxSearchBoxDoc/HxSearchBox_Demo.razor @@ -1,61 +1,62 @@  - -
Search for Mouse, Table or Door...
-
- -
Sorry, I did not find that...
-
+ Label="Example" + TItem="SearchBoxItem" + ItemTitleSelector="i => i.Title" + ItemSubtitleSelector="i => i.Subtitle" + ItemIconSelector="i => i.Icon" + Placeholder="Search" + OnItemSelected="OnItemSelected" + OnTextQueryTriggered="OnTextQueryTriggered"> + +
Search for Mouse, Table or Door...
+
+ +
Sorry, I did not find that...
+

- Last selected item: @selectedItem?.Title
- Last triggered text-query: @triggeredTextQuery
+ Last selected item: @selectedItem?.Title
+ Last triggered text-query: @triggeredTextQuery

@code { - private SearchBoxItem selectedItem; - private string triggeredTextQuery; - - List Data { get; set; } = new() - { - new() { Title = "Table", Subtitle = "50 000", Icon = BootstrapIcon.Table }, - new() { Title = "Mouse", Subtitle = "400", Icon = BootstrapIcon.Mouse }, - new() { Title = "Door", Subtitle = "1000", Icon = BootstrapIcon.DoorClosed }, - new() { Title = "Big table", Subtitle = "9 000", Icon = BootstrapIcon.Table }, - new() { Title = "Small table", Subtitle = "7 200", Icon = BootstrapIcon.Table } - }; - - private void OnItemSelected(SearchBoxItem item) - { - selectedItem = item; - } - - private void OnTextQueryTriggered(string text) - { - triggeredTextQuery = text; - } - - private async Task> ProvideSearchResults(SearchBoxDataProviderRequest request) - { - await Task.Delay(400); // imitate slower server API - - return new() - { - Data = Data.Where(i => i.Title.Contains(request.UserInput, StringComparison.OrdinalIgnoreCase)) - }; - } - - internal class SearchBoxItem - { - public string Title { get; set; } - public string Subtitle { get; set; } - public BootstrapIcon Icon { get; set; } - } + private SearchBoxItem selectedItem; + private string triggeredTextQuery; + + List Data { get; set; } = new() + { + new() { Title = "Table", Subtitle = "50 000", Icon = BootstrapIcon.Table }, + new() { Title = "Mouse", Subtitle = "400", Icon = BootstrapIcon.Mouse }, + new() { Title = "Door", Subtitle = "1000", Icon = BootstrapIcon.DoorClosed }, + new() { Title = "Big table", Subtitle = "9 000", Icon = BootstrapIcon.Table }, + new() { Title = "Small table", Subtitle = "7 200", Icon = BootstrapIcon.Table } + }; + + private void OnItemSelected(SearchBoxItem item) + { + selectedItem = item; + } + + private void OnTextQueryTriggered(string text) + { + triggeredTextQuery = text; + } + + private async Task> ProvideSearchResults(SearchBoxDataProviderRequest request) + { + await Task.Delay(400); // imitate slower server API + + return new() + { + Data = Data.Where(i => i.Title.Contains(request.UserInput, StringComparison.OrdinalIgnoreCase)) + }; + } + + internal class SearchBoxItem + { + public string Title { get; set; } + public string Subtitle { get; set; } + public BootstrapIcon Icon { get; set; } + } } diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor index cb813814..826cf574 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor @@ -13,44 +13,44 @@ OnHidden="HandleDropdownMenuHidden" id="@dropdownToggleElementId"> -
- @if (!string.IsNullOrEmpty(Label)) + @if (!string.IsNullOrEmpty(Label) && LabelType == Havit.Blazor.Components.Web.Bootstrap.LabelType.Regular) + { + + } +
+ + @if (InputGroupStartText is not null) { - + @InputGroupStartText } - - - @if (InputGroupStartText is not null) - { - @InputGroupStartText - } - @InputGroupStartTemplate + @InputGroupStartTemplate - - - @InputGroupEndTemplate + - @if (InputGroupEndText is not null) - { - @InputGroupEndText - } - + @if (!string.IsNullOrEmpty(Label) && LabelType == Havit.Blazor.Components.Web.Bootstrap.LabelType.Floating) + { + + } - @if (InputGroupEndText is null && InputGroupEndTemplate is null) + @if (!HasInputGroupEnd) { if (dataProviderInProgress) { @@ -71,6 +71,13 @@
} } + + @InputGroupEndTemplate + + @if (InputGroupEndText is not null) + { + @InputGroupEndText + }
diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs index 674e3e97..115d01a4 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs @@ -1,4 +1,5 @@ using Havit.Blazor.Components.Web.Bootstrap.Internal; +using Microsoft.Extensions.Localization; using Microsoft.JSInterop; namespace Havit.Blazor.Components.Web.Bootstrap; @@ -209,7 +210,9 @@ public partial class HxSearchBox : IAsyncDisposable [Inject] protected IJSRuntime JSRuntime { get; set; } - protected bool HasInputGroupsEffective => !String.IsNullOrWhiteSpace(InputGroupStartText) || !String.IsNullOrWhiteSpace(InputGroupEndText) || (InputGroupStartTemplate is not null) || (InputGroupEndTemplate is not null); + protected bool HasInputGroups => HasInputGroupStart || HasInputGroupEnd; + private bool HasInputGroupStart => !String.IsNullOrWhiteSpace(InputGroupStartText) || (InputGroupStartTemplate is not null); + private bool HasInputGroupEnd => !String.IsNullOrWhiteSpace(InputGroupEndText) || (InputGroupEndTemplate is not null); private string dropdownToggleElementId = "hx" + Guid.NewGuid().ToString("N"); private string dropdownId = "hx" + Guid.NewGuid().ToString("N"); @@ -229,7 +232,6 @@ public partial class HxSearchBox : IAsyncDisposable private IJSObjectReference jsModule; private DotNetObjectReference> dotnetObjectReference; private bool disposed = false; - public HxSearchBox() { dotnetObjectReference = DotNetObjectReference.Create(this); diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.css b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.css index f0b7bcb1..f99c4def 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.css +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.css @@ -10,13 +10,18 @@ transform: translateY(-50%); display: flex; align-items: center; - z-index: 1; + z-index: 10; } ::deep .hx-search-box-input-icon-end { right: .75rem; } +::deep .hx-search-box-input-with-search-icon { + border-top-right-radius: 0.375rem !important; + border-bottom-right-radius: 0.375rem !important; +} + .dropdown-item:not(:active) ::deep .hx-search-box-item-title { color: var(--hx-search-box-item-title-color); } diff --git a/Havit.Blazor.Grpc.Core/ProtoBufModelConfiguration.cs b/Havit.Blazor.Grpc.Core/ProtoBufModelConfiguration.cs index 82fd44b2..c5656307 100644 --- a/Havit.Blazor.Grpc.Core/ProtoBufModelConfiguration.cs +++ b/Havit.Blazor.Grpc.Core/ProtoBufModelConfiguration.cs @@ -25,6 +25,13 @@ public static RuntimeTypeModel RegisterApplicationContracts(this RuntimeTypeMode var fieldNumber = 1; foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { + // protobuf-net requires the property to have a setter (can be private) + // by adding this check we enable support for computed get-properties (not serialized) + if (property.GetSetMethod(nonPublic: true) is null) + { + continue; + } + modelType.AddField(fieldNumber, property.Name); fieldNumber++; }