Skip to content

Commit

Permalink
Added Menu and its demo page.
Browse files Browse the repository at this point in the history
  • Loading branch information
datvm committed Sep 28, 2023
1 parent 2e3f8b2 commit 2752989
Show file tree
Hide file tree
Showing 18 changed files with 430 additions and 97 deletions.
236 changes: 227 additions & 9 deletions BlazorMaterialWeb.Demo/Pages/Menu.razor
Original file line number Diff line number Diff line change
@@ -1,19 +1,237 @@
@page "/menu"

<PageTitle>Menus</PageTitle>
@inject IJSRuntime Js;

<h1>Menus</h1>
<ComponentDemoPage Name="Menus"
DesignUrl="https://m3.material.io/components/menus/overview"
ComponentUrl="https://material-web.dev/components/menu/"
ComponentSourcePath="menu"
BlazorComponentSourcePath="Menu"
BlazorDemoSourceName="Menu">
<Description>
Menus display a list of choices on a temporary surface.
</Description>
<ComponentDemo>
<div class="text-center">
<div>Menu opened: @(open)</div>

<p>
<a href="https://m3.material.io/components/menus/overview">Menus</a>
display a list of choices on a temporary surface.
</p>
<div>
<span class="position-relative">
<MdButton @onclick="OnOpenMenuRequested" @ref="btnOpen"
ButtonStyle="MdButtonStype.Filled" id="btn-usage"
style="min-width: min(100%, 500px)">
Open Menu (using @(useIdRef ? "idref" : "element ref"))
</MdButton>

<div class="alert alert-warning">
This component is still under development by Web Component.
</div>
<MdMenu @ref="mnu" @bind-Open="open"
Anchor="@(useIdRef ? "btn-usage" : null)"
Positioning="isFixed ? MdMenuPositioning.Fixed : MdMenuPositioning.Absolute"
HasOverflow="hasOverflow"
Quick="@(quick)"
AnchorCorner="@(anchorCorner)"
MenuCorner="@(menuCorner)"
StayOpenOnFocusout="@(stayOpenOnFocusout)"
StayOpenOnOutsideClick="@(stayOpenOnOutsideClick)"
SkipRestoreFocus="@(skipRestoreFocus)">
<MdSubMenu>
<!-- Submenu Fruits with A -->
<!-- The (parent) item that would open the submenu -->
<MdMenuItem slot="@(MdSubMenu.ItemSlot)">
Fruits with A
<MdIcon slot="@(MdMenuItem.EndSlot)">arrow_right</MdIcon>
</MdMenuItem>

<!-- The items of the submenu -->
<MdMenu slot="@(MdSubMenu.MenuSlot)">
<MdMenuItem>
Apricot
</MdMenuItem>
<MdMenuItem>
Avocado
</MdMenuItem>

<!-- More nested item -->
<MdSubMenu MenuCorner="MdMenuCorner.StartEnd"
AnchorCorner="MdMenuCorner.StartStart">
<!-- The (parent) item that would open the submenu -->
<MdMenuItem slot="@(MdSubMenu.ItemSlot)">
Apples

<MdIcon slot="@(MdMenuItem.StartSlot)">arrow_left</MdIcon>
</MdMenuItem>

<!-- The items of the submenu -->
<MdMenu slot="@(MdSubMenu.MenuSlot)">
<MdMenuItem>
Fuji
</MdMenuItem>
<MdMenuItem>
Granny Smith
</MdMenuItem>
<MdMenuItem>
Red Delicious
</MdMenuItem>
</MdMenu>
</MdSubMenu>
</MdMenu>
</MdSubMenu>

<MdMenuItem>
Banana
</MdMenuItem>

<MdMenuItem>
Cucumber
</MdMenuItem>

<MdDivider />

<MdMenuItem Href="https://github.com/datvm/BlazorMaterialWeb/" Target="_blank">
Open a Link

<MdIcon slot="@(MdMenuItem.StartSlot)">link</MdIcon>
<MdIcon slot="@(MdMenuItem.EndSlot)">open_in_new</MdIcon>
</MdMenuItem>

<MdMenuItem @onclick="() => selected = !selected"
Selected="selected"
KeepOpen="true">
Selectable item. Likes: @(likeCount)

