Skip to content

Commit a5b184f

Browse files
vnbaaijdvoituron
andauthored
Add tabindex to ProfileMenu and add handler to open menu on enter/space keydown (#4104)
Add a test Fix 2 code analyzer errors Co-authored-by: Denis Voituron <dvoituron@outlook.com>
1 parent 1cce5d5 commit a5b184f

9 files changed

+64
-19
lines changed

src/Core/Components/DataGrid/Columns/PropertyColumn.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
// This file is licensed to you under the MIT License.
33
// ------------------------------------------------------------------------
44

5+
using System.Linq.Expressions;
6+
using System.Reflection;
57
using Microsoft.AspNetCore.Components;
68
using Microsoft.AspNetCore.Components.Rendering;
79
using Microsoft.FluentUI.AspNetCore.Components.DataGrid.Infrastructure;
810
using Microsoft.FluentUI.AspNetCore.Components.Extensions;
9-
using System.Linq.Expressions;
10-
using System.Reflection;
1111

1212
namespace Microsoft.FluentUI.AspNetCore.Components;
1313

@@ -119,7 +119,6 @@ protected override void OnParametersSet()
119119
return (Func<TGridItem, string?>)method.Invoke(null, [getter, format])!;
120120
}
121121

122-
123122
if (typeof(IFormattable).IsAssignableFrom(typeof(TProp)))
124123
{
125124
//Struct

src/Core/Components/DataGrid/FluentDataGrid.razor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,7 @@ private void SaveStateToQueryString()
10331033
var order = _sortByAscending ? "asc" : "desc";
10341034
stateParams.Add($"{SaveStatePrefix}orderby", $"{_sortByColumn.Title} {order}");
10351035
}
1036-
stateParams.Add($"{SaveStatePrefix}page", Pagination?.CurrentPageIndex + 1 ?? null);
1036+
stateParams.Add($"{SaveStatePrefix}page", (Pagination?.CurrentPageIndex + 1) ?? null);
10371037
stateParams.Add($"{SaveStatePrefix}top", Pagination?.ItemsPerPage ?? null);
10381038
NavigationManager.NavigateTo(NavigationManager.GetUriWithQueryParameters(stateParams), replace: true);
10391039
}

src/Core/Components/ProfileMenu/FluentProfileMenu.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
@namespace Microsoft.FluentUI.AspNetCore.Components
22
@inherits FluentComponentBase
33

4-
<div id="@Id" class="@ClassValue" style="@StyleValue" top-corner="@TopCorner"
5-
@onclick="@ProfileMenuClickedAsync">
4+
<div id="@Id" class="@ClassValue" style="@StyleValue" top-corner="@TopCorner" tabindex="1"
5+
@onclick="@ProfileMenuClickedAsync" @onkeydown="@ProfileMenuKeyDownAsync" >
66
@StartTemplate
77
<FluentPersona Id="@PersonaId"
88
Image="@Image"

src/Core/Components/ProfileMenu/FluentProfileMenu.razor.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// ------------------------------------------------------------------------
44

55
using Microsoft.AspNetCore.Components;
6+
using Microsoft.AspNetCore.Components.Web;
67
using Microsoft.FluentUI.AspNetCore.Components.Utilities;
78

89
namespace Microsoft.FluentUI.AspNetCore.Components;
@@ -178,6 +179,15 @@ private async Task ProfileMenuClickedAsync()
178179
await OpenChangedHandlerAsync();
179180
}
180181

182+
private async Task ProfileMenuKeyDownAsync(KeyboardEventArgs args)
183+
{
184+
if (args.Key == "Enter" || args.Key == "NumpadEnter" || args.Key == " " || args.Key == "Spacebar")
185+
{
186+
Open = !Open;
187+
await OpenChangedHandlerAsync();
188+
}
189+
}
190+
181191
/// <summary />
182192
private async Task OpenChangedHandlerAsync()
183193
{

src/Core/Components/Splitter/FluentMultiSplitter.razor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// --------------------------------------------------------------
2-
// Copyright (c) Microsoft Corporation. All rights reserved.
3-
// --------------------------------------------------------------
1+
// ------------------------------------------------------------------------
2+
// This file is licensed to you under the MIT License.
3+
// ------------------------------------------------------------------------
44

55
using System.Globalization;
66
using Microsoft.AspNetCore.Components;
@@ -174,7 +174,7 @@ public async Task OnPaneResizedAsync(int paneIndex, double sizeNew, int? paneNex
174174
// cancel omitted because it is managed by the parent panel
175175
}
176176

177-
paneNext.SizeRuntime = sizeNextNew?.ToString("0.00", CultureInfo.InvariantCulture) + "%" ?? string.Empty;
177+
paneNext.SizeRuntime = (sizeNextNew?.ToString("0.00", CultureInfo.InvariantCulture) + "%") ?? string.Empty;
178178
paneNext.Refresh();
179179
}
180180
}

