Skip to content

Commit b48e9eb

Browse files
committed
Fix submenu keyboard contol not work issue (#124)
1 parent 128ce27 commit b48e9eb

File tree

3 files changed

+45
-14
lines changed

3 files changed

+45
-14
lines changed

library/ContextMenuItem.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import { inject, nextTick, onBeforeUnmount, onMounted, type PropType, ref, type
7070
import type { SubMenuParentContext } from './ContextSubMenu.vue'
7171
import type { GlobalHasSlot, GlobalRenderSlot } from './ContextMenu.vue'
7272
import type { MenuItem, MenuItemContext, MenuOptions } from './ContextMenuDefine'
73-
import { VNodeRender } from './ContextMenuUtils'
73+
import { hashCode, VNodeRender } from './ContextMenuUtils'
7474
import ContextMenuIconCheck from './ContextMenuIconCheck.vue'
7575
import ContextMenuIconRight from './ContextMenuIconRight.vue'
7676
@@ -228,6 +228,16 @@ const globalCloseMenu = inject('globalCloseMenu') as (fromItem: MenuItem|undefin
228228
229229
const menuContext = inject('menuContext') as SubMenuParentContext;
230230
231+
const nameForDebug = computed(() => {
232+
if (typeof label.value === 'string')
233+
return label.value;
234+
else if (typeof label.value === 'function')
235+
return hashCode(label.value.toString());
236+
return 'MenuItem[unknow]';
237+
})
238+
239+
provide('MenuItemName', nameForDebug);
240+
231241
//Instance Contet for keyboadr control
232242
const menuItemInstance : MenuItemContext = {
233243
getSubMenuInstance: () => undefined,

library/ContextMenuUtils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,16 @@ export function genContainer(options: MenuOptions) : {
114114
};
115115
}
116116

117+
export function hashCode(str: string) {
118+
let hash = 0;
119+
for (let i = 0; i < str.length; i++) {
120+
const chr = str.charCodeAt(i);
121+
hash = ((hash << 5) - hash) + chr;
122+
hash |= 0; // 转为32位整数
123+
}
124+
return hash;
125+
}
126+
117127
/**
118128
* Number to px string
119129
* @param value

library/ContextSubMenu.vue

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ import ContextMenuSeparator from './ContextMenuSeparator.vue'
107107
108108
//The internal info context for submenu instance
109109
export interface SubMenuContext {
110+
name: Ref<string>,
111+
el: Ref<HTMLElement|undefined>;
110112
isTopLevel: () => boolean;
111113
closeSelfAndActiveParent: () => boolean,
112114
openCurrentItemSubMenu: () => boolean,
@@ -219,6 +221,8 @@ const parentContext = inject('menuContext') as SubMenuParentContext;
219221
const options = inject('globalOptions') as Ref<MenuOptions>;
220222
const globalHasSlot = inject('globalHasSlot') as GlobalHasSlot;
221223
const globalRenderSlot = inject('globalRenderSlot') as GlobalRenderSlot;
224+
const debugMenuItemNameDefault = ref('UnknowOrRoot');
225+
const debugMenuItemName = inject<Ref<string>>('MenuItemName', debugMenuItemNameDefault);
222226
223227
//#endregion
224228
@@ -283,6 +287,8 @@ function onSubMenuBodyClick() {
283287
}
284288
285289
const thisMenuInsContext : SubMenuContext = {
290+
el: menu,
291+
name: debugMenuItemName,
286292
isTopLevel: () => parentContext.getParentContext() === null,
287293
closeSelfAndActiveParent: () => {
288294
const parent = thisMenuContext.getParentContext();
@@ -518,16 +524,6 @@ function doAdjustPosition() {
518524
});
519525
}
520526
521-
//Focus this submenu
522-
menuEl?.focus({
523-
preventScroll: true
524-
});
525-
526-
//Is this submenu opened by keyboard? If yes then select first item
527-
if (parentContext.isOpenedByKeyBoardFlag())
528-
setAndFocusNotDisableItem(true);
529-
530-
isMenuItemDataCollectedFlag = true;
531527
});
532528
}
533529
@@ -547,6 +543,22 @@ function showSolve() {
547543
position.value.x = x;
548544
position.value.y = y;
549545
}
546+
//Focus current
547+
nextTick(() => {
548+
549+
//Mark current item submenu is open
550+
globalSetCurrentSubMenu(thisMenuInsContext);
551+
552+
//Focus this submenu
553+
menu.value?.focus({ preventScroll: true });
554+
555+
//Is this submenu opened by keyboard? If yes then select first item
556+
if (parentContext.isOpenedByKeyBoardFlag())
557+
nextTick(() => setAndFocusNotDisableItem(true));
558+
559+
isMenuItemDataCollectedFlag = true;
560+
});
561+
//
550562
doAdjustPosition();
551563
}
552564
@@ -556,9 +568,8 @@ watch(() => props.show, (v) => {
556568
557569
onMounted(() => {
558570
mounted.value = true;
559-
//Mark current item submenu is open
560-
globalSetCurrentSubMenu(thisMenuInsContext);
561-
showSolve();
571+
if (props.show)
572+
showSolve();
562573
});
563574
onBeforeUnmount(() => {
564575
mounted.value = false;

0 commit comments

Comments
 (0)