From eae22a075f5fbdd98dde19f5437b55b6dc5d4d0e Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Wed, 4 Sep 2024 16:37:44 -0400 Subject: [PATCH 1/8] [HxRadioButtonList][HxCheckboxList] Adds Toggle Button view Adds toggle option to HxRadioButtonList and HxCheckboxList --- .../Forms/HxCheckbox.cs | 10 ++++- .../Forms/HxCheckboxList.cs | 12 ++++- .../Forms/HxInputBase.cs | 20 +++++++-- .../Forms/HxRadioButtonListBase.cs | 31 ++++++++----- .../Forms/Internal/IInputWithToggleButton.cs | 16 +++++++ .../InputAsToggle.cs | 15 +++++++ .../Havit.Blazor.Components.Web.Bootstrap.xml | 45 +++++++++++++++++++ 7 files changed, 131 insertions(+), 18 deletions(-) create mode 100644 Havit.Blazor.Components.Web.Bootstrap/Forms/Internal/IInputWithToggleButton.cs create mode 100644 Havit.Blazor.Components.Web.Bootstrap/InputAsToggle.cs diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckbox.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckbox.cs index aba50774e..2f66a1633 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckbox.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckbox.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Localization; +using Havit.Blazor.Components.Web.Bootstrap.Internal; +using Microsoft.Extensions.Localization; namespace Havit.Blazor.Components.Web.Bootstrap; @@ -7,7 +8,7 @@ namespace Havit.Blazor.Components.Web.Bootstrap; /// (Replaces the former HxInputCheckbox component which was dropped in v 4.0.0.) /// Full documentation and demos: https://havit.blazor.eu/components/HxCheckbox /// -public class HxCheckbox : HxInputBase +public class HxCheckbox : HxInputBase, IInputWithToggleButton { /// /// Set of settings to be applied to the component instance. @@ -19,6 +20,11 @@ public class HxCheckbox : HxInputBase /// protected override CheckboxSettings GetSettings() => Settings; + /// + /// Input as toggle or regular. + /// + [Parameter] public InputAsToggle? InputAsToggle { get; set; } + /// /// Text to display next to the checkbox. /// diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs index 52256298e..0c92f441b 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs @@ -1,4 +1,5 @@ using System.Linq.Expressions; +using Havit.Blazor.Components.Web.Bootstrap.Internal; namespace Havit.Blazor.Components.Web.Bootstrap; @@ -6,7 +7,7 @@ namespace Havit.Blazor.Components.Web.Bootstrap; /// Renders a multi-selection list of controls.
/// Full documentation and demos: https://havit.blazor.eu/components/HxCheckboxList /// -public class HxCheckboxList : HxInputBase> // cannot use an array: https://github.com/dotnet/aspnetcore/issues/15014 +public class HxCheckboxList : HxInputBase>, IInputWithToggleButton // cannot use an array: https://github.com/dotnet/aspnetcore/issues/15014 { /// /// Items to display. @@ -19,6 +20,11 @@ public class HxCheckboxList : HxInputBase> // cannot /// [Parameter] public Func ItemTextSelector { get; set; } + /// + /// Input as toggle or regular. + /// + [Parameter] public InputAsToggle? InputAsToggle { get; set; } + /// /// Selects the value from the item. /// Not required when TValue is the same as TItem. @@ -113,6 +119,8 @@ protected override void BuildRenderInput(RenderTreeBuilder builder) if (_itemsToRender.Count > 0) { + var inputAsToggleEffective = (this as IInputWithToggleButton).InputAsToggleEffective; + UglyHack uglyHack = new UglyHack(); // see comment below foreach (var item in _itemsToRender) @@ -126,7 +134,7 @@ protected override void BuildRenderInput(RenderTreeBuilder builder) builder.AddAttribute(4, nameof(HxCheckbox.ValueChanged), EventCallback.Factory.Create(this, @checked => HandleValueChanged(@checked, item))); builder.AddAttribute(5, nameof(HxCheckbox.Enabled), EnabledEffective); - builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, ItemCssClassSelector?.Invoke(item))); + builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-group" : null, ItemCssClassSelector?.Invoke(item))); builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxInputBase.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxInputBase.cs index 56cdfc0a4..5ad0f9e55 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxInputBase.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxInputBase.cs @@ -108,10 +108,22 @@ public abstract class HxInputBase : InputBase, ICascadeEnabledCo /// /// The CSS class to be rendered with the wrapping div. /// - private protected virtual string CoreCssClass => CssClassHelper.Combine("hx-form-group position-relative", - ((this is IInputWithLabelType inputWithLabelType) && (inputWithLabelType.LabelTypeEffective == LabelType.Floating)) - ? "form-floating" - : null); + private protected virtual string CoreCssClass + { + get + { + var cssClass = ""; + if ((this is IInputWithToggleButton tbutton) && (tbutton.InputAsToggleEffective == InputAsToggle.Toggle)) + { + cssClass = CssClassHelper.Combine(cssClass, "btn-group"); + } + if ((this is IInputWithLabelType inputWithLabelType) && (inputWithLabelType.LabelTypeEffective == LabelType.Floating)) + { + cssClass = CssClassHelper.Combine(cssClass, "form-floating"); + } + return CssClassHelper.Combine("hx-form-group position-relative", cssClass); + } + } /// /// The CSS class to be rendered with the input element. diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs index d5146271c..df6e92a84 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs @@ -1,4 +1,5 @@ -using Havit.Blazor.Components.Web.Infrastructure; +using Havit.Blazor.Components.Web.Bootstrap.Internal; +using Havit.Blazor.Components.Web.Infrastructure; namespace Havit.Blazor.Components.Web.Bootstrap; @@ -7,13 +8,18 @@ namespace Havit.Blazor.Components.Web.Bootstrap; /// /// Type of value. /// Type of items. -public abstract class HxRadioButtonListBase : HxInputBase +public abstract class HxRadioButtonListBase : HxInputBase, IInputWithToggleButton { /// /// Allows grouping radios on the same horizontal row by rendering them inline. Default is false. /// [Parameter] public bool Inline { get; set; } + /// + /// Input as toggle or regular. + /// + [Parameter] public InputAsToggle? InputAsToggle { get; set; } + /// /// Selects a value from an item. /// Not required when TValueType is the same as TItemTime. @@ -134,6 +140,7 @@ protected void BuildRenderInput_RenderRadioItem(RenderTreeBuilder builder, int i var item = _itemsToRender[index]; if (item != null) { + var inputAsToggleEffective = (this as IInputWithToggleButton).InputAsToggleEffective; bool selected = (index == _selectedItemIndex); if (selected) { @@ -142,13 +149,14 @@ protected void BuildRenderInput_RenderRadioItem(RenderTreeBuilder builder, int i string inputId = GroupName + "_" + index.ToString(); - builder.OpenElement(100, "div"); - - // TODO CoreCssClass - builder.AddAttribute(101, "class", CssClassHelper.Combine("form-check", Inline ? "form-check-inline" : null, ItemCssClassImpl, ItemCssClassSelectorImpl?.Invoke(item))); - + if (inputAsToggleEffective != Bootstrap.InputAsToggle.Toggle) + { + builder.OpenElement(100, "div"); + // TODO CoreCssClass + builder.AddAttribute(101, "class", CssClassHelper.Combine("form-check", Inline ? "form-check-inline" : null, ItemCssClassImpl, ItemCssClassSelectorImpl?.Invoke(item))); + } builder.OpenElement(200, "input"); - builder.AddAttribute(201, "class", CssClassHelper.Combine("form-check-input", ItemInputCssClassImpl, ItemInputCssClassSelectorImpl?.Invoke(item))); + builder.AddAttribute(201, "class", CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : "form -check-input", ItemInputCssClassImpl, ItemInputCssClassSelectorImpl?.Invoke(item))); builder.AddAttribute(202, "type", "radio"); builder.AddAttribute(203, "name", GroupName); builder.AddAttribute(204, "id", inputId); @@ -165,7 +173,7 @@ protected void BuildRenderInput_RenderRadioItem(RenderTreeBuilder builder, int i builder.CloseElement(); // input builder.OpenElement(300, "label"); - builder.AddAttribute(301, "class", CssClassHelper.Combine("form-check-label", ItemTextCssClassImpl, ItemTextCssClassSelectorImpl?.Invoke(item))); + builder.AddAttribute(301, "class", CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn" : "form-check-label", ItemTextCssClassImpl, ItemTextCssClassSelectorImpl?.Invoke(item))); builder.AddAttribute(302, "for", inputId); if (ItemTemplateImpl != null) { @@ -177,7 +185,10 @@ protected void BuildRenderInput_RenderRadioItem(RenderTreeBuilder builder, int i } builder.CloseElement(); // label - builder.CloseElement(); // div + if (inputAsToggleEffective != Bootstrap.InputAsToggle.Toggle) + { + builder.CloseElement(); // div + } } } diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/Internal/IInputWithToggleButton.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/Internal/IInputWithToggleButton.cs new file mode 100644 index 000000000..e9efd2968 --- /dev/null +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/Internal/IInputWithToggleButton.cs @@ -0,0 +1,16 @@ +namespace Havit.Blazor.Components.Web.Bootstrap.Internal; +/// +/// Represents an input with a toggle button option +/// +public interface IInputWithToggleButton +{ + /// + /// Gets or sets the input as toggle or regular. + /// + InputAsToggle? InputAsToggle { get; set; } + + /// + /// Gets the effective input type. + /// + InputAsToggle InputAsToggleEffective => InputAsToggle ?? Bootstrap.InputAsToggle.Regular; +} diff --git a/Havit.Blazor.Components.Web.Bootstrap/InputAsToggle.cs b/Havit.Blazor.Components.Web.Bootstrap/InputAsToggle.cs new file mode 100644 index 000000000..352679b6b --- /dev/null +++ b/Havit.Blazor.Components.Web.Bootstrap/InputAsToggle.cs @@ -0,0 +1,15 @@ +namespace Havit.Blazor.Components.Web.Bootstrap; +/// +/// Input display type. +/// +public enum InputAsToggle +{ + /// + /// Regular + /// + Regular = 0, + /// + /// Toggle buttons. + /// + Toggle = 1 +} diff --git a/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml b/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml index d7ebeed45..2b5c44f34 100644 --- a/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml +++ b/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml @@ -2999,6 +2999,21 @@ Gets the CSS class for the input group size. + + + Represents an input with a toggle button option + + + + + Gets or sets the input as toggle or regular. + + + + + Gets the effective input type. + + Specifies the render order of label and value/input. @@ -3367,6 +3382,11 @@ Returns an optional set of component settings. + + + Input as toggle or regular. + + Text to display next to the checkbox. @@ -3447,6 +3467,11 @@ When not set, ToString() is used. + + + Input as toggle or regular. + + Selects the value from the item. @@ -4713,6 +4738,11 @@ Allows grouping radios on the same horizontal row by rendering them inline. Default is false. + + + Input as toggle or regular. + + Selects a value from an item. @@ -6998,6 +7028,21 @@ + + + Input display type. + + + + + Regular + + + + + Toggle buttons. + + Non-generic API for . From 25a1341d9abe6ceae1bc631d255eada0a707a2bb Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Wed, 4 Sep 2024 16:44:59 -0400 Subject: [PATCH 2/8] Added documentation for CheckboxList and RadioButtonList --- .../HxCheckboxList_Demo_Toggle.razor | 25 +++++++++++++++++++ .../HxCheckboxList_Documentation.razor | 5 ++++ .../HxRadioButtonList_Demo_Toggle.razor | 22 ++++++++++++++++ .../HxRadioButtonList_Documentation.razor | 2 ++ 4 files changed, 54 insertions(+) create mode 100644 Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor create mode 100644 Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor diff --git a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor new file mode 100644 index 000000000..3f39d63d8 --- /dev/null +++ b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor @@ -0,0 +1,25 @@ +@inject IDemoDataService DemoDataService + + + +

