|
@@ -4,7 +4,7 @@
|
|
import { html } from "lit";
|
|
import { html } from "lit";
|
|
import { until } from "lit/directives/until.js";
|
|
import { until } from "lit/directives/until.js";
|
|
import { api, constants, u } from "@converse/headless";
|
|
import { api, constants, u } from "@converse/headless";
|
|
-import DOMNavigator from "shared/dom-navigator.js";
|
|
|
|
|
|
+import { DOMNavigator } from "shared/dom-navigator";
|
|
import DropdownBase from "shared/components/dropdownbase.js";
|
|
import DropdownBase from "shared/components/dropdownbase.js";
|
|
import "shared/components/icons.js";
|
|
import "shared/components/icons.js";
|
|
import { __ } from "i18n";
|
|
import { __ } from "i18n";
|
|
@@ -26,8 +26,6 @@ export default class Dropdown extends DropdownBase {
|
|
this.icon_classes = "fa fa-bars";
|
|
this.icon_classes = "fa fa-bars";
|
|
this.items = [];
|
|
this.items = [];
|
|
this.id = u.getUniqueId();
|
|
this.id = u.getUniqueId();
|
|
- this.addEventListener("hidden.bs.dropdown", () => this.onHidden());
|
|
|
|
- this.addEventListener("keyup", (ev) => this.handleKeyUp(ev));
|
|
|
|
}
|
|
}
|
|
|
|
|
|
render() {
|
|
render() {
|
|
@@ -52,25 +50,48 @@ export default class Dropdown extends DropdownBase {
|
|
this.initArrowNavigation();
|
|
this.initArrowNavigation();
|
|
}
|
|
}
|
|
|
|
|
|
- onHidden() {
|
|
|
|
- this.navigator?.disable();
|
|
|
|
|
|
+ connectedCallback() {
|
|
|
|
+ super.connectedCallback();
|
|
|
|
+ this.registerEvents();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ disconnectedCallback() {
|
|
|
|
+ this.removeEventListener("keydown", this.onGlobalKeyDown);
|
|
|
|
+ this.disableArrowNavigation();
|
|
|
|
+ super.disconnectedCallback();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ registerEvents() {
|
|
|
|
+ this.onGlobalKeyDown = (ev) => this.#onGlobalKeyDown(ev);
|
|
|
|
+ this.addEventListener("hide.bs.dropdown", () => this.onDropdownHide());
|
|
|
|
+ this.addEventListener("keydown", this.onGlobalKeyDown);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ onDropdownHide() {
|
|
|
|
+ this.disableArrowNavigation();
|
|
}
|
|
}
|
|
|
|
|
|
initArrowNavigation() {
|
|
initArrowNavigation() {
|
|
if (!this.navigator) {
|
|
if (!this.navigator) {
|
|
const options = /** @type DOMNavigatorOptions */ ({
|
|
const options = /** @type DOMNavigatorOptions */ ({
|
|
- "selector": ".dropdown-item",
|
|
|
|
- "onSelected": (el) => el.focus(),
|
|
|
|
|
|
+ selector: ".dropdown-menu li",
|
|
|
|
+ onSelected: (el) => el.focus(),
|
|
});
|
|
});
|
|
this.navigator = new DOMNavigator(/** @type HTMLElement */ (this.menu), options);
|
|
this.navigator = new DOMNavigator(/** @type HTMLElement */ (this.menu), options);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ disableArrowNavigation() {
|
|
|
|
+ this.navigator?.disable();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param {KeyboardEvent} [ev]
|
|
|
|
+ */
|
|
enableArrowNavigation(ev) {
|
|
enableArrowNavigation(ev) {
|
|
- if (ev) {
|
|
|
|
- ev.preventDefault();
|
|
|
|
- ev.stopPropagation();
|
|
|
|
- }
|
|
|
|
|
|
+ ev?.preventDefault();
|
|
|
|
+ ev?.stopPropagation();
|
|
|
|
+ this.disableArrowNavigation();
|
|
this.navigator.enable();
|
|
this.navigator.enable();
|
|
this.navigator.select(/** @type HTMLElement */ (this.menu.firstElementChild));
|
|
this.navigator.select(/** @type HTMLElement */ (this.menu.firstElementChild));
|
|
}
|
|
}
|
|
@@ -78,9 +99,25 @@ export default class Dropdown extends DropdownBase {
|
|
/**
|
|
/**
|
|
* @param {KeyboardEvent} ev
|
|
* @param {KeyboardEvent} ev
|
|
*/
|
|
*/
|
|
- handleKeyUp(ev) {
|
|
|
|
- if (ev.key === KEYCODES.DOWN_ARROW && !this.navigator.enabled) {
|
|
|
|
|
|
+ onEnterPressed(ev) {
|
|
|
|
+ ev.preventDefault();
|
|
|
|
+ ev.stopPropagation();
|
|
|
|
+ this.navigator.selected?.querySelector('a')?.click();
|
|
|
|
+ this.dropdown.hide();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param {KeyboardEvent} ev
|
|
|
|
+ */
|
|
|
|
+ #onGlobalKeyDown(ev) {
|
|
|
|
+ if (!this.navigator || !u.isVisible(this)) return;
|
|
|
|
+
|
|
|
|
+ if (ev.key === KEYCODES.ENTER) {
|
|
|
|
+ this.onEnterPressed(ev);
|
|
|
|
+ } else if (ev.key === KEYCODES.DOWN_ARROW && !this.navigator.enabled) {
|
|
this.enableArrowNavigation(ev);
|
|
this.enableArrowNavigation(ev);
|
|
|
|
+ } else if (ev.key === KEYCODES.ESCAPE) {
|
|
|
|
+ this.dropdown.hide();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|