Skip to content

Commit 2752989

Browse files
committed
Added Menu and its demo page.
1 parent 2e3f8b2 commit 2752989

File tree

18 files changed

+430
-97
lines changed

18 files changed

+430
-97
lines changed
Lines changed: 227 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,237 @@
11
@page "/menu"
22

3-
<PageTitle>Menus</PageTitle>
3+
@inject IJSRuntime Js;
44

5-
<h1>Menus</h1>
5+
<ComponentDemoPage Name="Menus"
6+
DesignUrl="https://m3.material.io/components/menus/overview"
7+
ComponentUrl="https://material-web.dev/components/menu/"
8+
ComponentSourcePath="menu"
9+
BlazorComponentSourcePath="Menu"
10+
BlazorDemoSourceName="Menu">
11+
<Description>
12+
Menus display a list of choices on a temporary surface.
13+
</Description>
14+
<ComponentDemo>
15+
<div class="text-center">
16+
<div>Menu opened: @(open)</div>
617

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

12-
<div class="alert alert-warning">
13-
This component is still under development by Web Component.
14-
</div>
26+
<MdMenu @ref="mnu" @bind-Open="open"
27+
Anchor="@(useIdRef ? "btn-usage" : null)"
28+
Positioning="isFixed ? MdMenuPositioning.Fixed : MdMenuPositioning.Absolute"
29+
HasOverflow="hasOverflow"
30+
Quick="@(quick)"
31+
AnchorCorner="@(anchorCorner)"
32+
MenuCorner="@(menuCorner)"
33+
StayOpenOnFocusout="@(stayOpenOnFocusout)"
34+
StayOpenOnOutsideClick="@(stayOpenOnOutsideClick)"
35+
SkipRestoreFocus="@(skipRestoreFocus)">
36+
<MdSubMenu>
37+
<!-- Submenu Fruits with A -->
38+
<!-- The (parent) item that would open the submenu -->
39+
<MdMenuItem slot="@(MdSubMenu.ItemSlot)">
40+
Fruits with A
41+
<MdIcon slot="@(MdMenuItem.EndSlot)">arrow_right</MdIcon>
42+
</MdMenuItem>
43+
44+
<!-- The items of the submenu -->
45+
<MdMenu slot="@(MdSubMenu.MenuSlot)">
46+
<MdMenuItem>
47+
Apricot
48+
</MdMenuItem>
49+
<MdMenuItem>
50+
Avocado
51+
</MdMenuItem>
52+
53+
<!-- More nested item -->
54+
<MdSubMenu MenuCorner="MdMenuCorner.StartEnd"
55+
AnchorCorner="MdMenuCorner.StartStart">
56+
<!-- The (parent) item that would open the submenu -->
57+
<MdMenuItem slot="@(MdSubMenu.ItemSlot)">
58+
Apples
59+
60+
<MdIcon slot="@(MdMenuItem.StartSlot)">arrow_left</MdIcon>
61+
</MdMenuItem>
62+
63+
<!-- The items of the submenu -->
64+
<MdMenu slot="@(MdSubMenu.MenuSlot)">
65+
<MdMenuItem>
66+
Fuji
67+
</MdMenuItem>
68+
<MdMenuItem>
69+
Granny Smith
70+
</MdMenuItem>
71+
<MdMenuItem>
72+
Red Delicious
73+
</MdMenuItem>
74+
</MdMenu>
75+
</MdSubMenu>
76+
</MdMenu>
77+
</MdSubMenu>
78+
79+
<MdMenuItem>
80+
Banana
81+
</MdMenuItem>
82+
83+
<MdMenuItem>
84+
Cucumber
85+
</MdMenuItem>
86+
87+
<MdDivider />
88+
89+
<MdMenuItem Href="https://github.com/datvm/BlazorMaterialWeb/" Target="_blank">
90+
Open a Link
91+
92+
<MdIcon slot="@(MdMenuItem.StartSlot)">link</MdIcon>
93+
<MdIcon slot="@(MdMenuItem.EndSlot)">open_in_new</MdIcon>
94+
</MdMenuItem>
95+
96+
<MdMenuItem @onclick="() => selected = !selected"
97+
Selected="selected"
98+
KeepOpen="true">
99+
Selectable item. Likes: @(likeCount)
100+
101+
<MdIcon slot="@(MdMenuItem.StartSlot)">touch_app</MdIcon>
102+
<div slot="@(MdMenuItem.SupportingTextSlot)">
103+
It should also be kept open when clicking
104+
</div>
105+
106+
<div slot="@(MdMenuItem.TrailingSupportingTextSlot)">
107+
Like it?
108+
</div>
109+
110+
<MdIconButton @onclick="() => likeCount++"
111+
slot="@(MdMenuItem.EndSlot)">
112+
<MdIcon>thumb_up</MdIcon>
113+
</MdIconButton>
114+
</MdMenuItem>
115+
</MdMenu>
116+
</span>
117+
</div>
118+
</div>
119+
</ComponentDemo>
120+
<Tweaks>
121+
<div class="hstack gap-3">
122+
<LabeledSwitch @bind-Selected="useIdRef" Label="Use idref" />
123+
<LabeledSwitch @bind-Selected="isFixed" Label="Fixed position (instead of absolute)" />
124+
<LabeledSwitch @bind-Selected="quick" Label="Quick (skip animations)" />
125+
</div>
126+
127+
<div class="hstack gap-3">
128+
<LabeledSwitch @bind-Selected="hasOverflow" Label="Has Overflow" />
129+
<span>(Submenu would not work properly without this)</span>
130+
</div>
131+
132+
<div class="hstack gap-3">
133+
<LabeledSwitch @bind-Selected="stayOpenOnFocusout" Label="Stay open on Focus-out" />
134+
<LabeledSwitch @bind-Selected="stayOpenOnOutsideClick" Label="Stay open on Outside Click" />
135+
<LabeledSwitch @bind-Selected="skipRestoreFocus" Label="Skip Restore Focus" />
136+
</div>
137+
138+
<MdRadioGroup Name="opt-anchor-corner" TValue="string"
139+
Value="@(anchorCorner.ToString())" ValueChanged="@((e) => SelectCorner(true, e))">
140+
<div class="hstack gap-3">
141+
<span>Anchor Corner:</span>
142+
143+
@foreach (var item in Enum.GetValues<MdMenuCorner>())
144+
{
145+
<LabeledRadio Value="item.ToString()" />
146+
}
147+
</div>
148+
</MdRadioGroup>
149+
150+
<MdRadioGroup Name="opt-menu-corner" TValue="string"
151+
Value="@(menuCorner.ToString())" ValueChanged="@((e) => SelectCorner(false, e))">
152+
<div class="hstack gap-3">
153+
<span>Menu Corner:</span>
154+
155+
@foreach (var item in Enum.GetValues<MdMenuCorner>())
156+
{
157+
<LabeledRadio Value="item.ToString()" />
158+
}
159+
</div>
160+
</MdRadioGroup>
161+
162+
<div class="hstack gap-3">
163+
<MdButton @onclick="() => ToggleMenu(true)">
164+
Call show()
165+
</MdButton>
166+
<MdButton @onclick="() => ToggleMenu(false)">
167+
Call close()
168+
</MdButton>
169+
<MdButton @onclick="PrintItemsAsync">
170+
Print items to console
171+
</MdButton>
172+
</div>
173+
</Tweaks>
174+
</ComponentDemoPage>
15175