+ Selected employee IDs: @String.Join(", ", selectedEmployeeIds.Select(i => i.ToString()) ?? Enumerable.Empty()) +

+ +@code +{ + private IEnumerable data; + private List selectedEmployeeIds { get; set; } = new(); + + protected override async Task OnParametersSetAsync() + { + data = await DemoDataService.GetPreferredEmployeesAsync(count: 5); + } +} diff --git a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor index f3f5df6b2..46e4813f5 100644 --- a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor +++ b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor @@ -8,4 +8,9 @@

Group checkboxes on the same horizontal row by adding Inline="true".

+ + +

Change the look of checkboxes by adding InputAsToggle="InputAsToggle.Toggle"

+ + diff --git a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor new file mode 100644 index 000000000..409a4e7a7 --- /dev/null +++ b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor @@ -0,0 +1,22 @@ +@inject IDemoDataService DemoDataService + + + +

Selected employee ID: @selectedEmployeeId

+ +@code { + private IEnumerable data; + private int? selectedEmployeeId; + + protected override async Task OnInitializedAsync() + { + data = await DemoDataService.GetPreferredEmployeesAsync(count: 5); + } +} \ No newline at end of file diff --git a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor index 0807f85dc..00f9fc4be 100644 --- a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor +++ b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor @@ -11,4 +11,6 @@

