Skip to content

Commit

Permalink
Context Menu Improvements
Browse files Browse the repository at this point in the history
- Accessibility - using Tab to traverse the menu
- Arrow key support within the menu, some funky logic there that should be cleared up, not the nicest code but it serves the purpose for now
  • Loading branch information
sandervonk committed Nov 6, 2022
1 parent 0968b96 commit 973b5ee
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
8 changes: 7 additions & 1 deletion css/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,10 @@ input:checked + .switch-label {
transition: background-color 0.1s ease-out;
overflow: hidden;
}
.context-menu .cm-item:hover {
.context-menu .cm-item:hover,
.context-menu .cm-item:active,
.context-menu .cm-item:focus,
.context-menu .cm-item:focus-within {
background: var(--cm-bg-hover);
}
.context-menu .cm-item > img {
Expand Down Expand Up @@ -1096,3 +1099,6 @@ input:checked + .switch-label {
#wordreference-button.disabled {
opacity: 0.5;
}
/* [tabindex] {
outline: none !important;
} */
22 changes: 22 additions & 0 deletions css/practice-setup.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,25 @@ form {
body {
padding: 0 !important;
}
@media (min-width: 500px) {
::-webkit-scrollbar-track {
opacity: 0 !important;
background: var(--bg);
display: none !important;
width: 16px;
height: 16px;
}
::-webkit-scrollbar-thumb {
border-radius: 16px;
background: var(--secondary-alt);
border: solid 4px var(--bg);
}
::-webkit-scrollbar {
width: 16px !important;
height: 16px !important;
}
::-webkit-scrollbar-corner {
opacity: 0;
background: transparent;
}
}
37 changes: 37 additions & 0 deletions js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ function closeContextMenu() {
setTimeout(function () {
$(".context-menu, .context-overlay").remove();
}, 200);
$(document.body).children("[tabindex]").removeAttr("tabindex");
}

$(window).on("click", "body[contextmenu] > *:not(.context-menu)", closeContextMenu);
Expand All @@ -83,6 +84,37 @@ $(window).on("keydown blur resize", function (event) {
closeContextMenu();
}
});
$(window).on("keydown", function (e) {
//if focus outside of the context menu (by tabbing) list it in the console
if ($(".context-menu").length) {
if (e.key === "Enter" && $(".context-menu .cm-item:focus").length) {
e.preventDefault();
$(".context-menu .cm-item:focus").click();
} else if (e.key.includes("Arrow") && $(".context-menu .cm-item:focus").length) {
e.preventDefault();
let focused = $(".context-menu .cm-item:focus"),
key = e.key.replace("Arrow", "");
let next = $(`.context-menu .cm-item[tabindex="${parseInt(focused.attr("tabindex")) + 1}"]`),
prev = $(`.context-menu .cm-item[tabindex="${parseInt(focused.attr("tabindex")) - 1}"]`),
chosen = {};
if (key == "Up" && prev.length && !focused.parent().is(prev.parent())) {
// if the previous and current items are in the same section, continue to the ArrowLeft logic, otherwise, pick the first item of the previous section
chosen = prev.parent().children().first();
} else if (key == "Down" && next.length && next.parent().attr("id") == "cm-buttons") {
// if the next and current items are in the same section, continue to the ArrowRight logic, otherwise, pick the first item of the next section
chosen = $("#cm-scrollable").children().first().children().first();
} else if (key == "Down" || key == "Right") {
chosen = next;
} else if (key == "Up" || key == "Left") {
chosen = prev;
}
if (chosen.length) chosen.focus();
} else if (e.key === "Tab" && $(".context-menu").length && ($("*:focus").closest(".context-menu").length == 0 || $(".context-menu > #cm-scrollable > #cm-default-items > :last-child:focus").length)) {
e.preventDefault();
$(".context-menu .cm-item").first().focus();
}
}
});
class ContextMenu {
constructor(e, item_ref, menuItems = [], options = { width: 300 }) {
this.defaults = [
Expand Down Expand Up @@ -179,6 +211,11 @@ class ContextMenu {
$(document.body).append(`<div class='context-overlay'></div>`, this.menu);
$(document.body).attr("contextmenu", "");
this.realign(x, y);
// for each menu item, add a increasing tabindex to make them accessible by keyboard
$(".context-menu .cm-item").each(function (i) {
$(this).attr("tabindex", i + 1);
});
$(".context-menu .cm-item").first().focus();
}
realign(x, y) {
this.menu.focus();
Expand Down

0 comments on commit 973b5ee

Please sign in to comment.