fix(ui): templates root-menu Escape + double-menu guard + reorder disabled tests (#258)
- Root context menu now has tabindex/focus + Escape-key close (OnRootMenuKeyDown) mirroring the node menu - Opening root menu calls _tree.DismissNodeContextMenu(); opening node menu fires OnNodeContextMenuOpened → DismissRootContextMenu so only one menu is ever visible - Add FolderContextMenu_MoveUp_IsDisabled_OnFirstSibling and FolderContextMenu_MoveDown_IsDisabled_OnLastSibling bUnit tests
This commit is contained in:
@@ -81,7 +81,8 @@
|
||||
SelectionMode="TreeViewSelectionMode.Single"
|
||||
ExtraTemplateChildren="BuildCompositionLeavesFor"
|
||||
Filter="@_searchText"
|
||||
StorageKey="templates-tree">
|
||||
StorageKey="templates-tree"
|
||||
OnNodeContextMenuOpened="DismissRootContextMenu">
|
||||
<NodeContent Context="node">
|
||||
@RenderNodeLabel(node)
|
||||
</NodeContent>
|
||||
@@ -98,8 +99,10 @@
|
||||
{
|
||||
<div class="tv-ctx-overlay" @onclick="DismissRootContextMenu"
|
||||
style="position:fixed;top:0;left:0;width:100vw;height:100vh;z-index:1049;background:transparent;"></div>
|
||||
<div class="dropdown-menu show tv-root-menu" @onclick="DismissRootContextMenu"
|
||||
style="position:fixed;top:@(_rootMenuY)px;left:@(_rootMenuX)px;z-index:1050;">
|
||||
<div class="dropdown-menu show tv-root-menu" tabindex="-1" @ref="_rootMenuRef"
|
||||
@onclick="DismissRootContextMenu"
|
||||
@onkeydown="OnRootMenuKeyDown"
|
||||
style="position:fixed;top:@(_rootMenuY)px;left:@(_rootMenuX)px;z-index:1050;outline:none;">
|
||||
<button class="dropdown-item" @onclick="() => OpenNewFolderDialog(null)">New Folder</button>
|
||||
<button class="dropdown-item" @onclick='() => NavigationManager.NavigateTo("/design/templates/create")'>New Template</button>
|
||||
</div>
|
||||
@@ -415,16 +418,41 @@
|
||||
private bool _showRootMenu;
|
||||
private double _rootMenuX;
|
||||
private double _rootMenuY;
|
||||
private bool _rootMenuNeedsFocus;
|
||||
private ElementReference _rootMenuRef;
|
||||
|
||||
private void OpenRootContextMenu(MouseEventArgs e)
|
||||
{
|
||||
// Guard: dismiss any open node context menu first so both menus are
|
||||
// never visible simultaneously (double-menu flash fix, #258).
|
||||
_tree.DismissNodeContextMenu();
|
||||
|
||||
_rootMenuX = e.ClientX;
|
||||
_rootMenuY = e.ClientY;
|
||||
_showRootMenu = true;
|
||||
_rootMenuNeedsFocus = true;
|
||||
}
|
||||
|
||||
private void DismissRootContextMenu() => _showRootMenu = false;
|
||||
|
||||
private void OnRootMenuKeyDown(KeyboardEventArgs e)
|
||||
{
|
||||
if (e.Key == "Escape")
|
||||
DismissRootContextMenu();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (_rootMenuNeedsFocus && _showRootMenu)
|
||||
{
|
||||
_rootMenuNeedsFocus = false;
|
||||
try { await _rootMenuRef.FocusAsync(); }
|
||||
catch (Microsoft.JSInterop.JSException) { }
|
||||
catch (Microsoft.JSInterop.JSDisconnectedException) { }
|
||||
catch (InvalidOperationException) { }
|
||||
}
|
||||
}
|
||||
|
||||
// Rename folder dialog: opened via IDialogService.ShowAsync. The body seeds the
|
||||
// input from the current name and returns the trimmed new name on Save, or null on
|
||||
// Cancel; server guard failures surface via a toast.
|
||||
|
||||
Reference in New Issue
Block a user