Group radios on the same horizontal row by adding Inline="true".

+ + \ No newline at end of file From c8250b464ef65d890cbf132abbc959fd22d59ef0 Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Wed, 4 Sep 2024 16:44:59 -0400 Subject: [PATCH 3/8] Added documentation for CheckboxList and RadioButtonList --- .../HxCheckboxList_Demo_Toggle.razor | 25 +++++++++++++++++++ .../HxCheckboxList_Documentation.razor | 5 ++++ .../HxRadioButtonList_Demo_Toggle.razor | 22 ++++++++++++++++ .../HxRadioButtonList_Documentation.razor | 3 +++ 4 files changed, 55 insertions(+) create mode 100644 Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor create mode 100644 Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor diff --git a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor new file mode 100644 index 000000000..3f39d63d8 --- /dev/null +++ b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor @@ -0,0 +1,25 @@ +@inject IDemoDataService DemoDataService + + + +

+ Selected employee IDs: @String.Join(", ", selectedEmployeeIds.Select(i => i.ToString()) ?? Enumerable.Empty()) +

+ +@code +{ + private IEnumerable data; + private List selectedEmployeeIds { get; set; } = new(); + + protected override async Task OnParametersSetAsync() + { + data = await DemoDataService.GetPreferredEmployeesAsync(count: 5); + } +} diff --git a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor index f3f5df6b2..46e4813f5 100644 --- a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor +++ b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Documentation.razor @@ -8,4 +8,9 @@