tests/Core/ProfileMenu/FluentProfileMenuTests.FluentProfileMenu_Customized.verified.razor.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
<div id="xxx" class="fluent-profile-menu" blazor:onclick="1" b-rsm9d6pikk="">
2+
<div id="xxx" class="fluent-profile-menu" tabindex="1" blazor:onclick="1" blazor:onkeydown="2" b-rsm9d6pikk="">
33
<div id="xxx" class="fluent-persona" style="height: inherit;" position="end" b-n7zog0zvqi="">
44
<div class="initials" b-n7zog0zvqi="">
55
<div class="fluent-presence-badge" title="" b-1o8tp31nhy="">
@@ -8,7 +8,7 @@
88
</div>
99
</div>
1010
</div>
11-
<div class="fluent-overlay" style="cursor: auto; position: fixed; display: flex; align-items: center; justify-content: center; z-index: 9900;" blazor:onclick="2" blazor:oncontextmenu="3" blazor:oncontextmenu:preventdefault="" b-xkrr7evqik="">
11+
<div class="fluent-overlay" style="cursor: auto; position: fixed; display: flex; align-items: center; justify-content: center; z-index: 9900;" blazor:onclick="3" blazor:oncontextmenu="4" blazor:oncontextmenu:preventdefault="" b-xkrr7evqik="">
1212
<div b-xkrr7evqik=""></div>
1313
</div>
1414
<fluent-anchored-region id="xxx" anchor="xxx" horizontal-positioning-mode="dynamic" horizontal-default-position="start" horizontal-inset="" horizontal-threshold="0" horizontal-scaling="content" vertical-positioning-mode="dynamic" vertical-default-position="bottom" vertical-threshold="0" vertical-scaling="content" auto-update-mode="auto" style="z-index: 9999;" b-2ov9fhztky="" blazor:elementreference="xxx">

tests/Core/ProfileMenu/FluentProfileMenuTests.FluentProfileMenu_Default.verified.razor.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

