Skip to content

Commit

Permalink
⌨ improved keyboard accessibility
Browse files Browse the repository at this point in the history
  • Loading branch information
prabhuignoto committed Nov 24, 2020
1 parent 9c2adca commit 7365a43
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 100 deletions.
13 changes: 12 additions & 1 deletion src/components/HelloWorld.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,25 @@ export default defineComponent({
},
{
name: "edit",
menu: [{ name: "Cut" }, { name: "Copy" }, { name: "Paste" }],
menu: [
{ name: "Undo" },
{ name: "Redo" },
{ isDivider: true },
{ name: "Cut" },
{ name: "Copy" },
{ name: "Paste" },
{ isDivider: true },
{ name: "Find" },
{ name: "Replace" },
],
},
{
name: "View",
menu: [
{ name: "Explorer" },
{ name: "Search" },
{ name: "Run" },
{ isDivider: true },
{
name: "Apperance",
menu: [{ name: "Full Screen" }, { name: "Zen Mode" }],
Expand Down
85 changes: 63 additions & 22 deletions src/components/Menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"
@focus="onFocus"
@blur="onBlur"
@keyup.enter="handleKeySelection"
>
<li
v-for="(item, index) of menuItems"
Expand Down Expand Up @@ -56,11 +57,12 @@
:is="MenuComponent"
:items="item.menu"
:dock="dock"
:parent="item.name"
:parent="`${parent}>${item.name}`"
:theme="theme"
:is-touch="isMobile"
:nested="true"
@selected="handleSelection"
:on-selected="onSelected"
:initial-highlight-index="subMenuHighlightIndex"
@closeMenu="handleCloseMenu"
/>
</div>
Expand Down Expand Up @@ -123,6 +125,17 @@ export default defineComponent({
type: Boolean,
default: false,
},
onSelected: {
required: true,
type: Function as PropType<
({ name, path }: { name: string; path: string }) => void
>,
},
initialHighlightIndex: {
required: false,
type: Number,
default: -1,
},
},
emits: ["selected", "close-menu"],
setup(props, { emit }) {
Expand All @@ -141,7 +154,8 @@ export default defineComponent({
const hasFocus = ref<boolean>();
const menuItemsRef = ref();
const highlightedIndex = ref<number>(-1);
const highlightedIndex = ref<number>(props.initialHighlightIndex);
const subMenuHighlightIndex = ref(-1);
const handleSelection = (selectedItem: SelectedItemModel) => {
selectedItem.event.stopPropagation();
Expand All @@ -154,12 +168,10 @@ export default defineComponent({
const { path, name } = selectedItem;
emit(
"selected",
Object.assign({}, selectedItem, {
path: `${props.parent}>${path ? path : name}`.toLowerCase(),
})
);
props.onSelected({
name,
path: `${props.parent}>${path ? path : name}`.toLowerCase(),
});
};
const menuItemStyle = computed(() => ({
Expand All @@ -185,12 +197,24 @@ export default defineComponent({
});
});
const focusMenuBar = () => {
const menuBarItems = (menuItemsRef.value as HTMLElement).closest(
".menu-bar-item-container"
);
if (menuBarItems) {
(menuBarItems as HTMLElement).focus();
}
};
const handleKeyUp = (event: KeyboardEvent) => {
if (!hasFocus.value) {
return;
}
event.stopPropagation();
const nextIndex = highlightedIndex.value - 1;
let nextIndex = highlightedIndex.value - 1;
nextIndex = menuItems.value[nextIndex]?.isDivider
? nextIndex - 1
: nextIndex;
if (nextIndex >= 0) {
highlightedIndex.value = nextIndex;
Expand All @@ -204,7 +228,10 @@ export default defineComponent({
return;
}
event.stopPropagation();
const nextIndex = highlightedIndex.value + 1;
let nextIndex = highlightedIndex.value + 1;
nextIndex = menuItems.value[nextIndex]?.isDivider
? nextIndex + 1
: nextIndex;
if (nextIndex >= 0 && nextIndex < menuItemsLen.value) {
highlightedIndex.value = nextIndex;
Expand All @@ -221,14 +248,10 @@ export default defineComponent({
if (menuItem && menuItem.menu) {
event.stopPropagation();
subMenuHighlightIndex.value = 0;
toggleSubMenu(!!menuItem.menu);
} else {
const menuBarItems = (menuItemsRef.value as HTMLElement).closest(
".menu-bar-item-container"
);
if (menuBarItems) {
(menuBarItems as HTMLElement).focus();
}
focusMenuBar();
}
};
Expand All @@ -240,11 +263,27 @@ export default defineComponent({
event.stopPropagation();
emit("close-menu");
} else {
const menuBarItems = (menuItemsRef.value as HTMLElement).closest(
".menu-bar-item-container"
);
if (menuBarItems) {
(menuBarItems as HTMLElement).focus();
focusMenuBar();
}
};
const handleKeySelection = (event: KeyboardEvent) => {
if (highlightedIndex.value >= 0) {
const menuItem = menuItems.value[highlightedIndex.value];
event.stopPropagation();
if (menuItem?.menu) {
subMenuHighlightIndex.value = 0;
toggleSubMenu(!!menuItem.menu);
nextTick(() => {
(menuItemsRef.value as HTMLElement).focus();
});
} else if (menuItem) {
props.onSelected({
name: menuItem.name as string,
path: `${props.parent}>${menuItem.name}`.toLowerCase(),
});
}
}
};
Expand Down Expand Up @@ -276,6 +315,8 @@ export default defineComponent({
onFocus,
onBlur,
handleCloseMenu,
handleKeySelection,
subMenuHighlightIndex,
};
},
});
Expand Down
Loading

0 comments on commit 7365a43

Please sign in to comment.