From 91bfcf61f44f353dfebc54a57b5b774721de3e9a Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 19 十月 2026 09:39:22 +0800
Subject: [PATCH] feat(auth): 更新门户认证页面布局和样式

---
 src/packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue |   39 +++++++++++++++++++++++++++++++++++++--
 1 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue b/src/packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue
index 6745b8e..2acc973 100644
--- a/src/packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue
+++ b/src/packages/@core/ui-kit/menu-ui/src/components/sub-menu.vue
@@ -3,7 +3,7 @@
 
 import type { MenuItemRegistered, MenuProvider, SubMenuProps } from '../types';
 
-import { computed, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
+import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref } from 'vue';
 
 import { useNamespace } from '../../../../composables/src';
 import { VbenHoverCard } from '../../../shadcn-ui/src';
@@ -41,6 +41,32 @@
 const items = ref<MenuProvider['items']>({});
 const subMenus = ref<MenuProvider['subMenus']>({});
 const timer = ref<null | ReturnType<typeof setTimeout>>(null);
+const popupRef = ref<HTMLElement>();
+const popupTriggerRef = ref<InstanceType<typeof SubMenuContent>>();
+
+function togglePopup() {
+  if (props.disabled) return;
+  if (timer.value) window.clearTimeout(timer.value);
+  if (opened.value) rootMenu.closeMenu(props.path, parentPaths.value);
+  else rootMenu.openMenu(props.path, parentPaths.value);
+}
+
+async function handlePopupKeydown(event: KeyboardEvent) {
+  if (props.disabled) return;
+  if (['Enter', ' ', 'ArrowDown'].includes(event.key)) {
+    event.preventDefault();
+    event.stopPropagation();
+    rootMenu.openMenu(props.path, parentPaths.value);
+    await nextTick();
+    popupRef.value?.querySelector<HTMLElement>('[role="menuitem"]')?.focus();
+  } else if (event.key === 'Escape') {
+    event.preventDefault();
+    event.stopPropagation();
+    rootMenu.closeMenu(props.path, parentPaths.value);
+    const trigger = popupTriggerRef.value?.$el;
+    if (trigger instanceof HTMLElement) trigger.focus();
+  }
+}
 
 createSubMenuContext({
   addSubMenu,
@@ -218,13 +244,19 @@
       >
         <template #trigger>
           <SubMenuContent
+            ref="popupTriggerRef"
             :class="is('active', active)"
             :icon="menuIcon"
             :is-menu-more="isSubMenuMore"
             :is-top-level-menu-submenu="isTopLevelMenuSubmenu"
             :level="currentLevel"
             :path="path"
-            @click.stop="handleClick"
+            role="menuitem"
+            :tabindex="disabled ? -1 : 0"
+            aria-haspopup="menu"
+            :aria-expanded="opened"
+            @click.stop="togglePopup"
+            @keydown="handlePopupKeydown"
           >
             <template #title>
               <slot name="title"></slot>
@@ -232,7 +264,9 @@
           </SubMenuContent>
         </template>
         <div
+          ref="popupRef"
           :class="[nsMenu.is(mode, true), nsMenu.e('popup')]"
+          @keydown.esc="handlePopupKeydown"
           @focus="(e) => handleMouseenter(e, 100)"
           @mouseenter="(e) => handleMouseenter(e, 100)"
           @mouseleave="() => handleMouseleave(true)"
@@ -240,6 +274,7 @@
           <ul
             :class="[nsMenu.b(), is('rounded', rounded)]"
             :style="subMenuStyle"
+            role="menu"
           >
             <slot></slot>
           </ul>

--
Gitblit v1.9.3