<MdIcon slot="@(MdMenuItem.StartSlot)">touch_app</MdIcon>
<div slot="@(MdMenuItem.SupportingTextSlot)">
It should also be kept open when clicking
</div>

<div slot="@(MdMenuItem.TrailingSupportingTextSlot)">
Like it?
</div>

<MdIconButton @onclick="() => likeCount++"
slot="@(MdMenuItem.EndSlot)">
<MdIcon>thumb_up</MdIcon>
</MdIconButton>
</MdMenuItem>
</MdMenu>
</span>
</div>
</div>
</ComponentDemo>
<Tweaks>
<div class="hstack gap-3">
<LabeledSwitch @bind-Selected="useIdRef" Label="Use idref" />
<LabeledSwitch @bind-Selected="isFixed" Label="Fixed position (instead of absolute)" />
<LabeledSwitch @bind-Selected="quick" Label="Quick (skip animations)" />
</div>

<div class="hstack gap-3">
<LabeledSwitch @bind-Selected="hasOverflow" Label="Has Overflow" />
<span>(Submenu would not work properly without this)</span>
</div>

<div class="hstack gap-3">
<LabeledSwitch @bind-Selected="stayOpenOnFocusout" Label="Stay open on Focus-out" />
<LabeledSwitch @bind-Selected="stayOpenOnOutsideClick" Label="Stay open on Outside Click" />
<LabeledSwitch @bind-Selected="skipRestoreFocus" Label="Skip Restore Focus" />
</div>

<MdRadioGroup Name="opt-anchor-corner" TValue="string"
Value="@(anchorCorner.ToString())" ValueChanged="@((e) => SelectCorner(true, e))">
<div class="hstack gap-3">
<span>Anchor Corner:</span>

@foreach (var item in Enum.GetValues<MdMenuCorner>())
{
<LabeledRadio Value="item.ToString()" />
}
</div>
</MdRadioGroup>

<MdRadioGroup Name="opt-menu-corner" TValue="string"
Value="@(menuCorner.ToString())" ValueChanged="@((e) => SelectCorner(false, e))">
<div class="hstack gap-3">
<span>Menu Corner:</span>

@foreach (var item in Enum.GetValues<MdMenuCorner>())
{
<LabeledRadio Value="item.ToString()" />
}
</div>
</MdRadioGroup>

<div class="hstack gap-3">
<MdButton @onclick="() => ToggleMenu(true)">
Call show()
</MdButton>
<MdButton @onclick="() => ToggleMenu(false)">
Call close()
</MdButton>
<MdButton @onclick="PrintItemsAsync">
Print items to console
</MdButton>
</div>
</Tweaks>
</ComponentDemoPage>

@code {

bool open;
bool isFixed;
bool useIdRef = true;
bool hasOverflow = true;
bool quick;
bool stayOpenOnOutsideClick;
bool stayOpenOnFocusout;
bool skipRestoreFocus;

bool selected = true;
int likeCount = 0;

MdMenuCorner anchorCorner = MdMenuCorner.EndStart;
MdMenuCorner menuCorner = MdMenuCorner.StartStart;

MdButton btnOpen = null!;
MdMenu mnu = null!;

async Task PrintItemsAsync()
{
var items = await mnu.GetItemsAsync();
await Js.InvokeVoidAsync("console.log", items);
}

async Task ToggleMenu(bool open)
{
if (open)
{
await mnu.ShowAsync();
}
else
{
await mnu.CloseAsync();
}
}

void SelectCorner(bool anchor, string value)
{
var enumValue = Enum.Parse<MdMenuCorner>(value);
if (anchor)
{
anchorCorner = enumValue;
}
else
{
menuCorner = enumValue;
}
}

async Task OnOpenMenuRequested()
{
if (!useIdRef)
{
await mnu.SetAnchorElementAsync(btnOpen.ElementReference);
}

open = true;
}

}
11 changes: 9 additions & 2 deletions BlazorMaterialWeb.Demo/Shared/PageNav.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

