Skip to content

Commit

Permalink
fix(): bug fixes for a better keyboard navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasGysemans committed Apr 25, 2021
1 parent 572221d commit e25a2a7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## [1.1.2] - April 25, 2021

Bug fixes

## [1.1.1] - April 23, 2021

Bug fixes
Expand Down
39 changes: 29 additions & 10 deletions src/JSPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,35 @@ class JSPanel {
}
}
});
this.button.addEventListener("click", (e) => this._togglePanel(e));
this.button.addEventListener("keydown", (e) => this._toggleOnKeyboardEvent(e));
this.button.onclick = (e) => { this._togglePanel(e); };
this.button.onkeydown = (e) => { this._toggleOnKeyboardEvent(e); };
this._insertAfterButton(this.panel);
this.panel.onkeydown = (e) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen())
this._focusInPanel(e);
}
};
// I absolutly want the focus to stay inside (and only INSIDE) the panel :)
// For that, I need to add a keydown event to the button too because
// I want to include it during the keyboard navigation (with Tab)
// So that it's easier for the user to close the panel with his/her keyboard.
this.button.onkeydown = (e) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen()) {
e.preventDefault();
const active_elements = this._getAllActiveItems();
if (active_elements && active_elements[0]) {
if (e.shiftKey === true) {
active_elements[active_elements.length - 2].focus(); // -2 because we don't want to take into account the button once again
}
else {
active_elements[0].focus();
}
}
}
}
};
}
/**
* Following the digital accessibility recommendations for this kind of panels,
Expand Down Expand Up @@ -140,7 +166,7 @@ class JSPanel {
}
/**
* Gets all the active items from the panel if it's open.
* @returns {Array<Element>|null} All the items that have an onclick property.
* @returns {Array<HTMLElement>|null} All the items that have an onclick property.
*/
_getAllActiveItems() {
if (this._isOpen()) {
Expand Down Expand Up @@ -213,7 +239,6 @@ class JSPanel {
else {
const button = this._createEl("button");
button.setAttribute("aria-label", item.title);
button.setAttribute("tabindex", "0");
if ((item.icon && !item.fontawesome_icon) || (item.icon && item.fontawesome_icon)) {
const icon = this._createEl("img", { attributes: [["src", item.icon]] });
button.appendChild(icon);
Expand Down Expand Up @@ -244,12 +269,6 @@ class JSPanel {
item.onclick();
this._closePanel();
});
button.addEventListener("keydown", (e) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen())
this._focusInPanel(e);
}
});
return button;
}
}
Expand Down
46 changes: 34 additions & 12 deletions src/JSPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,38 @@ class JSPanel {
}
}
});
this.button.addEventListener("click", (e) => this._togglePanel(e));
this.button.addEventListener("keydown", (e) => this._toggleOnKeyboardEvent(e));

this.button.onclick = (e) => { this._togglePanel(e) };
this.button.onkeydown = (e) => { this._toggleOnKeyboardEvent(e) };

this._insertAfterButton(this.panel);

this.panel.onkeydown = (e: KeyboardEvent) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen()) this._focusInPanel(e);
}
};

// I absolutly want the focus to stay inside (and only INSIDE) the panel :)
// For that, I need to add a keydown event to the button too because
// I want to include it during the keyboard navigation (with Tab)
// So that it's easier for the user to close the panel with his/her keyboard.
this.button.onkeydown = (e: KeyboardEvent) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen()) {
e.preventDefault();

const active_elements = this._getAllActiveItems();
if (active_elements && active_elements[0]) {
if (e.shiftKey === true) {
active_elements[active_elements.length - 2].focus(); // -2 because we don't want to take into account the button once again
} else {
active_elements[0].focus();
}
}
}
}
};
}

/**
Expand Down Expand Up @@ -192,9 +220,9 @@ class JSPanel {

/**
* Gets all the active items from the panel if it's open.
* @returns {Array<Element>|null} All the items that have an onclick property.
* @returns {Array<HTMLElement>|null} All the items that have an onclick property.
*/
private _getAllActiveItems(): Element[] | null {
private _getAllActiveItems(): HTMLElement[] | null {
if (this._isOpen()) {
const active_elements: HTMLElement[] = Array.from((this.panel as HTMLElement).querySelectorAll("button"));
active_elements.push(this.button as HTMLElement);
Expand Down Expand Up @@ -300,12 +328,6 @@ class JSPanel {
this._closePanel();
});

window.addEventListener("keydown", (e: KeyboardEvent) => {
if (e.key === "Tab" || e.keyCode === 9) {
if (this._isOpen()) this._focusInPanel(e);
}
});

return button;
}
}
Expand All @@ -330,7 +352,7 @@ class JSPanel {
if(index < 0) {
index = all_items.length - 1;
}
(all_items[index] as HTMLElement).focus();
all_items[index].focus();
}
}

Expand Down Expand Up @@ -376,4 +398,4 @@ class JSPanel {
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}
}
}

0 comments on commit e25a2a7

Please sign in to comment.