From 6776071f0246fc274ce81b157085337afee31037 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Mon, 22 Feb 2021 17:10:23 +0100 Subject: [PATCH] Keyboard support for drop-down menus with deferred initialization Fixes #3704 --- ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts | 20 +++++++++++++++++-- wcfsetup/install/files/js/WCF.js | 9 +++++++++ .../WoltLabSuite/Core/Ui/Dropdown/Simple.js | 20 +++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts b/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts index 52b6dd24e8..475f676186 100644 --- a/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts +++ b/ts/WoltLabSuite/Core/Ui/Dropdown/Simple.ts @@ -94,6 +94,7 @@ function toggle( alternateElement?: HTMLElement, disableAutoFocus?: boolean, ): boolean { + let isKeyboardClick = false; if (event !== null) { event.preventDefault(); event.stopPropagation(); @@ -102,7 +103,12 @@ function toggle( targetId = target.dataset.target; if (disableAutoFocus === undefined && event instanceof MouseEvent) { - disableAutoFocus = true; + if (Core.stringToBool(target.dataset.isKeyboardClick || "")) { + isKeyboardClick = true; + delete target.dataset.isKeyboardClick; + } else { + disableAutoFocus = true; + } } } @@ -235,6 +241,10 @@ function toggle( if (firstListItem !== null) { firstListItem.focus(); + + if (isKeyboardClick) { + (firstListItem as HTMLLIElement).classList.add("focus-visible"); + } } } }); @@ -254,7 +264,13 @@ function handleKeyDown(event: KeyboardEvent): void { if (event.key === "Enter" || event.key === "Space") { event.preventDefault(); - toggle(event); + + if (target.dataset.requiresSynthethicClick) { + target.dataset.isKeyboardClick = "true"; + target.click(); + } else { + toggle(event); + } } } diff --git a/wcfsetup/install/files/js/WCF.js b/wcfsetup/install/files/js/WCF.js index 1e44bace81..76d33dbb94 100755 --- a/wcfsetup/install/files/js/WCF.js +++ b/wcfsetup/install/files/js/WCF.js @@ -5578,10 +5578,19 @@ if (COMPILER_TARGET_DEFAULT) { return; } + $trigger[0].addEventListener("keydown", (event) => { + if (event.key === "Enter") { + event.preventDefault(); + $trigger[0].dataset.isKeyboardClick = "true"; + + self._show(event); + } + }); $trigger.on('click', $.proxy(self._show, self)).data( 'elementID', $elementID ); + $trigger[0].dataset.requiresSynthethicClick = true; if (self._quickOption) { // simulate click on target action $trigger.disableSelection().data( diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js index 1169bc7528..d1eda1748b 100644 --- a/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js +++ b/wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Dropdown/Simple.js @@ -86,13 +86,20 @@ define(["require", "exports", "tslib", "../../CallbackList", "../../Core", "../. * Toggles the drop-down's state between open and close. */ function toggle(event, targetId, alternateElement, disableAutoFocus) { + let isKeyboardClick = false; if (event !== null) { event.preventDefault(); event.stopPropagation(); const target = event.currentTarget; targetId = target.dataset.target; if (disableAutoFocus === undefined && event instanceof MouseEvent) { - disableAutoFocus = true; + if (Core.stringToBool(target.dataset.isKeyboardClick || "")) { + isKeyboardClick = true; + delete target.dataset.isKeyboardClick; + } + else { + disableAutoFocus = true; + } } } let dropdown = _dropdowns.get(targetId); @@ -206,6 +213,9 @@ define(["require", "exports", "tslib", "../../CallbackList", "../../Core", "../. UiDropdownSimple.setAlignment(dropdown, menu, alternateElement); if (firstListItem !== null) { firstListItem.focus(); + if (isKeyboardClick) { + firstListItem.classList.add("focus-visible"); + } } } }); @@ -221,7 +231,13 @@ define(["require", "exports", "tslib", "../../CallbackList", "../../Core", "../. } if (event.key === "Enter" || event.key === "Space") { event.preventDefault(); - toggle(event); + if (target.dataset.requiresSynthethicClick) { + target.dataset.isKeyboardClick = "true"; + target.click(); + } + else { + toggle(event); + } } } function dropdownMenuKeyDown(event) { -- 2.20.1