16176
@code {
17177

178+
bool open;
179+
bool isFixed;
180+
bool useIdRef = true;
181+
bool hasOverflow = true;
182+
bool quick;
183+
bool stayOpenOnOutsideClick;
184+
bool stayOpenOnFocusout;
185+
bool skipRestoreFocus;
186+
187+
bool selected = true;
188+
int likeCount = 0;
189+
190+
MdMenuCorner anchorCorner = MdMenuCorner.EndStart;
191+
MdMenuCorner menuCorner = MdMenuCorner.StartStart;
192+
193+
MdButton btnOpen = null!;
194+
MdMenu mnu = null!;
195+
196+
async Task PrintItemsAsync()
197+
{
198+
var items = await mnu.GetItemsAsync();
199+
await Js.InvokeVoidAsync("console.log", items);
200+
}
201+
202+
async Task ToggleMenu(bool open)
203+
{
204+
if (open)
205+
{
206+
await mnu.ShowAsync();
207+
}
208+
else
209+
{
210+
await mnu.CloseAsync();
211+
}
212+
}
213+
214+
void SelectCorner(bool anchor, string value)
215+
{
216+
var enumValue = Enum.Parse<MdMenuCorner>(value);
217+
if (anchor)
218+
{
219+
anchorCorner = enumValue;
220+
}
221+
else
222+
{
223+
menuCorner = enumValue;
224+
}
225+
}
226+
227+
async Task OnOpenMenuRequested()
228+
{
229+
if (!useIdRef)
230+
{
231+
await mnu.SetAnchorElementAsync(btnOpen.ElementReference);
232+
}
233+
234+
open = true;
235+
}
18236

19237
}

