Skip to content

Commit

Permalink
fix(accessibility): close menu when it loses focus
Browse files Browse the repository at this point in the history
See #354
  • Loading branch information
NickDJM authored Nov 8, 2024
1 parent eb9c3a4 commit 54a3a57
Show file tree
Hide file tree
Showing 18 changed files with 341 additions and 111 deletions.
2 changes: 1 addition & 1 deletion dist/accessible-menu.cjs.js

Large diffs are not rendered by default.

72 changes: 38 additions & 34 deletions dist/accessible-menu.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -702,8 +702,8 @@ class w {
controllerElement: h = null,
containerElement: m = null,
openClass: a = "show",
closeClass: p = "hide",
transitionClass: f = "transitioning",
closeClass: f = "hide",
transitionClass: p = "transitioning",
transitionDuration: g = 250,
openDuration: d = -1,
closeDuration: M = -1,
Expand Down Expand Up @@ -947,7 +947,7 @@ class w {
* @type {string[]}
*/
u(this, "_errors", []);
this._dom.menu = e, this._dom.controller = h, this._dom.container = m, this._selectors.menuItems = t, this._selectors.menuLinks = s, this._selectors.submenuItems = n, this._selectors.submenuToggles = i, this._selectors.submenus = l, this._elements.menuItems = [], this._elements.submenuToggles = [], this._elements.controller = null, this._elements.parentMenu = b, this._elements.rootMenu = y ? this : null, this._openClass = a || "", this._closeClass = p || "", this._transitionClass = f || "", this._transitionDuration = g, this._openDuration = d, this._closeDuration = M, this._prefix = v || "", this._root = y, this._hoverType = C, this._hoverDelay = T, this._enterDelay = E, this._leaveDelay = I;
this._dom.menu = e, this._dom.controller = h, this._dom.container = m, this._selectors.menuItems = t, this._selectors.menuLinks = s, this._selectors.submenuItems = n, this._selectors.submenuToggles = i, this._selectors.submenus = l, this._elements.menuItems = [], this._elements.submenuToggles = [], this._elements.controller = null, this._elements.parentMenu = b, this._elements.rootMenu = y ? this : null, this._openClass = a || "", this._closeClass = f || "", this._transitionClass = p || "", this._transitionDuration = g, this._openDuration = d, this._closeDuration = M, this._prefix = v || "", this._root = y, this._hoverType = C, this._hoverDelay = T, this._enterDelay = E, this._leaveDelay = I;
}
/**
* Initializes the menu.
Expand Down Expand Up @@ -1413,14 +1413,14 @@ class w {
hoverDelay: this._hoverDelay
});
a.status || (this._errors.push(a.error.message), e = !1);
const p = c("number", {
const f = c("number", {
enterDelay: this._enterDelay
});
p.status || (this._errors.push(p.error.message), e = !1);
const f = c("number", {
f.status || (this._errors.push(f.error.message), e = !1);
const p = c("number", {
leaveDelay: this._leaveDelay
});
f.status || (this._errors.push(f.error.message), e = !1);
p.status || (this._errors.push(p.error.message), e = !1);
const g = c("string", { prefix: this._prefix });
return g.status || (this._errors.push(g.error.message), e = !1), e;
}
Expand Down Expand Up @@ -1583,6 +1583,8 @@ class w {
* - Adds a `focus` listener to every menu item so when it gains focus,
* it will set the item's containing menu's focus state
* to "self".
* - Adds a `focusout` listener to the menu so when the menu loses focus,
* it will close.
*
* @protected
*/
Expand All @@ -1591,6 +1593,8 @@ class w {
e.dom.link.addEventListener("focus", () => {
this.focusState = "self", this.currentChild = t;
});
}), this.dom.menu.addEventListener("focusout", (e) => {
this.currentEvent !== "keyboard" || e.relatedTarget === null || this.dom.menu.contains(e.relatedTarget) || (this.focusState = "none", this.closeChildren());
});
}
/**
Expand All @@ -1609,7 +1613,7 @@ class w {
*/
_handleClick() {
function e(t, s, n) {
o(n), s.toggle(), s.isOpen && (t.focusState = "self", s.elements.controlledMenu.focusState = "none");
o(n), n.button === 0 && (s.toggle(), s.isOpen && (t.focusState = "self", s.elements.controlledMenu.focusState = "none"));
}
this.elements.menuItems.forEach((t, s) => {
t.dom.link.addEventListener(
Expand Down Expand Up @@ -2025,8 +2029,8 @@ class z extends w {
submenuSelector: h = "ul",
controllerElement: m = null,
containerElement: a = null,
openClass: p = "show",
closeClass: f = "hide",
openClass: f = "show",
closeClass: p = "hide",
transitionClass: g = "transitioning",
transitionDuration: d = 250,
openDuration: M = -1,
Expand All @@ -2050,8 +2054,8 @@ class z extends w {
submenuSelector: h,
controllerElement: m,
containerElement: a,
openClass: p,
closeClass: f,
openClass: f,
closeClass: p,
transitionClass: g,
transitionDuration: d,
openDuration: M,
Expand Down Expand Up @@ -2408,8 +2412,8 @@ class H extends w {
submenuSelector: h = "ul",
controllerElement: m = null,
containerElement: a = null,
openClass: p = "show",
closeClass: f = "hide",
openClass: f = "show",
closeClass: p = "hide",
transitionClass: g = "transitioning",
transitionDuration: d = 250,
isTopLevel: M = !0,
Expand All @@ -2430,8 +2434,8 @@ class H extends w {
submenuSelector: h,
controllerElement: m,
containerElement: a,
openClass: p,
closeClass: f,
openClass: f,
closeClass: p,
transitionClass: g,
transitionDuration: d,
isTopLevel: M,
Expand Down Expand Up @@ -2818,8 +2822,8 @@ class q extends w {
submenuSelector: h = "ul",
submenuSubtoggleSelector: m = "a",
controllerElement: a = null,
containerElement: p = null,
openClass: f = "show",
containerElement: f = null,
openClass: p = "show",
closeClass: g = "hide",
transitionClass: d = "transitioning",
transitionDuration: M = 250,
Expand All @@ -2841,8 +2845,8 @@ class q extends w {
submenuSelector: h,
submenuToggleSelector: l,
controllerElement: a,
containerElement: p,
openClass: f,
containerElement: f,
openClass: p,
closeClass: g,
transitionClass: d,
transitionDuration: M,
Expand Down Expand Up @@ -3347,8 +3351,8 @@ class j extends w {
submenuSelector: h = "ul",
controllerElement: m = null,
containerElement: a = null,
openClass: p = "show",
closeClass: f = "hide",
openClass: f = "show",
closeClass: p = "hide",
transitionClass: g = "transitioning",
transitionDuration: d = 250,
isTopLevel: M = !0,
Expand All @@ -3369,8 +3373,8 @@ class j extends w {
submenuSelector: h,
controllerElement: m,
containerElement: a,
openClass: p,
closeClass: f,
openClass: f,
closeClass: p,
transitionClass: g,
transitionDuration: d,
isTopLevel: M,
Expand Down Expand Up @@ -3597,28 +3601,28 @@ class j extends w {
* @param {string} char - The character to look for.
*/
focusNextNodeWithCharacter(t) {
function s(p) {
let f = [];
return p.elements.menuItems.forEach((g) => {
f.push(g), g.isSubmenuItem && g.elements.toggle.isOpen && (f = [
...f,
function s(f) {
let p = [];
return f.elements.menuItems.forEach((g) => {
p.push(g), g.isSubmenuItem && g.elements.toggle.isOpen && (p = [
...p,
...s(
g.elements.toggle.elements.controlledMenu
)
]);
}), f;
}), p;
}
const n = t.toLowerCase(), i = s(this.elements.rootMenu), l = i.indexOf(this.currentMenuItem) + 1, h = [
...i.slice(l),
...i.slice(0, l)
];
let m = 0, a = !1;
for (; !a && m < h.length; ) {
let p = "";
if (h[m].dom.item.innerText ? p = h[m].dom.item.innerText : p = h[m].dom.item.textContent, p = p.replace(/[\s]/g, "").toLowerCase().charAt(0), p === n) {
let f = "";
if (h[m].dom.item.innerText ? f = h[m].dom.item.innerText : f = h[m].dom.item.textContent, f = f.replace(/[\s]/g, "").toLowerCase().charAt(0), f === n) {
a = !0;
const f = h[m].elements.parentMenu, g = f.elements.menuItems.indexOf(h[m]);
this.elements.rootMenu.blurChildren(), f.focusChild(g);
const p = h[m].elements.parentMenu, g = p.elements.menuItems.indexOf(h[m]);
this.elements.rootMenu.blurChildren(), p.focusChild(g);
}
m++;
}
Expand Down
4 changes: 2 additions & 2 deletions dist/accessible-menu.iife.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/disclosure-menu.cjs.js

Large diffs are not rendered by default.

22 changes: 13 additions & 9 deletions dist/disclosure-menu.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function l(n, e) {
};
}
}
function L(n) {
function I(n) {
try {
if (typeof n != "object") {
const e = typeof n;
Expand Down Expand Up @@ -110,7 +110,7 @@ function b(n) {
);
else {
const s = {};
s[e] = n[e], L(s);
s[e] = n[e], I(s);
}
}
return {
Expand Down Expand Up @@ -713,7 +713,7 @@ class T {
hoverDelay: S = 250,
enterDelay: k = -1,
leaveDelay: A = -1,
prefix: I = "am-"
prefix: L = "am-"
}) {
/**
* The class to use when generating submenus.
Expand Down Expand Up @@ -947,7 +947,7 @@ class T {
* @type {string[]}
*/
r(this, "_errors", []);
this._dom.menu = e, this._dom.controller = c, this._dom.container = m, this._selectors.menuItems = t, this._selectors.menuLinks = s, this._selectors.submenuItems = i, this._selectors.submenuToggles = o, this._selectors.submenus = u, this._elements.menuItems = [], this._elements.submenuToggles = [], this._elements.controller = null, this._elements.parentMenu = v, this._elements.rootMenu = M ? this : null, this._openClass = f || "", this._closeClass = d || "", this._transitionClass = p || "", this._transitionDuration = g, this._openDuration = h, this._closeDuration = D, this._prefix = I || "", this._root = M, this._hoverType = w, this._hoverDelay = S, this._enterDelay = k, this._leaveDelay = A;
this._dom.menu = e, this._dom.controller = c, this._dom.container = m, this._selectors.menuItems = t, this._selectors.menuLinks = s, this._selectors.submenuItems = i, this._selectors.submenuToggles = o, this._selectors.submenus = u, this._elements.menuItems = [], this._elements.submenuToggles = [], this._elements.controller = null, this._elements.parentMenu = v, this._elements.rootMenu = M ? this : null, this._openClass = f || "", this._closeClass = d || "", this._transitionClass = p || "", this._transitionDuration = g, this._openDuration = h, this._closeDuration = D, this._prefix = L || "", this._root = M, this._hoverType = w, this._hoverDelay = S, this._enterDelay = k, this._leaveDelay = A;
}
/**
* Initializes the menu.
Expand Down Expand Up @@ -1363,13 +1363,13 @@ class T {
menuElement: this._dom.menu
}), t.status || (this._errors.push(t.error.message), e = !1);
let s;
if (this._selectors.submenuItems !== "" ? s = L({
if (this._selectors.submenuItems !== "" ? s = I({
menuItemSelector: this._selectors.menuItems,
menuLinkSelector: this._selectors.menuLinks,
submenuItemSelector: this._selectors.submenuItems,
submenuToggleSelector: this._selectors.submenuToggles,
submenuSelector: this._selectors.submenus
}) : s = L({
}) : s = I({
menuItemSelector: this._selectors.menuItems,
menuLinkSelector: this._selectors.menuLinks
}), s.status || (this._errors.push(s.error.message), e = !1), this._openClass !== "") {
Expand Down Expand Up @@ -1583,6 +1583,8 @@ class T {
* - Adds a `focus` listener to every menu item so when it gains focus,
* it will set the item's containing menu's focus state
* to "self".
* - Adds a `focusout` listener to the menu so when the menu loses focus,
* it will close.
*
* @protected
*/
Expand All @@ -1591,6 +1593,8 @@ class T {
e.dom.link.addEventListener("focus", () => {
this.focusState = "self", this.currentChild = t;
});
}), this.dom.menu.addEventListener("focusout", (e) => {
this.currentEvent !== "keyboard" || e.relatedTarget === null || this.dom.menu.contains(e.relatedTarget) || (this.focusState = "none", this.closeChildren());
});
}
/**
Expand All @@ -1609,7 +1613,7 @@ class T {
*/
_handleClick() {
function e(t, s, i) {
a(i), s.toggle(), s.isOpen && (t.focusState = "self", s.elements.controlledMenu.focusState = "none");
a(i), i.button === 0 && (s.toggle(), s.isOpen && (t.focusState = "self", s.elements.controlledMenu.focusState = "none"));
}
this.elements.menuItems.forEach((t, s) => {
t.dom.link.addEventListener(
Expand Down Expand Up @@ -2036,7 +2040,7 @@ class j extends T {
hoverType: S = "off",
hoverDelay: k = 250,
enterDelay: A = -1,
leaveDelay: I = -1,
leaveDelay: L = -1,
optionalKeySupport: K = !1,
prefix: V = "am-",
initialize: q = !0
Expand All @@ -2061,7 +2065,7 @@ class j extends T {
hoverType: S,
hoverDelay: k,
enterDelay: A,
leaveDelay: I,
leaveDelay: L,
prefix: V
});
/**
Expand Down
Loading

0 comments on commit 54a3a57

Please sign in to comment.