Group checkboxes on the same horizontal row by adding Inline="true".

+ + +

Change the look of checkboxes by adding InputAsToggle="InputAsToggle.Toggle"

+ + diff --git a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor new file mode 100644 index 000000000..409a4e7a7 --- /dev/null +++ b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Demo_Toggle.razor @@ -0,0 +1,22 @@ +@inject IDemoDataService DemoDataService + + + +

Selected employee ID: @selectedEmployeeId

+ +@code { + private IEnumerable data; + private int? selectedEmployeeId; + + protected override async Task OnInitializedAsync() + { + data = await DemoDataService.GetPreferredEmployeesAsync(count: 5); + } +} \ No newline at end of file diff --git a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor index 0807f85dc..18ad2344e 100644 --- a/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor +++ b/Havit.Blazor.Documentation/Pages/Components/HxRadioButtonListDoc/HxRadioButtonList_Documentation.razor @@ -11,4 +11,7 @@

Group radios on the same horizontal row by adding Inline="true".

+ +

Change the look of radios by adding InputAsToggle="InputAsToggle.Toggle"

+ \ No newline at end of file From 864e41a1d97431274aae7e1670227ecbbf6ea84c Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Sat, 12 Oct 2024 02:09:04 -0400 Subject: [PATCH 4/8] Updated CheckboxList Toggle view --- Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs index 0c92f441b..a07abbbe5 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs @@ -134,8 +134,8 @@ protected override void BuildRenderInput(RenderTreeBuilder builder) builder.AddAttribute(4, nameof(HxCheckbox.ValueChanged), EventCallback.Factory.Create(this, @checked => HandleValueChanged(@checked, item))); builder.AddAttribute(5, nameof(HxCheckbox.Enabled), EnabledEffective); - builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-group" : null, ItemCssClassSelector?.Invoke(item))); - builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); + builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : null, ItemCssClassSelector?.Invoke(item))); + builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn" : ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); // We need ValueExpression. Ehm, HxCheckbox needs ValueExpression. Because it is InputBase which needs ValueExpression. From 5785143c6bf2ef6e6adc5b8b188c58bb5bd54787 Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Sat, 12 Oct 2024 02:11:13 -0400 Subject: [PATCH 5/8] Fix update Checkbox list toggle view --- Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs index a07abbbe5..f3b62a9d9 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs @@ -135,8 +135,8 @@ protected override void BuildRenderInput(RenderTreeBuilder builder) builder.AddAttribute(5, nameof(HxCheckbox.Enabled), EnabledEffective); builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : null, ItemCssClassSelector?.Invoke(item))); - builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn" : ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); - builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); + builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); + builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn" : ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); // We need ValueExpression. Ehm, HxCheckbox needs ValueExpression. Because it is InputBase which needs ValueExpression. // We have nothing to give the HxCheckbox. So we make own class with property which we assign to the ValueExpression. From c965d895959de17004e91c36ca587f6d83d2bd43 Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Sat, 12 Oct 2024 02:30:07 -0400 Subject: [PATCH 6/8] Added Color management for CheckboxList toggle view --- .../Forms/HxCheckboxList.cs | 13 ++++++++++--- .../HxCheckboxList_Demo_Toggle.razor | 1 + .../Havit.Blazor.Components.Web.Bootstrap.xml | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs index f3b62a9d9..95bca1df9 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs @@ -112,6 +112,13 @@ private void RefreshState() } } + /// + /// Bootstrap button style - theme color.
+ /// The default is taken from ( if not customized). + ///
+ [Parameter] public ThemeColor? Color { get; set; } + protected ThemeColor ColorEffective => Color ?? throw new InvalidOperationException(nameof(Color) + " default for " + nameof(HxCheckboxList) + " has to be set."); + /// protected override void BuildRenderInput(RenderTreeBuilder builder) { @@ -134,9 +141,9 @@ protected override void BuildRenderInput(RenderTreeBuilder builder) builder.AddAttribute(4, nameof(HxCheckbox.ValueChanged), EventCallback.Factory.Create(this, @checked => HandleValueChanged(@checked, item))); builder.AddAttribute(5, nameof(HxCheckbox.Enabled), EnabledEffective); - builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : null, ItemCssClassSelector?.Invoke(item))); - builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); - builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn" : ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); + builder.AddAttribute(6, nameof(HxCheckbox.CssClass), CssClassHelper.Combine(ItemCssClass, ItemCssClassSelector?.Invoke(item))); + builder.AddAttribute(7, nameof(HxCheckbox.InputCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : null, ItemInputCssClass, ItemInputCssClassSelector?.Invoke(item))); + builder.AddAttribute(8, nameof(HxCheckbox.TextCssClass), CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? $"btn {ColorEffective.ToButtonColorCss(true)}" : null, ItemTextCssClass, ItemTextCssClassSelector?.Invoke(item))); // We need ValueExpression. Ehm, HxCheckbox needs ValueExpression. Because it is InputBase which needs ValueExpression. // We have nothing to give the HxCheckbox. So we make own class with property which we assign to the ValueExpression. diff --git a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor index 3f39d63d8..3c32df05e 100644 --- a/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor +++ b/Havit.Blazor.Documentation/Pages/Components/HxCheckboxListDoc/HxCheckboxList_Demo_Toggle.razor @@ -5,6 +5,7 @@ InputAsToggle="InputAsToggle.Toggle" Label="Employees" Data="@data" + Color="ThemeColor.Primary" ItemTextSelector="@(employee => employee.Name)" ItemValueSelector="@(employee => employee.Id)" @bind-Value="selectedEmployeeIds" /> diff --git a/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml b/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml index d342ea17a..f3cf6da0e 100644 --- a/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml +++ b/Havit.Blazor.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml @@ -3597,6 +3597,12 @@ Returns an optional set of component settings.
+ + + Bootstrap button style - theme color.
+ The default is taken from ( if not customized). +
+
From 74ebfe5ba59438866debf15eb9611741ad6fc9f7 Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Sat, 12 Oct 2024 02:58:29 -0400 Subject: [PATCH 7/8] Set Default Color as None --- Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs index 95bca1df9..5eb02729c 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxCheckboxList.cs @@ -117,7 +117,7 @@ private void RefreshState() /// The default is taken from ( if not customized). ///
[Parameter] public ThemeColor? Color { get; set; } - protected ThemeColor ColorEffective => Color ?? throw new InvalidOperationException(nameof(Color) + " default for " + nameof(HxCheckboxList) + " has to be set."); + protected ThemeColor ColorEffective => Color ?? ThemeColor.None; /// protected override void BuildRenderInput(RenderTreeBuilder builder) From 48d1a49817c3b910780e11b5ea482765dc5c892f Mon Sep 17 00:00:00 2001 From: Manuel Monteagudo Date: Mon, 25 Nov 2024 14:42:57 -0400 Subject: [PATCH 8/8] fixed check-input class on RadioButtonList --- .../Forms/HxRadioButtonListBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs index df6e92a84..fc080fe92 100644 --- a/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs +++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/HxRadioButtonListBase.cs @@ -156,7 +156,7 @@ protected void BuildRenderInput_RenderRadioItem(RenderTreeBuilder builder, int i builder.AddAttribute(101, "class", CssClassHelper.Combine("form-check", Inline ? "form-check-inline" : null, ItemCssClassImpl, ItemCssClassSelectorImpl?.Invoke(item))); } builder.OpenElement(200, "input"); - builder.AddAttribute(201, "class", CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : "form -check-input", ItemInputCssClassImpl, ItemInputCssClassSelectorImpl?.Invoke(item))); + builder.AddAttribute(201, "class", CssClassHelper.Combine(inputAsToggleEffective == Bootstrap.InputAsToggle.Toggle ? "btn-check" : "form-check-input", ItemInputCssClassImpl, ItemInputCssClassSelectorImpl?.Invoke(item))); builder.AddAttribute(202, "type", "radio"); builder.AddAttribute(203, "name", GroupName); builder.AddAttribute(204, "id", inputId);