BlazorMaterialWeb.Demo/Shared/PageNav.razor

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
@code {
44

5-
static readonly (string Text, string Url)[] NavUrls =
5+
static readonly (string Text, string Url)[] ComponentUrls =
66
{
77
("Buttons", "/button"),
88
("Checkbox", "/checkbox"),
@@ -28,7 +28,14 @@
2828
}
2929

3030
<MdList Type="MdListItemType.Link">
31-
@foreach (var url in NavUrls)
31+
<MdListItem Href="/"
32+
active="@((activeUrl?.Url?.Length ?? 0) < 2)">
33+
Setup
34+
</MdListItem>
35+
36+
<MdDivider />
37+
38+
@foreach (var url in ComponentUrls)
3239
{
3340
<MdListItem Href="@(url.Url)"
3441
active="@(url.Url == activeUrl?.Url)">

BlazorMaterialWeb.Demo/Shared/PageNav.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sealed partial class PageNav : IDisposable
88
void FindActiveItem()
99
{
1010
var path = new Uri(Nav.Uri).LocalPath;
11-
activeUrl = NavUrls
11+
activeUrl = ComponentUrls
1212
.FirstOrDefault(q => path.StartsWith(
1313
q.Url,
1414
StringComparison.OrdinalIgnoreCase));

BlazorMaterialWeb.Demo/wwwroot/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined">
1717
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/styles/default.min.css">
1818

19-
<link href="css/gfix.css" rel="stylesheet" />
2019
<link href="css/app.css" rel="stylesheet" />
2120
<link href="BlazorMaterialWeb.Demo.styles.css" rel="stylesheet" />
2221
</head>

BlazorMaterialWeb/EventHandlers.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@
3232
[EventHandler("ontabchanged", typeof(MdTabChangeEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
3333
[EventHandler("ontabactivated", typeof(MdCheckedEventArgs), enableStopPropagation: true, enablePreventDefault: true)]
3434

35+
// Menu
36+
[EventHandler("onmenuopening", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
37+
[EventHandler("onmenuopened", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
38+
[EventHandler("onmenuclosing", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
39+
[EventHandler("onmenuclosed", typeof(EventArgs), enableStopPropagation: true, enablePreventDefault: true)]
3540
public static class EventHandlers { }
3641

3742
public class MdCheckedEventArgs : EventArgs

BlazorMaterialWeb/MdButton.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
target="@(Target)"
77
trailing-icon="@(TrailingIcon)"
88
has-icon="@(HasIcon)"
9-
type="@(Type.ToString().ToLower())"
9+
type="@(Type?.ToString().ToLower())"
1010
value="@(Value)">
1111
@(ChildContent)
1212
</DynamicTag>

BlazorMaterialWeb/MdButton.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ partial class MdButton
2929
public bool HasIcon { get; set; }
3030

3131
[Parameter]
32-
public FormSubmitterType Type { get; set; } = FormSubmitterType.Submit;
32+
public FormSubmitterType? Type { get; set; }
3333

3434
[Parameter]
3535
public string? Value { get; set; }

BlazorMaterialWeb/Menu/MdMenu.razor

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,22 @@
55

66
<md-menu @attributes="AdditionalAttributes" @ref="el"
77
anchor="@(Anchor)"
8-
fixed="@(Fixed)"
8+
positioning="@(Positioning?.ToString().ToLower())"
99
quick="@(Quick)"
1010
has-overflow="@(HasOverflow)"
1111
open="@(Open)"
12-
-x-offset="@(XOffset)"
13-
-y-offset="@(YOffset)"
14-
list-tab-index="@(ListTabIndex)"
15-
type="@(Type)"
12+
x-offset="@(XOffset)"
13+
y-offset="@(YOffset)"
1614
typeahead-delay="@(TypeaheadDelay)"
17-
anchor-corner="@(AnchorCorner)"
18-
menu-corner="@(MenuCorner)"
15+
anchor-corner="@(GetCornerName( AnchorCorner))"
16+
menu-corner="@(GetCornerName( MenuCorner))"
1917
stay-open-on-outside-click="@(StayOpenOnOutsideClick)"
2018
stay-open-on-focusout="@(StayOpenOnFocusout)"
2119
skip-restore-focus="@(SkipRestoreFocus)"
22-
default-focus="@(DefaultFocus)"
23-
@onmenuopening="OnOpening"
24-
@onmenuopened="OnMenuOpened"
25-
@onmenuclosing="OnClosing"
26-
@onmenuclosed="OnMenuClosed">
20+
default-focus="@(GetFocusStateName(DefaultFocus))"
21+
@onmenuopening="OnOpening"
22+
@onmenuopened="@(() => OnOpenStatusChanged(true))"
23+
@onmenuclosing="OnClosing"
24+
@onmenuclosed="@(() => OnOpenStatusChanged(false))">
2725
@(ChildContent)
2826
</md-menu>

0 commit comments

Comments
 (0)