From 7a922f3917e65b81097bb446d335831ce1950f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jer=C3=B4me=20Bakker?= Date: Fri, 20 Oct 2023 12:15:17 +0200 Subject: [PATCH] fix(a11y): tab to first item in opened dropdown menu Also set focus back to the popup trigger when it's closed and the focus was inside the popup --- views/default/elgg/menus/dropdown.js | 7 +------ views/default/elgg/popup.js | 19 +++++++++++++++++++ views/default/icon/user/default.js | 4 ++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/views/default/elgg/menus/dropdown.js b/views/default/elgg/menus/dropdown.js index fe7d4def904..a129e77c1e3 100644 --- a/views/default/elgg/menus/dropdown.js +++ b/views/default/elgg/menus/dropdown.js @@ -21,12 +21,7 @@ define(['jquery', 'elgg', 'elgg/popup'], function ($, elgg, popup) { $trigger.addClass('elgg-menu-opened') .removeClass('elgg-menu-closed'); $trigger.parent().addClass('elgg-state-selected'); - }); - - $target.on('close', function () { - $trigger.addClass('elgg-menu-closed') - .removeClass('elgg-menu-opened'); - $trigger.parent().removeClass('elgg-state-selected'); + $target.find('a:first').focus(); }); } diff --git a/views/default/elgg/popup.js b/views/default/elgg/popup.js index 83b96341b69..80cb60061ad 100644 --- a/views/default/elgg/popup.js +++ b/views/default/elgg/popup.js @@ -17,6 +17,7 @@ define('elgg/popup', ['jquery', 'elgg', 'elgg/hooks', 'jquery-ui/position', 'jqu */ init: function () { $(document).on('click', function (e) { + // close the popup when clicked outside the popup if (e.isDefaultPrevented()) { return; } @@ -28,6 +29,16 @@ define('elgg/popup', ['jquery', 'elgg', 'elgg/hooks', 'jquery-ui/position', 'jqu popup.close(); }); + + $(document).on('keydown', function (e) { + // close the popup when the escape key is pressed + if (e.isDefaultPrevented() || e.key !== "Escape") { + return; + } + + popup.close(); + }); + // Bind events only once popup.init = function() {}; }, @@ -142,6 +153,14 @@ define('elgg/popup', ['jquery', 'elgg', 'elgg/hooks', 'jquery-ui/position', 'jqu $trigger.addClass('elgg-state-active'); $target.trigger('open'); + + if ($trigger.is('a')) { + $target.on('close', function() { + if ($target.find(':focus').length) { + $trigger.focus(); + } + }); + } }, /** * Hides a set of $targets. If not defined, closes all visible popup modules. diff --git a/views/default/icon/user/default.js b/views/default/icon/user/default.js index 063a7034792..6103e76e823 100644 --- a/views/default/icon/user/default.js +++ b/views/default/icon/user/default.js @@ -51,6 +51,10 @@ define(['jquery'], function ($) { $icon.data('hovermenu', $hovermenu); } + $hovermenu.on('open', function() { + $hovermenu.find('a:first').focus(); + }); + require(['elgg/popup'], function(popup) { if ($hovermenu.is(':visible')) { // close hovermenu if arrow is clicked & menu already open