+ @foreach (var (item, idx) in _items.Select((item, idx) => (item, idx)))
+ {
+ var isSelected = item == SelectedItem;
+ if (Sticky && isSelected) continue;
-
-
- @foreach (var (item, idx) in _items.Select((item, idx) => (item, idx)))
- {
- if (Sticky && item == SelectedItem) continue;
-
- var template = GetTemplate(item);
- var isEnabled = GetIsEnabled(item);
-
-
-
- }
-
-
\ No newline at end of file
+ var template = GetTemplate(item);
+ var isEnabled = GetIsEnabled(item);
+
+
+
+
+ }
+
+
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.razor.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.razor.cs
index 603afd16ee..1f51715736 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.razor.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.razor.cs
@@ -37,6 +37,12 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
///
[Parameter] public bool AriaHidden { get; set; }
+ ///
+ /// The background color kind of the callout.
+ ///
+ [Parameter, ResetClassBuilder]
+ public BitColorKind? Background { get; set; }
+
///
/// The value of the type attribute of the menu button.
///
@@ -68,6 +74,11 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
[Parameter, ResetClassBuilder]
public BitColor? Color { get; set; }
+ ///
+ /// Default value of the IsToggled parameter in toggle mode.
+ ///
+ [Parameter] public bool? DefaultIsToggled { get; set; }
+
///
/// Default value of the SelectedItem.
///
@@ -93,6 +104,11 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
///
[Parameter] public string? IconName { get; set; }
+ ///
+ /// If true, removes the icon from the header button.
+ ///
+ [Parameter] public bool NoIcon { get; set; }
+
///
/// Determines the opening state of the callout.
///
@@ -101,6 +117,12 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
[ResetClassBuilder, ResetStyleBuilder, TwoWayBound]
public bool IsOpen { get; set; }
+ ///
+ /// Determines whether the header button is in the checked/toggled state when Toggle is enabled.
+ ///
+ [Parameter, ResetClassBuilder, ResetStyleBuilder, TwoWayBound]
+ public bool IsToggled { get; set; }
+
///
/// List of items to show in the menu button.
///
@@ -126,6 +148,11 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
///
[Parameter] public EventCallback OnChange { get; set; }
+ ///
+ /// The callback that is called when the IsToggled value changes in toggle mode.
+ ///
+ [Parameter] public EventCallback OnToggleChange { get; set; }
+
///
/// Alias of the ChildContent.
///
@@ -152,7 +179,8 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
///
/// If true, the selected item is going to change the header item.
///
- [Parameter] public bool Sticky { get; set; }
+ [Parameter, ResetClassBuilder, ResetStyleBuilder]
+ public bool Sticky { get; set; }
///
/// Custom CSS styles for different parts of the menu button.
@@ -164,6 +192,12 @@ public partial class BitMenuButton : BitComponentBase where TItem : class
///
[Parameter] public string? Text { get; set; }
+ ///
+ /// If true, enables the toggling behavior on the header button in split mode.
+ ///
+ [Parameter, ResetClassBuilder, ResetStyleBuilder]
+ public bool Toggle { get; set; }
+
///
/// The visual variant of the menu button.
///
@@ -253,6 +287,8 @@ protected override void RegisterCssClasses()
ClassBuilder.Register(() => Split ? "bit-mnb-spl" : "bit-mnb-nsp");
+ ClassBuilder.Register(() => Toggle && Split && IsToggled ? $"bit-mnb-tgl {Classes?.Toggled}" : string.Empty);
+
ClassBuilder.Register(() => Variant switch
{
BitVariant.Fill => "bit-mnb-fil",
@@ -267,6 +303,8 @@ protected override void RegisterCssStyles()
StyleBuilder.Register(() => Styles?.Root);
StyleBuilder.Register(() => IsOpen ? Styles?.Opened : string.Empty);
+
+ StyleBuilder.Register(() => Toggle && Split && IsToggled ? Styles?.Toggled : string.Empty);
}
protected override async Task OnInitializedAsync()
@@ -274,6 +312,11 @@ protected override async Task OnInitializedAsync()
_calloutId = $"BitMenuButton-{UniqueId}-callout";
_overlayId = $"BitMenuButton-{UniqueId}-overlay";
+ if (Split && Toggle && IsToggledHasBeenSet is false && DefaultIsToggled.HasValue)
+ {
+ await AssignIsToggled(DefaultIsToggled.Value);
+ }
+
if (Sticky && SelectedItemHasBeenSet is false && DefaultSelectedItem is not null)
{
await AssignSelectedItem(DefaultSelectedItem);
@@ -536,6 +579,13 @@ private async Task HandleOnHeaderClick(TItem? item)
await OpenCallout();
}
+ if (Toggle && Split)
+ {
+ if (await AssignIsToggled(!IsToggled) is false) return;
+
+ await OnToggleChange.InvokeAsync(IsToggled);
+ }
+
if (item is not null)
{
if (GetIsEnabled(item) is false) return;
@@ -643,7 +693,20 @@ private string GetItemKey(TItem item, string defaultKey)
return GetKey(item) ?? $"{UniqueId}-{defaultKey}";
}
-
+ private string? GetCalloutCss()
+ {
+ var openClass = IsOpen ? "bit-mnb-ocl" : null;
+ var bgClass = Background switch
+ {
+ BitColorKind.Primary => "bit-mnb-bpg",
+ BitColorKind.Secondary => "bit-mnb-bsg",
+ BitColorKind.Tertiary => "bit-mnb-btg",
+ BitColorKind.Transparent => "bit-mnb-brg",
+ _ => null
+ };
+ var result = $"{openClass} {bgClass}".Trim();
+ return result.HasValue() ? result : null;
+ }
protected override async ValueTask DisposeAsync(bool disposing)
{
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.scss b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.scss
index ed6c18c215..70180bd280 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.scss
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButton.scss
@@ -1,4 +1,4 @@
-@import "../../../Styles/functions.scss";
+@import "../../../Styles/functions.scss";
.bit-mnb {
display: flex;
@@ -12,8 +12,6 @@
border-width: $shp-border-width;
border-style: $shp-border-style;
border-radius: $shp-border-radius;
- --bit-mnb-cal-opa: 0;
- --bit-mnb-cal-tra: translateY(#{spacing(-1.25)});
&.bit-dis {
cursor: default;
@@ -71,14 +69,19 @@
}
.bit-mnb-omn {
- --bit-mnb-cal-opa: 1;
- --bit-mnb-cal-tra: translateY(0);
--bit-mnb-clr-opb-txt: var(--bit-mnb-clr-opb-txt-nsp);
--bit-mnb-clr-opb-bg: var(--bit-mnb-clr-opb-bg-nsp);
--bit-mnb-clr-chb-txt: var(--bit-mnb-clr-txt);
--bit-mnb-clr-chb-bg: var(--bit-mnb-clr-active);
}
+.bit-mnb-tgl {
+ .bit-mnb-opb {
+ color: var(--bit-mnb-clr-txt);
+ background-color: var(--bit-mnb-clr-active);
+ }
+}
+
.bit-mnb-nsp {
--bit-mnb-clr-opb-txt-nsp: var(--bit-mnb-clr-txt);
--bit-mnb-clr-opb-bg-nsp: var(--bit-mnb-clr-active);
@@ -104,18 +107,25 @@
}
.bit-mnb-cal {
+ --bit-mnb-cal-opa: 0;
+ --bit-mnb-cal-tra: translateY(#{spacing(-1.25)});
display: none;
position: fixed;
overflow: hidden auto;
min-width: max-content;
box-sizing: border-box;
z-index: $zindex-callout;
- background-color: $clr-bg-pri;
opacity: var(--bit-mnb-cal-opa);
box-shadow: $box-shadow-callout;
transform: var(--bit-mnb-cal-tra);
transition: opacity 100ms, transform 300ms;
border-radius: 0 0 spacing(0.25) spacing(0.25);
+ background-color: var(--bit-mnb-cal-bg, #{$clr-bg-pri});
+
+ &.bit-mnb-ocl {
+ --bit-mnb-cal-opa: 1;
+ --bit-mnb-cal-tra: translateY(0);
+ }
}
.bit-mnb-cul {
@@ -346,3 +356,20 @@
font-size: spacing(2.0);
--bit-mnb-padding: #{spacing(1.0)} #{spacing(2.0)};
}
+
+
+.bit-mnb-bpg {
+ --bit-mnb-cal-bg: #{$clr-bg-pri};
+}
+
+.bit-mnb-bsg {
+ --bit-mnb-cal-bg: #{$clr-bg-sec};
+}
+
+.bit-mnb-btg {
+ --bit-mnb-cal-bg: #{$clr-bg-ter};
+}
+
+.bit-mnb-brg {
+ --bit-mnb-cal-bg: transparent;
+}
\ No newline at end of file
diff --git a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonClassStyles.cs b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonClassStyles.cs
index 800ae295e1..8aebd5c1a2 100644
--- a/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonClassStyles.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Components/Buttons/MenuButton/BitMenuButtonClassStyles.cs
@@ -7,6 +7,11 @@ public class BitMenuButtonClassStyles
///
public string? Root { get; set; }
+ ///
+ /// Custom CSS classes/styles for the checked/toggled state of the BitMenuButton.
+ ///
+ public string? Toggled { get; set; }
+
///
/// Custom CSS classes/styles for the opened callout state of the BitMenuButton.
///
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/BitMenuButtonDemo.razor.cs b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/BitMenuButtonDemo.razor.cs
index 88b94826ff..c80406d946 100644
--- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/BitMenuButtonDemo.razor.cs
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/BitMenuButtonDemo.razor.cs
@@ -19,6 +19,15 @@ public partial class BitMenuButtonDemo
Description = "If true, add an aria-hidden attribute instructing screen readers to ignore the menu button."
},
new()
+ {
+ Name = "Background",
+ Type = "BitColorKind?",
+ DefaultValue = "null",
+ Description = "The background color kind of the callout.",
+ LinkType = LinkType.Link,
+ Href = "#color-kind-enum",
+ },
+ new()
{
Name = "ButtonType",
Type = "BitButtonType?",
@@ -76,6 +85,13 @@ public partial class BitMenuButtonDemo
Description = "Default value of the SelectedItem."
},
new()
+ {
+ Name = "DefaultIsToggled",
+ Type = "bool?",
+ DefaultValue = "null",
+ Description = "Default value of the IsToggled parameter in toggle mode.",
+ },
+ new()
{
Name = "HeaderTemplate",
Type = "RenderFragment?",
@@ -106,6 +122,13 @@ public partial class BitMenuButtonDemo
Description = "Determines the opening state of the callout.",
},
new()
+ {
+ Name = "IsToggled",
+ Type = "bool",
+ DefaultValue = "false",
+ Description = "Determines whether the header button is in the toggled state when Toggle is enabled.",
+ },
+ new()
{
Name = "Items",
Type = "IEnumerable",
@@ -131,6 +154,13 @@ public partial class BitMenuButtonDemo
Href = "#name-selectors",
},
new()
+ {
+ Name = "NoIcon",
+ Type = "bool",
+ DefaultValue = "false",
+ Description = "If true, the icon of the header button is hidden.",
+ },
+ new()
{
Name = "OnClick",
Type = "EventCallback",
@@ -143,6 +173,12 @@ public partial class BitMenuButtonDemo
Description = "The callback that is called when the selected item has changed."
},
new()
+ {
+ Name = "OnToggleChange",
+ Type = "EventCallback",
+ Description = "The callback that is called when the IsToggled value changes in toggle mode.",
+ },
+ new()
{
Name = "Options",
Type = "RenderFragment?",
@@ -196,6 +232,13 @@ public partial class BitMenuButtonDemo
Description = "The text to show inside the header of menu button."
},
new()
+ {
+ Name = "Toggle",
+ Type = "bool",
+ DefaultValue = "false",
+ Description = "If true, enables toggle behavior on the header button in Split mode.",
+ },
+ new()
{
Name = "Variant",
Type = "BitVariant?",
@@ -493,6 +536,13 @@ public partial class BitMenuButtonDemo
DefaultValue = "null",
Description = "Custom CSS classes/styles for the text of the BitMenuButton."
},
+ new()
+ {
+ Name = "Toggled",
+ Type = "string?",
+ DefaultValue = "null",
+ Description = "Custom CSS classes/styles for the toggled state of the BitMenuButton."
+ },
],
},
new()
@@ -637,6 +687,39 @@ public partial class BitMenuButtonDemo
private readonly List componentSubEnums =
[
+ new()
+ {
+ Id = "color-kind-enum",
+ Name = "BitColorKind",
+ Description = "Defines the color kinds available in the bit BlazorUI.",
+ Items =
+ [
+ new()
+ {
+ Name = "Primary",
+ Description = "The primary color kind.",
+ Value = "0",
+ },
+ new()
+ {
+ Name = "Secondary",
+ Description = "The secondary color kind.",
+ Value = "1",
+ },
+ new()
+ {
+ Name = "Tertiary",
+ Description = "The tertiary color kind.",
+ Value = "2",
+ },
+ new()
+ {
+ Name = "Transparent",
+ Description = "The transparent color kind.",
+ Value = "3",
+ },
+ ]
+ },
new()
{
Id = "button-type-enum",
diff --git a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/_BitMenuButtonCustomDemo.razor b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/_BitMenuButtonCustomDemo.razor
index d6b843a0a2..357aae21ba 100644
--- a/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/_BitMenuButtonCustomDemo.razor
+++ b/src/BlazorUI/Demo/Client/Bit.BlazorUI.Demo.Client.Core/Pages/Components/Buttons/MenuButton/_BitMenuButtonCustomDemo.razor
@@ -1,4 +1,4 @@
-
+
@@ -40,7 +40,280 @@
-
+
+
+
+
Experience the Sticky functionality of BitMenuButton, showcasing a button that remains sticky after an item selection. The button displays the selected item and retains its state for continuous user interaction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Present BitMenuButton instances with customized icons, enriching the visual options for representing menu buttons.
+
+
+
+
+
+
+
+
+
Empower customization by overriding default styles and classes, allowing tailored design modifications to suit specific UI requirements.
+
+
Component's Style & Class:
+
+
+
+
+
+
+
Item's Style & Class:
+
+
Non-Sticky:
+
+
+
Sticky:
+
+
+
Styles & Classes:
+
+
+
+
+
+
+
+
+
+
Use the Background parameter to control the background color of the callout using BitColorKind values.
+
+
+
+
+
+
+
+
+
+
+
+ Enable toggle behavior on the header button in Split mode. Clicking the operator button toggles the IsToggled state, while the chevron button still opens the callout.
+
+
+
Toggle:
+
+
+
+
+
+
DefaultIsToggled:
+
+
+
+
+
+
Two-way binding:
+
+
+
+
+
+
+
OnToggleChange: @customToggledValue
+
+
+
+
+
+
Use the NoIcon parameter to hide the header icon of the menu button.
Note that if Sticky set to true, HeaderTemplate and Text will be ignored.
+
+
HeaderTemplate
+
+
+
+ Custom Header!
+
+
+
+
+
ItemTemplate
+
+
+
+ @item.Name (@item.Id)
+
+
+
+
+
Item's template
+
+
+
+
+
Demonstrate BitMenuButton instances highlighting item click events, offering versatile interactions within the menu buttons.
+
+
+
Non-Sticky
+
+
+
+
+
+
+
Sticky
+
+
+
+
+
+
+
+
Changed custom item: @eventsChangedCustom
+
Clicked custom item: @eventsClickedCustom
+
+
+
+
This example demonstrates different ways to handle item selection and changes within the component.
+
+
+
DefaultSelectedItem:
+
+
+
+
+
+
Two-way SelectedItem:
+
+
+
+
+
+
+
Item's IsSelected:
+
+
+
+
+
One-way IsOpen (closes after 2 seconds):
+
+
+
+
+
+
+
Two-way IsOpen:
+
+
+
+
+
+
+
+
+
External icon libraries like FontAwesome can be used with the Icon parameter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Offering a range of specialized color variants with Primary being the default, providing visual cues for specific actions or states within your application.
@@ -250,7 +523,7 @@
-
+
Varying sizes for menu buttons tailored to meet diverse design needs, ensuring flexibility and visual hierarchy within your interface.
@@ -272,229 +545,12 @@
-
-
Experience the Sticky functionality of BitMenuButton, showcasing a button that remains sticky after an item selection. The button displays the selected item and retains its state for continuous user interaction.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Present BitMenuButton instances with customized icons, enriching the visual options for representing menu buttons.
-
-
-
-
-
-
-
-
-
Empower customization by overriding default styles and classes, allowing tailored design modifications to suit specific UI requirements.