@code {

static readonly (string Text, string Url)[] NavUrls =
static readonly (string Text, string Url)[] ComponentUrls =
{
("Buttons", "/button"),
("Checkbox", "/checkbox"),
Expand All @@ -28,7 +28,14 @@
}

<MdList Type="MdListItemType.Link">
@foreach (var url in NavUrls)
<MdListItem Href="/"
active="@((activeUrl?.Url?.Length ?? 0) < 2)">
Setup
</MdListItem>

<MdDivider />

@foreach (var url in ComponentUrls)
{
<MdListItem Href="@(url.Url)"
active="@(url.Url == activeUrl?.Url)">
Expand Down
2 changes: 1 addition & 1 deletion BlazorMaterialWeb.Demo/Shared/PageNav.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sealed partial class PageNav : IDisposable
void FindActiveItem()
{
var path = new Uri(Nav.Uri).LocalPath;
activeUrl = NavUrls
activeUrl = ComponentUrls
.FirstOrDefault(q => path.StartsWith(
q.Url,
StringComparison.OrdinalIgnoreCase));
Expand Down
1 change: 0 additions & 1 deletion BlazorMaterialWeb.Demo/wwwroot/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.8.0/build/styles/default.min.css">

<link href="css/gfix.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
<link href="BlazorMaterialWeb.Demo.styles.css" rel="stylesheet" />
</head>
Expand Down
5 changes: 5 additions & 0 deletions BlazorMaterialWeb/EventHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
[EventHandler("ontabchanged", typeof(MdTabChangeEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
[EventHandler("ontabactivated", typeof(MdCheckedEventArgs), enableStopPropagation: true, enablePreventDefault: true)]

// Menu
[EventHandler("onmenuopening", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
[EventHandler("onmenuopened", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
[EventHandler("onmenuclosing", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
[EventHandler("onmenuclosed", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
public static class EventHandlers { }

public class MdCheckedEventArgs : EventArgs
Expand Down
2 changes: 1 addition & 1 deletion BlazorMaterialWeb/MdButton.razor
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
target="@(Target)"
trailing-icon="@(TrailingIcon)"
has-icon="@(HasIcon)"
type="@(Type.ToString().ToLower())"
type="@(Type?.ToString().ToLower())"
value="@(Value)">
@(ChildContent)
</DynamicTag>
2 changes: 1 addition & 1 deletion BlazorMaterialWeb/MdButton.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ partial class MdButton
public bool HasIcon { get; set; }

[Parameter]
public FormSubmitterType Type { get; set; } = FormSubmitterType.Submit;
public FormSubmitterType? Type { get; set; }

[Parameter]
public string? Value { get; set; }
Expand Down
22 changes: 10 additions & 12 deletions BlazorMaterialWeb/Menu/MdMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,22 @@

<md-menu @attributes="AdditionalAttributes" @ref="el"
anchor="@(Anchor)"
fixed="@(Fixed)"
positioning="@(Positioning?.ToString().ToLower())"
quick="@(Quick)"
has-overflow="@(HasOverflow)"
open="@(Open)"
-x-offset="@(XOffset)"
-y-offset="@(YOffset)"
list-tab-index="@(ListTabIndex)"
type="@(Type)"
x-offset="@(XOffset)"
y-offset="@(YOffset)"
typeahead-delay="@(TypeaheadDelay)"
anchor-corner="@(AnchorCorner)"
menu-corner="@(MenuCorner)"
anchor-corner="@(GetCornerName( AnchorCorner))"
menu-corner="@(GetCornerName( MenuCorner))"
stay-open-on-outside-click="@(StayOpenOnOutsideClick)"
stay-open-on-focusout="@(StayOpenOnFocusout)"
skip-restore-focus="@(SkipRestoreFocus)"
default-focus="@(DefaultFocus)"
@onmenuopening="OnOpening"
@onmenuopened="OnMenuOpened"
@onmenuclosing="OnClosing"
@onmenuclosed="OnMenuClosed">
default-focus="@(GetFocusStateName(DefaultFocus))"
@onmenuopening="OnOpening"
@onmenuopened="@(() => OnOpenStatusChanged(true))"
@onmenuclosing="OnClosing"
@onmenuclosed="@(() => OnOpenStatusChanged(false))">
@(ChildContent)
</md-menu>
Loading

0 comments on commit 2752989

Please sign in to comment.