2-
<div id="xxx" class="fluent-profile-menu" blazor:onclick="1" b-rsm9d6pikk="">
2+
<div id="xxx" class="fluent-profile-menu" tabindex="1" blazor:onclick="1" blazor:onkeydown="2" b-rsm9d6pikk="">
33
<div id="xxx" class="fluent-persona" style="height: inherit;" position="end" b-n7zog0zvqi="">
44
<div class="initials" b-n7zog0zvqi="">
55
<div class="fluent-presence-badge" title="I'm available" b-1o8tp31nhy="">
66
<div style="display: table-cell; vertical-align: middle; width: 20px; min-width: 20px; height: 20px; min-height: 20px;" b-n7zog0zvqi="">
77
<img src="iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=" alt="Bill Gates" title="Bill Gates" style="max-width: 20px; max-height: 20px;" b-n7zog0zvqi="">
88
</div>
9-
<svg class="status" style="width: 12px; fill: var(--presence-available);" focusable="false" viewBox="0 0 24 24" aria-hidden="true" blazor:onkeydown="2" blazor:onclick="3">
9+
<svg class="status" style="width: 12px; fill: var(--presence-available);" focusable="false" viewBox="0 0 24 24" aria-hidden="true" blazor:onkeydown="3" blazor:onclick="4">
1010
<title>I'm available</title>
1111
<path d="M12 24a12 12 0 1 0 0-24 12 12 0 0 0 0 24Zm5.06-13.44-5.5 5.5a1.5 1.5 0 0 1-2.12 0l-2-2a1.5 1.5 0 0 1 2.12-2.12l.94.94 4.44-4.44a1.5 1.5 0 0 1 2.12 2.12Z"></path>
1212
</svg>
@@ -15,7 +15,7 @@
1515
<div class="name" b-n7zog0zvqi="">Bill Gates</div>
1616
</div>
1717
</div>
18-
<div class="fluent-overlay" style="cursor: auto; position: fixed; display: flex; align-items: center; justify-content: center; z-index: 9900;" blazor:onclick="4" blazor:oncontextmenu="5" blazor:oncontextmenu:preventdefault="" b-xkrr7evqik="">
18+
<div class="fluent-overlay" style="cursor: auto; position: fixed; display: flex; align-items: center; justify-content: center; z-index: 9900;" blazor:onclick="5" blazor:oncontextmenu="6" blazor:oncontextmenu:preventdefault="" b-xkrr7evqik="">
1919
<div b-xkrr7evqik=""></div>
2020
</div>
2121
<fluent-anchored-region id="xxx" anchor="xxx" horizontal-positioning-mode="dynamic" horizontal-default-position="start" horizontal-inset="" horizontal-threshold="0" horizontal-scaling="content" vertical-positioning-mode="dynamic" vertical-default-position="bottom" vertical-threshold="0" vertical-scaling="content" auto-update-mode="auto" style="z-index: 9999;" b-2ov9fhztky="" blazor:elementreference="xxx">
@@ -26,7 +26,7 @@
2626
<div class="stack-horizontal" style="justify-content: start; align-items: center; column-gap: 10px; row-gap: 10px; width: 100%;" b-0nr62qx0mz="">
2727
<p part="header-label" typo="body" class="fluent-typography" b-1nnnfjehkp="">Microsoft</p>
2828
<div style="flex-grow: 1;"></div>
29-
<fluent-button type="button" appearance="stealth" blazor:onclick="6" part="header-button" b-x1200685t0="" blazor:elementreference="xxx">Sign out</fluent-button>
29+
<fluent-button type="button" appearance="stealth" blazor:onclick="7" part="header-button" b-x1200685t0="" blazor:elementreference="xxx">Sign out</fluent-button>
3030
</div>
3131
</div>
3232
<div part="body" b-qp3z8ghd2d="">
@@ -50,7 +50,7 @@ <h5 part="fullname" typo="header" class="fluent-typography" style="font-weight:
5050
<div class="stack-horizontal" style="justify-content: start; align-items: center; column-gap: 10px; row-gap: 10px; width: 100%;" b-0nr62qx0mz="">
5151
<p part="footer-label" typo="body" class="fluent-typography" b-1nnnfjehkp="">v 3.14</p>
5252
<div style="flex-grow: 1;"></div>
53-
<fluent-anchor href="#" appearance="hypertext" blazor:onclick="7" blazor:onclick:preventdefault="" part="footer-link" blazor:elementreference="xxx">View account</fluent-anchor>
53+
<fluent-anchor href="#" appearance="hypertext" blazor:onclick="8" blazor:onclick:preventdefault="" part="footer-link" b-acyx52swce="" blazor:elementreference="xxx">View account</fluent-anchor>
5454
</div>
5555
</div>
5656
</div>
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
<div id="xxx" class="fluent-profile-menu" blazor:onclick="1" b-rsm9d6pikk="">Before
2+
<div id="xxx" class="fluent-profile-menu" tabindex="1" blazor:onclick="1" blazor:onkeydown="2" b-rsm9d6pikk="">Before
33
<div id="xxx" class="fluent-persona" style="height: inherit;" position="end" b-n7zog0zvqi="">
44
<div class="initials" b-n7zog0zvqi="">
55
<div class="fluent-presence-badge" title="" b-1o8tp31nhy="">
@@ -9,4 +9,4 @@
99
</div>
1010
</div>
1111
</div>
12-
After</div>
12+
After</div>

tests/Core/ProfileMenu/FluentProfileMenuTests.razor

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,42 @@
4242
cut.Verify();
4343
}
4444

45+
[Theory]
46+
[InlineData("Enter")]
47+
[InlineData(" ")]
48+
[InlineData("Spacebar")]
49+
[InlineData("NumpadEnter")]
50+
public void FluentProfileMenu_OpenWithKeyboard(string key)
51+
{
52+
bool opened = false;
53+
54+
// Arrange && Act
55+
var cut = Render(
56+
@<FluentProfileMenu Image="@SamplePicture"
57+
ButtonSize="20px"
58+
ImageSize="48px"
59+
@bind-Open="@opened"
60+
Status="@PresenceStatus.Available"
61+
StatusTitle="I'm available"
62+
HeaderLabel="Microsoft"
63+
FooterLabel="v 3.14"
64+
Initials="BG"
65+
FullName="Bill Gates"
66+
EMail="bill.gates@microsoft.com" />
67+
);
68+
69+
Assert.False(opened);
70+
71+
// Open the Popover
72+
//var button = cut.Find(".initials");
73+
//button.Click();
74+
cut.Find(".fluent-profile-menu").KeyDown(key);
75+
76+
// Assert
77+
Assert.True(opened);
78+
79+
}
80+
4581
[Fact]
4682
public void FluentProfileMenu_Buttons()
4783
{

0 commit comments

Comments
 (0)